diff options
author | Michael Heiss | 2014-01-13 13:15:12 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2014-02-26 20:55:16 +0000 |
commit | 7a825d8ba511f89a3194ba43951a58bff0c86f6e (patch) | |
tree | 97b244b1a59619881ae2468ffa6dfdf391205e97 | |
parent | 869ac6e13d99a15a81f24dce9e09b9636008ddde (diff) | |
download | org.eclipse.nebula.widgets.nattable-7a825d8ba511f89a3194ba43951a58bff0c86f6e.tar.gz org.eclipse.nebula.widgets.nattable-7a825d8ba511f89a3194ba43951a58bff0c86f6e.tar.xz org.eclipse.nebula.widgets.nattable-7a825d8ba511f89a3194ba43951a58bff0c86f6e.zip |
Bug 392535 - Cell editor is now managed by the table
*) The active cell editor is now kept as an instance variable inside the
table istself. The table listens to a new layer event
(CellEditorCreatedEvent) in order to be notified about new editors.
*) All references to the ActiveCellEditorRegistry have been changed in
order to use the new API on the table itself.
*) The ActiveCellEditorRegistry have been marked as deprecated in order
to not break the backward compatibility.
*) The ScrollBarHandlerTemplate has been enhanced so that the table can
be set. This is required in order to properly be able to close the
editor when starting to scroll.
Change-Id: If99a1e9ae2f01f12a03fbf4424a5057ead70c77a
Signed-off-by: Michael Heiss <michael.heiss@salomon.at>
12 files changed, 292 insertions, 72 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtilsTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtilsTest.java index 87ed0eb3..dce03ef1 100644 --- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtilsTest.java +++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtilsTest.java @@ -19,7 +19,6 @@ import static org.junit.Assert.assertTrue; import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes; import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate; import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter; -import org.eclipse.nebula.widgets.nattable.edit.ActiveCellEditorRegistry; import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; import org.eclipse.nebula.widgets.nattable.edit.editor.CheckBoxCellEditor; import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor; @@ -46,9 +45,6 @@ public class EditUtilsTest { gridLayerStack = new DummyGridLayerStack(5, 5); selectionLayer = gridLayerStack.getBodyLayer().getSelectionLayer(); natTable = new NatTableFixture(gridLayerStack); - - // Ensure no active editor (static) is present - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); } @Test diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/integration/EditIntegrationTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/integration/EditIntegrationTest.java index 7d153670..11f7b3a1 100644 --- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/integration/EditIntegrationTest.java +++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/integration/EditIntegrationTest.java @@ -30,6 +30,7 @@ import org.eclipse.nebula.widgets.nattable.data.validate.IDataValidator; import org.eclipse.nebula.widgets.nattable.edit.ActiveCellEditorRegistry; import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; import org.eclipse.nebula.widgets.nattable.edit.command.EditCellCommand; +import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils; import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditBindings; import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration; import org.eclipse.nebula.widgets.nattable.edit.editor.CheckBoxCellEditor; @@ -64,7 +65,6 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; -import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -83,9 +83,6 @@ public class EditIntegrationTest { public void setup() { gridLayerStack = new DummyGridLayerStack(5, 5); natTable = new NatTableFixture(gridLayerStack); - - // Ensure no active editor (static) is present - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); } @Test @@ -93,7 +90,7 @@ public class EditIntegrationTest { ILayerCell cell = natTable.getCellByPosition(4, 4); natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); } @Test @@ -103,7 +100,7 @@ public class EditIntegrationTest { ILayerCell cell = natTable.getCellByPosition(4, 4); natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); - ICellEditor cellEditor = ActiveCellEditorRegistry.getActiveCellEditor(); + ICellEditor cellEditor = natTable.getActiveCellEditor(); assertNotNull(cellEditor); assertTrue(cellEditor instanceof TextCellEditor); TextCellEditor textCellEditor = (TextCellEditor) cellEditor; @@ -126,12 +123,12 @@ public class EditIntegrationTest { natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), natTable.getCellByPosition(4, COLUMN_HEADER_ROW_COUNT + 2))); - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNotNull(natTable.getActiveCellEditor()); natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), natTable.getCellByPosition(4, COLUMN_HEADER_ROW_COUNT + 3))); - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); - assertFalse(ActiveCellEditorRegistry.getActiveCellEditor().isClosed()); + assertNotNull(natTable.getActiveCellEditor()); + assertFalse(natTable.getActiveCellEditor().isClosed()); } @Test @@ -141,16 +138,16 @@ public class EditIntegrationTest { ILayerCell cell = natTable.getCellByPosition(4, 4); natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); assertEquals(new Rectangle(340, 80, 99, 19), - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().getBounds()); + natTable.getActiveCellEditor().getEditorControl().getBounds()); natTable.doCommand(new ColumnResizeCommand(natTable, 2, 110)); assertEquals(new Rectangle(340, 80, 99, 19), - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().getBounds()); - - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().notifyListeners( + natTable.getActiveCellEditor().getEditorControl().getBounds()); + + natTable.getActiveCellEditor().getEditorControl().notifyListeners( SWT.FocusOut, null); //ActiveCellEditor should be closed if a ColumnResizeCommand is executed and the editor loses focus - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); } @Test @@ -174,14 +171,14 @@ public class EditIntegrationTest { // Column index 0 never valid natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); - assertFalse(ActiveCellEditorRegistry.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); + assertFalse(natTable.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); cell = natTable.getCellByPosition(2, 1); assertEquals("Col: 2, Row: 1", cell.getDataValue()); // Column index 1 always valid natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); - assertTrue(ActiveCellEditorRegistry.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); + assertTrue(natTable.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); } @Test @@ -194,7 +191,7 @@ public class EditIntegrationTest { natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); // Press tab - 3 times - Text textControl = ((Text) ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); + Text textControl = ((Text) natTable.getActiveCellEditor().getEditorControl()); textControl.notifyListeners(SWT.Traverse, SWTUtils.keyEvent(SWT.TAB)); natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.TAB)); @@ -207,7 +204,7 @@ public class EditIntegrationTest { assertEquals(0, lastSelectedCellPosition.rowPosition); // Verify that no cell is being edited - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); } @Test public void testNavigationUsingTabButtonWhenAnInvalidValueIsEntered() throws InterruptedException { @@ -224,19 +221,19 @@ public class EditIntegrationTest { // Column position 1 - originally valid natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); - assertTrue(ActiveCellEditorRegistry.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); + assertTrue(natTable.getActiveCellEditor().validateCanonicalValue(cell.getDataValue())); // Set an invalid value in cell - AA - Text textControl = ((Text) ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); + Text textControl = ((Text) natTable.getActiveCellEditor().getEditorControl()); textControl.setText("AA"); - assertEquals("AA", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); - assertFalse(ActiveCellEditorRegistry.getActiveCellEditor().validateCanonicalValue( - ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue())); + assertEquals("AA", natTable.getActiveCellEditor().getCanonicalValue()); + assertFalse(natTable.getActiveCellEditor().validateCanonicalValue( + natTable.getActiveCellEditor().getCanonicalValue())); // Press tab textControl.notifyListeners(SWT.Traverse, SWTUtils.keyEvent(SWT.TAB)); - assertEquals(textControl, ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); - assertEquals("AA", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertEquals(textControl, natTable.getActiveCellEditor().getEditorControl()); + assertEquals("AA", natTable.getActiveCellEditor().getCanonicalValue()); } @Test @@ -247,8 +244,8 @@ public class EditIntegrationTest { natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEventWithChar('A')); // Verify edit mode - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); - assertEquals("A", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertNotNull(natTable.getActiveCellEditor()); + assertEquals("A", natTable.getActiveCellEditor().getCanonicalValue()); } @Test @@ -263,28 +260,28 @@ public class EditIntegrationTest { // Enter 'A' in the cell natTable.doCommand(new SelectCellCommand(natTable, 1, 1, false, false)); natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEventWithChar('A')); - assertEquals("A", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); - assertFalse(ActiveCellEditorRegistry.getActiveCellEditor().validateCanonicalValue( - ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue())); + assertEquals("A", natTable.getActiveCellEditor().getCanonicalValue()); + assertFalse(natTable.getActiveCellEditor().validateCanonicalValue( + natTable.getActiveCellEditor().getCanonicalValue())); // Press 'Enter' - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); + natTable.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); // Value not committed - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); - assertEquals("A", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertNotNull(natTable.getActiveCellEditor().getEditorControl()); + assertEquals("A", natTable.getActiveCellEditor().getCanonicalValue()); // Enter a valid value - 'C' natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEventWithChar('C')); - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); - assertEquals("C", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertNotNull(natTable.getActiveCellEditor().getEditorControl()); + assertEquals("C", natTable.getActiveCellEditor().getCanonicalValue()); // Press 'Enter' again - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); + natTable.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); // Value committed and editor closed assertEquals("C", natTable.getCellByPosition(1, 1).getDataValue()); - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); } @Test @@ -331,14 +328,14 @@ public class EditIntegrationTest { SWTUtils.pressCharKey('A', natTable); // Verify edit mode - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); - assertEquals("A", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertNotNull(natTable.getActiveCellEditor()); + assertEquals("A", natTable.getActiveCellEditor().getCanonicalValue()); // Press ESC - SWTUtils.pressKeyOnControl(SWT.ESC, ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl()); + SWTUtils.pressKeyOnControl(SWT.ESC, natTable.getActiveCellEditor().getEditorControl()); // Verify state - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); assertEquals("Col: 1, Row: 1", natTable.getDataValueByPosition(1, 1)); } @@ -376,10 +373,10 @@ public class EditIntegrationTest { // Click - expand combo SWTUtils.leftClick(startX + 10, startY + 10, SWT.NONE, natTable); - NatCombo combo = (NatCombo) ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl(); + NatCombo combo = (NatCombo) natTable.getActiveCellEditor().getEditorControl(); assertNotNull(combo); - assertTrue(ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue() instanceof PricingTypeBean); - assertEquals("MN", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue().toString()); + assertTrue(natTable.getActiveCellEditor().getCanonicalValue() instanceof PricingTypeBean); + assertEquals("MN", natTable.getActiveCellEditor().getCanonicalValue().toString()); // Click - expand select value 'Automatic' combo.select(1); @@ -387,7 +384,7 @@ public class EditIntegrationTest { assertTrue(natTable.getDataValueByPosition(columnPosition, rowPosition) instanceof PricingTypeBean); assertEquals("AT", natTable.getDataValueByPosition(columnPosition, rowPosition).toString()); - assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNull(natTable.getActiveCellEditor()); } @Test @@ -420,8 +417,8 @@ public class EditIntegrationTest { natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.F2)); // Verify edit mode - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); - assertEquals("Col: 1, Row: 1", ActiveCellEditorRegistry.getActiveCellEditor().getCanonicalValue()); + assertNotNull(natTable.getActiveCellEditor()); + assertEquals("Col: 1, Row: 1", natTable.getActiveCellEditor().getCanonicalValue()); //verify that inline editing is used and not dialog assertTrue("No InlineCellEditEvent fired", inlineFired[0]); @@ -450,9 +447,9 @@ public class EditIntegrationTest { natTable.doCommand(new SelectCellCommand(natTable, 1, 1, false, false)); natTable.notifyListeners(SWT.KeyDown, SWTUtils.keyEventWithChar('C')); - assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertNotNull(natTable.getActiveCellEditor()); - ActiveCellEditorRegistry.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); + natTable.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); assertEquals("C", dataProvider.getDataValue(0, 0)); assertEquals("C", dataProvider.getDataValue(0, 1)); @@ -460,6 +457,77 @@ public class EditIntegrationTest { assertEquals("C", dataProvider.getDataValue(1, 1)); } + /** + * Test case that ensures that the active editor is also available via the {@linkplain ActiveCellEditorRegistry}. + * <p> + * Ensures that the backward compatibility is not broken. + * </p> + */ + @Test + public void testEditorRegisteredInActiveCellEditorRegistry() { + natTable.enableEditingOnAllCells(); + + ILayerCell cell = natTable.getCellByPosition(4, 4); + natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); + + assertNotNull(natTable.getActiveCellEditor()); + assertNotNull(ActiveCellEditorRegistry.getActiveCellEditor()); + assertEquals(natTable.getActiveCellEditor(),ActiveCellEditorRegistry.getActiveCellEditor()); + + // Close the editor again + natTable.getActiveCellEditor().getEditorControl().notifyListeners(SWT.KeyDown, SWTUtils.keyEvent(SWT.CR)); + assertNull(natTable.getActiveCellEditor()); + assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + } + + /** + * Test case that ensures that an editor, which is committed through the {@linkplain EditUtils}, is also removed + * from the table. + * <p> + * Ensures that the backward compatibility is not broken. + * </p> + */ + @Test + public void testEditorRemovedWhenCommitted() { + natTable.enableEditingOnAllCells(); + + ILayerCell cell = natTable.getCellByPosition(4, 4); + natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); + + Text editor = (Text) natTable.getActiveCellEditor().getEditorControl(); + editor.setText("A"); + + // Close the again + EditUtils.commitAndCloseActiveEditor(); + + // check if value is saved and editor is gone + assertEquals("A",natTable.getCellByPosition(4, 4).getDataValue()); + assertNull(natTable.getActiveCellEditor()); + assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + } + + /** + * Test case that ensures that an editor, which is closed via API, is also removed + * from the table. + * <p> + * Ensures that the backward compatibility is not broken. + * </p> + */ + @Test + public void testEditorRemovedWhenClosed() { + natTable.enableEditingOnAllCells(); + + ILayerCell cell = natTable.getCellByPosition(4, 4); + natTable.doCommand(new EditCellCommand(natTable, natTable.getConfigRegistry(), cell)); + + // close the editor + ActiveCellEditorRegistry.getActiveCellEditor().close(); + + // check if editor is gone + assertNull(natTable.getActiveCellEditor()); + assertNull(ActiveCellEditorRegistry.getActiveCellEditor()); + } + // *** Convenience methods ***. // Mostly code from the EditableGridExample. // The sane fixtures are used to ensure that the example keeps working without fail @@ -507,10 +575,5 @@ public class EditIntegrationTest { }; } - @After - public void clearStaticEditor() { - ActiveCellEditorRegistry.unregisterActiveCellEditor(); - } - } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java index 0d1b3104..575d1ce2 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java @@ -31,7 +31,9 @@ import org.eclipse.nebula.widgets.nattable.conflation.IEventConflater; import org.eclipse.nebula.widgets.nattable.conflation.VisualChangeEventConflater; import org.eclipse.nebula.widgets.nattable.coordinate.Range; import org.eclipse.nebula.widgets.nattable.edit.ActiveCellEditorRegistry; +import org.eclipse.nebula.widgets.nattable.edit.CellEditorCreatedEvent; import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils; +import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor; import org.eclipse.nebula.widgets.nattable.grid.command.ClientAreaResizeCommand; import org.eclipse.nebula.widgets.nattable.grid.command.InitializeGridCommand; import org.eclipse.nebula.widgets.nattable.layer.ILayer; @@ -47,6 +49,7 @@ import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter; import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter; import org.eclipse.nebula.widgets.nattable.painter.layer.NatLayerPainter; import org.eclipse.nebula.widgets.nattable.persistence.IPersistable; +import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; import org.eclipse.nebula.widgets.nattable.selection.event.CellSelectionEvent; import org.eclipse.nebula.widgets.nattable.style.theme.ThemeConfiguration; import org.eclipse.nebula.widgets.nattable.style.theme.ThemeManager; @@ -73,6 +76,7 @@ import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; @@ -124,10 +128,10 @@ public class NatTable extends Canvas implements ILayer, PaintListener, IClientAr public void handleEvent(Event event) { //as resizing doesn't cause the current active editor to loose focus //we are closing the current active editor manually - if (!EditUtils.commitAndCloseActiveEditor()) { + if (!commitAndCloseActiveCellEditor()) { //if committing didn't work out we need to perform a hard close //otherwise the state of the table would be unstale - ActiveCellEditorRegistry.getActiveCellEditor().close(); + getActiveCellEditor().close(); } } }; @@ -142,6 +146,12 @@ public class NatTable extends Canvas implements ILayer, PaintListener, IClientAr * The {@link ThemeManager} that is used to switch {@link ThemeConfiguration}s at runtime. */ private ThemeManager themeManager; + + /** + * The active cell editor or {@code null} if there is no one. + */ + private ICellEditor activeCellEditor; + public NatTable(Composite parent) { this(parent, DEFAULT_STYLE_OPTIONS); @@ -530,6 +540,25 @@ public class NatTable extends Canvas implements ILayer, PaintListener, IClientAr re.printStackTrace(); } } + + if (event instanceof CellEditorCreatedEvent) { + CellEditorCreatedEvent editorEvent = (CellEditorCreatedEvent) event; + activeCellEditor = editorEvent.getEditor(); + Control editorControl = activeCellEditor.getEditorControl(); + if (editorControl != null && !editorControl.isDisposed()) { + editorControl.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + activeCellEditor = null; + ActiveCellEditorRegistry.unregisterActiveCellEditor(); + } + }); + } else { + activeCellEditor = null; + } + ActiveCellEditorRegistry.registerActiveCellEditor(activeCellEditor); + } } @@ -916,4 +945,31 @@ public class NatTable extends Canvas implements ILayer, PaintListener, IClientAr doCommand(new VisualRefreshCommand()); } + // Editor + /** + * Returns the active cell editor that is currently open or {@code null} if + * there is no editor active. + * + * @return the active editor or {@code null} + */ + public ICellEditor getActiveCellEditor() { + return activeCellEditor; + } + + /** + * Checks if there is an active cell editor registered. If there is one, it is + * tried to commit the value that is currently entered there. + * + * @return <code>false</code> if there is an open editor that can not be + * committed because of conversion/validation errors, + * <code>true</code> if there is no active open editor or it could + * be closed after committing the value. + */ + public boolean commitAndCloseActiveCellEditor() { + if (activeCellEditor != null) { + return activeCellEditor.commit(MoveDirectionEnum.NONE, true); + } + return true; + } + } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/ActiveCellEditorRegistry.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/ActiveCellEditorRegistry.java index 88f55419..647bada4 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/ActiveCellEditorRegistry.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/ActiveCellEditorRegistry.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.nebula.widgets.nattable.edit; +import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor; /** @@ -37,8 +38,15 @@ import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor; * * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=392535">bug 392535</a> * + * @deprecated Storing the editor in a global registry has certain drawbacks as outlined + * in the documentation and the bug report. In order to resolve that the active editor + * is now an instance field of the table. The methods provided in here to register + * or retrieve the editor are available on the {@linkplain NatTable table} itself. + * Therefore this registry is obsolete and should not be used any more. + * * @author Dirk Fauth */ +@Deprecated public class ActiveCellEditorRegistry { /** @@ -49,25 +57,36 @@ public class ActiveCellEditorRegistry { /** * Register the given {@link ICellEditor} as the current active one. + * + * @deprecated replaced by firing the {@linkplain CellEditorCreatedEvent} + * * @param editor The editor that should be registered as the current * active one. */ + @Deprecated public static void registerActiveCellEditor(ICellEditor editor) { activeCellEditor = editor; } /** * Will unregister the current active cell editor if there is one. + * + * @deprecated The explicit unregistering is not needed any more. + * The instance will automatically be set to {@code null} if the editor + * gets disposed. */ + @Deprecated public static void unregisterActiveCellEditor() { activeCellEditor = null; } /** + * @deprecated replaced by {@linkplain NatTable#getActiveCellEditor()}. * * @return The current active {@link ICellEditor} or <code>null</code> if * there is none. */ + @Deprecated public static ICellEditor getActiveCellEditor() { return activeCellEditor; } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/CellEditorCreatedEvent.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/CellEditorCreatedEvent.java new file mode 100644 index 00000000..f0038b57 --- /dev/null +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/CellEditorCreatedEvent.java @@ -0,0 +1,57 @@ +package org.eclipse.nebula.widgets.nattable.edit;
+
+import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * The {@code CellEditorCreatedEvent} is fired by the
+ * {@linkplain EditController} whenever a {@linkplain ICellEditor editor} has been
+ * created.
+ * <p>
+ * Please keep in mind that there is no event fired when the editor is
+ * destroyed. Clients should associate a {@linkplain DisposeListener dispose
+ * listener} to the {@linkplain ICellEditor#getEditorControl() editor widget} to
+ * be informed whenever the editor get destroyed.
+ * </p>
+ * <p>
+ * This event is typically consumed by the {@code NatTable} itself to keep track
+ * of the active editor. Any other layer may also consume this event to do
+ * whatever necessary.
+ * </p>
+ */
+public class CellEditorCreatedEvent implements ILayerEvent {
+
+ private final ICellEditor editor;
+
+ /**
+ * Creates a new event passing the created editor
+ *
+ * @param editor
+ * the new editor
+ */
+ public CellEditorCreatedEvent(ICellEditor editor) {
+ this.editor = editor;
+ }
+
+ @Override
+ public boolean convertToLocal(ILayer localLayer) {
+ return true; // no conversion needed
+ }
+
+ @Override
+ public ILayerEvent cloneEvent() {
+ return this; // cloning not needed
+ }
+
+ /**
+ * Returns the editor associated with this event.
+ *
+ * @return the created editor
+ */
+ public ICellEditor getEditor() {
+ return editor;
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/EditController.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/EditController.java index f998e7af..23ecd469 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/EditController.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/EditController.java @@ -105,7 +105,7 @@ public class EditController { //because of the strange behaviour on Mac OS where a control loses focus //if its bounds are set cellEditor.addEditorControlListeners(); - ActiveCellEditorRegistry.registerActiveCellEditor(cellEditor); + layer.fireLayerEvent(new CellEditorCreatedEvent(cellEditor)); } } else { diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtils.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtils.java index d140eef0..146c117a 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtils.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/command/EditUtils.java @@ -15,6 +15,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes; import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; import org.eclipse.nebula.widgets.nattable.config.IEditableRule; @@ -205,10 +206,15 @@ public class EditUtils { /** * Checks if there is an active editor registered. If there is one, it is tried to * commit the value that is currently entered there. + * + * @deprecated Has been replaced by {@link NatTable#commitAndCloseActiveCellEditor()}. The active editor is now managed + * by the table itself. Therefore the static helpers to access the editor should not be used any more. + * * @return <code>false</code> if there is an open editor that can not be committed * because of conversion/validation errors, <code>true</code> if there is * no active open editor or it could be closed after committing the value. */ + @Deprecated public static boolean commitAndCloseActiveEditor() { ICellEditor activeCellEditor = ActiveCellEditorRegistry.getActiveCellEditor(); if (activeCellEditor != null) { diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java index c261f22d..dfe73f5e 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java @@ -21,7 +21,6 @@ import org.eclipse.nebula.widgets.nattable.data.convert.ConversionFailedExceptio import org.eclipse.nebula.widgets.nattable.data.convert.IDisplayConverter; import org.eclipse.nebula.widgets.nattable.data.validate.IDataValidator; import org.eclipse.nebula.widgets.nattable.data.validate.ValidationFailedException; -import org.eclipse.nebula.widgets.nattable.edit.ActiveCellEditorRegistry; import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; import org.eclipse.nebula.widgets.nattable.edit.EditConfigHelper; import org.eclipse.nebula.widgets.nattable.edit.ICellEditHandler; @@ -385,8 +384,6 @@ public abstract class AbstractCellEditor implements ICellEditor { if (editorControl != null && !editorControl.isDisposed()) { editorControl.dispose(); } - - ActiveCellEditorRegistry.unregisterActiveCellEditor(); } @Override diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/ConfigurableModeEventHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/ConfigurableModeEventHandler.java index e6f7224d..20a0cd74 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/ConfigurableModeEventHandler.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/ConfigurableModeEventHandler.java @@ -12,7 +12,6 @@ package org.eclipse.nebula.widgets.nattable.ui.mode; import org.eclipse.nebula.widgets.nattable.NatTable; -import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils; import org.eclipse.nebula.widgets.nattable.ui.NatEventData; import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; import org.eclipse.nebula.widgets.nattable.ui.action.IKeyAction; @@ -44,7 +43,7 @@ public class ConfigurableModeEventHandler extends AbstractModeEventHandler { @Override public void mouseDown(MouseEvent event) { - if (EditUtils.commitAndCloseActiveEditor()) { + if (natTable.commitAndCloseActiveCellEditor()) { IMouseAction mouseDownAction = natTable.getUiBindingRegistry().getMouseDownAction(event); if (mouseDownAction != null) { event.data = NatEventData.createInstanceFromEvent(event); diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/MouseModeEventHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/MouseModeEventHandler.java index 6ef4a1e9..f6b4671a 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/MouseModeEventHandler.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/ui/mode/MouseModeEventHandler.java @@ -11,7 +11,6 @@ package org.eclipse.nebula.widgets.nattable.ui.mode; import org.eclipse.nebula.widgets.nattable.NatTable; -import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils; import org.eclipse.nebula.widgets.nattable.ui.NatEventData; import org.eclipse.nebula.widgets.nattable.ui.action.DragModeEventHandler; import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; @@ -60,7 +59,7 @@ public class MouseModeEventHandler extends AbstractModeEventHandler { if (singleClickAction != null) { //convert/validate/commit/close possible open editor //needed in case of conversion/validation errors to cancel any action - if (EditUtils.commitAndCloseActiveEditor()) { + if (natTable.commitAndCloseActiveCellEditor()) { if (doubleClickAction != null && (isActionExclusive(singleClickAction) || isActionExclusive(doubleClickAction))) { //If a doubleClick action is registered and either the single click or the double @@ -129,7 +128,7 @@ public class MouseModeEventHandler extends AbstractModeEventHandler { @Override public synchronized void mouseMove(MouseEvent event) { if (mouseDown && dragMode != null) { - if (EditUtils.commitAndCloseActiveEditor()) { + if (natTable.commitAndCloseActiveCellEditor()) { dragMode.mouseDown(natTable, initialMouseDownEvent); switchMode(new DragModeEventHandler(getModeSupport(), natTable, dragMode, this, initialMouseDownEvent)); } @@ -150,7 +149,7 @@ public class MouseModeEventHandler extends AbstractModeEventHandler { private void executeClickAction(IMouseAction action, MouseEvent event) { //convert/validate/commit/close possible open editor //needed in case of conversion/validation errors to cancel any action - if (EditUtils.commitAndCloseActiveEditor()) { + if (natTable.commitAndCloseActiveCellEditor()) { if (action != null && event != null) { event.data = NatEventData.createInstanceFromEvent(event); action.run(natTable, event); diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ScrollBarHandlerTemplate.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ScrollBarHandlerTemplate.java index 8d9fce3e..d2f17383 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ScrollBarHandlerTemplate.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ScrollBarHandlerTemplate.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.eclipse.nebula.widgets.nattable.viewport; -import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils; +import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; import org.eclipse.swt.SWT; @@ -47,6 +47,14 @@ public abstract class ScrollBarHandlerTemplate implements Listener { */ private boolean globalHandle = true; + /** + * The table control of this scroll bar handler. + * <p> + * Required in order to close the active editor when the user starts to scroll + * </p> + */ + private NatTable table; + public ScrollBarHandlerTemplate(ViewportLayer viewportLayer, IScroller<?> scroller) { this.viewportLayer = viewportLayer; this.scrollableLayer = viewportLayer.getScrollableLayer(); @@ -66,7 +74,7 @@ public abstract class ScrollBarHandlerTemplate implements Listener { //Only try to commit and close an possible open editor once //when starting the drag operation. Otherwise the conversion //and validation errors would raise multiple times. - if (!EditUtils.commitAndCloseActiveEditor()) { + if (table != null && !table.commitAndCloseActiveCellEditor()) { this.globalHandle = false; } } @@ -138,6 +146,19 @@ public abstract class ScrollBarHandlerTemplate implements Listener { } /** + * Sets the table belonging to this handler. + * <p> + * The table is required to close the active editor when scrolling. If the + * table is NOT set then the active editor will stay open during the + * scrolling leading to drawing errors. + * </p> + * @param table the table + */ + void setTable(NatTable table) { + this.table = table; + } + + /** * Methods to be implemented by the Horizontal/Vertical scroll bar handlers. * @return */ diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java index a8f5957b..ebbb361c 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java @@ -10,6 +10,7 @@ ******************************************************************************/ package org.eclipse.nebula.widgets.nattable.viewport; +import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.command.ILayerCommand; import org.eclipse.nebula.widgets.nattable.coordinate.PixelCoordinate; import org.eclipse.nebula.widgets.nattable.coordinate.Range; @@ -926,6 +927,9 @@ public class ViewportLayer extends AbstractLayerTransform implements IUniqueInde } hBarListener = new HorizontalScrollBarHandler(this, horizontalScroller); + if(scrollable instanceof NatTable) { + hBarListener.setTable((NatTable)scrollable); + } } if (vBarListener == null && verticalScrollbarEnabled) { ScrollBar vBar = scrollable.getVerticalBar(); @@ -937,6 +941,9 @@ public class ViewportLayer extends AbstractLayerTransform implements IUniqueInde } vBarListener = new VerticalScrollBarHandler(this, verticalScroller); + if(scrollable instanceof NatTable) { + vBarListener.setTable((NatTable)scrollable); + } } handleGridResize(); |