diff options
author | Vincent Lorenzo | 2016-04-25 15:39:09 +0000 |
---|---|---|
committer | Vincent Lorenzo | 2016-05-02 07:27:21 +0000 |
commit | 267f9956cb6af04d6d4e95072d4d0f3994fc7194 (patch) | |
tree | 1d4eeedc04e13062fd4e7b6288f2dc429c9da12e /plugins/uml | |
parent | ebb18cdd8a293fee283b45620c02dd3a354660a6 (diff) | |
download | org.eclipse.papyrus-267f9956cb6af04d6d4e95072d4d0f3994fc7194.tar.gz org.eclipse.papyrus-267f9956cb6af04d6d4e95072d4d0f3994fc7194.tar.xz org.eclipse.papyrus-267f9956cb6af04d6d4e95072d4d0f3994fc7194.zip |
bug 483357: [Table] Popup menu must be available in each context!
Change-Id: I6f89e92b9d8f9522652d191fea191ccb0ea6241f
Signed-off-by: Vincent Lorenzo <vincent.lorenzo@cea.fr>
Diffstat (limited to 'plugins/uml')
6 files changed, 729 insertions, 84 deletions
diff --git a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/META-INF/MANIFEST.MF b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/META-INF/MANIFEST.MF index e38ce3cf25d..00d503a2b55 100644 --- a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/META-INF/MANIFEST.MF +++ b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/META-INF/MANIFEST.MF @@ -6,7 +6,7 @@ Export-Package: org.eclipse.papyrus.uml.nattable.clazz.config, org.eclipse.papyrus.uml.nattable.clazz.config.manager.axis Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-Localization: plugin Bundle-Name: %Bundle-Name Bundle-Activator: org.eclipse.papyrus.uml.nattable.clazz.config.Activator diff --git a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/pom.xml b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/pom.xml index d29df297815..9ec082bd1ea 100644 --- a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/pom.xml +++ b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.clazz.config/pom.xml @@ -7,6 +7,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.uml.nattable.clazz.config</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.stereotype.display/src/org/eclipse/papyrus/uml/nattable/stereotype/display/manager/axis/NotationTreeTableAxisManager.java b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.stereotype.display/src/org/eclipse/papyrus/uml/nattable/stereotype/display/manager/axis/NotationTreeTableAxisManager.java index 5312ff102ec..68a48d1bbee 100644 --- a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.stereotype.display/src/org/eclipse/papyrus/uml/nattable/stereotype/display/manager/axis/NotationTreeTableAxisManager.java +++ b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable.stereotype.display/src/org/eclipse/papyrus/uml/nattable/stereotype/display/manager/axis/NotationTreeTableAxisManager.java @@ -18,8 +18,8 @@ import org.eclipse.nebula.widgets.nattable.hideshow.RowHideShowLayer; import org.eclipse.nebula.widgets.nattable.hideshow.command.RowHideCommand; import org.eclipse.nebula.widgets.nattable.layer.ILayer; import org.eclipse.nebula.widgets.nattable.tree.TreeLayer; +import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe; import org.eclipse.papyrus.infra.emf.nattable.manager.axis.EObjectTreeAxisManagerForEventList; -import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe; import org.eclipse.papyrus.infra.nattable.layer.PapyrusGridLayer; import org.eclipse.papyrus.infra.nattable.layerstack.RowHeaderHierarchicalLayerStack; import org.eclipse.papyrus.infra.nattable.manager.axis.IAxisManagerForEventList; @@ -113,13 +113,14 @@ public class NotationTreeTableAxisManager extends EObjectTreeAxisManagerForEvent } final Command cmd = getAddAxisCommand(getTableEditingDomain(), selectionList); - - try { - GMFUnsafe.write(getTableEditingDomain(), cmd); - } catch (InterruptedException e) { - Activator.log.error(e); - } catch (RollbackException e) { - Activator.log.error(e); + if (cmd != null) { + try { + GMFUnsafe.write(getTableEditingDomain(), cmd); + } catch (InterruptedException e) { + Activator.log.error(e); + } catch (RollbackException e) { + Activator.log.error(e); + } } // because event will be propagated and children will be set! return; @@ -324,7 +325,7 @@ public class NotationTreeTableAxisManager extends EObjectTreeAxisManagerForEvent return; } final TreeLayer treeLayer = getTreeLayer(); - if(null != treeLayer){ + if (null != treeLayer) { for (int cpt = selectionList.size() - 1; cpt >= 0; cpt--) { // Expand the tree item treeLayer.expandTreeRow(cpt); diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/NattablePropertyEditor.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/NattablePropertyEditor.java index 45cf7dd85a1..354a03849d3 100644 --- a/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/NattablePropertyEditor.java +++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/NattablePropertyEditor.java @@ -12,28 +12,52 @@ *****************************************************************************/ package org.eclipse.papyrus.uml.properties.widgets; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; +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.ecore.xmi.XMLResource; +import org.eclipse.emf.edit.command.AddCommand; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emf.transaction.RecordingCommand; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gef.EditPart; import org.eclipse.gef.editparts.AbstractEditPart; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.nebula.widgets.nattable.NatTable; +import org.eclipse.papyrus.infra.core.resource.EditingDomainServiceFactory; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.services.ServiceDescriptor; +import org.eclipse.papyrus.infra.core.services.ServiceDescriptor.ServiceTypeKind; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceMultiException; +import org.eclipse.papyrus.infra.core.services.ServiceStartKind; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.emf.nattable.selection.EObjectSelectionExtractor; import org.eclipse.papyrus.infra.emf.utils.EMFHelper; import org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager; import org.eclipse.papyrus.infra.nattable.manager.table.NattableModelManager; import org.eclipse.papyrus.infra.nattable.manager.table.TreeNattableModelManager; import org.eclipse.papyrus.infra.nattable.model.nattable.NattableFactory; +import org.eclipse.papyrus.infra.nattable.model.nattable.NattablePackage; import org.eclipse.papyrus.infra.nattable.model.nattable.Table; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxis.IAxis; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation; @@ -42,11 +66,11 @@ import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfigurati import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.TableHeaderAxisConfiguration; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.NattableaxisproviderFactory; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.NattableaxisproviderPackage; import org.eclipse.papyrus.infra.nattable.model.nattable.nattableconfiguration.TableConfiguration; import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.BooleanValueStyle; -import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.NattablestylePackage; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.NattablestyleFactory; import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.Style; -import org.eclipse.papyrus.infra.nattable.tree.CollapseAndExpandActionsEnum; import org.eclipse.papyrus.infra.nattable.tree.ITreeItemAxisHelper; import org.eclipse.papyrus.infra.nattable.utils.HeaderAxisConfigurationManagementUtils; import org.eclipse.papyrus.infra.nattable.utils.NamedStyleConstants; @@ -63,15 +87,13 @@ import org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor; import org.eclipse.papyrus.uml.properties.Activator; import org.eclipse.papyrus.uml.properties.modelelement.UMLNotationModelElement; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; import org.eclipse.uml2.uml.Element; /** @@ -80,6 +102,28 @@ import org.eclipse.uml2.uml.Element; public class NattablePropertyEditor extends AbstractPropertyEditor { /** + * the save option to uses + */ + private static final Map<Object, Object> saveOptions = new HashMap<Object, Object>(); + + static { + saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); + saveOptions.put(Resource.OPTION_LINE_DELIMITER, Resource.OPTION_LINE_DELIMITER_UNSPECIFIED); + saveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, true); + } + /** + * the folders in which we wil save the table configured by the user. + */ + private static final String TABLES_PREFERENCES_FOLDER_NAME = "tables";//$NON-NLS-1$ + + /** + * The file in which the table will be saved + * + * It doesn't work using .notation as extension file. In this case, the commands are not executed, because it is read-only, but why ? + */ + private static final String FILE_EXTENSION = "table";//$NON-NLS-1$ + + /** * The composite. */ protected Group self = null;; @@ -110,6 +154,31 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { private IDataSourceListener dataSourceListener; /** + * The service registry used to manipulate the table + */ + private ServicesRegistry serviceRegistry = null; + + /** + * the resource where the table will be saved + */ + private Resource resource = null; + + /** + * the edited Papyrus table + */ + private Table table = null; + + /** + * the table configuration + */ + private TableConfiguration tableConfiguration = null; + + /** + * if <code>true</code> we register table configuration by eClass and not only by table type + */ + private boolean registerTableConfigurationByEClass = false; + + /** * Constructor. * * @param parent @@ -126,12 +195,22 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { } /** + * + * @param newValue + * if <code>true</code> we register the table configuration by type AND by the ECLass of the selected element + */ + public final void setRegisterTableConfigurationByEClass(final boolean newValue) { + this.registerTableConfigurationByEClass = newValue; + } + + /** * Set the table URI. * * @param uri * The URI of the table (as String). + * @since 2.0 */ - public void setTableURI(final String uri) { + public void setTableConfigurationURI(final String uri) { tableConfigURI = URI.createURI(uri); checkInput(); } @@ -140,11 +219,38 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * Get the table configuration URI. * * @return The table configuration URI. + * @since 2.0 + * */ - public String getTableURI() { + public String getTableConfigurationURI() { return tableConfigURI == null ? null : tableConfigURI.toString(); } + /** + * Set the table URI. + * + * @param uri + * The URI of the table (as String). + * + * @deprecated since 2.0, use setTableConfigurationURI instead + */ + @Deprecated + public void setTableURI(final String uri) { + setTableConfigurationURI(uri); + } + + /** + * Get the table configuration URI. + * + * @return The table configuration URI. + * @deprecated since 2.0, use getTableConfigurationUri instead + */ + public String getTableURI() { + return getTableConfigurationURI(); + } + + + /** * {@inheritDoc} @@ -211,7 +317,7 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { } /** - * This allow to create the table widget. + * This allow to create the table widget or to reuse a table previously used in the property view * * @param sourceElement * The source Element. @@ -219,47 +325,190 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * The parent structural feature. * @param rows * The rows of the table. + * + * @since 2.0 */ protected void createTableWidget(final EObject sourceElement, final EStructuralFeature feature, final Collection<?> rows) { + // 1. we initialize a service registry + if (this.serviceRegistry == null) { + try { + this.serviceRegistry = createServiceRegistry(sourceElement); + } catch (Exception e) { + Activator.log.error(e); + } + } + + if (this.serviceRegistry == null) { + displayError("Cannot initialize the service registry"); //$NON-NLS-1$ + return; + } - // Create the table - final Table table = createTable(sourceElement, feature, rows); - if (table == null) { + // 2. get the editing domain + TransactionalEditingDomain domain = getTableEditingDomain(); + if (domain == null) { + displayError("Cannot found the editing domain"); //$NON-NLS-1$ + return; + } + + // 3. Create the table or get an existing one + this.table = getOrCreateTable(sourceElement, feature, rows); + + if (this.table == null) { displayError("Cannot initialize the table"); //$NON-NLS-1$ return; } - - manageTableNamedStyle(table); - - // Create the widget - nattableManager = NattableModelManagerFactory.INSTANCE.createNatTableModelManager(table, new EObjectSelectionExtractor()); - natTableWidget = nattableManager.createNattable(self, SWT.NONE, null); - if (nattableManager instanceof TreeNattableModelManager) { - configureTreeTable((TreeNattableModelManager) nattableManager, sourceElement, feature, rows); - ((TreeNattableModelManager) nattableManager).doCollapseExpandAction(CollapseAndExpandActionsEnum.EXPAND_ALL, null); + // 4. we configure the table + final CompoundCommand cc = new CompoundCommand("Configure table command");//$NON-NLS-1$ + + // 4.1 we register it into a resource if required + if (this.table.eResource() == null) { + cc.append(addTableToResource(domain, this.resource, this.table)); } - - self.addDisposeListener(getDisposeListener()); - natTableWidget.setBackground(self.getBackground()); + // 4.2 we configure the table + configureTable(domain, this.table, sourceElement, feature, rows, cc); + + if (!cc.canExecute()) { + displayError("The table can't be initialized");//$NON-NLS-1$ + return; + } + domain.getCommandStack().execute(cc); + if (this.table.getContext() == null) { + displayError("The context of the table hasn't be set");//$NON-NLS-1$ + return; + } + // 5. Create the widget + this.nattableManager = NattableModelManagerFactory.INSTANCE.createNatTableModelManager(this.table, new EObjectSelectionExtractor()); + this.natTableWidget = createNatTableWidget(this.nattableManager, self, SWT.NONE, rows); + + self.addDisposeListener(getDisposeListener()); // Configure the layout and the layout data configureLayout(); - - ((NattableModelManager)nattableManager).refreshNatTable(); + + ((NattableModelManager) nattableManager).refreshNatTable(); + } + + /** + * + * @param parent + * the composite parent + * @param style + * the style to use to create the nattable widget + * @param rows + * the initial rows + * @return + * the created nattable widget + * @since 2.0 + */ + protected NatTable createNatTableWidget(final INattableModelManager manager, final Composite parent, final int style, Collection<?> rows) { + NatTable natTable = manager.createNattable(self, style, null); + natTable.setBackground(self.getBackground()); + return natTable; + } + + /** + * + * @param sourceElement + * the source element used to initiatiaze the table + * @return + * the service registry to use for the table displayed in property view + * @throws Exception + * + * Duplicated code from org.eclipse.papyrus.junit.utils.rules.ModelSetFixture + * @since 2.0 + */ + protected ServicesRegistry createServiceRegistry(EObject sourceElement) throws Exception { + ServicesRegistry result = new ServicesRegistry(); + + result.add(ModelSet.class, 10, new ModelSet()); + + ServiceDescriptor desc = new ServiceDescriptor(TransactionalEditingDomain.class, EditingDomainServiceFactory.class.getName(), ServiceStartKind.STARTUP, 10);// , Collections.singletonList(ResourceSet.class.getName())); + desc.setServiceTypeKind(ServiceTypeKind.serviceFactory); + desc.setClassBundleID(Activator.PLUGIN_ID); + result.add(desc); + + result.startRegistry(); + return result; + } + + /** + * + * @param domain + * the editing domain to use + * @param table + * the edited table + * @param sourceElement + * the source element (id the context of the table + * @param synchronizedFeature + * the feature on which the table is synchronized + * @param rows + * the initial rows for the table + * @param command + * the compound command used to do additional stuff + * + * @since 2.0 + */ + protected void configureTable(final TransactionalEditingDomain domain, final Table table, final EObject sourceElement, final EStructuralFeature synchronizedFeature, Collection<?> rows, CompoundCommand command) { + Assert.isNotNull(domain); + // 1. we register the context of the table + Command setContextCommand = SetCommand.create(domain, table, NattablePackage.eINSTANCE.getTable_Context(), sourceElement); + command.append(setContextCommand); } /** + * This method initialize the context of the table, the feature to listen and the intial rows list element + * + * @since 2.0 + * + * @deprecated since 2.0, use {@link #configureTable(TransactionalEditingDomain, Table, EObject, EStructuralFeature, Collection, Command)} instead + */ + @Deprecated + protected void configureTable(Table table, EObject sourceElement, EStructuralFeature synchronizedFeature, Collection<?> rows) { + final TransactionalEditingDomain domain = getTableEditingDomain(); + if (null != domain) { + Command setContextCommand = SetCommand.create(domain, table, NattablePackage.eINSTANCE.getTable_Context(), sourceElement); + getTableEditingDomain().getCommandStack().execute(setContextCommand); + Assert.isNotNull(table.getContext()); + + if (TableHelper.isTreeTable(table) && null != rows && !rows.isEmpty()) {// add test on TreeTable to fix bug 476623 + final AbstractAxisProvider axisProvider = table.getCurrentRowAxisProvider(); + TableHeaderAxisConfiguration conf = (TableHeaderAxisConfiguration) HeaderAxisConfigurationManagementUtils.getRowAbstractHeaderAxisInTableConfiguration(table); + AxisManagerRepresentation rep = conf.getAxisManagers().get(0); + for (Object context : rows) { + addTreeItemAxis(axisProvider, rep, context); + } + } + } + } + + + /** * This allows to add some named style to the table. * - * @param table The current table. + * @param table + * The current table. + * @since 2.0 + * + * @deprecated since 2.0 done directly in the creation of the table */ - protected void manageTableNamedStyle(final Table table){ - final Style fillColumnsSizeStyle = table.getTableConfiguration().createStyle(NattablestylePackage.eINSTANCE.getBooleanValueStyle()); - ((BooleanValueStyle)fillColumnsSizeStyle).setName(NamedStyleConstants.FILL_COLUMNS_SIZE); - ((BooleanValueStyle)fillColumnsSizeStyle).setBooleanValue(true); + @Deprecated + protected void manageTableNamedStyle(final Table table) { + final org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.BooleanValueStyle style = NattablestyleFactory.eINSTANCE.createBooleanValueStyle(); + style.setName(NamedStyleConstants.FILL_COLUMNS_SIZE); + style.setBooleanValue(true); + final TransactionalEditingDomain domain = getTableEditingDomain(); + RecordingCommand rc = new RecordingCommand(domain) { + + @Override + protected void doExecute() { + table.getStyles().add(style); + + } + }; + domain.getCommandStack().execute(rc); } - + /** * This allows to configure the tree table. * @@ -271,15 +520,17 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * The feature. * @param rows * The rows of the table. + * @deprecated since 2.0, moved into {@link TreeNattablePropertyEditor} */ + @Deprecated protected void configureTreeTable(final TreeNattableModelManager nattableManager, final EObject sourceElement, final EStructuralFeature feature, final Collection<?> rows) { - // Do nohting + // Do nothing } - + /** * This allows to configure the layout and the layout data. */ - protected void configureLayout(){ + protected void configureLayout() { // Adapt the group to the table preferred size final GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); @@ -325,15 +576,128 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * This allow to display the error. * * @param message - * The error mesage to display. + * The error message to display. */ protected void displayError(final String message) { - final Label label = new Label(self, SWT.NONE); + final CLabel label = new CLabel(self, SWT.NONE); label.setText(message); label.setImage(org.eclipse.papyrus.infra.widgets.Activator.getDefault().getImage("icons/error.gif")); //$NON-NLS-1$ } /** + * + * @param sourceElement + * the source Element + * @param synchronizedFeature + * the synchronized feature + * @param rows + * @return + * the existing table of the new created one + * @since 2.0 + */ + protected Table getOrCreateTable(final EObject sourceElement, final EStructuralFeature synchronizedFeature, final Collection<?> rows) { + Table returnedTable = null; + final TableConfiguration tableConfiguration = getTableConfiguration(); + if (tableConfiguration == null) { + return null; + } + + if (this.serviceRegistry != null) { + URI tableURI = createTableURI(sourceElement, tableConfiguration); + final ResourceSet resourceSet = getResourceSet(); + ((ModelSet) resourceSet).createModels(tableURI); + boolean exists = resourceSet.getURIConverter().exists(tableURI, Collections.emptyMap()); + if (exists) { + this.resource = resourceSet.getResource(tableURI, true); + } else { + this.resource = resourceSet.createResource(tableURI); + } + + Iterator<EObject> iter = this.resource.getContents().iterator(); + while (iter.hasNext() && returnedTable == null) {// the resource should contains only 1 table and this one will get the good type + EObject object = iter.next(); + if (object instanceof Table) { + TableConfiguration configuration = ((Table) object).getTableConfiguration(); + if (configuration != null && configuration.getType().equals(getTableConfiguration().getType())) { + returnedTable = (Table) object; + } + } + } + + if (null == returnedTable) { + returnedTable = createTable(sourceElement, synchronizedFeature); + } + + } + + return returnedTable; + } + + /** + * + * @return + * the resource set to use to load/store emf files + * @since 2.0 + */ + protected ResourceSet getResourceSet() { + ResourceSet set = null; + if (this.serviceRegistry != null) { + try { + set = this.serviceRegistry.getService(ModelSet.class); + } catch (ServiceException e) { + Activator.log.error(e); + } + } + return set; + } + + /** + * + * @param sourceElement + * the source Element + * @param tableConfiguration + * the tableConfiguration + * @return + * the URI to use to save and load the table + * @since 2.0 + */ + protected URI createTableURI(final EObject sourceElement, final TableConfiguration tableConfiguration) { + IPath preferencePath = Activator.getDefault().getStateLocation(); + // we create a folder to save the tables used by the property view and we start to create the name of the model owning the table + preferencePath = preferencePath.append(TABLES_PREFERENCES_FOLDER_NAME).append(tableConfiguration.getType()); + + // we continue to build the path, adding the good suffix to the name of the model + final StringBuilder b = new StringBuilder().append(preferencePath.toPortableString()); + if (this.registerTableConfigurationByEClass) { + final ModelElement modelElement = input.getModelElement(propertyPath); + EClass eClass = null; + if (modelElement instanceof CompositeModelElement) { + CompositeModelElement compoModelElement = (CompositeModelElement) modelElement; + Iterator<ModelElement> iter = compoModelElement.getSubElements().iterator(); + while (eClass == null && iter.hasNext()) { + ModelElement tmp = iter.next(); + if (tmp instanceof UMLNotationModelElement) { + EditPart part = ((UMLNotationModelElement) tmp).getEditPart(); + eClass = EMFHelper.getEObject(part).eClass(); + } else if (tmp instanceof EMFModelElement) { + eClass = ((EMFModelElement) tmp).getSource().eClass(); + } + } + } + + if (modelElement instanceof UMLNotationModelElement) { + EditPart part = ((UMLNotationModelElement) modelElement).getEditPart(); + eClass = EMFHelper.getEObject(part).eClass(); + } + b.append("_"); //$NON-NLS-1$ + b.append(eClass.getName()); + } + URI newURI = URI.createFileURI(b.toString()).appendFileExtension(FILE_EXTENSION); + return newURI; + } + + + /** * This allow to create the nattable. * * @param sourceElement @@ -342,20 +706,18 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * The synchronized feature. * @param rows * The rows of the table. - * @return The created nattable. + * @return The created table. + * + * @since 2.0 */ - protected Table createTable(final EObject sourceElement, final EStructuralFeature synchronizedFeature, final Collection<?> rows) { - + protected Table createTable(final EObject sourceElement, final EStructuralFeature synchronizedFeature) { final TableConfiguration tableConfiguration = getTableConfiguration(); if (tableConfiguration == null) { return null; } - - final Property property = getModelProperty(); final Table table = NattableFactory.eINSTANCE.createTable(); - table.setTableConfiguration(tableConfiguration); - + final Property property = getModelProperty(); if (property != null) { String description = property.getDescription(); if (description != null) { @@ -387,29 +749,94 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { } } } - + table.getColumnAxisProvidersHistory().add(columnProvider); table.setCurrentColumnAxisProvider(columnProvider); + table.getRowAxisProvidersHistory().add(rowProvider); table.setCurrentRowAxisProvider(rowProvider); - - table.setContext(sourceElement); - for (final Style style : tableConfiguration.getStyles()) { table.getStyles().add(EcoreUtil.copy(style)); } - // Manage the construction of axis here because the table editing domain is null - if (TableHelper.isTreeTable(table) && null != rows && !rows.isEmpty()) {// add test on TreeTable to fix bug 476623 - final AbstractAxisProvider axisProvider = table.getCurrentRowAxisProvider(); - TableHeaderAxisConfiguration conf = (TableHeaderAxisConfiguration) HeaderAxisConfigurationManagementUtils.getRowAbstractHeaderAxisInTableConfiguration(table); - AxisManagerRepresentation rep = conf.getAxisManagers().get(0); - for (Object context : rows) { - addTreeItemAxis(axisProvider, rep, context); + // for the table displayed in property view, we want to use all the available place, so we add a specific named style each time + final BooleanValueStyle fillStyle = NattablestyleFactory.eINSTANCE.createBooleanValueStyle(); + fillStyle.setName(NamedStyleConstants.FILL_COLUMNS_SIZE); + fillStyle.setBooleanValue(true); + table.getStyles().add(fillStyle); + + // for the table displayed in property view, we expand all directly + final BooleanValueStyle expandStyle = NattablestyleFactory.eINSTANCE.createBooleanValueStyle(); + expandStyle.setName(NamedStyleConstants.EXPAND_ALL); + expandStyle.setBooleanValue(true); + table.getStyles().add(expandStyle); + + return table; + } + + /** + * This allow to create the nattable. + * + * @param sourceElement + * The context element. + * @param synchronizedFeature + * The synchronized feature. + * @param rows + * The rows of the table. + * @return The created table. + * + * @deprecated since 2.0, use the same method without the collections of rows as arguments. Rows are set later in the new implementation + */ + @Deprecated + protected Table createTable(final EObject sourceElement, final EStructuralFeature synchronizedFeature, final Collection<?> rows) { + final TableConfiguration tableConfiguration = getTableConfiguration(); + if (tableConfiguration == null) { + return null; + } + final Table table = NattableFactory.eINSTANCE.createTable(); + table.setTableConfiguration(tableConfiguration); + final Property property = getModelProperty(); + if (property != null) { + String description = property.getDescription(); + if (description != null) { + table.setDescription(description); } } + table.setName(getLabel()); + + AbstractAxisProvider rowProvider = tableConfiguration.getDefaultRowAxisProvider(); + if (rowProvider == null) { + rowProvider = NattableaxisproviderFactory.eINSTANCE.createMasterObjectAxisProvider(); + } else { + rowProvider = EcoreUtil.copy(rowProvider); + } + + AbstractAxisProvider columnProvider = tableConfiguration.getDefaultColumnAxisProvider(); + if (columnProvider == null) { + columnProvider = NattableaxisproviderFactory.eINSTANCE.createSlaveObjectAxisProvider(); + } else { + columnProvider = EcoreUtil.copy(columnProvider); + } + + if (null != synchronizedFeature) { + TableHeaderAxisConfiguration rowHeaderAxisconfig = tableConfiguration.getRowHeaderAxisConfiguration(); + for (IAxisConfiguration axisConfig : rowHeaderAxisconfig.getOwnedAxisConfigurations()) { + if (axisConfig instanceof EStructuralFeatureValueFillingConfiguration) { + ((EStructuralFeatureValueFillingConfiguration) axisConfig).setListenFeature(synchronizedFeature); + } + } + } + table.getColumnAxisProvidersHistory().add(columnProvider); + table.setCurrentColumnAxisProvider(columnProvider); + table.getRowAxisProvidersHistory().add(rowProvider); + table.setCurrentRowAxisProvider(rowProvider); + for (final Style style : tableConfiguration.getStyles()) { + table.getStyles().add(EcoreUtil.copy(style)); + } + return table; } + /** * This allow to add the tree item axis. * @@ -419,15 +846,36 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * The axis manager representation. * @param object * The object to add. + * + * @deprecated since 2.0, moved into {@link TreeNattablePropertyEditor} with command */ + @Deprecated protected void addTreeItemAxis(final AbstractAxisProvider axisProvider, final AxisManagerRepresentation rep, final Object object) { if (object instanceof View && isStereotypedElement((View) object)) { + TransactionalEditingDomain domain = getTableEditingDomain(); final IAxis axis = ITreeItemAxisHelper.createITreeItemAxis(null, null, object, rep); - axisProvider.getAxis().add(axis); + Command addCommand = AddCommand.create(getTableEditingDomain(), axisProvider, NattableaxisproviderPackage.eINSTANCE.getAxisProvider_Axis(), Collections.singleton(axis)); + domain.getCommandStack().execute(addCommand); } } /** + * + * @return + * the editing domain to use + * + * @since 2.0 + */ + protected TransactionalEditingDomain getTableEditingDomain() { + try { + return this.serviceRegistry.getService(TransactionalEditingDomain.class); + } catch (ServiceException e) { + Activator.log.error(e); + } + return null; + } + + /** * Check is the element of the view is stereotyped. * * @param view @@ -448,16 +896,17 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * @return The table configuration. */ protected TableConfiguration getTableConfiguration() { - ResourceSet resourceSet = new ResourceSetImpl(); - try { - final TableConfiguration tableConfiguration = (TableConfiguration) EMFHelper.loadEMFModel(resourceSet, - tableConfigURI); - return tableConfiguration; - } catch (Exception ex) { - Activator.log.error("Invalid table configuration", ex); //$NON-NLS-1$ + if (this.tableConfiguration == null) { + ResourceSet resourceSet = getResourceSet(); + if (resourceSet != null) { + try { + this.tableConfiguration = (TableConfiguration) EMFHelper.loadEMFModel(resourceSet, this.tableConfigURI); + } catch (Exception ex) { + Activator.log.error("Invalid table configuration", ex); //$NON-NLS-1$ + } + } } - - return null; + return this.tableConfiguration; } /** @@ -466,12 +915,36 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { * @return The dispose nattable manager listener. */ protected DisposeListener getDisposeListener() { - if (null == nattableDisposeListener) { - nattableDisposeListener = new DisposeListener() { + if (null == this.nattableDisposeListener) { + this.nattableDisposeListener = new DisposeListener() { public void widgetDisposed(DisposeEvent e) { - nattableManager.dispose(); - natTableWidget.dispose(); + + if (NattablePropertyEditor.this.serviceRegistry != null) { + // we dispose it to avoid unecessary refresh + NattablePropertyEditor.this.nattableManager.dispose(); + NattablePropertyEditor.this.natTableWidget.dispose(); + + TransactionalEditingDomain domain = getTableEditingDomain(); + Command cmd = getDisposeCommand(domain, table); + domain.getCommandStack().execute(cmd); + + if (NattablePropertyEditor.this.resource != null) { + try { + NattablePropertyEditor.this.resource.save(saveOptions); + } catch (IOException e1) { + Activator.log.error(e1); + } + } + try { + NattablePropertyEditor.this.serviceRegistry.disposeRegistry(); + } catch (ServiceMultiException e1) { + Activator.log.error(e1); + } + NattablePropertyEditor.this.serviceRegistry = null; + NattablePropertyEditor.this.table = null; + + } } }; } @@ -479,6 +952,26 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { } /** + * + * @param domain + * the editing domain + * @param table + * the table to clean before dispose + * @return + * the command to use to clean the table before disposing it + * @since 2.0 + */ + protected CompoundCommand getDisposeCommand(final TransactionalEditingDomain domain, final Table table) { + CompoundCommand disposeCommand = new CompoundCommand("Command used to clean the table before disposing it"); //$NON-NLS-1$ + disposeCommand.append(SetCommand.create(domain, table, NattablePackage.eINSTANCE.getTable_Context(), null)); + disposeCommand.append(SetCommand.create(domain, table, NattablePackage.eINSTANCE.getTable_Owner(), null)); + // assuming the table is synchronized and not inverted : + disposeCommand.append(SetCommand.create(domain, table.getCurrentRowAxisProvider(), NattableaxisproviderPackage.eINSTANCE.getAxisProvider_Axis(), Collections.emptyList())); + + return disposeCommand; + } + + /** * {@inheritDoc} * * @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#unhookDataSourceListener(org.eclipse.papyrus.infra.properties.ui.modelelement.DataSource) @@ -501,7 +994,7 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { /** * This allow to create the data source listener. * - * @return The created data source listeer. + * @return The created data source listener. */ private IDataSourceListener getDataSourceListener() { if (dataSourceListener == null) { @@ -535,7 +1028,7 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { } // Get the model element - if(0 < contexts.size()){ + if (0 < contexts.size()) { final ModelElement modelElement = dataSource.getModelElement(propertyPath); EObject sourceElement = EMFHelper.getEObject(contexts.get(0)); EStructuralFeature feature = null; @@ -550,7 +1043,7 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { final EMFModelElement emfModelElement = (EMFModelElement) modelElement; feature = emfModelElement.getFeature(getLocalPropertyPath()); } - + // Recreate the table widget createTableWidget(sourceElement, feature, contexts); } @@ -560,4 +1053,25 @@ public class NattablePropertyEditor extends AbstractPropertyEditor { return dataSourceListener; } + + /** + * + * @param domain + * the editing domain to use + * @param resource + * the resource where the table must be saved + * @param table + * the table to add to the resource + * @return + * the command to add the table to the resource + */ + private static final Command addTableToResource(final TransactionalEditingDomain domain, final Resource resource, final Table table) { + return new RecordingCommand(domain) { + + @Override + protected void doExecute() { + resource.getContents().add(table); + } + }; + } } diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/StereotypeDisplayNattablePropertyEditor.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/StereotypeDisplayNattablePropertyEditor.java index 5d479a90033..c0d51e833a8 100644 --- a/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/StereotypeDisplayNattablePropertyEditor.java +++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/StereotypeDisplayNattablePropertyEditor.java @@ -16,15 +16,18 @@ import java.util.Collection; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.hideshow.RowHideShowLayer; import org.eclipse.nebula.widgets.nattable.hideshow.command.RowHideCommand; +import org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager; import org.eclipse.papyrus.infra.nattable.manager.table.TreeNattableModelManager; +import org.eclipse.papyrus.infra.nattable.utils.AxisUtils; import org.eclipse.swt.widgets.Composite; /** * The property editor for the stereotype display nattable widget. */ -public class StereotypeDisplayNattablePropertyEditor extends NattablePropertyEditor { +public class StereotypeDisplayNattablePropertyEditor extends TreeNattablePropertyEditor { /** * Constructor. @@ -43,7 +46,10 @@ public class StereotypeDisplayNattablePropertyEditor extends NattablePropertyEdi * * @see org.eclipse.papyrus.uml.properties.widgets.NattablePropertyEditor#configureTreeTable(org.eclipse.papyrus.infra.nattable.manager.table.TreeNattableModelManager, org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, * java.util.Collection) + * + * @deprecated since 2.0, done in the override of {@link #createNatTableWidget(INattableModelManager, Composite, int, Collection)} */ + @Deprecated @Override protected void configureTreeTable(TreeNattableModelManager nattableManager, final EObject sourceElement, final EStructuralFeature feature, final Collection<?> rows) { super.configureTreeTable(nattableManager, sourceElement, feature, rows); @@ -56,4 +62,30 @@ public class StereotypeDisplayNattablePropertyEditor extends NattablePropertyEdi } } } + + /** + * @see org.eclipse.papyrus.uml.properties.widgets.NattablePropertyEditor#createNatTableWidget(org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager, org.eclipse.swt.widgets.Composite, int, Collection) + * + * @param manager + * @param parent + * @param style + * @return + */ + @Override + protected NatTable createNatTableWidget(INattableModelManager manager, Composite parent, int style, Collection<?> rows) { + NatTable natTable = super.createNatTableWidget(manager, parent, style, rows); + // Bug 470252 : This allow to remove the 'view' rows + if (null != rows && !rows.isEmpty()) { + // the widget is already expanded + final RowHideShowLayer layer = nattableManager.getBodyLayerStack().getRowHideShowLayer(); + for (Object current : manager.getRowElementsList()) { + if (rows.contains(AxisUtils.getRepresentedElement(current))) { + int index = manager.getRowElementsList().indexOf(current); + int realIndex = layer.underlyingToLocalRowPosition(natTable, index); + natTable.doCommand(new RowHideCommand(layer, realIndex)); + } + } + } + return natTable; + } } diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/TreeNattablePropertyEditor.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/TreeNattablePropertyEditor.java new file mode 100644 index 00000000000..e6d5edea2a2 --- /dev/null +++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties/src/org/eclipse/papyrus/uml/properties/widgets/TreeNattablePropertyEditor.java @@ -0,0 +1,98 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.properties.widgets; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.command.AddCommand; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.infra.nattable.model.nattable.Table; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxis.IAxis; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.TableHeaderAxisConfiguration; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider; +import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.NattableaxisproviderPackage; +import org.eclipse.papyrus.infra.nattable.tree.ITreeItemAxisHelper; +import org.eclipse.papyrus.infra.nattable.utils.HeaderAxisConfigurationManagementUtils; +import org.eclipse.papyrus.infra.nattable.utils.TableHelper; +import org.eclipse.swt.widgets.Composite; + +/** + * @author VL222926 + * @since 2.0 + * + * Nattable Editor to use for tree table + * + */ +public class TreeNattablePropertyEditor extends NattablePropertyEditor { + + /** + * Constructor. + * + * @param parent + * @param style + */ + public TreeNattablePropertyEditor(Composite parent, int style) { + super(parent, style); + } + + /** + * @see org.eclipse.papyrus.uml.properties.widgets.NattablePropertyEditor#configureTable(org.eclipse.emf.transaction.TransactionalEditingDomain, org.eclipse.papyrus.infra.nattable.model.nattable.Table, org.eclipse.emf.ecore.EObject, + * org.eclipse.emf.ecore.EStructuralFeature, java.util.Collection, org.eclipse.emf.common.command.CompoundCommand) + * + * @param domain + * @param table + * @param sourceElement + * @param synchronizedFeature + * @param rows + * @param command + */ + @Override + protected void configureTable(TransactionalEditingDomain domain, Table table, EObject sourceElement, EStructuralFeature synchronizedFeature, Collection<?> rows, CompoundCommand command) { + super.configureTable(domain, table, sourceElement, synchronizedFeature, rows, command); + if (TableHelper.isTreeTable(table) && null != rows && !rows.isEmpty()) {// add test on TreeTable to fix bug 476623 + final AbstractAxisProvider axisProvider = table.getCurrentRowAxisProvider(); + TableHeaderAxisConfiguration conf = (TableHeaderAxisConfiguration) HeaderAxisConfigurationManagementUtils.getRowAbstractHeaderAxisInTableConfiguration(table); + AxisManagerRepresentation rep = conf.getAxisManagers().get(0); + for (Object context : rows) { + addTreeItemAxis(domain, axisProvider, rep, context, command); + } + } + } + + /** + * This allow to add the tree item axis. + * + * @param axisProvider + * The axis provider. + * @param rep + * The axis manager representation. + * @param object + * The object to add. + * + */ + protected void addTreeItemAxis(final TransactionalEditingDomain domain, final AbstractAxisProvider axisProvider, final AxisManagerRepresentation rep, final Object object, final CompoundCommand command) { + if (object instanceof View && isStereotypedElement((View) object)) { + final IAxis axis = ITreeItemAxisHelper.createITreeItemAxis(null, null, object, rep); + Command addCommand = AddCommand.create(getTableEditingDomain(), axisProvider, NattableaxisproviderPackage.eINSTANCE.getAxisProvider_Axis(), Collections.singleton(axis)); + command.append(addCommand); + } + } +} |