blob: dbc77f9318a2ef5f9b9046bbee5d28e4f3eb8052 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2021 CEA LIST 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
* http://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Asma Smaoui (CEA LIST) asma.smaoui@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.aas.ui.widgets;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
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 java.util.Objects;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
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.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.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.editparts.AbstractEditPart;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.papyrus.aas.ConceptDescription;
import org.eclipse.papyrus.aas.HasSemantics;
import org.eclipse.papyrus.aas.Reference;
import org.eclipse.papyrus.aas.profile.ui.Activator;
import org.eclipse.papyrus.aas.ui.utils.IAASElementTypes;
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.gmf.command.GMFtoEMFCommandWrapper;
import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
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;
import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.EStructuralFeatureValueFillingConfiguration;
import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.IAxisConfiguration;
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.NattablestyleFactory;
import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.NattablestylePackage;
import org.eclipse.papyrus.infra.nattable.model.nattable.nattablestyle.Style;
import org.eclipse.papyrus.infra.nattable.resource.TableResourceHelper;
import org.eclipse.papyrus.infra.nattable.tree.ITreeItemAxisHelper;
import org.eclipse.papyrus.infra.nattable.utils.HeaderAxisConfigurationManagementUtils;
import org.eclipse.papyrus.infra.nattable.utils.NamedStyleConstants;
import org.eclipse.papyrus.infra.nattable.utils.NattableModelManagerFactory;
import org.eclipse.papyrus.infra.nattable.utils.TableHelper;
import org.eclipse.papyrus.infra.nattable.utils.TableResourceConstants;
import org.eclipse.papyrus.infra.properties.contexts.Property;
import org.eclipse.papyrus.infra.properties.ui.modelelement.CompositeModelElement;
import org.eclipse.papyrus.infra.properties.ui.modelelement.DataSource;
import org.eclipse.papyrus.infra.properties.ui.modelelement.DataSourceChangedEvent;
import org.eclipse.papyrus.infra.properties.ui.modelelement.EMFModelElement;
import org.eclipse.papyrus.infra.properties.ui.modelelement.IDataSourceListener;
import org.eclipse.papyrus.infra.properties.ui.modelelement.ModelElement;
import org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.infra.widgets.creation.IAtomicOperationExecutor;
import org.eclipse.papyrus.uml.properties.modelelement.UMLNotationModelElement;
import org.eclipse.papyrus.uml.properties.widgets.TreeNattablePropertyEditor;
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.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyComposite;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.util.UMLUtil;
/**
* The property editor for the nattable widget.
*/
@SuppressWarnings("restriction")
public class AASNattablePropertyEditor extends AbstractPropertyEditor {
/**
* The save options to use.
*
* @deprecated since 3.0. Use TableResourceFactory.
*/
@Deprecated
private static final Map<Object, Object> saveOptions = new HashMap<>();
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 will 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 ?
*
* @deprecated since 3.0. Use TableResourceConstants.TABLE_FILE_EXTENSION.
*/
@Deprecated
@SuppressWarnings("unused")
private static final String FILE_EXTENSION = "table";//$NON-NLS-1$
/**
* The composite.
*/
protected Group self = null;;
/**
* The table configuration URI.
*/
private URI tableConfigURI = null;
/**
* The nattable widget.
*/
protected NatTable natTableWidget = null;
/**
* The nattable manager.
*/
protected INattableModelManager nattableManager = null;
/**
* The dispose listener.
*/
private DisposeListener nattableDisposeListener = null;
/**
* The data source listener.
*/
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
* The parent composite.
* @param style
* The style of the composite.
*/
public AASNattablePropertyEditor(final Composite parent, final int style) {
self = new Group(parent, SWT.NONE);
FillLayout fillLayout = new FillLayout();
fillLayout.marginHeight = 10;
fillLayout.marginWidth = 10;
self.setLayout(fillLayout);
}
/**
*
* @param newValue
* if <code>true</code> we register the table configuration by type AND by the ECLass of the selected element
* @since 2.0
*/
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 setTableConfigurationURI(final String uri) {
tableConfigURI = URI.createURI(uri);
checkInput();
}
/**
* Get the table configuration URI.
*
* @return The table configuration URI.
* @since 2.0
*
*/
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
*/
@Deprecated
public String getTableURI() {
return getTableConfigurationURI();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#checkInput()
*/
@Override
protected void checkInput() {
if (tableConfigURI != null) {
super.checkInput();
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#doBinding()
*/
@Override
protected void doBinding() {
super.doBinding();
// final ModelElement modelElement = input.getModelElement(propertyPath);
ModelElement modelElement = null;
final ModelElement modelElementHassemantic = input.getModelElement("AAS:HasSemantics:semanticId");
final ModelElement modelElementConceptDescription = input.getModelElement("AAS:ConceptDescription:isCaseOf");
// final ModelElement modelElementdataSpecification = input.getModelElement("AAS:HasDataSpecification:dataSpecification");
// final ModelElement modelElementMultiLanguageProp = input.getModelElement("AAS:MultiLanguageProperty:valueId");
final List<ModelElement> modelElements = new ArrayList(Arrays.asList(modelElementHassemantic, modelElementConceptDescription));
// final List<ModelElement> modelElements = new ArrayList(Arrays.asList(modelElementHassemantic, modelElementConceptDescription, modelElementdataSpecification, modelElementMultiLanguageProp));
if (modelElements.stream().filter(Objects::nonNull).findAny().isPresent()) {
modelElement = modelElements.stream().filter(Objects::nonNull).findAny().get();
}
// The data needed to create the table
final List<Object> rows = new ArrayList<>();
EObject sourceElement = null;
EStructuralFeature feature = null;
// Manage the data needed for the table creation
if (modelElement instanceof CompositeModelElement) {
if (!((CompositeModelElement) modelElement).getSubElements().isEmpty()) {
if (((CompositeModelElement) modelElement).getSubElements().get(0) instanceof UMLNotationModelElement) {
final EModelElement eModelElement = ((UMLNotationModelElement) ((CompositeModelElement) modelElement).getSubElements().get(0)).getEModelElement();
// Fill the list of views to determinate the axis to display (cannot be created without the table editing domain)
for (ModelElement subModelElement : ((CompositeModelElement) modelElement).getSubElements()) {
if (subModelElement instanceof UMLNotationModelElement) {
rows.add(((UMLNotationModelElement) subModelElement).getEModelElement());
}
}
sourceElement = eModelElement;
} else if (((CompositeModelElement) modelElement).getSubElements().get(0) instanceof EMFModelElement) {
final EMFModelElement emfModelElement = (EMFModelElement) ((CompositeModelElement) modelElement).getSubElements().get(0);
sourceElement = emfModelElement.getSource();
feature = emfModelElement.getFeature(getLocalPropertyPath());
}
}
} else if (modelElement instanceof UMLNotationModelElement) {
final EModelElement eModelElement = ((UMLNotationModelElement) modelElement).getEModelElement();
// Fill the list of views to determinate the axis to display (cannot be created without the table editing domain)
rows.add(eModelElement);
sourceElement = eModelElement;
} else if (modelElement instanceof EMFModelElement) {
final EMFModelElement emfModelElement = (EMFModelElement) modelElement;
EObject source = emfModelElement.getSource();
// case of hasSemantic
if (source != null && source instanceof HasSemantics) {
if (((HasSemantics) source).getSemanticId() != null) {
source = ((HasSemantics) source).getSemanticId();
} else {
Element element = UMLUtil.getBaseElement(source);
HasSemantics has = (HasSemantics) source;
getOperationExecutor(element).execute(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
if (element instanceof Element) {
Element container = element.getModel();
EditingDomain domain = EMFHelper.resolveEditingDomain(container);
IElementType referenceElementType = ElementTypeRegistry.getInstance().getType(IAASElementTypes.REFERENCE_ID);
CreateElementRequest request = null;
request = new CreateElementRequest((TransactionalEditingDomain) domain, container, referenceElementType);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
ICommand createReference = provider.getEditCommand(request);
if (createReference.canExecute()) {
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(createReference));
Object result = createReference.getCommandResult().getReturnValue();
Reference reference = getReference(result);
has.setSemanticId(reference);
} else {
System.out.println("can not execute command");
}
}
}
}, "message");
// Create the Reference if the sourceElement is a HasSemantic
source = ((HasSemantics) source).getSemanticId();
}
} // case of ConceptDescription
else if (source != null && source instanceof ConceptDescription) {
if (((ConceptDescription) source).getIsCaseOf() != null && !((ConceptDescription) source).getIsCaseOf().isEmpty()) {
source = ((ConceptDescription) source).getIsCaseOf().get(0);
} else {
Element element = UMLUtil.getBaseElement(source);
ConceptDescription cons = (ConceptDescription) source;
getOperationExecutor(element).execute(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
if (element instanceof Element) {
Element container = element.getModel();
EditingDomain domain = EMFHelper.resolveEditingDomain(container);
IElementType referenceElementType = ElementTypeRegistry.getInstance().getType(IAASElementTypes.REFERENCE_ID);
CreateElementRequest request = null;
request = new CreateElementRequest((TransactionalEditingDomain) domain, container, referenceElementType);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
ICommand createReference = provider.getEditCommand(request);
if (createReference.canExecute()) {
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(createReference));
Object result = createReference.getCommandResult().getReturnValue();
Reference reference = getReference(result);
cons.getIsCaseOf().add(reference);
} else {
System.out.println("can not execute command");
}
}
}
}, "message");
// Create the Reference if the sourceElement is a HasSemantic
source = ((ConceptDescription) source).getIsCaseOf().get(0);
}
}
if (!(source instanceof Element)) {
final Element baseElement = UMLUtil.getBaseElement(source);
if (baseElement != null) {// in other case we will get an exeption somewhere
source = baseElement;
}
}
sourceElement = source;
if (emfModelElement.getSource() instanceof HasSemantics) {
feature = emfModelElement.getFeature("semanticId");
} else if (emfModelElement.getSource() instanceof ConceptDescription) {
feature = emfModelElement.getFeature("isCaseOf");
}
// rows.add(emfModelElement);
} else {
displayError("Invalid table context"); //$NON-NLS-1$
return;
}
// Create the widgets
createWidgets(sourceElement, feature, rows);
}
/**
* This allow to create the widgets.
*
* @param sourceElement
* The source Element.
* @param feature
* The feature.
* @param rows
* The rows of the table.
* @since 2.0
*/
protected void createWidgets(final EObject sourceElement, final EStructuralFeature feature, final Collection<?> rows) {
createPreviousWidgets(sourceElement, feature);
createTableWidget(sourceElement, feature, rows);
createFollowingWidgets(sourceElement, feature);
// Configure the layout and the layout data
configureLayout(sourceElement);
self.layout();
}
/**
* This allow to create the widgets displayed before the table widget.
*
* @param sourceElement
* The source Element.
* @param feature
* The feature.
* @since 2.0
*/
protected void createPreviousWidgets(final EObject sourceElement, final EStructuralFeature feature) {
// To implement if some widgets are needed before 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.
* @param feature
* 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;
}
// 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;
}
// 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));
}
// 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;
}
final ResourceSet resourceSet = getResourceSet();
// Bug 502160: Remove the resource from the resource set to execute the command without using the editing command stack
resourceSet.getResources().remove(this.resource);
try {
GMFUnsafe.write(domain, cc);
} catch (InterruptedException e) {
// Activator.log.error(e);
} catch (RollbackException e) {
// Activator.log.error(e);
} finally {
// Bug 502160: Re-add the removed resource before the command execute
resourceSet.getResources().add(this.resource);
}
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();
}
/**
* This allow to create the widgets displayed after the table widget.
*
* @param sourceElement
* The source Element.
* @param feature
* The feature.
* @since 2.0
*/
protected void createFollowingWidgets(final EObject sourceElement, final EStructuralFeature feature) {
// To implement if some widgets are needed after the table widget
}
/**
*
* @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;
}
/**
* This allows to configure the tree table.
*
* @param nattableManager
* The nattable model manager.
* @param sourceElement
* The source Element.
* @param feature
* 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 nothing
}
/**
* This allows to configure the layout and the layout data.
*
* @deprecated since 2.0.0
*/
@Deprecated
protected void configureLayout() {
// Adapt the group to the table preferred size
final GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
// The preferred height of the nattable calculate it for each row (even if some are hidden)
// So to calculate the correct height for the composite :
// - Calculate the header height
// - Calculate the body height
// Add these values and add some extra to have correct displays
final int headerHeight = natTableWidget.getPreferredHeight() - nattableManager.getBodyLayerStack().getRowHideShowLayer().getPreferredHeight();
final int bodyHeight = nattableManager.getBodyLayerStack().getRowHideShowLayer().getHeight();
// 16px must be added because of the left area slider
final int extra = 20 + 16;
data.minimumHeight = headerHeight + bodyHeight + extra;
self.setLayoutData(data);
self.layout();
natTableWidget.layout();
}
/**
* This allows to configure the layout and the layout data.
*
* @param sourceElement
* The source element.
* @since 2.0
*/
protected void configureLayout(final EObject sourceElement) {
// must be done first!
((NattableModelManager) nattableManager).refreshNatTable();
// Configure the size of the parent container
configureSize(sourceElement);
natTableWidget.layout();
}
/**
* This allows to configure the size of the parent container.
*
* @param sourceElement
* The source element.
* @since 2.0
*/
protected void configureSize(final EObject sourceElement) {
// Adapt the group to the table preferred size
final GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
// The preferred height of the nattable calculate it for each row (even if some are hidden)
// So to calculate the correct height for the composite :
// - Calculate the header height
// - Calculate the body height
// Add these values and add some extra to have correct displays
final int headerHeight = natTableWidget.getPreferredHeight() - nattableManager.getBodyLayerStack().getRowHideShowLayer().getPreferredHeight();
final int bodyHeight = nattableManager.getBodyLayerStack().getRowHideShowLayer().getHeight();
// 16px must be added because of the left area slider
final int extra = 20 + 16;
data.minimumHeight = headerHeight + bodyHeight + extra;
self.setLayoutData(data);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#updateDescription(java.lang.String)
*/
@Override
protected void updateDescription(String description) {
self.setToolTipText(description);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#updateLabel(java.lang.String)
*/
@Override
public void updateLabel(final String label) {
if (showLabel) {
self.setText(getLabel());
}
}
/**
* This allow to display the error.
*
* @param message
* The error message to display.
*/
protected void displayError(final String message) {
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 or 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();
// Install the table support to manage the table as a correct Resource
TableResourceHelper.installTableSupport(resourceSet);
((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() != 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;
}
/**
* Create URI for the table configuration.
*
* @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) {
// If the source element has an EClass, the table configuration file name
// will be suffixed by the name of its eClass
setRegisterTableConfigurationByEClass((sourceElement != null) && (sourceElement.eClass() != null));
IPath preferencePath = InternalPlatform.getDefault().getStateLocation(Activator.getContext().getBundle(), true);
// 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) {
ModelElement modelElement = input.getModelElement(propertyPath);
EClass eClass = null;
if (modelElement instanceof CompositeModelElement) {
CompositeModelElement compoModelElement = (CompositeModelElement) modelElement;
for (ModelElement next : compoModelElement.getSubElements()) {
if ((next instanceof UMLNotationModelElement)
|| (next instanceof EMFModelElement)) {
modelElement = next;
break;
}
}
}
if (modelElement instanceof UMLNotationModelElement) {
EditPart part = ((UMLNotationModelElement) modelElement).getEditPart();
eClass = EMFHelper.getEObject(part).eClass();
} else if (modelElement instanceof EMFModelElement) {
EObject source = ((EMFModelElement) modelElement).getSource();
if (source != null) {
eClass = source.eClass();
}
}
if (eClass != null) {
b.append("_"); //$NON-NLS-1$
b.append(eClass.getName());
}
}
URI newURI = URI.createFileURI(b.toString()).appendFileExtension(TableResourceConstants.TABLE_FILE_EXTENSION);
return newURI;
}
/**
* 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.
*
* @since 2.0
*/
protected Table createTable(final EObject sourceElement, final EStructuralFeature synchronizedFeature) {
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());
// for table used in property view, the kindId was null, because it is given by the AF. So we propose to use the type for kindId
table.setTableKindId(table.getTableConfiguration().getType());
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);
}
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));
}
// for the table displayed in property view, we want to use all the available place, so we add a specific named style each time
// We manage it with percentage named style
BooleanValueStyle columnsWidthAsPercentage = (BooleanValueStyle) table.getNamedStyle(NattablestylePackage.eINSTANCE.getBooleanValueStyle(), NamedStyleConstants.COLUMNS_WIDTH_AS_PERCENTAGE);
// if the name style already exists we do nothing
if (null == columnsWidthAsPercentage) {
// for the table displayed in property view, we want to use all the available place, so we add a specific named style each time
BooleanValueStyle fillStyle = (BooleanValueStyle) table.getNamedStyle(NattablestylePackage.eINSTANCE.getBooleanValueStyle(), NamedStyleConstants.FILL_COLUMNS_SIZE);
// if the name style already exists we do nothing
if (null == fillStyle) {
columnsWidthAsPercentage = NattablestyleFactory.eINSTANCE.createBooleanValueStyle();
columnsWidthAsPercentage.setName(NamedStyleConstants.COLUMNS_WIDTH_AS_PERCENTAGE);
columnsWidthAsPercentage.setBooleanValue(true);
table.getStyles().add(columnsWidthAsPercentage);
}
}
// for the table displayed in property view, we expand all directly
BooleanValueStyle expandStyle = (BooleanValueStyle) table.getNamedStyle(NattablestylePackage.eINSTANCE.getBooleanValueStyle(), NamedStyleConstants.EXPAND_ALL);
// if the name style already exists we do nothing
if (null == expandStyle) {
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;
}
/**
*
* @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;
}
/**
* Get the table configuration (from the table configuration URI).
*
* @return The table configuration.
*/
protected TableConfiguration getTableConfiguration() {
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 this.tableConfiguration;
}
/**
* This allow to create the dispose listener for the nattable table manager.
*
* @return The dispose nattable manager listener.
*/
protected DisposeListener getDisposeListener() {
if (null == this.nattableDisposeListener) {
this.nattableDisposeListener = new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
disposeListener();
}
};
}
return nattableDisposeListener;
}
/**
* This allows to dispose the listeners.
*
* @since 2.0
*/
protected void disposeListener() {
if (AASNattablePropertyEditor.this.serviceRegistry != null) {
// we dispose it to avoid unecessary refresh
if (null != this.nattableManager) {
this.nattableManager.dispose();
}
if (null != this.natTableWidget) {
this.natTableWidget.dispose();
}
if (AASNattablePropertyEditor.this.resource != null) {
try {
AASNattablePropertyEditor.this.resource.save(null);
} catch (IOException e1) {
Activator.log.error(e1);
}
}
try {
AASNattablePropertyEditor.this.serviceRegistry.disposeRegistry();
} catch (ServiceMultiException e1) {
Activator.log.error(e1);
}
AASNattablePropertyEditor.this.serviceRegistry = null;
AASNattablePropertyEditor.this.table = null;
}
}
/**
*
* @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
* @deprecated since 3.0
*/
@Deprecated
protected CompoundCommand getDisposeTableCommand(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)
*/
@Override
protected void unhookDataSourceListener(DataSource oldInput) {
oldInput.removeDataSourceListener(getDataSourceListener());
}
/**
* {@inheritDoc}
*
* @see org.eclipse.papyrus.infra.properties.ui.widgets.AbstractPropertyEditor#hookDataSourceListener(org.eclipse.papyrus.infra.properties.ui.modelelement.DataSource)
*/
@Override
protected void hookDataSourceListener(DataSource newInput) {
newInput.addDataSourceListener(getDataSourceListener());
}
public static Reference getReference(Object result) {
Reference ref = null;
if (result != null) {
ref = UMLUtil.getStereotypeApplication((Element) result, Reference.class);
}
return ref;
}
public static ConceptDescription getConceptDescription(EObject sourceElement) {
ConceptDescription conceptDescription = null;
if (sourceElement != null && sourceElement instanceof Element) {
conceptDescription = UMLUtil.getStereotypeApplication((Element) sourceElement, ConceptDescription.class);
}
return conceptDescription;
}
public static HasSemantics gethasSemantic(EObject sourceElement) {
HasSemantics HasSem = null;
if (sourceElement != null && sourceElement instanceof Element) {
HasSem = UMLUtil.getStereotypeApplication((Element) sourceElement, HasSemantics.class);
}
return HasSem;
}
/**
* This allow to create the data source listener.
*
* @return The created data source listener.
*/
private IDataSourceListener getDataSourceListener() {
if (dataSourceListener == null) {
dataSourceListener = new IDataSourceListener() {
@Override
public void dataSourceChanged(final DataSourceChangedEvent event) {
// bug 494537 - The diagram selection changed, but the property view has not been disposed
disposeListener();
// Bug 492560: The self children control was not all disposed correclty
if (null != self) {
if (self.getChildren().length > 0) {
for (Control control : self.getChildren()) {
control.dispose();
}
}
self.removeDisposeListener(getDisposeListener());
nattableDisposeListener = null;
self.layout();
}
// Get the datasource
final DataSource dataSource = event.getDataSource();
final StructuredSelection selection = (StructuredSelection) dataSource.getSelection();
// Manage the context selection
final List<Object> contexts = new ArrayList<>(selection.size());
EObject sourceElement = null;
final Iterator<?> selectionIterator = selection.iterator();
while (selectionIterator.hasNext()) {
Object selectedObject = selectionIterator.next();
if (selectedObject instanceof AbstractEditPart) {
// contexts.add(((AbstractEditPart) selectedObject).getModel());
} else {
// contexts.add(selectedObject);
}
if (sourceElement == null) {
// An edit-part in GMF can resolve its semantic element
// to something different to the element referenced by
// its notation view, so don't rely on the notation
sourceElement = EMFHelper.getEObject(selectedObject);
}
}
// Get the model element
if (sourceElement != null) {
ModelElement modelElement = null;
if (gethasSemantic(sourceElement) != null) {
modelElement = dataSource.getModelElement("AAS:HasSemantics:semanticId");
} else if (getConceptDescription(sourceElement) != null) {
modelElement = dataSource.getModelElement("AAS:ConceptDescription:isCaseOf");
}
sourceElement = getEObjectAsTableContext(sourceElement); // Convert to table context
EStructuralFeature feature = null;
if (modelElement instanceof CompositeModelElement) {
if (!((CompositeModelElement) modelElement).getSubElements().isEmpty()) {
if (((CompositeModelElement) modelElement).getSubElements().get(0) instanceof EMFModelElement) {
final EMFModelElement emfModelElement = (EMFModelElement) ((CompositeModelElement) modelElement).getSubElements().get(0);
if (emfModelElement instanceof HasSemantics) {
feature = emfModelElement.getFeature("semanticId");
} else if (emfModelElement instanceof ConceptDescription) {
feature = emfModelElement.getFeature("isCaseOf");
}
}
}
} else if (modelElement instanceof EMFModelElement) {
final EMFModelElement emfModelElement = (EMFModelElement) modelElement;
if (sourceElement != null && gethasSemantic(sourceElement) != null) {
if (gethasSemantic(sourceElement).getSemanticId() != null) {
sourceElement = gethasSemantic(sourceElement).getSemanticId();
}
} else if (sourceElement != null && getConceptDescription(sourceElement) != null) {
if (getConceptDescription(sourceElement).getIsCaseOf() != null && getConceptDescription(sourceElement).getIsCaseOf().isEmpty()) {
sourceElement = getConceptDescription(sourceElement).getIsCaseOf().get(0);
}
}
if (!(sourceElement instanceof Element)) {
final Element baseElement = UMLUtil.getBaseElement(sourceElement);
if (baseElement != null) {// in other case we will get an exeption somewhere
sourceElement = baseElement;
}
}
if (gethasSemantic(sourceElement) != null || getConceptDescription(sourceElement) != null) {
HasSemantics has = gethasSemantic(sourceElement);
ConceptDescription cons = getConceptDescription(sourceElement);
if (has != null && has.getSemanticId() == null) {
Element element = (Element) sourceElement;
getOperationExecutor(element).execute(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
if (element instanceof Element) {
Element container = element.getModel();
EditingDomain domain = EMFHelper.resolveEditingDomain(container);
IElementType referenceElementType = ElementTypeRegistry.getInstance().getType(IAASElementTypes.REFERENCE_ID);
CreateElementRequest request = null;
request = new CreateElementRequest((TransactionalEditingDomain) domain, container, referenceElementType);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
ICommand createReference = provider.getEditCommand(request);
if (createReference.canExecute()) {
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(createReference));
Object result = createReference.getCommandResult().getReturnValue();
Reference reference = getReference(result);
has.setSemanticId(reference);
} else {
System.out.println("can not execute command");
}
}
}
}, "message");
// Create the Reference if the sourceElement is a HasSemantic
} else if (cons != null && (cons.getIsCaseOf() == null || cons.getIsCaseOf().isEmpty())) {
Element element = (Element) sourceElement;
getOperationExecutor(element).execute(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
if (element instanceof Element) {
Element container = element.getModel();
EditingDomain domain = EMFHelper.resolveEditingDomain(container);
IElementType referenceElementType = ElementTypeRegistry.getInstance().getType(IAASElementTypes.REFERENCE_ID);
CreateElementRequest request = null;
request = new CreateElementRequest((TransactionalEditingDomain) domain, container, referenceElementType);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
ICommand createReference = provider.getEditCommand(request);
if (createReference.canExecute()) {
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(createReference));
Object result = createReference.getCommandResult().getReturnValue();
Reference reference = getReference(result);
cons.getIsCaseOf().add(reference);
} else {
System.out.println("can not execute command");
}
}
}
}, "message");
// Create the Reference if the sourceElement is a HasSemantic
}
if (has != null) {
sourceElement = UMLUtil.getBaseElement(has.getSemanticId());
feature = emfModelElement.getFeature("semanticId");
} else if (cons != null) {
sourceElement = UMLUtil.getBaseElement(cons.getIsCaseOf().get(0));
feature = emfModelElement.getFeature("isCaseOf");
}
}
// Recreate the table widget, its adjuncts, and their layout
createWidgets(sourceElement, feature, contexts);
// We need to refresh the parent composite to get the needed space
Composite parent = self.getParent();
boolean found = false;
while (null != parent && !found) {
if (parent instanceof TabbedPropertyComposite) {
found = true;
} else {
parent.layout(true, true);
parent.redraw();
parent.update();
}
parent = parent.getParent();
}
}
}
}
};
}
return dataSourceListener;
}
/**
* This allows to get the table context as EObject (and avoid View).
*
* @param element
* The initial source element.
* @return The source element defining Table context.
* @since 2.1
*/
protected EObject getEObjectAsTableContext(final EObject element) {
EObject result = element;
if (result instanceof View) {
result = ((View) result).getElement();
}
return result;
}
/**
*
* @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);
}
};
}
/**
* @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
*/
protected void configureTable(TransactionalEditingDomain domain, Table table, EObject sourceElement, 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);
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) {
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);
}
public IAtomicOperationExecutor getOperationExecutor(Object context) {
IAtomicOperationExecutor result;
if (context instanceof IAdaptable) {
result = ((IAdaptable) context).getAdapter(IAtomicOperationExecutor.class);
} else if (context != null) {
result = Platform.getAdapterManager().getAdapter(context, IAtomicOperationExecutor.class);
} else {
// We can't adapt null, of course, so we will have to settle for the default executor
result = null;
}
if (result == null) {
result = IAtomicOperationExecutor.DEFAULT;
}
return result;
}
}