| /******************************************************************************* |
| * 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 |
| * Christian W. Damus - bugs 527740, 544116, 545686, 527686, 547787, 548592 |
| * |
| *******************************************************************************/ |
| package org.eclipse.emf.ecp.view.spi.table.swt; |
| |
| import static java.util.Arrays.asList; |
| import static org.hamcrest.CoreMatchers.instanceOf; |
| import static org.hamcrest.CoreMatchers.is; |
| import static org.hamcrest.CoreMatchers.notNullValue; |
| import static org.hamcrest.Matchers.equalTo; |
| import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
| import static org.hamcrest.Matchers.hasItem; |
| import static org.hamcrest.Matchers.lessThan; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| 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 static org.junit.Assume.assumeThat; |
| import static org.mockito.Matchers.any; |
| import static org.mockito.Matchers.anyBoolean; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.PrintStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.TimeUnit; |
| |
| import javax.inject.Inject; |
| |
| import org.eclipse.core.databinding.observable.map.IObservableMap; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.emf.common.command.BasicCommandStack; |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| 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.EPackage; |
| 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.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecp.common.spi.UniqueSetting; |
| import org.eclipse.emf.ecp.edit.spi.ReferenceService; |
| 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.internal.context.ViewModelContextImpl; |
| 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.ViewModelContextFactory; |
| 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.VDiagnostic; |
| 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.VFeatureDomainModelReferenceSegment; |
| 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.swt.masterdetail.DetailViewCache; |
| import org.eclipse.emf.ecp.view.spi.table.model.DetailEditing; |
| import org.eclipse.emf.ecp.view.spi.table.model.VEnablementConfiguration; |
| 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.model.VTableFactory; |
| import org.eclipse.emf.ecp.view.spi.table.swt.action.AddRowAction; |
| import org.eclipse.emf.ecp.view.spi.table.swt.action.DuplicateRowAction; |
| import org.eclipse.emf.ecp.view.spi.table.swt.action.MoveRowDownAction; |
| import org.eclipse.emf.ecp.view.spi.table.swt.action.MoveRowUpAction; |
| import org.eclipse.emf.ecp.view.spi.table.swt.action.RemoveRowAction; |
| 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.template.style.tableValidation.model.VTTableValidationFactory; |
| import org.eclipse.emf.ecp.view.template.style.tableValidation.model.VTTableValidationStyleProperty; |
| 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.emf.ecp.view.test.common.swt.spi.SWTViewTestHelper.RendererResult; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; |
| import org.eclipse.emfforms.common.Optional; |
| 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.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.SWTDataElementIdHelper; |
| import org.eclipse.emfforms.spi.swt.core.di.EMFFormsContextProvider; |
| import org.eclipse.emfforms.spi.swt.core.di.EMFFormsDIRendererService; |
| import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell; |
| import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription; |
| import org.eclipse.emfforms.view.spi.multisegment.model.VMultiDomainModelReferenceSegment; |
| import org.eclipse.emfforms.view.spi.multisegment.model.VMultisegmentFactory; |
| import org.eclipse.jface.viewers.CellEditor; |
| import org.eclipse.jface.viewers.CellLabelProvider; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.ScrolledComposite; |
| import org.eclipse.swt.custom.StackLayout; |
| import org.eclipse.swt.widgets.Button; |
| 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.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.TableItem; |
| 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; |
| import org.osgi.framework.ServiceRegistration; |
| |
| @SuppressWarnings({ "restriction", "deprecation" }) |
| @RunWith(DatabindingClassRunner.class) |
| public class SWTTable_PTest { |
| private static String log; |
| private static ServiceReference<EMFFormsRendererFactory> factoryServiceReference; |
| private static EMFFormsRendererFactory rendererFactory; |
| private static PrintStream systemErr; |
| private Shell shell; |
| private EObject domainElement; |
| private ComposedAdapterFactory adapterFactory; |
| |
| @BeforeClass |
| public static void beforeClass() { |
| systemErr = System.err; |
| System.setErr(new PrintStreamWrapper(systemErr)); |
| final BundleContext bundleContext = FrameworkUtil.getBundle(SWTTable_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(SWTTable_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; |
| |
| // Add domain element to resource with editing domain |
| final ResourceSet rs = new ResourceSetImpl(); |
| adapterFactory = new ComposedAdapterFactory(new AdapterFactory[] { |
| new ReflectiveItemProviderAdapterFactory(), |
| new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) }); |
| final AdapterFactoryEditingDomain editingDomain = new AdapterFactoryEditingDomain( |
| adapterFactory, new BasicCommandStack(), rs); |
| rs.eAdapters().add(new AdapterFactoryEditingDomain.EditingDomainProvider(editingDomain)); |
| final Resource resource = rs.createResource(URI.createURI("VIRTUAL_URI")); //$NON-NLS-1$ |
| resource.getContents().add(domainElement); |
| } |
| |
| @After |
| public void after() { |
| if (!log.isEmpty()) { |
| fail("Unexpected log to System.err: " + log); |
| } |
| adapterFactory.dispose(); |
| if (shell != null && !shell.isDisposed()) { |
| shell.dispose(); |
| } |
| } |
| |
| @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 testTableActionControlOrderAndSWTData() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| handle.getTableControl().setMoveUpDownDisabled(false); |
| final Control render = SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| assertEquals("UUID#control", render.getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)); |
| assertEquals("UUID#table_moveUp", SWTTestUtil.findControl(render, 0, Button.class) |
| .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)); |
| assertEquals("UUID#table_moveDown", SWTTestUtil.findControl(render, 1, Button.class) |
| .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)); |
| assertEquals("UUID#table_add", SWTTestUtil.findControl(render, 2, Button.class) |
| .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)); |
| assertEquals("UUID#table_remove", SWTTestUtil.findControl(render, 3, Button.class) |
| .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)); |
| } |
| |
| @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 Table); |
| final Table table = (Table) 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 Table); |
| final Table table = (Table) 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 Table); |
| final Table table = (Table) control; |
| assertEquals(2 + 1, table.getColumnCount()); |
| |
| } |
| |
| @Test |
| public void testTableCustomColumnHeading() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| |
| // The custom label is specified by the Enablement Configuration |
| final VEnablementConfiguration config = VTableFactory.eINSTANCE.createEnablementConfiguration(); |
| config.setColumnDomainReference(handle.getTableColumn2()); |
| final String customHeading = "Custom Heading"; |
| config.setName(customHeading); |
| config.setLabel(customHeading); // Normally, the view localization service would supply this |
| handle.getTableControl().getColumnConfigurations().add(config); |
| |
| final Control render = SWTViewTestHelper.render(handle.getTableControl(), domainElement, shell); |
| assumeThat("Expected a composite", render, instanceOf(Composite.class)); |
| |
| final Control control = getTable(render); |
| assumeThat("Expected a Table", control, instanceOf(Table.class)); |
| final Table table = (Table) control; |
| assumeThat("Expected three columns (including validation status)", |
| table.getColumnCount(), is(1 + 2)); |
| |
| final TableColumn column = table.getColumn(2); |
| assertThat("Wrong column heading", column.getText(), is(customHeading)); |
| } |
| |
| @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 Table); |
| final Table table = (Table) 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 Table table = (Table) 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 Table table = (Table) 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 Table table = (Table) 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 Composite tableComposite = (Composite) controlComposite.getChildren()[0]; |
| final Table table = (Table) tableComposite.getChildren()[0]; |
| final ScrolledComposite scrolledComposite = (ScrolledComposite) controlComposite.getChildren()[1]; |
| final Composite parentForECPView = (Composite) scrolledComposite.getChildren()[0]; |
| assertEquals(2, table.getItemCount()); |
| final TableViewer tableViewer = 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).getEStructuralFeatures().clear(); |
| final EAttribute attribute1 = createEAttribute("a2", EcorePackage.Literals.ESTRING, 0, 2); |
| final EAttribute attribute2 = createEAttribute("a10", EcorePackage.Literals.ESTRING, 0, 11); |
| final EAttribute attribute3 = createEAttribute("a10b", 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 |
| 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 Table table = SWTTestUtil.findControl(control, 0, Table.class); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| |
| // column 0 is validation column |
| |
| // select column 1 |
| // ascending |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting |
| // descending |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute3, attribute2, attribute1); |
| assertEquals(SWT.UP, table.getSortDirection()); // SWT.UP := descending sorting |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.NONE, table.getSortDirection()); |
| |
| // select column 2 |
| // ascending |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute3, attribute1, attribute2); |
| assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting |
| // descending |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute2, attribute1, attribute3); |
| assertEquals(SWT.UP, table.getSortDirection()); // SWT.UP := descending sorting |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.NONE, table.getSortDirection()); |
| } |
| |
| @Test |
| public void testTableSortingWithCellEditor() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // 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 |
| 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 Table table = SWTTestUtil.findControl(control, 0, Table.class); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| |
| // column 0 is validation column |
| |
| // select column 1; for this the sort orders are inverted due to the custom cell editor |
| // ascending configured -> results in descending sorting |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute3, attribute2, attribute1); |
| assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting |
| // descending configured -> results in ascending sorting |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.UP, table.getSortDirection()); // SWT.UP := descending sorting |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.NONE, table.getSortDirection()); |
| |
| // select column 2; no custom cell editor registered => should sort normally |
| // ascending |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute3, attribute1, attribute2); |
| assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting |
| // descending |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute2, attribute1, attribute3); |
| assertEquals(SWT.UP, table.getSortDirection()); // SWT.UP := descending sorting |
| // none |
| SWTTestUtil.selectWidget(table.getColumns()[2]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.NONE, table.getSortDirection()); |
| } |
| |
| @Test |
| public void tableSorting_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 Table table = SWTTestUtil.findControl(control, 0, Table.class); |
| |
| // column 0 is validation column |
| // select column 1 (name) and ascending sorting |
| SWTTestUtil.selectWidget(table.getColumns()[1]); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute1, attribute2, attribute3); |
| assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting |
| |
| // Change the attribute the sorting is currently applied on and assert that the table was automatically |
| // re-sorted |
| attribute1.setName("z"); |
| SWTTestUtil.waitForUIThread(); |
| assertTableItemOrder(table, attribute2, attribute3, attribute1); |
| |
| final TableItem sortItem = table.getItem(2); |
| // Calculate the lower item bound relative to the table. We need to add the header height because the y |
| // coordinates of the table items start at the lower end of the header but the header height is included in the |
| // table height. |
| final int itemLowerEnd = sortItem.getBounds().y + sortItem.getBounds().height + table.getHeaderHeight(); |
| // Assert that the edited table item was revealed after it had been moved to the end of the table. |
| assertThat( |
| "The edited table item is not fully visible after the auto sort because the table didn't scroll down.", |
| itemLowerEnd, lessThan(table.getBounds().height)); |
| assertThat( |
| "The edited table item is not fully visible after the auto sort because the table is scrolled too far down.", |
| sortItem.getBounds().y, greaterThanOrEqualTo(0)); |
| } |
| |
| @Test |
| public void testTableReadonlyHidesAddRemoveButtons() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = createTableWithTwoTableColumns(); |
| handle.getTableControl().setReadonly(true); |
| shell.open(); |
| final RendererResult result = SWTViewTestHelper.renderControl(handle.getTableControl(), domainElement, shell); |
| assertTrue(result.getControl().isPresent() && result.getControl().get() instanceof Composite); |
| |
| final TableControlSWTRenderer swtRenderer = TableControlSWTRenderer.class.cast(result.getRenderer()); |
| |
| final Optional<Control> addRowButton = swtRenderer.getControlForAction(AddRowAction.ACTION_ID); |
| final Optional<Control> removeRowButton = swtRenderer.getControlForAction(RemoveRowAction.ACTION_ID); |
| final Optional<Control> duplicateRowButton = swtRenderer.getControlForAction(DuplicateRowAction.ACTION_ID); |
| |
| assertFalse(addRowButton.isPresent()); |
| assertFalse(removeRowButton.isPresent()); |
| assertFalse(duplicateRowButton.isPresent()); |
| |
| } |
| |
| @Test |
| public void testTable_unchangeableFeature_doNotRenderButtons() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model, we need a feature that is unchangeable |
| final VTableControl tableControl = VTableFactory.eINSTANCE.createTableControl(); |
| final VTableDomainModelReference tableDmr = VTableFactory.eINSTANCE.createTableDomainModelReference(); |
| final VFeaturePathDomainModelReference dmr = VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); |
| final VMultiDomainModelReferenceSegment segment = VMultisegmentFactory.eINSTANCE |
| .createMultiDomainModelReferenceSegment(); |
| segment.setDomainModelFeature("eReferences"); |
| dmr.getSegments().add(segment); |
| tableDmr.setDomainModelReference(dmr); |
| final VFeaturePathDomainModelReference columnDmr = VViewFactory.eINSTANCE |
| .createFeaturePathDomainModelReference(); |
| final VFeatureDomainModelReferenceSegment columnSegment = VViewFactory.eINSTANCE |
| .createFeatureDomainModelReferenceSegment(); |
| columnDmr.getSegments().add(columnSegment); |
| segment.getChildDomainModelReferences().add(columnDmr); |
| tableControl.setDomainModelReference(tableDmr); |
| tableControl.setDuplicateDisabled(false); |
| tableControl.setMoveUpDownDisabled(false); |
| tableControl.setAddRemoveDisabled(false); |
| |
| shell.open(); |
| final RendererResult result = SWTViewTestHelper.renderControl(tableControl, domainElement, shell); |
| assertTrue(result.getControl().isPresent() && result.getControl().get() instanceof Composite); |
| |
| final TableControlSWTRenderer swtRenderer = TableControlSWTRenderer.class.cast(result.getRenderer()); |
| |
| final Optional<Control> addRowButton = swtRenderer.getControlForAction(AddRowAction.ACTION_ID); |
| final Optional<Control> removeRowButton = swtRenderer.getControlForAction(RemoveRowAction.ACTION_ID); |
| final Optional<Control> duplicateRowButton = swtRenderer.getControlForAction(DuplicateRowAction.ACTION_ID); |
| final Optional<Control> moveRowUpButton = swtRenderer.getControlForAction(MoveRowUpAction.ACTION_ID); |
| final Optional<Control> moveRowDownButton = swtRenderer.getControlForAction(MoveRowDownAction.ACTION_ID); |
| |
| // If the feature is unchangeable, the buttons that allow to change the feature must not be rendered |
| assertFalse(addRowButton.isPresent()); |
| assertFalse(removeRowButton.isPresent()); |
| assertFalse(duplicateRowButton.isPresent()); |
| assertFalse(moveRowUpButton.isPresent()); |
| assertFalse(moveRowDownButton.isPresent()); |
| } |
| |
| @Test |
| public void testTable_AddRow_WithTableService() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| // mock the TableControlService used to create a new element |
| final TableControlService tableService = mock(TableControlService.class); |
| final EClass newEClass = EcoreFactory.eINSTANCE.createEClass(); |
| newEClass.setName("NewlyAddedEClass"); |
| when(tableService.createNewElement(any(EClass.class), any(EObject.class), any(EStructuralFeature.class))) |
| .thenReturn(Optional.of((EObject) newEClass)); |
| |
| final ViewModelContextWithoutServices context = new ViewModelContextWithoutServices(handle.getTableControl()); |
| context.addService(tableService, TableControlService.class); |
| |
| // Render the table |
| final TableControlSWTRenderer tableRenderer = TableControlSWTRenderer.class |
| .cast(rendererFactory.getRendererInstance( |
| handle.getTableControl(), context)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| final Control control = getTable(render); |
| assertTrue(control instanceof Table); |
| final Table table = (Table) control; |
| |
| // The domain model is initialized with one super type in #init() |
| assertEquals(1, table.getItemCount()); |
| |
| // Add a new row |
| tableRenderer.addRow(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| |
| // Verify that the new EClass was added to the domain object and the table, and that the TableControlService was |
| // used |
| assertEquals(2, table.getItemCount()); |
| assertEquals(2, EClass.class.cast(domainElement).getESuperTypes().size()); |
| assertEquals(newEClass, EClass.class.cast(domainElement).getESuperTypes().get(1)); |
| assertEquals(1, table.getSelectionIndex()); |
| verify(tableService).createNewElement(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| } |
| |
| @Test |
| public void testTable_AddRow_WithTableService_EmptyResult() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| // mock the TableControlService used to create a new element |
| final TableControlService tableService = mock(TableControlService.class); |
| when(tableService.createNewElement(any(EClass.class), any(EObject.class), any(EStructuralFeature.class))) |
| .thenReturn(Optional.<EObject> empty()); |
| |
| final ViewModelContextWithoutServices context = new ViewModelContextWithoutServices(handle.getTableControl()); |
| context.addService(tableService, TableControlService.class); |
| |
| // Render the table |
| final TableControlSWTRenderer tableRenderer = TableControlSWTRenderer.class |
| .cast(rendererFactory.getRendererInstance( |
| handle.getTableControl(), context)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| final Control control = getTable(render); |
| assertTrue(control instanceof Table); |
| final Table table = (Table) control; |
| |
| // The domain model is initialized with one super type in #init() |
| assertEquals(1, table.getItemCount()); |
| |
| // Add a new row |
| tableRenderer.addRow(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| |
| // Verify that the no new EClass was added to the domain object and the table, and that the TableControlService |
| // was used |
| assertEquals(1, table.getItemCount()); |
| assertEquals(1, EClass.class.cast(domainElement).getESuperTypes().size()); |
| verify(tableService).createNewElement(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| } |
| |
| @Test |
| public void testTable_AddRow_WithTableService_NullResult() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| // mock the TableControlService to return null |
| final TableControlService tableService = mock(TableControlService.class); |
| when(tableService.createNewElement(any(EClass.class), any(EObject.class), any(EStructuralFeature.class))) |
| .thenReturn(null); |
| // mock the ReferenceService used to create a new element |
| final EClass newEClass = EcoreFactory.eINSTANCE.createEClass(); |
| newEClass.setName("NewlyAddedEClass"); |
| final ReferenceService referenceService = mock(ReferenceService.class); |
| when(referenceService.addNewModelElements(any(EObject.class), any(EReference.class), anyBoolean())) |
| .thenReturn(Optional.of((EObject) newEClass)); |
| |
| final ViewModelContextWithoutServices context = new ViewModelContextWithoutServices(handle.getTableControl()); |
| context.addService(tableService, TableControlService.class); |
| context.addService(referenceService, ReferenceService.class); |
| |
| // Render the table |
| final TableControlSWTRenderer tableRenderer = TableControlSWTRenderer.class |
| .cast(rendererFactory.getRendererInstance( |
| handle.getTableControl(), context)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| final Control control = getTable(render); |
| assertTrue(control instanceof Table); |
| final Table table = (Table) control; |
| |
| // The domain model is initialized with one super type in #init() |
| assertEquals(1, table.getItemCount()); |
| |
| // Add a new row |
| tableRenderer.addRow(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| |
| // Verify that the new EClass was added although the table service returned null |
| assertEquals(2, table.getItemCount()); |
| assertEquals(2, EClass.class.cast(domainElement).getESuperTypes().size()); |
| assertEquals(1, table.getSelectionIndex()); |
| verify(tableService).createNewElement(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| verify(referenceService).addNewModelElements(domainElement, EcorePackage.eINSTANCE.getEClass_ESuperTypes(), |
| false); |
| } |
| |
| @Test |
| public void testTable_AddRow_WithReferenceService() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| // setup model |
| final TableControlHandle handle = TableTestUtil.createInitializedTableWithoutTableColumns(); |
| |
| // mock the ReferenceService used to create a new element |
| final EClass newEClass = EcoreFactory.eINSTANCE.createEClass(); |
| newEClass.setName("NewlyAddedEClass"); |
| final ReferenceService referenceService = mock(ReferenceService.class); |
| when(referenceService.addNewModelElements(any(EObject.class), any(EReference.class), anyBoolean())) |
| .thenReturn(Optional.of((EObject) newEClass)); |
| |
| final ViewModelContextWithoutServices context = new ViewModelContextWithoutServices(handle.getTableControl()); |
| context.addService(referenceService, ReferenceService.class); |
| |
| // Render the table |
| final TableControlSWTRenderer tableRenderer = TableControlSWTRenderer.class |
| .cast(rendererFactory.getRendererInstance( |
| handle.getTableControl(), context)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| final Control control = getTable(render); |
| assertTrue(control instanceof Table); |
| final Table table = (Table) control; |
| |
| // The domain model is initialized with one super type in #init() |
| assertEquals(1, table.getItemCount()); |
| |
| // Add a new row |
| tableRenderer.addRow(EcorePackage.eINSTANCE.getEClass(), domainElement, |
| EcorePackage.eINSTANCE.getEClass_ESuperTypes()); |
| |
| // Verify that the new EClass was added to the domain object and the table, and that the reference service was |
| // used |
| assertEquals(2, table.getItemCount()); |
| assertEquals(2, EClass.class.cast(domainElement).getESuperTypes().size()); |
| assertEquals(newEClass, EClass.class.cast(domainElement).getESuperTypes().get(1)); |
| assertEquals(1, table.getSelectionIndex()); |
| verify(referenceService).addNewModelElements(domainElement, EcorePackage.eINSTANCE.getEClass_ESuperTypes(), |
| false); |
| } |
| |
| /** |
| * Tests that the table's summary validation icon's tooltip shows validation messages related directly to the |
| * table's reference even if the table style property 'showValidationSummaryTooltip' is false (this is the case by |
| * default). Furthermore, the test checks that validation messages of objects contained in the table's reference are |
| * not shown in this case. |
| * |
| * @throws EMFFormsNoRendererException |
| * @throws NoRendererFoundException |
| * @throws NoPropertyDescriptorFoundExeption |
| */ |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| @Test |
| public void testTable_summaryToolTip_defaultSettings() |
| throws EMFFormsNoRendererException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { |
| // ----- Create Test Model |
| final EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage(); |
| final EClass foo = EcoreFactory.eINSTANCE.createEClass(); |
| foo.setName("Foo"); |
| final EClass bar = EcoreFactory.eINSTANCE.createEClass(); |
| bar.setName("Bar"); |
| ePackage.getEClassifiers().add(foo); |
| ePackage.getEClassifiers().add(bar); |
| |
| final EReference fooToBar = EcoreFactory.eINSTANCE.createEReference(); |
| fooToBar.setContainment(true); |
| fooToBar.setEType(bar); |
| fooToBar.setLowerBound(1); |
| fooToBar.setUpperBound(-1); |
| fooToBar.setName("fooToBar"); |
| foo.getEStructuralFeatures().add(fooToBar); |
| |
| final EAttribute barAttribute = EcoreFactory.eINSTANCE.createEAttribute(); |
| barAttribute.setEType(EcorePackage.Literals.ESTRING); |
| barAttribute.setName("barAttribute"); |
| bar.getEStructuralFeatures().add(barAttribute); |
| barAttribute.setLowerBound(1); |
| barAttribute.setUpperBound(1); |
| // ----- |
| |
| final VTableDomainModelReference tableDmr = VTableFactory.eINSTANCE.createTableDomainModelReference(); |
| final VFeaturePathDomainModelReference featureDmr = VViewFactory.eINSTANCE |
| .createFeaturePathDomainModelReference(); |
| featureDmr.setDomainModelEFeature(fooToBar); |
| tableDmr.setDomainModelReference(featureDmr); |
| |
| final VTableControl tableControl = VTableFactory.eINSTANCE.createTableControl(); |
| tableControl.setDomainModelReference(tableDmr); |
| |
| domainElement = EcoreUtil.create(foo); |
| final VView view = VViewFactory.eINSTANCE.createView(); |
| view.setRootEClass(bar); |
| view.getChildren().add(tableControl); |
| final ViewModelContext context = new ViewModelContextImpl(view, domainElement); |
| |
| // Render the table |
| final TableControlSWTRenderer tableRenderer = TableControlSWTRenderer.class |
| .cast(rendererFactory.getRendererInstance( |
| tableControl, context)); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (render == null) { |
| fail(); |
| } |
| |
| // Get the validation icon |
| Composite composite = (Composite) render; |
| composite = (Composite) composite.getChildren()[0]; |
| composite = (Composite) composite.getChildren()[0]; |
| final Label validationIcon = (Label) composite.getChildren()[1]; |
| |
| // Apply validation and wait for Async operation to finish |
| tableRenderer.applyValidation(); |
| SWTTestUtil.waitForUIThread(); |
| |
| assertEquals("The tooltip text should contain the multiplicity error.", |
| "The feature 'fooToBar' of 'Foo' with 0 values must have at least 1 values", |
| validationIcon.getToolTipText()); |
| |
| // Add a new Bar object to the foo to bar reference. This removes the validation error from the reference and |
| // adds a validation error on the created Bar object. |
| ((EList) domainElement.eGet(fooToBar)).add(EcoreUtil.create(bar)); |
| |
| // Apply validation and wait for Async operation to finish |
| tableRenderer.applyValidation(); |
| SWTTestUtil.waitForUIThread(); |
| |
| assertEquals("The tool tip text should be empty.", "", validationIcon.getToolTipText()); |
| } |
| |
| /** |
| * Test that on validation status changes the table renderer does not update the entire |
| * table but only the rows that have validation changes. |
| * |
| * @see <a href="http://eclip.se/544116">bug 544116</a> |
| */ |
| @Test |
| public void testValidationUpdates() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, |
| EMFFormsNoRendererException { |
| |
| // 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); |
| final EAttribute attribute4 = createEAttribute("d", EcorePackage.Literals.ESTRING, 0, 1); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute1); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute2); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute3); |
| ((EClass) domainElement).getEStructuralFeatures().add(attribute4); |
| |
| // 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 |
| final ViewModelContext context = new ViewModelContextImpl(tableControl, domainElement); |
| final Set<String> requestedCells = new HashSet<>(); // Cell updates are unordered |
| final TableControlSWTRenderer tableRenderer = new TableControlSWTRenderer(tableControl, context, |
| context.getService(ReportService.class), |
| context.getService(EMFFormsDatabindingEMF.class), |
| context.getService(EMFFormsLabelProvider.class), |
| context.getService(VTViewTemplateProvider.class), |
| context.getService(ImageRegistryService.class), |
| context.getService(EMFFormsEditSupport.class)) { |
| |
| @Override |
| protected CellLabelProvider createCellLabelProvider(EStructuralFeature feature, CellEditor cellEditor, |
| @SuppressWarnings("rawtypes") IObservableMap attributeMap, VTableControl vTableControl, |
| VDomainModelReference dmr, |
| Control table) { |
| |
| if (feature == EcorePackage.Literals.ENAMED_ELEMENT__NAME) { |
| final StringCellEditor editor = new StringCellEditor() { |
| @Override |
| public String getFormatedString(Object value) { |
| requestedCells.add((String) value); |
| return super.getFormatedString(value); |
| } |
| }; |
| cellEditor = editor; |
| } |
| return super.createCellLabelProvider(feature, cellEditor, attributeMap, vTableControl, dmr, table); |
| } |
| }; |
| tableRenderer.init(); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control control = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| if (control == null) { |
| fail("No control was rendered"); |
| } |
| tableRenderer.finalizeRendering(shell); |
| |
| // Initialize the validation status |
| VDiagnostic vdiag = VViewFactory.eINSTANCE.createDiagnostic(); |
| Diagnostic diag = new BasicDiagnostic(Diagnostic.ERROR, "source", 0, "error", |
| new Object[] { attribute2, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE }); |
| vdiag.getDiagnostics().add(diag); |
| tableControl.setDiagnostic(vdiag); |
| |
| SWTTestUtil.waitForUIThread(); |
| |
| // Reset our tracking of accessed cells |
| requestedCells.clear(); |
| |
| // Update the validation results |
| vdiag = VViewFactory.eINSTANCE.createDiagnostic(); |
| diag = new BasicDiagnostic(Diagnostic.ERROR, "source", 0, "error", |
| // A different object than the initial validation status |
| new Object[] { attribute3, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE }); |
| vdiag.getDiagnostics().add(diag); |
| tableControl.setDiagnostic(vdiag); |
| |
| waitFor(tableRenderer); |
| |
| // Notably, we updated these two rows in order and *neither* "a" nor "d" |
| assertThat(requestedCells, equalTo(set("b", "c"))); |
| } |
| |
| @Test |
| public void testTable_validationColumnImage() |
| throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { |
| // Register test table renderer with configured column image |
| final ColumnImageTableRendererService rendererService = new ColumnImageTableRendererService(); |
| final BundleContext bundleContext = FrameworkUtil.getBundle(SWTTable_PTest.class).getBundleContext(); |
| @SuppressWarnings("rawtypes") |
| final ServiceRegistration<EMFFormsDIRendererService> registration = bundleContext.registerService( |
| EMFFormsDIRendererService.class, rendererService, new Hashtable<String, Object>()); |
| |
| // setup model and render table |
| 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 Table); |
| final Table table = (Table) control; |
| final TableColumn validationColumn = table.getColumn(0); |
| |
| // If the asserts pass, we know the image was loaded because the default error image is 6x6 pixels |
| assertEquals("The configured valdiation column image is not present", 16, |
| validationColumn.getImage().getImageData().height); |
| assertEquals("The configured valdiation column image is not present", 16, |
| validationColumn.getImage().getImageData().width); |
| |
| // Unregister test renderer |
| registration.unregister(); |
| } |
| |
| /** |
| * Verify the reuse of detail renderings with caching. |
| */ |
| @Test |
| public void testPanelTableDetailReused() 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 ViewModelContext context = new ViewModelContextWithoutServices(handle.getTableControl()); |
| context.putContextValue(DetailViewCache.DETAIL_VIEW_CACHE_SIZE, 5); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), context); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| final Control control = Composite.class.cast(render).getChildren()[0]; |
| assertThat("No control was rendered", control, notNullValue()); |
| |
| final Composite controlComposite = (Composite) ((Composite) control).getChildren()[1]; |
| final Composite tableComposite = (Composite) controlComposite.getChildren()[0]; |
| final Table table = (Table) tableComposite.getChildren()[0]; |
| final ScrolledComposite scrolledComposite = (ScrolledComposite) controlComposite.getChildren()[1]; |
| final Composite parentForECPView = (Composite) scrolledComposite.getChildren()[0]; |
| assumeThat("Not enough rows in the table", table.getItemCount(), greaterThanOrEqualTo(2)); |
| final TableViewer tableViewer = getTableViewerFromRenderer(tableRenderer); |
| |
| // Select an EClass |
| tableViewer.setSelection(new StructuredSelection(table.getItem(0).getData())); |
| assertThat("Composite for selection not present", |
| asList(parentForECPView.getChildren()), hasItem(instanceOf(Composite.class))); |
| final Composite stackComposite = (Composite) parentForECPView.getChildren()[0]; |
| final StackLayout stack = (StackLayout) stackComposite.getLayout(); |
| Composite detailComposite = (Composite) stack.topControl; |
| assertThat("Composite for details not present", detailComposite, notNullValue()); |
| final Control[] detailChildren = detailComposite.getChildren(); |
| assertThat("Insufficient number of detail controls", detailChildren.length, greaterThanOrEqualTo(6)); |
| |
| // Select another EClass |
| tableViewer.setSelection(new StructuredSelection(table.getItem(1).getData())); |
| assertThat(parentForECPView.getChildren().length, is(1)); |
| detailComposite = (Composite) stack.topControl; |
| assertThat("Detail controls not reused", detailComposite.getChildren(), is(detailChildren)); |
| } |
| |
| /** |
| * Verify the replacement of the parent context root domain model object while a detail |
| * is showing, in which the detail must be put away because the table selection is lost. |
| */ |
| @Test |
| public void testRootDomainModelChangedWhilePanelTableDetail() |
| 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 ViewModelContext context = ViewModelContextFactory.INSTANCE |
| .createViewModelContext(handle.getView(), domainElement); |
| context.putContextValue(DetailViewCache.DETAIL_VIEW_CACHE_SIZE, 5); |
| final AbstractSWTRenderer<VElement> tableRenderer = rendererFactory.getRendererInstance( |
| handle.getTableControl(), context); |
| tableRenderer.getGridDescription(new SWTGridDescription()); |
| final Control render = tableRenderer.render(new SWTGridCell(0, 0, tableRenderer), shell); |
| final Control control = Composite.class.cast(render).getChildren()[0]; |
| assumeThat("No control was rendered", control, notNullValue()); |
| |
| final Composite controlComposite = (Composite) ((Composite) control).getChildren()[1]; |
| final Composite tableComposite = (Composite) controlComposite.getChildren()[0]; |
| final Table table = (Table) tableComposite.getChildren()[0]; |
| final ScrolledComposite scrolledComposite = (ScrolledComposite) controlComposite.getChildren()[1]; |
| final Composite parentForECPView = (Composite) scrolledComposite.getChildren()[0]; |
| assumeThat("Not enough rows in the table", table.getItemCount(), greaterThanOrEqualTo(2)); |
| final TableViewer tableViewer = getTableViewerFromRenderer(tableRenderer); |
| |
| // Select an EClass |
| tableViewer.setSelection(new StructuredSelection(table.getItem(0).getData())); |
| assumeThat("Composite for selection not present", |
| asList(parentForECPView.getChildren()), hasItem(instanceOf(Composite.class))); |
| final Composite stackComposite = (Composite) parentForECPView.getChildren()[0]; |
| final StackLayout stack = (StackLayout) stackComposite.getLayout(); |
| Composite detailComposite = (Composite) stack.topControl; |
| assumeThat("Composite for details not present", detailComposite, notNullValue()); |
| Control[] detailChildren = detailComposite.getChildren(); |
| assumeThat("Insufficient number of detail controls", detailChildren.length, greaterThanOrEqualTo(6)); |
| |
| // Now, replace the parent context domain model element |
| context.changeDomainModel(eClass); |
| |
| // Assert that the table is now empty and the detail is the "No selection" label |
| assertThat("Table should be empty", table.getItemCount(), is(0)); |
| detailComposite = (Composite) stack.topControl; |
| detailChildren = detailComposite.getChildren(); |
| assumeThat("Wrong number of detail controls", detailChildren.length, is(1)); |
| assertThat("Detail is not a label", detailChildren[0], instanceOf(Label.class)); |
| } |
| |
| // |
| // Test framework |
| // |
| |
| @SafeVarargs |
| static <T> Set<T> set(T... elements) { |
| return new HashSet<>(Arrays.asList(elements)); |
| } |
| |
| /** |
| * Wait for any pending updates in a table renderer to be completed. |
| * |
| * @param tableRenderer a table renderer to wait for |
| */ |
| final void waitFor(TableControlSWTRenderer tableRenderer) { |
| try { |
| if (!tableRenderer.getRunnableManager().waitForIdle(1L, TimeUnit.SECONDS)) { |
| fail("Timed out waiting for table updates"); |
| } |
| } catch (final InterruptedException e) { |
| fail("Interrupted waiting for table updates"); |
| } |
| |
| } |
| |
| private static class ColumnImageTableRenderer extends TableControlSWTRenderer { |
| // BEGIN COMPLEX CODE |
| @Inject |
| ColumnImageTableRenderer(VTableControl vElement, ViewModelContext viewContext, |
| ReportService reportService, EMFFormsDatabindingEMF emfFormsDatabinding, |
| EMFFormsLabelProvider emfFormsLabelProvider, VTViewTemplateProvider vtViewTemplateProvider, |
| ImageRegistryService imageRegistryService, EMFFormsEditSupport emfFormsEditSupport) { |
| // END COMPLEX CODE |
| super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, |
| vtViewTemplateProvider, |
| imageRegistryService, emfFormsEditSupport); |
| } |
| |
| @Override |
| protected VTTableValidationStyleProperty getTableValidationStyleProperty() { |
| final VTTableValidationStyleProperty property = VTTableValidationFactory.eINSTANCE |
| .createTableValidationStyleProperty(); |
| property.setImagePath("platform:/plugin/org.eclipse.emf.ecp.view.table.ui.swt/icons/cake.png"); |
| return property; |
| } |
| } |
| |
| private static class ColumnImageTableRendererService implements EMFFormsDIRendererService<VTableControl> { |
| |
| @Override |
| public double isApplicable(VElement vElement, ViewModelContext viewModelContext) { |
| if (vElement instanceof VTableControl) { |
| return Double.MAX_VALUE; |
| } |
| return NOT_APPLICABLE; |
| } |
| |
| @Override |
| public Class<? extends AbstractSWTRenderer<VTableControl>> getRendererClass() { |
| return ColumnImageTableRenderer.class; |
| } |
| |
| } |
| |
| private TableControlSWTRenderer 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 TableControlSWTRenderer tableControlSWTRenderer = new TableControlSWTRenderer( |
| 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)) { |
| |
| @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 assertTableItemOrder(Table table, Object... objects) { |
| assertEquals(objects.length, table.getItemCount()); |
| final TableItem[] items = table.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| assertSame(objects[i], items[i].getData()); |
| } |
| } |
| |
| 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; |
| } |
| |
| private TableViewer getTableViewerFromRenderer(AbstractSWTRenderer<VElement> renderer) { |
| try { |
| final Method method = TableControlSWTRenderer.class.getDeclaredMethod("getTableViewer"); |
| method.setAccessible(true); |
| return (TableViewer) method.invoke(renderer); |
| } catch (final NoSuchMethodException ex) { |
| fail(ex.getMessage()); |
| } catch (final SecurityException ex) { |
| fail(ex.getMessage()); |
| } catch (final IllegalAccessException ex) { |
| fail(ex.getMessage()); |
| } catch (final IllegalArgumentException ex) { |
| fail(ex.getMessage()); |
| } catch (final InvocationTargetException ex) { |
| fail(ex.getMessage()); |
| } |
| return null; |
| } |
| |
| /** |
| * Stub implementation without getting services from ex. point. |
| * |
| * @author jfaltermeier |
| * |
| */ |
| private class ViewModelContextWithoutServices implements ViewModelContext { |
| |
| private final VElement view; |
| private final EMFFormsContextProvider contextProvider; |
| private final Map<Class<?>, Object> services = new LinkedHashMap<>(); |
| private final Map<String, Object> contextValues = new HashMap<>(); |
| |
| 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 |
| } |
| |
| public <T> void addService(T service, Class<? super T> serviceClass) { |
| services.put(serviceClass, service); |
| } |
| |
| /** |
| * {@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; |
| } |
| if (services.containsKey(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 (T) services.get(serviceType); |
| } |
| |
| /** |
| * {@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; |
| } |
| |
| @Override |
| public Object getContextValue(String key) { |
| Object result = contextValues.get(key); |
| if (result == null && getParentContext() != null) { |
| result = getParentContext().getContextValue(key); |
| } |
| return result; |
| } |
| |
| @Override |
| public void putContextValue(String key, Object value) { |
| contextValues.put(key, value); |
| } |
| |
| @Override |
| public void registerDisposeListener(ViewModelContextDisposeListener listener) { |
| // do nothing |
| } |
| |
| @Override |
| public void addContextUser(Object user) { |
| // do nothing |
| } |
| |
| @Override |
| public void removeContextUser(Object user) { |
| // do nothing |
| } |
| |
| @Deprecated |
| @Override |
| public ViewModelContext getChildContext(EObject eObject, VElement parent, VView vView, |
| ViewModelService... viewModelServices) { |
| |
| final ViewModelContextWithoutServices vmcws = new ViewModelContextWithoutServices(vView); |
| return vmcws; |
| } |
| |
| @Override |
| public ViewModelContext getChildContext(EObject eObject, VElement parent, VView vView, |
| ViewModelServiceProvider viewModelServiceProvider) { |
| |
| return new ViewModelContextWithoutServices(vView); |
| } |
| |
| @Override |
| public void registerEMFFormsContextListener(EMFFormsContextListener contextListener) { |
| } |
| |
| @Override |
| public void unregisterEMFFormsContextListener(EMFFormsContextListener contextListener) { |
| } |
| |
| @Override |
| public ViewModelContext getParentContext() { |
| return null; |
| } |
| |
| @Override |
| public void changeDomainModel(EObject newDomainModel) { |
| // do nothing |
| } |
| |
| @Override |
| public void registerRootDomainModelChangeListener(RootDomainModelChangeListener rootDomainModelChangeListener) { |
| // do nothing |
| } |
| |
| @Override |
| public void unregisterRootDomainModelChangeListener( |
| RootDomainModelChangeListener rootDomainModelChangeListener) { |
| // do nothing |
| } |
| |
| @Override |
| public VElement getParentVElement() { |
| 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; |
| } |
| |
| } |
| |
| } |