| /******************************************************************************* |
| * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Johannes Faltermeier - initial API and implementation |
| * Mat Hansen - modifications for Nebula Grid |
| * Christian W. Damus - bugs 527686, 548592 |
| *******************************************************************************/ |
| package org.eclipse.emf.ecp.view.internal.table.nebula.grid; |
| |
| import static java.util.Arrays.asList; |
| import static org.hamcrest.CoreMatchers.notNullValue; |
| import static org.hamcrest.Matchers.greaterThan; |
| import static org.hamcrest.Matchers.hasItem; |
| import static org.hamcrest.Matchers.instanceOf; |
| import static org.hamcrest.Matchers.lessThan; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertThat; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.PrintStream; |
| import java.util.Arrays; |
| import java.util.Set; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EStructuralFeature.Setting; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecp.common.spi.UniqueSetting; |
| import org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditorComparator; |
| import org.eclipse.emf.ecp.edit.spi.swt.table.StringCellEditor; |
| import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; |
| import org.eclipse.emf.ecp.view.spi.context.ViewModelContextDisposeListener; |
| import org.eclipse.emf.ecp.view.spi.context.ViewModelService; |
| import org.eclipse.emf.ecp.view.spi.context.ViewModelServiceProvider; |
| import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener; |
| import org.eclipse.emf.ecp.view.spi.model.VControl; |
| import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference; |
| import org.eclipse.emf.ecp.view.spi.model.VElement; |
| import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference; |
| import org.eclipse.emf.ecp.view.spi.model.VView; |
| import org.eclipse.emf.ecp.view.spi.model.VViewFactory; |
| import org.eclipse.emf.ecp.view.spi.model.VViewPackage; |
| import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption; |
| import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException; |
| import org.eclipse.emf.ecp.view.spi.table.model.DetailEditing; |
| import org.eclipse.emf.ecp.view.spi.table.model.VTableControl; |
| import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference; |
| import org.eclipse.emf.ecp.view.spi.table.nebula.grid.GridControlSWTRenderer; |
| import org.eclipse.emf.ecp.view.spi.table.swt.TableControlSWTRenderer; |
| import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService; |
| import org.eclipse.emf.ecp.view.table.test.common.TableControlHandle; |
| import org.eclipse.emf.ecp.view.table.test.common.TableTestUtil; |
| import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider; |
| import org.eclipse.emf.ecp.view.test.common.swt.spi.DatabindingClassRunner; |
| import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTTestUtil; |
| import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTViewTestHelper; |
| import org.eclipse.emfforms.spi.common.converter.EStructuralFeatureValueConverterService; |
| import org.eclipse.emfforms.spi.common.report.ReportService; |
| import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF; |
| import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport; |
| import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider; |
| import org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener; |
| import org.eclipse.emfforms.spi.core.services.view.RootDomainModelChangeListener; |
| import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService; |
| import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer; |
| import org.eclipse.emfforms.spi.swt.core.EMFFormsNoRendererException; |
| import org.eclipse.emfforms.spi.swt.core.EMFFormsRendererFactory; |
| import org.eclipse.emfforms.spi.swt.core.di.EMFFormsContextProvider; |
| import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell; |
| import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription; |
| import org.eclipse.jface.viewers.CellEditor; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.nebula.jface.gridviewer.GridTableViewer; |
| import org.eclipse.nebula.widgets.grid.Grid; |
| import org.eclipse.nebula.widgets.grid.GridItem; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.SashForm; |
| import org.eclipse.swt.custom.ScrolledComposite; |
| import org.eclipse.swt.custom.StackLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.FrameworkUtil; |
| import org.osgi.framework.ServiceReference; |
| |
| /** |
| * This is a basically a copy of the SWTTable_PTest for the sake of completeness. |
| * |
| * @author Mat Hansen <mhansen@eclipsesource.com> |
| * |
| */ |
| @RunWith(DatabindingClassRunner.class) |
| public class GridTable_PTest { |
| private static String log; |
| private static ServiceReference<EMFFormsRendererFactory> factoryServiceReference; |
| private static EMFFormsRendererFactory rendererFactory; |
| private static PrintStream systemErr; |
| private Shell shell; |
| private EObject domainElement; |
| |
| @BeforeClass |
| public static void beforeClass() { |
| systemErr = System.err; |
| System.setErr(new PrintStreamWrapper(systemErr)); |
| final BundleContext bundleContext = FrameworkUtil.getBundle(GridTable_PTest.class).getBundleContext(); |
| factoryServiceReference = bundleContext.getServiceReference(EMFFormsRendererFactory.class); |
| rendererFactory = bundleContext.getService(factoryServiceReference); |
| } |
| |
| @AfterClass |
| public static void afterClass() { |
| System.setErr(systemErr); |
| final BundleContext bundleContext = FrameworkUtil.getBundle(GridTable_PTest.class).getBundleContext(); |
| bundleContext.ungetService(factoryServiceReference); |
| } |
| |
| @Before |
| public void init() { |
| log = ""; |
| shell = SWTViewTestHelper.createShell(); |
| |
| final EClass eClass = EcoreFactory.eINSTANCE.createEClass(); |
| eClass.getESuperTypes().add(EcorePackage.eINSTANCE.getEClass()); |
| domainElement = eClass; |
| } |
| |
| @After |
| public void after() { |
| if (!log.isEmpty()) { |
| fail("Unexpected log to System.err: " + log); |
| } |
| } |
| |
| @Test |
| public void testUninitializedTableWithoutColumns() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createUninitializedTableWithoutColumns(); |
| // |
| final Control render = SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| assertTrue(Label.class.isInstance(render));// Error label with error text |
| assertEquals("The field domainModelEFeature of the given VFeaturePathDomainModelReference must not be null.", |
| Label.class.cast(render).getText()); |
| } |
| |
| @Test |
| public void testInitializedTableWithoutColumnsAndEmptyReference() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // setup model |
| final EClass createEClass = EcoreFactory.eINSTANCE.createEClass(); |
| createEClass.eUnset(EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| domainElement = createEClass; |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| try { |
| SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| } catch (final NullPointerException e) { |
| fail("Fails without a reference in domain object"); |
| } |
| |
| } |
| |
| @Ignore |
| @Test |
| public void testInitializedTableWithoutColumnsSingleReference() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // setup model |
| final VView view = VViewFactory.eINSTANCE.createView(); |
| view.setRootEClass(VViewPackage.eINSTANCE.getView()); |
| domainElement = view; |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| final VFeaturePathDomainModelReference domainModelReference = VViewFactory.eINSTANCE |
| .createFeaturePathDomainModelReference(); |
| domainModelReference.setDomainModelEFeature(VViewPackage.eINSTANCE.getView_RootEClass()); |
| handle.getTableControl().setDomainModelReference(domainModelReference); |
| |
| try { |
| SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| } catch (final ClassCastException e) { |
| e.printStackTrace(); |
| fail("Fails with single reference in domain object"); |
| } |
| |
| } |
| |
| @Ignore |
| @Test |
| public void testInitializedTableWithoutColumnsEmptySingleReference() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // setup model |
| final VView view = VViewFactory.eINSTANCE.createView(); |
| domainElement = view; |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| final VFeaturePathDomainModelReference domainModelReference = VViewFactory.eINSTANCE |
| .createFeaturePathDomainModelReference(); |
| domainModelReference.setDomainModelEFeature(VViewPackage.eINSTANCE.getView_RootEClass()); |
| handle.getTableControl().setDomainModelReference(domainModelReference); |
| |
| try { |
| SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| } catch (final NullPointerException e) { |
| fail("Fails with empty single reference in domain object"); |
| } |
| |
| } |
| |
| @Test |
| public void testTableWithoutColumns() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| final Control render = SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| assertTrue(render instanceof Composite); |
| |
| // see bug #533262, TableColumnGenerator now includes attributes from super types |
| // if this is not desired the user has to specify the columns in the view model |
| assertEquals(domainElement.eClass().getEAllAttributes().size(), |
| VTableDomainModelReference.class.cast(handle.getTableControl().getDomainModelReference()) |
| .getColumnDomainModelReferences().size()); |
| |
| final Control control = getTable(render); |
| assertTrue(control instanceof Grid); |
| final Grid table = (Grid) control; |
| assertEquals(domainElement.eClass().getEAllAttributes().size() + 1, table.getColumnCount()); |
| } |
| |
| @Test |
| public void testTableWithoutColumnsWithoutViewServices() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| assertTrue(render instanceof Composite); |
| |
| assertEquals(0, VTableDomainModelReference.class.cast(handle.getTableControl().getDomainModelReference()) |
| .getColumnDomainModelReferences().size()); |
| |
| final Control control = getTable(render); |
| assertTrue(control instanceof Grid); |
| final Grid table = (Grid) control; |
| assertEquals(1, table.getColumnCount()); |
| } |
| |
| @Test |
| public void testTableWithTwoColumns() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| final Control render = SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| assertTrue(render instanceof Composite); |
| |
| final Control control = getTable(render); |
| assertTrue(control instanceof Grid); |
| final Grid table = (Grid) control; |
| assertEquals(2 + 1, table.getColumnCount()); |
| |
| } |
| |
| @Test |
| public void testTableWithTwoColumnsWithoutViewServices() throws NoRendererFoundException, |
| NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| assertTrue(render instanceof Composite); |
| |
| final Control control = getTable(render); |
| assertTrue(control instanceof Grid); |
| final Grid table = (Grid) control; |
| assertEquals(2 + 1, table.getColumnCount()); |
| } |
| |
| @Test |
| public void testTableWithTwoColumnsAdd() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = (Grid) getTable(control); |
| assertEquals(1, table.getItemCount()); |
| final EClass eClass = EcoreFactory.eINSTANCE.createEClass(); |
| ((EClass) domainElement).getESuperTypes().add(eClass); |
| assertEquals(2, table.getItemCount()); |
| } |
| |
| @Test |
| public void testTableWithTwoColumnsRemove() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = (Grid) getTable(control); |
| assertEquals(1, table.getItemCount()); |
| final EClass eClass = ((EClass) domainElement).getESuperTypes().get(0); |
| ((EClass) domainElement).getESuperTypes().remove(eClass); |
| assertEquals(0, table.getItemCount()); |
| } |
| |
| @Test |
| public void testTableWithTwoColumnsClear() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| final EClass eClass = EcoreFactory.eINSTANCE.createEClass(); |
| ((EClass) domainElement).getESuperTypes().add(eClass); |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = (Grid) getTable(control); |
| assertEquals(2, table.getItemCount()); |
| ((EClass) domainElement).getESuperTypes().clear(); |
| assertEquals(0, table.getItemCount()); |
| } |
| |
| @Test |
| public void testPanelTableWithTwoColumns() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| final EClass eClass = EcoreFactory.eINSTANCE.createEClass(); |
| ((EClass) domainElement).getESuperTypes().add(eClass); |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| handle.getTableControl().setDetailEditing(DetailEditing.WITH_PANEL); |
| handle.getTableControl().setDetailView(createDetailView()); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), |
| new ViewModelContextWithoutServices(handle.getTableControl())); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| final Control control = Composite.class.cast(render).getChildren()[0]; |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Composite controlComposite = (Composite) ((Composite) control).getChildren()[1]; |
| final SashForm sash = (SashForm) controlComposite.getChildren()[0]; |
| final Composite tableWrapperComposite = (Composite) sash.getChildren()[0]; |
| final Composite tableComposite = (Composite) tableWrapperComposite.getChildren()[0]; |
| final Grid table = (Grid) tableComposite.getChildren()[0]; |
| final ScrolledComposite scrolledComposite = (ScrolledComposite) sash.getChildren()[1]; |
| final Composite parentForECPView = (Composite) scrolledComposite.getChildren()[0]; |
| assertEquals(2, table.getItemCount()); |
| final GridTableViewer tableViewer = GridTestsUtil.getTableViewerFromRenderer(tableRenderer); |
| |
| // no initial selection |
| assertThat("Composite for no selection not present", |
| asList(parentForECPView.getChildren()), hasItem(instanceOf(Composite.class))); |
| final Composite stackComposite = (Composite) parentForECPView.getChildren()[0]; |
| final StackLayout stack = (StackLayout) stackComposite.getLayout(); |
| Composite labelComposite = (Composite) stack.topControl; |
| assertThat("Composite for label not present", labelComposite, notNullValue()); |
| assertThat("Label for no selection not present", |
| asList(labelComposite.getChildren()), hasItem(instanceOf(Label.class))); |
| |
| // single selection |
| tableViewer.setSelection(new StructuredSelection(table.getItem(0).getData())); |
| Composite detailComposite = (Composite) stack.topControl; |
| assertEquals(6, detailComposite.getChildren().length); |
| |
| // multi selection (it's like no selection) |
| tableViewer.setSelection(new StructuredSelection(new Object[] { table.getItem(0).getData(), |
| table.getItem(1).getData() })); |
| detailComposite = (Composite) stack.topControl; |
| assertThat("Label for multi selection not present", |
| asList(labelComposite.getChildren()), hasItem(instanceOf(Label.class))); |
| |
| // select again |
| tableViewer.setSelection(new StructuredSelection(table.getItem(0).getData())); |
| detailComposite = (Composite) stack.topControl; |
| assertEquals(6, detailComposite.getChildren().length); |
| |
| // no selection |
| tableViewer.setSelection(new StructuredSelection()); |
| labelComposite = (Composite) stack.topControl; |
| assertThat("Composite for label not present", labelComposite, notNullValue()); |
| assertThat("Label for no selection not present", |
| asList(labelComposite.getChildren()), hasItem(instanceOf(Label.class))); |
| } |
| |
| @Test |
| public void testTableSorting() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // domain |
| ((EClass) domainElement).getESuperTypes().clear(); |
| final EClass class1 = createEClass("a", "b"); |
| final EClass class2 = createEClass("b", "c"); |
| final EClass class3 = createEClass("c", "a"); |
| ((EClass) domainElement).getESuperTypes().add(class1); |
| ((EClass) domainElement).getESuperTypes().add(class2); |
| ((EClass) domainElement).getESuperTypes().add(class3); |
| |
| // table control |
| final VTableControl tableControl = TableTestUtil.createTableControl(); |
| final VTableDomainModelReference tableDMR = (VTableDomainModelReference) tableControl.getDomainModelReference(); |
| tableDMR.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| tableDMR.getColumnDomainModelReferences().add(createDMR(EcorePackage.eINSTANCE.getENamedElement_Name())); |
| tableDMR.getColumnDomainModelReferences().add( |
| createDMR(EcorePackage.eINSTANCE.getEClassifier_InstanceClassName())); |
| |
| // render |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance(tableControl, |
| new ViewModelContextWithoutServices(tableControl)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = SWTTestUtil.findControl(control, 0, Grid.class); |
| assertGridItemOrder(table, class1, class2, class3); |
| |
| // column 0 is validation column |
| |
| // select column 1 |
| // up |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| // down |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class3, class2, class1); |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| |
| // select column 2 |
| // up |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class3, class1, class2); |
| // down |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class2, class1, class3); |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| } |
| |
| @Test |
| public void testTableSortingWithCellEditor() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // domain |
| ((EClass) domainElement).getESuperTypes().clear(); |
| final EClass class1 = createEClass("a", "b"); |
| final EClass class2 = createEClass("b", "c"); |
| final EClass class3 = createEClass("c", "a"); |
| ((EClass) domainElement).getESuperTypes().add(class1); |
| ((EClass) domainElement).getESuperTypes().add(class2); |
| ((EClass) domainElement).getESuperTypes().add(class3); |
| |
| // table control |
| final VTableControl tableControl = TableTestUtil.createTableControl(); |
| final VTableDomainModelReference tableDMR = (VTableDomainModelReference) tableControl.getDomainModelReference(); |
| tableDMR.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| tableDMR.getColumnDomainModelReferences().add(createDMR(EcorePackage.eINSTANCE.getENamedElement_Name())); |
| tableDMR.getColumnDomainModelReferences().add( |
| createDMR(EcorePackage.eINSTANCE.getEClassifier_InstanceClassName())); |
| |
| // render |
| final TableControlSWTRenderer tableRenderer = createRendererInstanceWithCustomCellEditor(tableControl); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = SWTTestUtil.findControl(control, 0, Grid.class); |
| assertGridItemOrder(table, class1, class2, class3); |
| |
| // column 0 is validation column |
| |
| // select column 1 |
| // up |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class3, class2, class1); |
| // down |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| |
| // select column 2 |
| // up |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class3, class1, class2); |
| // down |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class2, class1, class3); |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(table, class1, class2, class3); |
| } |
| |
| @Test |
| public void gridSorting_autoSortOnEdit() |
| throws EMFFormsNoRendererException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { |
| // domain |
| ((EClass) domainElement).getEStructuralFeatures().clear(); |
| final EAttribute attribute1 = createEAttribute("a", EcorePackage.Literals.ESTRING, 0, 2); |
| final EAttribute attribute2 = createEAttribute("b", EcorePackage.Literals.ESTRING, 0, 11); |
| final EAttribute attribute3 = createEAttribute("c", EcorePackage.Literals.ESTRING, 0, 1); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute1); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute2); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute3); |
| |
| // table control |
| final VTableControl tableControl = TableTestUtil.createTableControl(); |
| final VTableDomainModelReference tableDMR = (VTableDomainModelReference) tableControl.getDomainModelReference(); |
| tableDMR.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_EAttributes()); |
| tableDMR.getColumnDomainModelReferences().add(createDMR(EcorePackage.eINSTANCE.getENamedElement_Name())); |
| tableDMR.getColumnDomainModelReferences().add( |
| createDMR(EcorePackage.eINSTANCE.getETypedElement_UpperBound())); |
| |
| // render |
| shell.open(); |
| // With this shell size, the table will be 77 pixels high and show 2 rows |
| shell.setSize(200, 150); |
| final Control control = SWTViewTestHelper.render(tableControl, domainElement, shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| shell.layout(); |
| final Grid grid = SWTTestUtil.findControl(control, 0, Grid.class); |
| |
| // column 0 is validation column |
| // select column 1 (name) and ascending sorting |
| SWTTestUtil.selectWidget(grid.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(grid, attribute1, attribute2, attribute3); |
| |
| // Change the attribute the sorting is currently applied on and assert that the table was automatically |
| // re-sorted |
| attribute1.setName("z"); |
| SWTTestUtil.waitForUIThread(); |
| assertGridItemOrder(grid, attribute2, attribute3, attribute1); |
| |
| final GridItem sortItem = grid.getItem(2); |
| final int itemLowerEnd = sortItem.getBounds(1).y + sortItem.getBounds(1).height; |
| // Assert that the edited grid item was revealed after it had been moved to the end of the grid. |
| assertThat( |
| "The edited grid item is not fully visible after the auto sort because the grid didn't scroll down.", |
| itemLowerEnd, lessThan(grid.getBounds().height)); |
| assertThat( |
| "The edited grid item is not fully visible after the auto sort because the grid is scrolled too far down.", |
| sortItem.getBounds(1).y, greaterThan(grid.getHeaderHeight())); |
| |
| shell.close(); |
| } |
| |
| /** Tests that the sort indicator of a column is removed when another column is used for sorting. */ |
| @Test |
| public void gridSorting_sortIndicatorReset() |
| throws EMFFormsNoRendererException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { |
| // domain |
| ((EClass) domainElement).getESuperTypes().clear(); |
| final EClass class1 = createEClass("a", "b"); |
| final EClass class2 = createEClass("b", "c"); |
| ((EClass) domainElement).getESuperTypes().add(class1); |
| ((EClass) domainElement).getESuperTypes().add(class2); |
| |
| // table control |
| final VTableControl tableControl = TableTestUtil.createTableControl(); |
| final VTableDomainModelReference tableDMR = (VTableDomainModelReference) tableControl.getDomainModelReference(); |
| tableDMR.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| tableDMR.getColumnDomainModelReferences().add(createDMR(EcorePackage.eINSTANCE.getENamedElement_Name())); |
| tableDMR.getColumnDomainModelReferences().add( |
| createDMR(EcorePackage.eINSTANCE.getEClassifier_InstanceClassName())); |
| |
| // render |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance(tableControl, |
| new ViewModelContextWithoutServices(tableControl)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| final Grid table = SWTTestUtil.findControl(control, 0, Grid.class); |
| assertEquals(SWT.NONE, table.getColumn(1).getSort()); |
| assertEquals(SWT.NONE, table.getColumn(2).getSort()); |
| |
| // column 0 is validation column |
| |
| // select column 1 |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertEquals(SWT.DOWN, table.getColumn(1).getSort()); |
| assertEquals(SWT.NONE, table.getColumn(2).getSort()); |
| |
| // select column 2 -> column 1 indicator should be reset |
| SWTTestUtil.selectWidget(table.getColumn(2)); |
| SWTTestUtil.waitForUIThread(); |
| assertEquals(SWT.NONE, table.getColumn(1).getSort()); |
| assertEquals(SWT.DOWN, table.getColumn(2).getSort()); |
| } |
| |
| private GridControlSWTRenderer createRendererInstanceWithCustomCellEditor(final VTableControl tableControl) |
| throws EMFFormsNoRendererException { |
| final ViewModelContextWithoutServices viewModelContext = new ViewModelContextWithoutServices(tableControl); |
| final EMFFormsContextProvider contextProvider = viewModelContext.getService(EMFFormsContextProvider.class); |
| final IEclipseContext eclipseContext = contextProvider.getContext(); |
| final GridControlSWTRenderer tableControlSWTRenderer = new GridControlSWTRenderer( |
| tableControl, |
| viewModelContext, |
| eclipseContext.get(ReportService.class), |
| eclipseContext.get(EMFFormsDatabindingEMF.class), |
| eclipseContext.get(EMFFormsLabelProvider.class), |
| eclipseContext.get(VTViewTemplateProvider.class), |
| eclipseContext.get(ImageRegistryService.class), |
| eclipseContext.get(EMFFormsEditSupport.class), |
| eclipseContext.get(EStructuralFeatureValueConverterService.class), |
| eclipseContext.get(EMFFormsLocalizationService.class)) { |
| |
| @Override |
| protected CellEditor createCellEditor(EObject tempInstance, EStructuralFeature feature, Composite table) { |
| if (feature == EcorePackage.eINSTANCE.getENamedElement_Name()) { |
| return new CompareCellEditor(table); |
| } |
| return super.createCellEditor(tempInstance, feature, table); |
| } |
| }; |
| tableControlSWTRenderer.init(); |
| return tableControlSWTRenderer; |
| } |
| |
| private static void assertGridItemOrder(Grid table, Object... objects) { |
| assertEquals(objects.length, table.getItemCount()); |
| final GridItem[] items = table.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| assertSame(objects[i], items[i].getData()); |
| } |
| } |
| |
| private static EClass createEClass(String name, String instanceClassName) { |
| final EClass clazz = EcoreFactory.eINSTANCE.createEClass(); |
| clazz.setName(name); |
| clazz.setInstanceClassName(instanceClassName); |
| return clazz; |
| } |
| |
| private static EAttribute createEAttribute(String name, EClassifier classifier, int lowerBound, int upperBound) { |
| final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute(); |
| attribute.setName(name); |
| attribute.setEType(classifier); |
| attribute.setLowerBound(lowerBound); |
| attribute.setUpperBound(upperBound); |
| return attribute; |
| } |
| |
| private static VFeaturePathDomainModelReference createDMR(EAttribute attribute, EReference... refs) { |
| final VFeaturePathDomainModelReference dmr = VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); |
| dmr.setDomainModelEFeature(attribute); |
| dmr.getDomainModelEReferencePath().addAll(Arrays.asList(refs)); |
| return dmr; |
| } |
| |
| private VView createDetailView() { |
| final VView detailView = VViewFactory.eINSTANCE.createView(); |
| final VControl name = VViewFactory.eINSTANCE.createControl(); |
| final VFeaturePathDomainModelReference nameRef = VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); |
| nameRef.setDomainModelEFeature(EcorePackage.eINSTANCE.getENamedElement_Name()); |
| name.setDomainModelReference(nameRef); |
| detailView.getChildren().add(name); |
| final VControl abstr = VViewFactory.eINSTANCE.createControl(); |
| final VFeaturePathDomainModelReference abstractRef = VViewFactory.eINSTANCE |
| .createFeaturePathDomainModelReference(); |
| abstractRef.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_Abstract()); |
| abstr.setDomainModelReference(abstractRef); |
| detailView.getChildren().add(abstr); |
| return detailView; |
| |
| } |
| |
| private Control getTable(Control render) { |
| Composite composite = (Composite) render; |
| composite = (Composite) composite.getChildren()[0]; |
| composite = (Composite) composite.getChildren()[1]; |
| // composite = (Composite) composite.getChildren()[0]; |
| // composite = (Composite) composite.getChildren()[0]; |
| // composite = (Composite) composite.getChildren()[0]; |
| return composite.getChildren()[0]; |
| } |
| |
| private static TableControlHandle createTableWithTwoTableColumns() { |
| final TableControlHandle tableControlHandle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| final VDomainModelReference tableColumn1 = TableTestUtil |
| .createTableColumn(EcorePackage.eINSTANCE.getEClass_Abstract()); |
| |
| tableControlHandle.addFirstTableColumn(tableColumn1); |
| final VDomainModelReference tableColumn2 = TableTestUtil |
| .createTableColumn(EcorePackage.eINSTANCE.getEClass_Abstract()); |
| tableControlHandle.addSecondTableColumn(tableColumn2); |
| return tableControlHandle; |
| } |
| |
| /** |
| * Stub implementation without getting services from ex. point. |
| * |
| * @author jfaltermeier |
| * |
| */ |
| private class ViewModelContextWithoutServices implements ViewModelContext { |
| |
| private final VElement view; |
| private final EMFFormsContextProvider contextProvider; |
| |
| @SuppressWarnings("restriction") |
| ViewModelContextWithoutServices(VElement view) { |
| this.view = view; |
| contextProvider = new org.eclipse.emfforms.internal.swt.core.di.EMFFormsContextProviderImpl(); |
| contextProvider.instantiate(this); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getViewModel() |
| */ |
| @Override |
| public VElement getViewModel() { |
| return view; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getDomainModel() |
| */ |
| @Override |
| public EObject getDomainModel() { |
| return domainElement; |
| } |
| |
| /** |
| * |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#registerViewChangeListener(org.eclipse.emf.ecp.view.spi.model.ModelChangeListener) |
| */ |
| @Override |
| public void registerViewChangeListener(ModelChangeListener modelChangeListener) { |
| // not needed |
| } |
| |
| /** |
| * |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#unregisterViewChangeListener(org.eclipse.emf.ecp.view.spi.model.ModelChangeListener) |
| */ |
| @Override |
| public void unregisterViewChangeListener(ModelChangeListener modelChangeListener) { |
| // not needed |
| } |
| |
| /** |
| * |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#registerDomainChangeListener(org.eclipse.emf.ecp.view.spi.model.ModelChangeListener) |
| */ |
| @Override |
| public void registerDomainChangeListener(ModelChangeListener modelChangeListener) { |
| // not needed |
| } |
| |
| /** |
| * |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#unregisterDomainChangeListener(org.eclipse.emf.ecp.view.spi.model.ModelChangeListener) |
| */ |
| @Override |
| public void unregisterDomainChangeListener(ModelChangeListener modelChangeListener) { |
| // not needed |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#dispose() |
| */ |
| @Override |
| public void dispose() { |
| // not needed |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#hasService(java.lang.Class) |
| */ |
| @Override |
| public <T> boolean hasService(Class<T> serviceType) { |
| if (EMFFormsContextProvider.class.equals(serviceType)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getService(java.lang.Class) |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> T getService(Class<T> serviceType) { |
| if (EMFFormsContextProvider.class.equals(serviceType)) { |
| return (T) contextProvider; |
| } |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getControlsFor(org.eclipse.emf.ecore.EStructuralFeature.Setting) |
| * @deprecated |
| */ |
| @Deprecated |
| @Override |
| public Set<VControl> getControlsFor(Setting setting) { |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getControlsFor(org.eclipse.emf.ecp.common.spi.UniqueSetting) |
| * @deprecated |
| */ |
| @Deprecated |
| @Override |
| public Set<VElement> getControlsFor(UniqueSetting setting) { |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getContextValue(java.lang.String) |
| */ |
| @Override |
| public Object getContextValue(String key) { |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#putContextValue(java.lang.String, |
| * java.lang.Object) |
| */ |
| @Override |
| public void putContextValue(String key, Object value) { |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#registerDisposeListener(org.eclipse.emf.ecp.view.spi.context.ViewModelContextDisposeListener) |
| */ |
| @Override |
| public void registerDisposeListener(ViewModelContextDisposeListener listener) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#addContextUser(java.lang.Object) |
| */ |
| @Override |
| public void addContextUser(Object user) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#removeContextUser(java.lang.Object) |
| */ |
| @Override |
| public void removeContextUser(Object user) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getChildContext(org.eclipse.emf.ecore.EObject, |
| * org.eclipse.emf.ecp.view.spi.model.VElement, org.eclipse.emf.ecp.view.spi.model.VView, |
| * org.eclipse.emf.ecp.view.spi.context.ViewModelService[]) |
| */ |
| @Override |
| public ViewModelContext getChildContext(EObject eObject, VElement parent, VView vView, |
| ViewModelService... viewModelServices) { |
| // TODO Auto-generated method stub |
| final ViewModelContextWithoutServices vmcws = new ViewModelContextWithoutServices(vView); |
| |
| return vmcws; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext#registerEMFFormsContextListener(org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener) |
| */ |
| @Override |
| public void registerEMFFormsContextListener(EMFFormsContextListener contextListener) { |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext#unregisterEMFFormsContextListener(org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener) |
| */ |
| @Override |
| public void unregisterEMFFormsContextListener(EMFFormsContextListener contextListener) { |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getParentContext() |
| */ |
| @Override |
| public ViewModelContext getParentContext() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext#changeDomainModel(org.eclipse.emf.ecore.EObject) |
| */ |
| @Override |
| public void changeDomainModel(EObject newDomainModel) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext#registerRootDomainModelChangeListener(org.eclipse.emfforms.spi.core.services.view.RootDomainModelChangeListener) |
| */ |
| @Override |
| public void registerRootDomainModelChangeListener(RootDomainModelChangeListener rootDomainModelChangeListener) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext#unregisterRootDomainModelChangeListener(org.eclipse.emfforms.spi.core.services.view.RootDomainModelChangeListener) |
| */ |
| @Override |
| public void unregisterRootDomainModelChangeListener( |
| RootDomainModelChangeListener rootDomainModelChangeListener) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getParentVElement() |
| */ |
| @Override |
| public VElement getParentVElement() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.ecp.view.spi.context.ViewModelContext#getChildContext(org.eclipse.emf.ecore.EObject, |
| * org.eclipse.emf.ecp.view.spi.model.VElement, org.eclipse.emf.ecp.view.spi.model.VView, |
| * org.eclipse.emf.ecp.view.spi.context.ViewModelServiceProvider) |
| */ |
| @Override |
| public ViewModelContext getChildContext(EObject eObject, VElement parent, VView vView, |
| ViewModelServiceProvider viewModelServiceProvider) { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void pause() { |
| // do nothing |
| } |
| |
| @Override |
| public void reactivate() { |
| // do nothing |
| } |
| |
| } |
| |
| private static class PrintStreamWrapper extends PrintStream { |
| |
| private final PrintStream printStream; |
| |
| PrintStreamWrapper(PrintStream printStream) { |
| super(new ByteArrayOutputStream()); |
| this.printStream = printStream; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see java.io.PrintStream#print(java.lang.String) |
| */ |
| @Override |
| public void print(String s) { |
| log = log.concat("\n" + s); |
| printStream.print(s + "\n"); |
| } |
| } |
| |
| private static class CompareCellEditor extends StringCellEditor implements ECPCellEditorComparator { |
| |
| CompareCellEditor(Composite table) { |
| super(table); |
| } |
| |
| @Override |
| public int compare(Object e1, Object e2, int direction) { |
| final String value1 = String.class.cast(e1); |
| final String value2 = String.class.cast(e2); |
| int result; |
| if (value1 == null) { |
| result = 1; |
| } else if (value2 == null) { |
| result = -1; |
| } else { |
| result = value1.toString().compareTo(value2.toString()) * -1;// we flip the oder in our custom |
| // comparator |
| } |
| // If descending order, flip the direction |
| if (direction == 2) { |
| result = -result; |
| } |
| return result; |
| } |
| |
| } |
| |
| } |