diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java index d2d99021f65..cd473c68c03 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java @@ -1124,11 +1124,11 @@ void destroyItem (TableItem item) { } if (index == itemCount) return; long selection = GTK.gtk_tree_view_get_selection (handle); + System.arraycopy (items, index + 1, items, index, --itemCount - index); + items [itemCount] = null; OS.g_signal_handlers_block_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); GTK.gtk_list_store_remove (modelHandle, item.handle); OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); - System.arraycopy (items, index + 1, items, index, --itemCount - index); - items [itemCount] = null; if (itemCount == 0) resetCustomDraw (); } @@ -2664,11 +2664,11 @@ public void remove (int index) { } if (!disposed) { long selection = GTK.gtk_tree_view_get_selection (handle); + System.arraycopy (items, index + 1, items, index, --itemCount - index); + items [itemCount] = null; OS.g_signal_handlers_block_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); GTK.gtk_list_store_remove (modelHandle, iter); OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); - System.arraycopy (items, index + 1, items, index, --itemCount - index); - items [itemCount] = null; } OS.g_free (iter); } @@ -2703,20 +2703,17 @@ public void remove (int start, int end) { long selection = GTK.gtk_tree_view_get_selection (handle); long iter = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); if (iter == 0) error (SWT.ERROR_NO_HANDLES); - int index = -1; - for (index = start; index <= end; index++) { - if (index == start) GTK.gtk_tree_model_iter_nth_child (modelHandle, iter, 0, index); - TableItem item = items [index]; + GTK.gtk_tree_model_iter_nth_child (modelHandle, iter, 0, start); + for (int index = start; index <= end; index++) { + TableItem item = items [start]; if (item != null && !item.isDisposed ()) item.release (false); + System.arraycopy (items, start + 1, items, start, --itemCount - start); + items [itemCount] = null; OS.g_signal_handlers_block_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); GTK.gtk_list_store_remove (modelHandle, iter); OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); } OS.g_free (iter); - index = end + 1; - System.arraycopy (items, index, items, start, itemCount - index); - for (int i=itemCount-(index-start); i>> 16; + isGtk3 = (gtkMajorVersion == 3); + } + Assume.assumeTrue("Test is only for Gtk3.", isGtk3); + } + + @Before + public void setUp() { + shell = new Shell(); + shell.setMinimumSize(400, 400); + shell.setLayout(new FillLayout()); + } + + @After + public void tearDown() { + if (table != null) { + table.dispose(); + } + if (shell != null) { + shell.dispose(); + } + } + + @Test + public void test_remove_focused_row_remove_one() { + test_remove_focused_row_remove_method_arg(() -> table.remove(0)); + } + + @Test + public void test_remove_focused_row_remove_array() { + test_remove_focused_row_remove_method_arg(() -> table.remove(new int[] { 0 })); + } + + @Test + public void test_remove_focused_row_remove_interval() { + test_remove_focused_row_remove_method_arg(() -> table.remove(0, 0)); + } + + private void test_remove_focused_row_remove_method_arg(Runnable removeRow0) { + table = new Table(shell, SWT.VIRTUAL); + table.setItemCount(2); + table.addListener(SWT.SetData, event -> { + var item = (TableItem) event.item; + item.setText("Item #" + System.identityHashCode(item) + " " + item.toString()); + }); + + shell.pack(); + shell.open(); + + processUiEvents(); + + // set focus on row[0] + table.setFocus(); + + processUiEvents(); + + table.clear(0); + removeRow0.run(); + + processUiEvents(); + } + + private void processUiEvents() { + while (table.getDisplay().readAndDispatch()) { + // continue to next event + } + } + +}