Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui')
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/api/helper/TreeUIHelper.java113
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/HierarchyLabelTreeProvider.java95
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUI.java35
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUIServices.java325
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/propertysource/TreeCompositeEObjectPropertySource.java40
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/common/AbstractDTreePropertySection.java383
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/core/CorePropertySection.java80
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/semantic/SemanticPropertySection.java130
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/api/editor/DTreeEditor.java41
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/CreateLineCommandFromToolRecordingCommand.java84
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/EMFCommandFactoryUI.java31
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeActionBarContributor.java46
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java666
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeMenuListener.java426
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewer.java111
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java493
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/RefreshAtOpeningActivator.java83
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolAction.java107
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolItemAction.java85
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateRepresentationFromRepresentationCreationDescription.java143
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateToolItemAction.java193
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/DeleteTreeItemsAction.java158
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorCreateTreeItemMenuAction.java189
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorRefreshAction.java100
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/OpenRepresentationAction.java96
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/RefreshAction.java140
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeItemExpansionChecker.java142
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeViewerListener.java115
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/preferences/SiriusPreferenceChangeListener.java51
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeColumnLabelProvider.java176
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java290
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java139
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeDecoratingLabelProvider.java56
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDragListener.java92
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDropListener.java518
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditingSupport.java298
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditorFocusListener.java160
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreePopupMenuContributionSupport.java339
38 files changed, 6769 insertions, 0 deletions
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/api/helper/TreeUIHelper.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/api/helper/TreeUIHelper.java
new file mode 100644
index 0000000000..e1c77d4b2e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/api/helper/TreeUIHelper.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.business.api.helper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+import org.eclipse.sirius.tree.DTreeItem;
+
+/**
+ * Utility methods to handle Tree models.
+ *
+ * @author jdupont
+ */
+public final class TreeUIHelper {
+
+ private TreeUIHelper() {
+
+ }
+
+ /**
+ * Add elements to a tree descriptor.
+ *
+ * @param expected
+ * tree descriptor to update.
+ * @param str
+ * data to add.
+ */
+ public static void addLineToTree(final List<String> expected, final String str) {
+ expected.add(str);
+ }
+
+ /**
+ * Export the given tree to HTML format.
+ *
+ * @param tree
+ * tree to export.
+ * @return a string with the HTML tree.
+ */
+ public static String toContentHTMl(final Tree tree) {
+ return TreeUIHelper.toHTML(TreeUIHelper.toTreeDescriptor(tree));
+ }
+
+ /**
+ * Transform a graphical tree to a tree descriptor.
+ *
+ * @param tree
+ * tree to transform.
+ * @return a list of element representing the tree.
+ */
+ public static List<String> toTreeDescriptor(final Tree tree) {
+ final List<String> expected = new ArrayList<String>();
+ for (final TreeItem treeItem : tree.getItems()) {
+ expected.add(treeItem.getText());
+ if (treeItem.getData() instanceof DTreeItem) {
+ for (String str : TreeUIHelper.addLineToDescriptor(((DTreeItem) treeItem.getData()).getOwnedTreeItems())) {
+ expected.add(str);
+ }
+ }
+ }
+ return expected;
+ }
+
+ private static List<String> addLineToDescriptor(EList<DTreeItem> treeItemSpecs) {
+ final List<String> expected = new ArrayList<String>();
+ for (final DTreeItem dTreeItem : treeItemSpecs) {
+ expected.add(dTreeItem.getName());
+ if (!dTreeItem.getOwnedTreeItems().isEmpty()) {
+ for (String str : TreeUIHelper.addLineToDescriptor(dTreeItem.getOwnedTreeItems())) {
+ expected.add(str);
+ }
+ // addLineToDescriptor(dTreeItem.getOwnedTreeItems());
+ }
+ }
+ return expected;
+
+ }
+
+ /**
+ * Transform a tree descriptor to an HTML representation.
+ *
+ * @param descriptor
+ * the tree descriptor.
+ * @return an HTML tree.
+ */
+ public static String toHTML(final List<String> descriptor) {
+ final StringBuffer result = new StringBuffer();
+ result.append("<table>\n");
+ for (String line : descriptor) {
+ result.append("<tr>");
+ result.append("<td>");
+ result.append(line);
+ result.append("</td>");
+ result.append("</tr>\n");
+
+ }
+ result.append("</table>");
+ return result.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/HierarchyLabelTreeProvider.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/HierarchyLabelTreeProvider.java
new file mode 100644
index 0000000000..953cc87452
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/HierarchyLabelTreeProvider.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2009 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.business.internal.dialect;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
+import org.eclipse.sirius.description.AbstractNodeMapping;
+import org.eclipse.sirius.description.Group;
+import org.eclipse.sirius.description.IdentifiedElement;
+import org.eclipse.sirius.tree.description.TreeDescription;
+import org.eclipse.sirius.tree.description.TreeMapping;
+import org.eclipse.sirius.tree.description.TreeNavigationDescription;
+
+/**
+ * A label provider for mappings to display their hierarchy.
+ *
+ * @author jdupont
+ */
+public class HierarchyLabelTreeProvider extends LabelProvider {
+
+ private static final String DELIMITER = " > ";
+
+ private ILabelProvider wrappedProvider;
+
+ /**
+ * Create a new instance without existing providers.
+ */
+ public HierarchyLabelTreeProvider() {
+ }
+
+ /**
+ * Create a new instance with wrapped label provider as base type.
+ *
+ * @param wrappedLabelProvider
+ * the wrapped label provider
+ */
+ public HierarchyLabelTreeProvider(final ILabelProvider wrappedLabelProvider) {
+ this.wrappedProvider = wrappedLabelProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(final Object element) {
+ return wrappedProvider != null ? wrappedProvider.getImage(element) : super.getImage(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(final Object element) {
+ if (element instanceof TreeMapping || element instanceof TreeDescription || element instanceof TreeNavigationDescription) {
+ final IdentifiedElement mapping = (IdentifiedElement) element;
+ String text = mapping.getName();
+ EObject container = mapping.eContainer();
+ while (container != null && !(container instanceof Group)) {
+ text = getLabel(container) + DELIMITER + text;
+ container = container.eContainer();
+ }
+ return text;
+ }
+ return wrappedProvider != null ? wrappedProvider.getText(element) : super.getText(element);
+ }
+
+ private String getLabel(final EObject eObject) {
+
+ String label = null;
+
+ if (eObject instanceof IdentifiedElement) {
+ label = new IdentifiedElementQuery((IdentifiedElement) eObject).getLabel();
+ } else if (eObject instanceof AbstractNodeMapping) {
+ label = ((AbstractNodeMapping) eObject).getName();
+ }
+ return label != null ? label : "Element whithout name";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUI.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUI.java
new file mode 100644
index 0000000000..e9a2851571
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUI.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.business.internal.dialect;
+
+import org.eclipse.sirius.ui.business.api.dialect.DialectUI;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIServices;
+
+/**
+ * The UI part of the tree dialect.
+ *
+ * @author pcdavid
+ */
+public class TreeDialectUI implements DialectUI {
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return "tree";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DialectUIServices getServices() {
+ return new TreeDialectUIServices();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUIServices.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUIServices.java
new file mode 100644
index 0000000000..39f7b39e79
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/business/internal/dialect/TreeDialectUIServices.java
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.business.internal.dialect;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.DRepresentation;
+import org.eclipse.sirius.DRepresentationElement;
+import org.eclipse.sirius.DSemanticDecorator;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.description.DescriptionPackage;
+import org.eclipse.sirius.description.RepresentationDescription;
+import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.internal.metamodel.TreeToolVariables;
+import org.eclipse.sirius.tree.description.DescriptionFactory;
+import org.eclipse.sirius.tree.description.TreeCreationDescription;
+import org.eclipse.sirius.tree.description.TreeDescription;
+import org.eclipse.sirius.tree.description.TreeNavigationDescription;
+import org.eclipse.sirius.tree.provider.TreeItemProviderAdapterFactory;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeEditor;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIServices;
+import org.eclipse.sirius.ui.business.api.dialect.ExportFormat;
+import org.eclipse.sirius.ui.business.api.session.SessionEditorInput;
+
+/**
+ * Implementation of the UI services for the tree dialect.
+ *
+ * @author pcdavid
+ */
+public class TreeDialectUIServices implements DialectUIServices {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#canHandle(org.eclipse.sirius.DRepresentation)
+ */
+ public boolean canHandle(DRepresentation representation) {
+ return representation instanceof DTree;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#canHandleEditor(org.eclipse.ui.IEditorPart)
+ */
+ public boolean canHandleEditor(IEditorPart editorPart) {
+ return editorPart instanceof DTreeEditor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#openEditor(org.eclipse.sirius.business.api.session.Session,
+ * org.eclipse.sirius.DRepresentation)
+ */
+ public IEditorPart openEditor(Session session, DRepresentation representation) {
+ return openEditor(session, representation, new NullProgressMonitor());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IEditorPart openEditor(Session session, DRepresentation dRepresentation, IProgressMonitor monitor) {
+ IEditorPart editorPart = null;
+ try {
+ monitor.beginTask("tree opening", 10);
+ if (dRepresentation instanceof DTree) {
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.OPEN_TREE_KEY);
+ URI uri = EcoreUtil.getURI(dRepresentation);
+ final IEditorInput editorInput = new SessionEditorInput(uri, getEditorName(dRepresentation), session);
+ monitor.worked(2);
+ monitor.subTask("tree opening : " + dRepresentation.getName());
+ RunnableWithResult<IEditorPart> runnable = new RunnableWithResult.Impl<IEditorPart>() {
+ public void run() {
+ final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ setResult(page.openEditor(editorInput, DTreeEditor.ID));
+ } catch (final PartInitException e) {
+ // silent catch
+ }
+ }
+ };
+ PlatformUI.getWorkbench().getDisplay().syncExec(runnable);
+ monitor.worked(8);
+ IEditorPart result = runnable.getResult();
+ if (canHandleEditor(result)) {
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.OPEN_TREE_KEY);
+ editorPart = result;
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ return editorPart;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#getEditorName(org.eclipse.sirius.DRepresentation)
+ */
+ public String getEditorName(DRepresentation representation) {
+ String editorName = representation.getName();
+ if (StringUtil.isEmpty(editorName)) {
+ editorName = "New Tree";
+ }
+ return editorName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean closeEditor(IEditorPart editorPart, boolean save) {
+ boolean result = false;
+ if (canHandleEditor(editorPart)) {
+ try {
+ ((DTreeEditor) editorPart).close(save);
+ } catch (NullPointerException e) {
+ // we might have an exception closing an editor which is
+ // already in trouble
+ }
+ // We suppose it is closed.
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#isRepresentationManagedByEditor(org.eclipse.sirius.DRepresentation,
+ * org.eclipse.ui.IEditorPart)
+ */
+ public boolean isRepresentationManagedByEditor(DRepresentation representation, IEditorPart editorPart) {
+ boolean isRepresentationManagedByEditor = false;
+ if (canHandleEditor(editorPart)) {
+ DTreeEditor dTreeEditor = (DTreeEditor) editorPart;
+ isRepresentationManagedByEditor = dTreeEditor.getRepresentation() != null && dTreeEditor.getRepresentation().equals(representation);
+ }
+ return isRepresentationManagedByEditor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#isRepresentationDescriptionManagedByEditor(org.eclipse.sirius.description.RepresentationDescription,
+ * org.eclipse.ui.IEditorPart)
+ */
+ public boolean isRepresentationDescriptionManagedByEditor(RepresentationDescription representationDescription, IEditorPart editorPart) {
+ if (canHandleEditor(editorPart)) {
+ DTreeEditor dtreeEditor = (DTreeEditor) editorPart;
+ return EcoreUtil.equals(dtreeEditor.getTreeModel().getDescription(), representationDescription);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#createAdapterFactory()
+ */
+ public AdapterFactory createAdapterFactory() {
+ final ComposedAdapterFactory factory = new ComposedAdapterFactory();
+ factory.addAdapterFactory(new org.eclipse.sirius.tree.description.provider.DescriptionItemProviderAdapterFactory());
+ factory.addAdapterFactory(new TreeItemProviderAdapterFactory());
+ return factory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#canExport(org.eclipse.sirius.ui.business.api.dialect.ExportFormat)
+ */
+ public boolean canExport(ExportFormat format) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#export(org.eclipse.sirius.DRepresentation,
+ * org.eclipse.sirius.business.api.session.Session,
+ * org.eclipse.core.runtime.IPath,
+ * org.eclipse.sirius.ui.business.api.dialect.ExportFormat,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void export(DRepresentation representation, Session session, IPath path, ExportFormat format, IProgressMonitor monitor) {
+ // Nothing to do for trees.
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#provideNewChildDescriptors()
+ */
+ public Collection<CommandParameter> provideNewChildDescriptors() {
+ Collection<CommandParameter> newChilds = Lists.newArrayList();
+ TreeDescription treeDescription = org.eclipse.sirius.tree.description.DescriptionFactory.eINSTANCE.createTreeDescription();
+ newChilds.add(new CommandParameter(null, DescriptionPackage.Literals.VIEWPOINT__OWNED_REPRESENTATIONS, treeDescription));
+ return newChilds;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#provideRepresentationCreationToolDescriptors(java.lang.Object)
+ */
+ public Collection<CommandParameter> provideRepresentationCreationToolDescriptors(Object feature) {
+ Collection<CommandParameter> newChilds = Lists.newArrayList();
+ TreeCreationDescription treeCreationDescription = DescriptionFactory.eINSTANCE.createTreeCreationDescription();
+ new TreeToolVariables().doSwitch(treeCreationDescription);
+ newChilds.add(new CommandParameter(null, feature, treeCreationDescription));
+ return newChilds;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#provideRepresentationNavigationToolDescriptors(java.lang.Object)
+ */
+ public Collection<CommandParameter> provideRepresentationNavigationToolDescriptors(Object feature) {
+ Collection<CommandParameter> newChilds = Lists.newArrayList();
+ TreeNavigationDescription treeNavigationDescription = DescriptionFactory.eINSTANCE.createTreeNavigationDescription();
+ new TreeToolVariables().doSwitch(treeNavigationDescription);
+ newChilds.add(new CommandParameter(null, feature, treeNavigationDescription));
+ return newChilds;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#provideTools(org.eclipse.emf.ecore.EObject)
+ */
+ public Collection<CommandParameter> provideTools(EObject object) {
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#provideAdditionalMappings(org.eclipse.emf.ecore.EObject)
+ */
+ public Collection<CommandParameter> provideAdditionalMappings(EObject object) {
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#getHierarchyLabelProvider(ILabelProvider)
+ */
+ public ILabelProvider getHierarchyLabelProvider(ILabelProvider currentLabelProvider) {
+ return new HierarchyLabelTreeProvider(currentLabelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setSelection(DialectEditor dialectEditor, List<DRepresentationElement> selection) {
+ if (dialectEditor instanceof DTreeEditor) {
+ Viewer viewer = ((DTreeEditor) dialectEditor).getViewer();
+ Iterable<DTreeItem> items = Iterables.filter(selection, DTreeItem.class);
+ viewer.setSelection(new StructuredSelection(Lists.newArrayList(items)));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectUIServices#getSelection(org.eclipse.sirius.ui.business.api.dialect.DialectEditor)
+ */
+ public Collection<DSemanticDecorator> getSelection(DialectEditor editor) {
+ Collection<DSemanticDecorator> selection = Sets.newLinkedHashSet();
+ if (editor instanceof DTreeEditor) {
+ DTreeEditor dEditor = (DTreeEditor) editor;
+ ISelection sel = dEditor.getSite().getSelectionProvider().getSelection();
+
+ if (sel instanceof IStructuredSelection) {
+ Iterables.addAll(selection, Iterables.filter(((IStructuredSelection) sel).toList(), DSemanticDecorator.class));
+ }
+ }
+ return selection;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/propertysource/TreeCompositeEObjectPropertySource.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/propertysource/TreeCompositeEObjectPropertySource.java
new file mode 100644
index 0000000000..3aedc1c1f3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/propertysource/TreeCompositeEObjectPropertySource.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.properties.propertysource;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.ui.IEditorPart;
+
+import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeEditor;
+import org.eclipse.sirius.ui.tools.api.properties.AbstractEObjectPropertySource;
+
+public class TreeCompositeEObjectPropertySource extends AbstractEObjectPropertySource {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.tools.api.properties.AbstractEObjectPropertySource#getItemProvidersAdapterFactory()
+ */
+ @Override
+ protected AdapterFactory getItemProvidersAdapterFactory() {
+ AdapterFactory adapterFactory = null;
+ final IEditorPart part = EclipseUIUtil.getActiveEditor();
+ if (part instanceof DTreeEditor) {
+ adapterFactory = ((DTreeEditor) part).getAdapterFactory();
+ } else {
+ adapterFactory = TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory();
+ }
+ return adapterFactory;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/common/AbstractDTreePropertySection.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/common/AbstractDTreePropertySection.java
new file mode 100644
index 0000000000..c96f289d7c
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/common/AbstractDTreePropertySection.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.properties.section.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.emf.transaction.DemultiplexingListener;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.IPropertySourceProvider;
+import org.eclipse.ui.views.properties.PropertySheetPage;
+import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
+import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeEditor;
+import org.eclipse.sirius.ui.tools.api.properties.DTablePropertySheetpage;
+import org.eclipse.sirius.ui.tools.api.properties.UndoableModelPropertySheetEntry;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
+
+/**
+ * An abstract implementation of a property tab section for the property sheet.<BR>
+ * This implementation uses a {@link PropertySheetPage} in the section to manage
+ * {@link org.eclipse.ui.views.properties.PropertySheetEntry} and
+ * {@link org.eclipse.emf.edit.ui.provider.PropertySource}
+ *
+ * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a>
+ *
+ */
+public abstract class AbstractDTreePropertySection extends AbstractPropertySection implements IPropertySourceProvider {
+
+ /** The parent property sheet page for this section. */
+ protected DTablePropertySheetpage parentPropertySheetPage;
+
+ /**
+ * the content property sheet page witch manages SheetEntry for this
+ * section.
+ */
+ protected PropertySheetPage contentPage;
+
+ /**
+ * Current selected object or first object in the selection when multiple
+ * objects are selected.
+ */
+ protected EObject eObject;
+
+ /** The list of currently selected objects. */
+ protected List<Object> eObjectList;
+
+ /**
+ * Plugin's
+ * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+ * AdapterFactoryLabelProvider}.
+ */
+ protected AdapterFactoryLabelProvider adapterFactoryLabelProvider;
+
+ /**
+ * Model event listener.<BR>
+ * Listen the editing domain
+ */
+ protected DemultiplexingListener eventListener = new DemultiplexingListener(getFilter()) {
+
+ @Override
+ protected void handleNotification(final TransactionalEditingDomain domain, final Notification notification) {
+ update(domain, notification);
+ }
+ };
+
+ /**
+ * The editing domain of the corresponding {@link AbstractDTableEditor
+ * editor}
+ */
+ private TransactionalEditingDomain editingDomain;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(final Composite parent, final TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ if (aTabbedPropertySheetPage instanceof DTablePropertySheetpage) {
+ this.parentPropertySheetPage = (DTablePropertySheetpage) aTabbedPropertySheetPage;
+ }
+
+ final Composite composite = getWidgetFactory().createFlatFormComposite(parent);
+
+ //
+ // remove the other page.
+ contentPage = new PropertySheetPage();
+ final UndoableModelPropertySheetEntry root = new UndoableModelPropertySheetEntry(OperationHistoryFactory.getOperationHistory());
+
+ root.setPropertySourceProvider(getPropertySourceProvider());
+ contentPage.setRootEntry(root);
+
+ contentPage.createControl(composite);
+ final FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, 0);
+ data.bottom = new FormAttachment(100, 0);
+ data.height = 100;
+ data.width = 100;
+ contentPage.getControl().setLayoutData(data);
+ // setActionBars(aTabbedPropertySheetPage.getSite().getActionBars());
+ // ((SortedPropertySheetPage) page).setSorter(new AirPropertySorter());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#setInput(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public void setInput(final IWorkbenchPart part, final ISelection selection) {
+ super.setInput(part, selection);
+ if (!(selection instanceof IStructuredSelection)) {
+ if (selection instanceof EObject) {
+ eObject = (EObject) selection;
+ }
+ } else if (((IStructuredSelection) selection).getFirstElement() instanceof EObject) {
+ eObject = (EObject) ((IStructuredSelection) selection).getFirstElement();
+ eObjectList = ((IStructuredSelection) selection).toList();
+ }
+ // get the editing domain of the IWorkbenchPart
+ final IEditingDomainProvider provider = (IEditingDomainProvider) part.getAdapter(IEditingDomainProvider.class);
+ if (provider != null) {
+ final EditingDomain theEditingDomain = provider.getEditingDomain();
+ if (theEditingDomain instanceof TransactionalEditingDomain) {
+ setEditingDomain((TransactionalEditingDomain) theEditingDomain);
+ }
+ }
+
+ contentPage.selectionChanged(part, selection);
+ }
+
+ /**
+ * Fetches the
+ * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+ * AdapterFactoryLabelProvider} adapted to the given object.
+ *
+ * @param eObj
+ * The object
+ * @return The plugin's
+ * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+ * AdapterFactoryLabelProvider} .
+ */
+ protected AdapterFactoryLabelProvider getAdapterFactoryLabelProvider(final EObject eObj) {
+ if (adapterFactoryLabelProvider == null) {
+ if (getPart() instanceof AbstractDTreeEditor) {
+ adapterFactoryLabelProvider = new AdapterFactoryLabelProvider(((AbstractDTreeEditor) getPart()).getAdapterFactory());
+ } else {
+ return new AdapterFactoryLabelProvider(rescueAdapterFactory());
+ }
+ }
+ return adapterFactoryLabelProvider;
+ }
+
+ /**
+ * Return a default AdapterFactory.
+ *
+ * @return a default AdapterFactory
+ */
+ protected AdapterFactory rescueAdapterFactory() {
+ final List<ComposedAdapterFactory> factories = new ArrayList<ComposedAdapterFactory>();
+ factories.add(new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE));
+ return new ComposedAdapterFactory(factories);
+ }
+
+ /**
+ * Fetches the plugin's
+ * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+ * AdapterFactoryLabelProvider}.
+ *
+ * @return The plugin's
+ * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+ * AdapterFactoryLabelProvider} .
+ */
+ protected AdapterFactoryLabelProvider getAdapterFactoryLabelProvider() {
+ return getAdapterFactoryLabelProvider(null);
+ }
+
+ /**
+ * Returns the PropertySource provider.
+ *
+ * @return The PropertySource provider
+ */
+ protected IPropertySourceProvider getPropertySourceProvider() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#dispose()
+ */
+ @Override
+ public void dispose() {
+ super.dispose();
+
+ if (contentPage != null) {
+ contentPage.dispose();
+ contentPage = null;
+ }
+ if (eObjectList != null) {
+ try {
+ eObjectList.clear();
+ } catch (final UnsupportedOperationException e) {
+ // Do nothing
+ }
+ }
+ eObject = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.REFRESH_PROPERTIES_VIEW_SECTION_KEY);
+ contentPage.refresh();
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.REFRESH_PROPERTIES_VIEW_SECTION_KEY);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#aboutToBeHidden()
+ */
+ @Override
+ public void aboutToBeHidden() {
+ super.aboutToBeHidden();
+
+ final TransactionalEditingDomain theEditingDomain = getEditingDomain();
+ if (theEditingDomain != null) {
+ theEditingDomain.removeResourceSetListener(getEventListener());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#aboutToBeShown()
+ */
+ @Override
+ public void aboutToBeShown() {
+ super.aboutToBeShown();
+
+ final TransactionalEditingDomain theEditingDomain = getEditingDomain();
+ if (theEditingDomain != null) {
+ theEditingDomain.addResourceSetListener(getEventListener());
+ }
+ }
+
+ /**
+ * Return the model event listener.
+ *
+ * @return Returns the eventListener.
+ */
+ protected DemultiplexingListener getEventListener() {
+ return eventListener;
+ }
+
+ /**
+ * Subclasses overriding this method should remember to override
+ * {@link #update(TransactionalEditingDomain, Notification)} as required.
+ * The default implementation of
+ * {@link #update(TransactionalEditingDomain, Notification)} will only
+ * update if the notifier is an <code>EObject</code>.
+ *
+ * @return the filter for events used by my <code>eventListener</code>.
+ */
+ public NotificationFilter getFilter() {
+ return NotificationFilter.createEventTypeFilter(Notification.SET).or(NotificationFilter.createEventTypeFilter(Notification.UNSET))
+ .and(NotificationFilter.createNotifierTypeFilter(EObject.class));
+ }
+
+ /**
+ * Updates me if the notifier is an <code>EObject</code> by calling
+ * {@link #update(Notification, EObject)}. Does nothing otherwise.
+ * Subclasses should override this method if they need to update based on
+ * non-EObject notifiers.
+ *
+ * @param domain
+ * the editing domain
+ * @param notification
+ * the event notification
+ */
+ protected void update(final TransactionalEditingDomain domain, final Notification notification) {
+ if (parentPropertySheetPage.isUpdateEnabled()) {
+ Object notifier = notification.getNotifier();
+ if (notifier instanceof EObject && contentPage != null && contentPage.getControl() != null) {
+ final Control control = contentPage.getControl();
+ control.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ if (!control.isDisposed() && control.isVisible()) {
+ refresh();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Gets the editing domain from my EObject input.
+ *
+ * @return my editing domain
+ */
+ protected TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ /**
+ * Sets the editingDomain.
+ *
+ * @param editingDomain
+ * The editingDomain to set.
+ */
+ protected void setEditingDomain(final TransactionalEditingDomain editingDomain) {
+ this.editingDomain = editingDomain;
+ }
+
+ /**
+ * Override to use all vertical space.<BR> {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#shouldUseExtraSpace()
+ */
+ @Override
+ public boolean shouldUseExtraSpace() {
+ return true;
+ }
+
+ /**
+ * Get the adapter factory.
+ *
+ * @param object
+ * the object
+ * @return the retrieved adapter factory
+ */
+ protected AdapterFactory getAdapterFactory(final Object object) {
+ AdapterFactory adapterFactory = null;
+ if (object != null) {
+ if (getPart() instanceof DTreeEditor) {
+ adapterFactory = ((DTreeEditor) getPart()).getAdapterFactory();
+ } else {
+ adapterFactory = TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory();
+ }
+ }
+ return adapterFactory;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/core/CorePropertySection.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/core/CorePropertySection.java
new file mode 100644
index 0000000000..8d77ec292f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/core/CorePropertySection.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008, 2009 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.properties.section.core;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.emf.edit.ui.provider.PropertySource;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.ui.properties.propertysource.TreeCompositeEObjectPropertySource;
+import org.eclipse.sirius.tree.ui.properties.section.common.AbstractDTreePropertySection;
+import org.eclipse.sirius.ui.tools.api.properties.AbstractEObjectPropertySource;
+
+/**
+ * Properties for the semantic model.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class CorePropertySection extends AbstractDTreePropertySection {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySourceProvider#getPropertySource(java.lang.Object)
+ */
+ public IPropertySource getPropertySource(final Object object) {
+ IPropertySource propSrc = null;
+
+ if (object instanceof IPropertySource) {
+ propSrc = (IPropertySource) object;
+ } else if (object instanceof DTreeItem) {
+ final DTreeItem line = (DTreeItem) object;
+ propSrc = getPropertySource(line);
+ } else {
+ final AdapterFactory af = getAdapterFactory(object);
+ if (af != null) {
+ final IItemPropertySource ips = (IItemPropertySource) af.adapt(object, IItemPropertySource.class);
+ if (ips != null) {
+ return new PropertySource(object, ips);
+ }
+ }
+ if (object instanceof IAdaptable) {
+ propSrc = (IPropertySource) ((IAdaptable) object).getAdapter(IPropertySource.class);
+ }
+ }
+ return propSrc;
+ }
+
+ /**
+ * Returns a property source for the given {@link DLine line}.
+ *
+ * @param line
+ * the line
+ * @return the property source for the line passed in (maybe
+ * <code>null</code>)
+ */
+ protected AbstractEObjectPropertySource getPropertySource(final DTreeItem line) {
+ final AbstractEObjectPropertySource propertySource = new TreeCompositeEObjectPropertySource();
+ final AdapterFactory af = getAdapterFactory(line);
+ if (af != null) {
+ final IItemPropertySource ips = (IItemPropertySource) af.adapt(line, IItemPropertySource.class);
+ if (ips != null) {
+ final IPropertySource targetPropertySource = new PropertySource(line, ips);
+ propertySource.addPropertySource(line, targetPropertySource);
+ }
+ }
+ return propertySource;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/semantic/SemanticPropertySection.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/semantic/SemanticPropertySection.java
new file mode 100644
index 0000000000..a303274bc0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/properties/section/semantic/SemanticPropertySection.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.properties.section.semantic;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.emf.edit.ui.provider.PropertySource;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+import org.eclipse.sirius.DSemanticDecorator;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.ui.properties.propertysource.TreeCompositeEObjectPropertySource;
+import org.eclipse.sirius.tree.ui.properties.section.common.AbstractDTreePropertySection;
+import org.eclipse.sirius.ui.tools.api.properties.AbstractCompositeEObjectPropertySource;
+import org.eclipse.sirius.ui.tools.api.properties.AbstractEObjectPropertySource;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+
+/**
+ * Properties for the semantic model.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class SemanticPropertySection extends AbstractDTreePropertySection {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySourceProvider#getPropertySource(java.lang.Object)
+ */
+ public IPropertySource getPropertySource(final Object object) {
+ IPropertySource propSrc = null;
+
+ if (object instanceof IPropertySource) {
+ propSrc = (IPropertySource) object;
+ } else if (object instanceof DSemanticDecorator) {
+ final DSemanticDecorator semanticDecorator = (DSemanticDecorator) object;
+ propSrc = getPropertySource(semanticDecorator);
+ } else {
+ final AdapterFactory af = getAdapterFactory(object);
+ if (af != null) {
+ final IItemPropertySource ips = (IItemPropertySource) af.adapt(object, IItemPropertySource.class);
+ if (ips != null) {
+ return new PropertySource(object, ips);
+ }
+ }
+ if (object instanceof IAdaptable) {
+ propSrc = (IPropertySource) ((IAdaptable) object).getAdapter(IPropertySource.class);
+ }
+ }
+ return propSrc;
+ }
+
+ /**
+ * Returns a property source for the given {@link DTableElement table
+ * element}.
+ *
+ * @param tableElement
+ * the table element
+ * @return the property source for the cell passed in (maybe
+ * <code>null</code>)
+ */
+ protected IPropertySource getPropertySource(final DTreeItem tableElement) {
+ final ModelAccessor accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(tableElement);
+ return getPropertySource(accessor, tableElement.getSemanticElements());
+ }
+
+ /**
+ * Returns a property source for the given {@link DCell cell}.
+ *
+ * @param accessor
+ * the model accessor
+ * @param eObjects
+ * collection of object
+ * @return the property source for the cell passed in (maybe
+ * <code>null</code>)
+ */
+ protected IPropertySource getPropertySource(final ModelAccessor accessor, final Collection<EObject> eObjects) {
+ final Iterator<EObject> iterElements = eObjects.iterator();
+ final AbstractEObjectPropertySource propertySource = new TreeCompositeEObjectPropertySource();
+ while (iterElements.hasNext()) {
+ final EObject semanticElement = iterElements.next();
+ fillPropertySource(accessor, semanticElement, propertySource);
+ }
+ return propertySource;
+ }
+
+ /**
+ * Returns a property source for the given {@link DSemanticDecorator
+ * semanticDecorator}.
+ *
+ * @param semanticDecorator
+ * the semanticDecorator
+ * @return the property source for the semanticDecorator passed in (maybe
+ * <code>null</code>)
+ */
+ protected IPropertySource getPropertySource(final DSemanticDecorator semanticDecorator) {
+ final AbstractEObjectPropertySource propertySource = new TreeCompositeEObjectPropertySource();
+ final ModelAccessor accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(semanticDecorator);
+ final EObject semanticElement = semanticDecorator.getTarget();
+ fillPropertySource(accessor, semanticElement, propertySource);
+ return propertySource;
+ }
+
+ private void fillPropertySource(final ModelAccessor accessor, final EObject semanticElement, final AbstractCompositeEObjectPropertySource propertySource) {
+ if (!(accessor.isExtension(semanticElement))) {
+ final AdapterFactory af = getAdapterFactory(semanticElement);
+ if (af != null) {
+ final IItemPropertySource ips = (IItemPropertySource) af.adapt(semanticElement, IItemPropertySource.class);
+ if (ips != null) {
+ final IPropertySource targetPropertySource = new PropertySource(semanticElement, ips);
+ propertySource.addPropertySource(semanticElement, targetPropertySource);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/api/editor/DTreeEditor.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/api/editor/DTreeEditor.java
new file mode 100644
index 0000000000..0f31286e44
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/api/editor/DTreeEditor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.api.editor;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+
+/**
+ * {@link DialectEditor} for TreeDialect.
+ *
+ * @author <a href="mailto:mariot.chauvin@obeo.fr">Mariot Chauvin</a>
+ */
+public interface DTreeEditor extends DialectEditor {
+
+ /**
+ * Get the associated SWT control.
+ *
+ * @return the associated control
+ */
+ Control getControl();
+
+ /**
+ * Return the adapter factory used for providing views of the model of this
+ * editor.
+ *
+ * @return the adapter factory used for providing views of the model of this
+ * editor.
+ */
+ AdapterFactory getAdapterFactory();
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/CreateLineCommandFromToolRecordingCommand.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/CreateLineCommandFromToolRecordingCommand.java
new file mode 100644
index 0000000000..04f2aa3288
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/CreateLineCommandFromToolRecordingCommand.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.command;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.DTreeItemContainer;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.description.TreeItemCreationTool;
+
+/**
+ * A Recording Command to call
+ * tableCommandFactory.buildCreateLineCommandFromTool.
+ *
+ * @author smonnier
+ */
+public class CreateLineCommandFromToolRecordingCommand extends RecordingCommand {
+
+ /**
+ * The line concerned with this action
+ */
+ private DTreeItem line;
+
+ private DTree tree;
+
+ private ITreeCommandFactory treeCommandFactory;
+
+ private TreeItemCreationTool tool;
+
+ /**
+ * Constructor.
+ *
+ * @param domain
+ * the editing domain.
+ * @param label
+ * the name of the command.
+ * @param line
+ * the line in which to create the new line.
+ * @param tree
+ * the tree in which to create the line.
+ * @param treeCommandFactory
+ * the factory to use to build commands.
+ * @param tool
+ * the line creation tool.
+ */
+ public CreateLineCommandFromToolRecordingCommand(TransactionalEditingDomain domain, String label, DTreeItem line, DTree tree, ITreeCommandFactory treeCommandFactory, TreeItemCreationTool tool) {
+ super(domain, label);
+ this.line = line;
+ this.tree = tree;
+ this.treeCommandFactory = treeCommandFactory;
+ this.tool = tool;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doExecute() {
+ // The CreateLineAction can be launch from the table
+ EObject target;
+ DTreeItemContainer lineContainer;
+ if (line != null) {
+ target = line.getTarget();
+ lineContainer = (DTreeItemContainer) line.eContainer();
+ } else {
+ target = tree.getTarget();
+ lineContainer = tree;
+ }
+ treeCommandFactory.buildCreateLineCommandFromTool(lineContainer, target, tool).execute();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/EMFCommandFactoryUI.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/EMFCommandFactoryUI.java
new file mode 100644
index 0000000000..56784273cd
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/command/EMFCommandFactoryUI.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.command;
+
+import org.eclipse.sirius.tree.tools.api.interpreter.IInterpreterSiriusTreeVariables;
+import org.eclipse.sirius.ui.tools.api.command.AbstractSWTCallback;
+
+/**
+ * Implementation of the
+ * {@link org.eclipse.sirius.tools.api.command.ui.UICallBack} interface using
+ * SWT.
+ *
+ * @author nlepine
+ */
+public class EMFCommandFactoryUI extends AbstractSWTCallback {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getVariableNameForRepresentation() {
+ return IInterpreterSiriusTreeVariables.TREE;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeActionBarContributor.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeActionBarContributor.java
new file mode 100644
index 0000000000..e344ed1504
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeActionBarContributor.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.EditorCreateTreeItemMenuAction;
+
+/**
+ * This is a contributor for a DTree editor.
+ *
+ * @author cbrun
+ */
+public class DTreeActionBarContributor extends EditingDomainActionBarContributor {
+
+ /**
+ * Constructor.
+ */
+ public DTreeActionBarContributor() {
+
+ }
+
+ /**
+ * Add the create tree item menu to the toolbar.
+ *
+ * @param editorCreateLineMenuAction
+ * the menu to add
+ */
+ public void addCreateTreeItemMenu(final EditorCreateTreeItemMenuAction editorCreateLineMenuAction) {
+ final IToolBarManager toolBarManager = getActionBars().getToolBarManager();
+ toolBarManager.remove(EditorCreateTreeItemMenuAction.ID);
+ toolBarManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, editorCreateLineMenuAction); //$NON-NLS-1$
+ toolBarManager.update(true);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java
new file mode 100644
index 0000000000..7c50845945
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeEditor.java
@@ -0,0 +1,666 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.ui.URIEditorInput;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.ComposedImage;
+import org.eclipse.emf.edit.provider.IDisposable;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.part.FileEditorInput;
+
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.DRepresentation;
+import org.eclipse.sirius.DSemanticDecorator;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.dialect.DialectManager;
+import org.eclipse.sirius.business.api.dialect.command.RefreshRepresentationsCommand;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.provider.SiriusEditPlugin;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterRegistry;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeElementSynchronizer;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.business.api.command.TreeCommandFactoryService;
+import org.eclipse.sirius.tree.business.internal.helper.TreeHelper;
+import org.eclipse.sirius.tree.business.internal.refresh.DTreeElementSynchronizerSpec;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.command.EMFCommandFactoryUI;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.preferences.SiriusPreferenceChangeListener;
+import org.eclipse.sirius.ui.business.api.descriptor.ComposedImageDescriptor;
+import org.eclipse.sirius.ui.business.api.dialect.marker.TraceabilityMarkerNavigationProvider;
+import org.eclipse.sirius.ui.business.api.session.IEditingSession;
+import org.eclipse.sirius.ui.business.api.session.SessionEditorInput;
+import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+
+/**
+ * Editor for tree representations.
+ *
+ * @author nlepine
+ *
+ */
+public class DTreeEditor extends AbstractDTreeEditor implements org.eclipse.sirius.tree.ui.tools.api.editor.DTreeEditor {
+
+ /**
+ * The DTreeEditor ID.
+ */
+ public static final String ID = "org.eclipse.sirius.tree.ui.EditorID";
+
+ /** The context ID. */
+ private static final String CONTEXT_ID = ID + ".treeContext";
+
+ /** Initial title image descriptor **/
+ private static final ImageDescriptor INITIAL_TITLE_IMAGE_DESCRIPTOR = TreeUIPlugin.getBundledImageDescriptor("icons/full/obj16/TreeDescription.gif");
+
+ private IPartListener refreshAtOpeningActivator;
+
+ private DTree treeModel;
+
+ private IPreferenceChangeListener viewPointPreferenceChangeListener;
+
+ /**
+ * Creates a new Editor for tree representations.
+ *
+ */
+ public DTreeEditor() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor#getInitialImage()
+ */
+ public Image getInitialImage() {
+ if (initialTitleImage == null || initialTitleImage.isDisposed()) {
+ initialTitleImage = SiriusEditPlugin.getPlugin().getImage(INITIAL_TITLE_IMAGE_DESCRIPTOR);
+ }
+ return initialTitleImage;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor#getFrozenRepresentationImage()
+ */
+ @Override
+ public Image getFrozenRepresentationImage() {
+ if (frozenRepresentationImage == null || frozenRepresentationImage.isDisposed()) {
+ Image refreshImage = TreeUIPlugin.getImage(TreeUIPlugin.getBundledImageDescriptor("icons/" + DTreeViewerManager.REFRESH_IMG + ".gif"));
+ List<Object> images = new ArrayList<Object>(2);
+ images.add(refreshImage);
+ Image lockByOtherOverlayImage = SiriusEditPlugin.getPlugin()
+ .getImage(SiriusEditPlugin.Implementation.getBundledImageDescriptor("icons/full/decorator/permission_denied_overlay.gif"));
+ images.add(lockByOtherOverlayImage);
+ ImageDescriptor composedImageDescriptor = new ComposedImageDescriptor(new ComposedImage(images));
+ frozenRepresentationImage = SiriusEditPlugin.getPlugin().getImage(composedImageDescriptor);
+ }
+ return frozenRepresentationImage;
+ }
+
+ /**
+ * We have to take care of the case when Eclipse starts up with a session
+ * and diagram already open.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(final IEditorSite site, final IEditorInput input) throws PartInitException {
+ setSite(site);
+
+ final Collection<Session> sessions = SessionManager.INSTANCE.getSessions();
+
+ /*
+ * we are during eclipse boot, we are not trying to close the editor
+ */
+ if (sessions.isEmpty() && (!isClosing)) {
+ SessionManager.INSTANCE.addSessionsListener(sessionManagerListener);
+ }
+ isClosing = false;
+
+ if (input instanceof SessionEditorInput) {
+ final URI uri = ((SessionEditorInput) input).getURI();
+ this.session = ((SessionEditorInput) input).getSession();
+ setTreeModel(getDTree(uri, false));
+ } else if (input instanceof URIEditorInput) {
+ /* This happens when Eclipse is launched with an open tree editor */
+ final URI uri = ((URIEditorInput) input).getURI();
+ final DTree rootElement = getDTree(uri, true);
+ if (rootElement != null) {
+ setTreeModel(rootElement);
+ }
+ }
+
+ setInput(input);
+
+ if (session != null) {
+ session.addListener(this);
+ }
+
+ initCommandFactoryProviders();
+
+ adapterFactory = new ComposedAdapterFactory(TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory());
+
+ final IEditingSession uiSession = SessionUIManager.INSTANCE.getOrCreateUISession(this.session);
+ uiSession.open();
+ uiSession.attachEditor(this);
+ setAccessor(SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(getTreeModel()));
+
+ if (getTreeModel() != null) {
+ /*
+ * let's activate the model listening
+ */
+ final DTreeElementSynchronizer sync = new DTreeElementSynchronizerSpec(getInterpreter(), getAccessor());
+ getTreeModel().activate(sync);
+
+ /* Update title. Semantic tree could have been renamed */
+ notify(PROP_TITLE);
+
+ /* handle preferences */
+ new InstanceScope().getNode(SiriusPlugin.ID).addPreferenceChangeListener(viewPointPreferenceChangeListener);
+
+ // Launch the refresh if needed
+ if (DialectManager.INSTANCE.isRefreshActivatedOnRepresentationOpening()) {
+ launchRefresh(true);
+ }
+
+ initCollaborativeIPermissionAuthority(getTreeModel());
+ }
+ }
+
+ /**
+ * Creates the SWT controls for this workbench part.
+ * <p>
+ * Subclasses must implement this method. For a detailed description of the
+ * requirements see <code>IWorkbenchPart</code>
+ * </p>
+ *
+ * @param parent
+ * the parent control
+ * @see org.eclipse.ui.IWorkbenchPart
+ */
+ @Override
+ public void createPartControl(final Composite parent) {
+ super.createPartControl(parent);
+
+ // DslCommonPlugin.PROFILER.startWork(SiriusTasks.CREATE_TREE);
+ if (getTreeModel() == null) {
+ /* eclipse was closed with an editor opened and not saved */
+ final Label errorLabel = new Label(parent, SWT.CENTER);
+ errorLabel.setText("This tree was not saved. You can close the editor");
+ return;
+ }
+ treeViewerManager = new DTreeViewerManager(parent, getTreeModel(), getEditingDomain(), accessor, emfCommandFactory, this);
+ // DslCommonPlugin.PROFILER.stopWork(SiriusTasks.CREATE_TREE);
+ getSite().setSelectionProvider(treeViewerManager.getTreeViewer());
+
+ /* initialize Java Service. */
+ EObject semantic = null;
+ if (treeModel != null) {
+ semantic = treeModel.getTarget();
+ }
+ if (semantic == null) {
+ final TreeIterator<?> allContents = this.getEditingDomain().getResourceSet().getAllContents();
+ while (allContents.hasNext() && semantic == null) {
+ final Object next = allContents.next();
+ if (next instanceof DSemanticDecorator) {
+ semantic = ((DSemanticDecorator) next).getTarget();
+ }
+ }
+ }
+ EObject anyEObject = semantic;
+ final Iterator<Resource> iterResources = this.getEditingDomain().getResourceSet().getResources().iterator();
+ while (iterResources.hasNext() && anyEObject == null) {
+ final Resource res = iterResources.next();
+ if (!res.getContents().isEmpty()) {
+ anyEObject = res.getContents().get(0);
+ }
+ }
+ if (anyEObject.eResource().getResourceSet() != getEditingDomain().getResourceSet()) {
+ anyEObject.eResource().unload();
+ }
+ if (anyEObject != null) {
+ final IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(anyEObject);
+ InterpreterRegistry.prepareImportsFromSession(interpreter, SessionManager.INSTANCE.getSession(anyEObject));
+ }
+ // add a listener to selection
+ getSite().getPage().addSelectionListener(this);
+ // Add the CreateTreeItem menu of the toolbar
+ ((DTreeActionBarContributor) getEditorSite().getActionBarContributor()).addCreateTreeItemMenu(((DTreeViewerManager) this.getTableViewer()).getCreateTreeItemMenu());
+
+ refreshAtOpeningActivator = new RefreshAtOpeningActivator(this);
+ getSite().getPage().addPartListener(refreshAtOpeningActivator);
+
+ // Activate context
+ IContextService contextService = (IContextService) getSite().getService(IContextService.class);
+ contextService.activateContext(CONTEXT_ID);
+ }
+
+ /**
+ * Overridden to update the UI part when the {@link DTree} model is changed
+ * outside of a EMF Command (which notify DTreeContentAdapter) in case of
+ * collab model.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void setInput(IEditorInput input) {
+ super.setInput(input);
+
+ // Expands the TreeItem according to the model
+ Viewer viewer = getViewer();
+ if (viewer instanceof TreeViewer) {
+ TreeViewer treeViewer = (TreeViewer) viewer;
+ treeViewer.setExpandedElements(TreeHelper.getExpandedItems(getTreeModel()).toArray());
+ }
+ }
+
+ private DTree getDTree(final URI uri, final boolean loadOnDemand) {
+ DTree result = null;
+ final Resource resource = getEditingDomain().getResourceSet().getResource(uri.trimFragment(), loadOnDemand);
+ if (resource != null && resource.isLoaded()) {
+ if (uri.fragment() != null) {
+ final EObject rootElement = resource.getEObject(uri.fragment());
+ if (rootElement instanceof DTree) {
+ result = (DTree) rootElement;
+ }
+ }
+ }
+ return result;
+ }
+
+ private void initCommandFactoryProviders() {
+ /* get IEMFCommandFactories */
+ emfCommandFactory = TreeCommandFactoryService.getInstance().getNewProvider().getCommandFactory(getEditingDomain());
+ // Set the automatic refresh according to the preference
+ ((ITreeCommandFactory) emfCommandFactory).setAutoRefreshDTree(isAutoRefresh());
+ /*
+ * We add a callback for UI stuffs
+ */
+ emfCommandFactory.setUserInterfaceCallBack(new EMFCommandFactoryUI());
+
+ /* Set viewpoint preference change listener */
+ viewPointPreferenceChangeListener = new SiriusPreferenceChangeListener((ITreeCommandFactory) emfCommandFactory);
+
+ }
+
+ private IInterpreter getInterpreter() {
+ return SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(getTreeModel().getTarget());
+ }
+
+ /**
+ * @param accessor
+ * the accessor to set
+ */
+ private void setAccessor(final ModelAccessor accessor) {
+ this.accessor = accessor;
+ ((ITreeCommandFactory) emfCommandFactory).setModelAccessor(this.accessor);
+ }
+
+ /**
+ * {@inheritDoc}
+ * */
+ protected void launchRefresh(boolean loading) {
+ getEditingDomain().getCommandStack().execute(new RefreshRepresentationsCommand(getEditingDomain(), getTreeModel()));
+ if (!loading) {
+ getViewer().refresh();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor#launchRefresh()
+ */
+ @Override
+ protected void launchRefresh() {
+ launchRefresh(false);
+ }
+
+ private void setTreeModel(final DTree rootElement) {
+ this.treeModel = rootElement;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.business.api.dialect.DialectEditor#validateRepresentation()
+ */
+ public void validateRepresentation() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Closes this DTreeEditor.
+ *
+ * @param save
+ * indicates whether the modifications should save or not
+ */
+ public void close(final boolean save) {
+ Display display = getSite().getShell().getDisplay();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (treeViewerManager != null) {
+ getSite().getPage().closeEditor(DTreeEditor.this, save);
+ }
+ }
+ });
+
+ }
+
+ public DTree getTreeModel() {
+ return this.treeModel;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DRepresentation getRepresentation() {
+ return getTreeModel();
+ }
+
+ public String getContributorId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(final IProgressMonitor progressMonitor) {
+
+ if (isDeleted(getEditorInput())) {
+
+ if (isSaveAsAllowed()) {
+
+ /*
+ * 1GEUSSR: ITPUI:ALL - User should never loose changes made in
+ * the editors. Changed Behavior to make sure that if called
+ * inside a regular save (because of deletion of input element)
+ * there is a way to report back to the caller.
+ */
+ performSaveAs(progressMonitor);
+
+ } else {
+
+ // final Shell shell = getSite().getShell();
+ // final String title =
+ // Messages.dTableEditor_ErrorSaveDeletedTitle;
+ // final String msg =
+ // Messages.dTableEditor_ErrorSaveDeletedMessage;
+ // MessageDialog.openError(shell, title, msg);
+ }
+
+ } else {
+ // Update the readonly state
+ // updateState(getEditorInput());
+ // Valide the state
+ // validateState(getEditorInput());
+ performSave(false, progressMonitor);
+ }
+ // Indicates that the editor is saved
+ }
+
+ /**
+ * Perform the saveAs action.
+ *
+ * @param progressMonitor
+ * The progress monitor
+ */
+ private void performSaveAs(final IProgressMonitor progressMonitor) {
+ final Shell shell = getSite().getShell();
+ final IEditorInput input = getEditorInput();
+ final SaveAsDialog dialog = new SaveAsDialog(shell);
+ final IFile original = input instanceof IFileEditorInput ? ((IFileEditorInput) input).getFile() : null;
+ if (original != null) {
+ dialog.setOriginalFile(original);
+ }
+ dialog.create();
+ // if (isDeleted(input) && original != null) {
+ // final String message =
+ // NLS.bind(Messages.dTableEditor_SavingDeletedFile,
+ // original.getName());
+ // dialog.setErrorMessage(null);
+ // dialog.setMessage(message, IMessageProvider.WARNING);
+ // }
+ if (dialog.open() == Window.CANCEL) {
+ if (progressMonitor != null) {
+ progressMonitor.setCanceled(true);
+ }
+ } else {
+ final IPath filePath = dialog.getResult();
+ if (filePath == null) {
+ if (progressMonitor != null) {
+ progressMonitor.setCanceled(true);
+ }
+ return;
+ }
+ final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ final IFile file = workspaceRoot.getFile(filePath);
+ final IEditorInput newInput = new FileEditorInput(file);
+ // Check if the editor is already open
+ final IEditorMatchingStrategy matchingStrategy = getEditorDescriptor().getEditorMatchingStrategy();
+ final IEditorReference[] editorRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
+ for (IEditorReference editorRef : editorRefs) {
+ if (matchingStrategy.matches(editorRef, newInput)) {
+ // MessageDialog.openWarning(shell,
+ // Messages.dTableEditor_SaveAsErrorTitle,
+ // Messages.dTableEditor_SaveAsErrorMessage);
+ return;
+ }
+ }
+ final boolean success = false;
+ // try {
+ // provider.aboutToChange(newInput);
+ // getDocumentProvider(newInput).saveDocument(progressMonitor,
+ // newInput,
+ // getDocumentProvider().getDocument(getEditorInput()), true);
+ // success = true;
+ // } catch (final CoreException x) {
+ // final IStatus status = x.getStatus();
+ // if (status == null || status.getSeverity() != IStatus.CANCEL) {
+ // ErrorDialog.openError(shell, Messages.dTableEditorSaveErrorTitle,
+ // Messages.dTableEditorSaveErrorMessage, x.getStatus());
+ // }
+ // } finally {
+ // provider.changed(newInput);
+ // if (success) {
+ // setInput(newInput);
+ // }
+ // }
+ if (progressMonitor != null) {
+ progressMonitor.setCanceled(!success);
+ }
+ }
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void doSaveAs() {
+ if (isSaveAsAllowed()) {
+ performSaveAs(new NullProgressMonitor());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources.IMarker)
+ */
+ public void gotoMarker(IMarker marker) {
+ if (TraceabilityMarkerNavigationProvider.isTraceabilityMarker(marker)) {
+ new TraceabilityMarkerNavigationProvider(this).gotoMarker(marker);
+ } else {
+ doGoToMarker(marker);
+ }
+ }
+
+ /**
+ * Sets the cursor and selection state for an editor to reveal the position
+ * of the given marker.
+ *
+ * @param marker
+ * the marker to go to
+ */
+ // TODO for now on, this implementation only allow to handle Traceability
+ // markers
+ protected void doGoToMarker(IMarker marker) {
+ final String treeURI = marker.getAttribute(TraceabilityMarkerNavigationProvider.REPRESENTATION_URI, null);
+ final String elementId = marker.getAttribute(TraceabilityMarkerNavigationProvider.REPRESENTATION_ELEMENT_ID, null);
+
+ if (treeURI == null || elementId == null) {
+ return;
+ }
+
+ final URI markerTreeURI = URI.createURI(treeURI);
+ final DTree markerTree = (DTree) this.getTreeModel().eResource().getEObject(markerTreeURI.fragment());
+
+ if (markerTree != null) {
+ EObject searchedElement = markerTree.eResource().getEObject(elementId);
+ TreeViewer viewer = this.treeViewerManager.getTreeViewer();
+
+ // FIXME : contrary to tables, getItems() of the Tree returns only
+ // expanded elements. So we expand it manually
+ Object[] expandedElements = viewer.getExpandedElements();
+ ((TreeViewer) this.getViewer()).expandAll();
+ TreeItem contains = contains(viewer.getTree().getItems(), searchedElement);
+ ((TreeViewer) this.getViewer()).setExpandedElements(expandedElements);
+
+ if (contains != null) {
+ ISelection selection = new TreeSelection(getTreePathFromItem(contains));
+ ((TreeViewer) this.getViewer()).setSelection(selection, true);
+ }
+
+ }
+ }
+
+ /**
+ * Returns the tree path for the given item.
+ *
+ * @param item
+ * the item from which obtain the path
+ * @return {@link TreePath}
+ *
+ * @since 3.2
+ */
+ protected TreePath getTreePathFromItem(TreeItem item) {
+ LinkedList<Object> segments = new LinkedList<Object>();
+ TreeItem myItem = item;
+ while (myItem != null) {
+ Object segment = item.getData();
+ Assert.isNotNull(segment);
+ segments.addFirst(segment);
+ myItem = myItem.getParentItem();
+ }
+ return new TreePath(segments.toArray());
+ }
+
+ /**
+ * Return the adapter factory used for providing views of the model of this
+ * editor.
+ *
+ * @return the adapter factory used for providing views of the model of this
+ * editor.
+ */
+ public AdapterFactory getAdapterFactory() {
+ if (adapterFactory == null) {
+ // Create an adapter factory that yields item providers.
+ adapterFactory = TreeUIPlugin.getPlugin().createAdapterFactory();
+ }
+ return adapterFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (refreshAtOpeningActivator != null) {
+ getSite().getPage().removePartListener(refreshAtOpeningActivator);
+ }
+ refreshAtOpeningActivator = null;
+ super.dispose();
+ if (getAdapterFactory() instanceof IDisposable) {
+ ((IDisposable) getAdapterFactory()).dispose();
+ }
+
+ new InstanceScope().getNode(SiriusPlugin.ID).removePreferenceChangeListener(viewPointPreferenceChangeListener);
+ viewPointPreferenceChangeListener = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.tree.ui.tools.api.editor.DTreeEditor#getControl()
+ */
+ public Control getControl() {
+ TreeViewer treeViewer = this.getTableViewer().getTreeViewer();
+ return treeViewer.getTree();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeMenuListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeMenuListener.java
new file mode 100644
index 0000000000..a94644c167
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeMenuListener.java
@@ -0,0 +1,426 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.SubContributionItem;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.DDiagram;
+import org.eclipse.sirius.DRepresentation;
+import org.eclipse.sirius.DRepresentationElement;
+import org.eclipse.sirius.DSemanticDecorator;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.dialect.DialectManager;
+import org.eclipse.sirius.business.api.helper.task.InitInterpreterVariablesTask;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerInterpreter;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.description.tool.AbstractVariable;
+import org.eclipse.sirius.description.tool.RepresentationCreationDescription;
+import org.eclipse.sirius.description.tool.RepresentationNavigationDescription;
+import org.eclipse.sirius.description.tool.ToolPackage;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.description.TreeMapping;
+import org.eclipse.sirius.tree.ui.tools.internal.command.EMFCommandFactoryUI;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.AbstractToolAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.AbstractToolItemAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.CreateRepresentationFromRepresentationCreationDescription;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.CreateToolItemAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.DeleteTreeItemsAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.OpenRepresentationAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.RefreshAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.TreePopupMenuContributionSupport;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
+
+/**
+ * A menu listener which show or hide the menu according to :
+ * <UL>
+ * <LI>the current selection</LI>
+ * <LI>and the tool precondition.
+ * </UL>
+ *
+ * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a>
+ *
+ */
+public class DTreeMenuListener implements IMenuListener {
+
+ private static final String MENU_NAVIGATE_ID = "popup.navigate";
+
+ private static final String NEW_REPRESENTATION_GROUP_SEPARATOR = "newRepresentation";
+
+ private static final String EXISTING_REPRESENTATION_GROUP_SEPARATOR = "existingRepresentation";
+
+ private static final String NAVIGATE_REPRESENTATION_GROUP_SEPARATOR = "navigateRepresentationGroup";
+
+ private static final String PROPERTIES_SEPARATOR = "properties";
+
+ private static final String LOCK_SEPARATOR = "lockGroup";
+
+ private final AdapterFactory adapterFactory;
+
+ private final DTree dTree;
+
+ private final DTreeViewerManager treeViewManager;
+
+ private RefreshAction refreshAction;
+
+ private final DeleteTreeItemsAction deleteItemsAction;
+
+ private Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions;
+
+ private List<AbstractToolAction> createActionsForTree;
+
+ /**
+ * The support to use for handling contextual menu contributions.
+ */
+ private TreePopupMenuContributionSupport treePopupMenuContributionHandler;
+
+ /**
+ * Default constructor.
+ *
+ * @param tree
+ * The tree associates with this menu
+ * @param treeViewManager
+ * The manager of the TreeView
+ * @param mappingToCreateActions
+ * A map which associates {@link TreeMapping} with the
+ * corresponding list of {@link AbstractToolAction} (
+ * {@link org.eclipse.sirius.tree.ui.tools.internal.editor.action.CreateLineAction}
+ * or
+ * {@link org.eclipse.sirius.tree.ui.tools.internal.editor.action.CreateTargetColumnAction}
+ * )
+ * @param createActionsForTree
+ * A list of the actions for create lines under the tree.
+ */
+ public DTreeMenuListener(final DTree tree, final DTreeViewerManager treeViewManager, final Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions,
+ final List<AbstractToolAction> createActionsForTree) {
+ super();
+ adapterFactory = DialectUIManager.INSTANCE.createAdapterFactory();
+ this.dTree = tree;
+ this.treeViewManager = treeViewManager;
+ this.treePopupMenuContributionHandler = new TreePopupMenuContributionSupport(this.treeViewManager.getEditingDomain(), this.treeViewManager.getTreeCommandFactory());
+ this.deleteItemsAction = new DeleteTreeItemsAction(treeViewManager.getEditingDomain(), treeViewManager.getTreeCommandFactory());
+
+ setMappingToCreateActions(mappingToCreateActions);
+ setCreateActionsForTree(createActionsForTree);
+ refreshAction = new RefreshAction((DTreeEditor) treeViewManager.getEditor());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+ */
+ public void menuAboutToShow(final IMenuManager manager) {
+ // Refresh the cached actions if needed
+ treeViewManager.fillMenu();
+ // Add line menus
+ addTreeItemMenus(manager);
+ // Add navigate menus
+ addNavigateMenu(manager);
+ manager.add(new Separator());
+ // Add viewpoint menus
+ addRefreshMenu(manager);
+ manager.add(new Separator());
+ manager.add(new Separator(DTreeMenuListener.LOCK_SEPARATOR));
+ addTreeMenus(manager);
+ // Add show properties view
+ manager.add(new Separator(DTreeMenuListener.PROPERTIES_SEPARATOR));
+ manager.add(new Separator());
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+
+ /**
+ * Add the tree menus if any line is selected.<BR>
+ *
+ * @param manager
+ * the menu manager
+ */
+ private void addTreeMenus(final IMenuManager manager) {
+ final Collection<DTreeItem> selectedItems = treeViewManager.getSelectedItems();
+ if (selectedItems != null && !selectedItems.isEmpty()) {
+ for (final AbstractToolAction abstractToolAction : getCreateActionsForTree()) {
+ if (abstractToolAction instanceof CreateToolItemAction) {
+ final CreateToolItemAction createLineAction = (CreateToolItemAction) abstractToolAction;
+ if (createLineAction.canExecute()) {
+ manager.add(createLineAction);
+ }
+
+ }
+ }
+ manager.add(new Separator());
+ }
+ }
+
+ /**
+ * Add the navigate sub menu and its actions if needed.
+ *
+ * @param manager
+ * The menu manager
+ */
+ private void addNavigateMenu(final IMenuManager manager) {
+ // Create a new sub-menu manager
+ final MenuManager navigateMenuManager = new MenuManager("Navigate", DTreeMenuListener.MENU_NAVIGATE_ID);
+ // Create the item to add to the main manager
+ final SubContributionItem navigateMenuItem = new SubContributionItem(navigateMenuManager);
+ manager.add(navigateMenuItem);
+ // Add menus to navigate through existing representations (created by
+ // RepresentationCreationDescription)
+ final Separator existingGroup = new Separator(DTreeMenuListener.EXISTING_REPRESENTATION_GROUP_SEPARATOR);
+ navigateMenuManager.add(existingGroup);
+ // Add menus to navigate through existing representations (corresponding
+ // to the RepresentationNavigationDescription)
+ final Separator navigateRepresentationGroup = new Separator(NAVIGATE_REPRESENTATION_GROUP_SEPARATOR);
+ navigateMenuManager.add(navigateRepresentationGroup);
+ // Add menus to navigate through new representations (corresponding to
+ // the RepresentationCreationDescription)
+ final Separator createGroup = new Separator(DTreeMenuListener.NEW_REPRESENTATION_GROUP_SEPARATOR);
+ navigateMenuManager.add(createGroup);
+ final Collection<DTreeItem> currentTreeElements = treeViewManager.getSelectedItems();
+ if (currentTreeElements != null && currentTreeElements.size() == 1) {
+ DTreeItem currentTreeElement = currentTreeElements.iterator().next();
+ // Add actions to navigate to existing representation
+ createNavigationAction(navigateMenuItem, currentTreeElement);
+ // Add actions to navigate to new representation
+ if (currentTreeElement instanceof DTreeItem) {
+ createDetailsActions((DTreeItem) currentTreeElement, navigateMenuItem);
+ }
+ } else {
+ // Add actions to navigate to existing representation
+ createNavigationAction(navigateMenuItem, dTree);
+ }
+ }
+
+ /**
+ * @param navigateMenuItem
+ * @param semanticElement
+ */
+ private void createNavigationAction(final SubContributionItem navigate, final DSemanticDecorator decorator) {
+ final EObject semanticElement = decorator.getTarget();
+ final Session session = SessionManager.INSTANCE.getSession(semanticElement);
+ if (session != null) {
+ final Collection<DRepresentation> otherRepresentations = DialectManager.INSTANCE.getRepresentations(semanticElement, session);
+ for (final DRepresentation representation : otherRepresentations) {
+ navigate.setVisible(true);
+ ((IMenuManager) navigate.getInnerItem()).appendToGroup(EXISTING_REPRESENTATION_GROUP_SEPARATOR, buildOpenRepresentationAction(session, representation));
+ }
+ if (decorator instanceof DRepresentationElement) {
+ if (buildNavigableRepresentationsMenu((IMenuManager) navigate.getInnerItem(), decorator, session)) {
+ // if at least one navigable representation menu
+ // has been created, we have to make the navigate menu
+ // visible
+ navigate.setVisible(true);
+ }
+ }
+ }
+ }
+
+ private boolean buildNavigableRepresentationsMenu(final IMenuManager navigate, final EObject designerObj, final Session session) {
+ final DRepresentationElement element = (DRepresentationElement) designerObj;
+ if (element.getMapping() != null) {
+
+ for (final RepresentationNavigationDescription navDesc : element.getMapping().getNavigationDescriptions()) {
+ final IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(element.getTarget());
+
+ final Map<AbstractVariable, Object> variables = new HashMap<AbstractVariable, Object>();
+ variables.put(navDesc.getContainerVariable(), element.getTarget());
+ variables.put(navDesc.getContainerViewVariable(), element);
+
+ final InitInterpreterVariablesTask init = new InitInterpreterVariablesTask(variables, interpreter, new EMFCommandFactoryUI());
+ init.execute();
+
+ boolean precondition = true;
+ if (!StringUtil.isEmpty(navDesc.getPrecondition())) {
+ try {
+ precondition = interpreter.evaluateBoolean(element.getTarget(), navDesc.getPrecondition());
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(navDesc, ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition(), e);
+ }
+ }
+
+ if (precondition) {
+ // VP-2659 : we return true if at least one action has been
+ // added in the menu to make it visible
+ return buildOpenRepresentationActions(navigate, interpreter, navDesc, element, session);
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean buildOpenRepresentationActions(final IMenuManager navigate, final IInterpreter interpreter, final RepresentationNavigationDescription navDesc,
+ final DRepresentationElement element, final Session session) {
+ boolean atLeastOneRepresentationActionsWasCreated = false;
+ Collection<EObject> candidates;
+ if (!StringUtil.isEmpty(navDesc.getBrowseExpression())) {
+ final RuntimeLoggerInterpreter safeInterpreter = RuntimeLoggerManager.INSTANCE.decorate(interpreter);
+ candidates = safeInterpreter.evaluateCollection(element.getTarget(), navDesc, ToolPackage.eINSTANCE.getRepresentationNavigationDescription_BrowseExpression());
+ } else {
+ candidates = new ArrayList<EObject>();
+ final Iterator<EObject> it = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(element.getTarget()).eAllContents(element.getTarget());
+ while (it.hasNext()) {
+ candidates.add(it.next());
+ }
+ }
+ final Collection<DRepresentation> representations = DialectManager.INSTANCE.getRepresentations(navDesc.getRepresentationDescription(), session);
+ for (final DRepresentation representation : representations) {
+ if (representation instanceof DSemanticDecorator && candidates.contains(((DSemanticDecorator) representation).getTarget())) {
+ interpreter.setVariable(navDesc.getRepresentationNameVariable().getName(), representation.getName());
+ String label = new StringBuffer("Open ").append(navDesc.getName()).append(" : ").append(representation.getName()).toString();
+ if (!StringUtil.isEmpty(navDesc.getNavigationNameExpression())) {
+ try {
+ label = interpreter.evaluateString(element.getTarget(), navDesc.getNavigationNameExpression());
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(navDesc, ToolPackage.eINSTANCE.getRepresentationNavigationDescription_NavigationNameExpression(), e);
+ }
+ }
+ navigate.appendToGroup(NAVIGATE_REPRESENTATION_GROUP_SEPARATOR, buildOpenRepresentationAction(session, representation, label));
+ atLeastOneRepresentationActionsWasCreated = true;
+ }
+ }
+ return atLeastOneRepresentationActionsWasCreated;
+ }
+
+ private IAction buildOpenRepresentationAction(final Session session, final DRepresentation representation) {
+ String representationName = representation.getName();
+ if (StringUtil.isEmpty(representationName)) {
+ representationName = "(unnamed)";
+ if (representation instanceof DDiagram) {
+ representationName += " " + new IdentifiedElementQuery(((DDiagram) representation).getDescription()).getLabel();
+ }
+ }
+ return buildOpenRepresentationAction(session, representation, "Open " + representationName);
+ }
+
+ private IAction buildOpenRepresentationAction(final Session session, final DRepresentation representation, final String label) {
+
+ ImageDescriptor imageDescriptor = null;
+ final IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory.adapt(representation, IItemLabelProvider.class);
+ if (labelProvider != null) {
+ imageDescriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(labelProvider.getImage(representation));
+ }
+ return new OpenRepresentationAction(label, imageDescriptor, representation, session);
+
+ }
+
+ private void addRefreshMenu(final IMenuManager manager) {
+ manager.add(refreshAction);
+ }
+
+ private void addTreeItemMenus(final IMenuManager manager) {
+ final Collection<DTreeItem> selectedItems = treeViewManager.getSelectedItems();
+ if (selectedItems != null && !selectedItems.isEmpty()) {
+ manager.add(new Separator());
+
+ // Expose popup menus if there is only one selected line.
+ if (selectedItems.size() == 1) {
+ DTreeItem firstSelectedItem = selectedItems.iterator().next();
+ // VP-915 : handling users contributing throw PopupMenus tools
+ treePopupMenuContributionHandler.contributeToPopupMenu(manager, firstSelectedItem);
+ }
+
+ addDeleteItemsAction(manager, selectedItems);
+
+ // Expose create actions if there is only one selected line.
+ if (selectedItems.size() == 1) {
+ DTreeItem firstSelectedItem = selectedItems.iterator().next();
+ addCreateActions(manager, firstSelectedItem);
+ }
+
+ }
+ }
+
+ private void addCreateActions(IMenuManager manager, DTreeItem singleSelectedItem) {
+ if (singleSelectedItem.getActualMapping() != null) {
+ final List<AbstractToolAction> createActions = getMappingToCreateActions().get(singleSelectedItem.getActualMapping());
+ if (createActions != null && !createActions.isEmpty()) {
+ for (final AbstractToolAction createAction : createActions) {
+ ((AbstractToolItemAction) createAction).setLine(singleSelectedItem);
+ if (createAction.canExecute()) {
+ manager.add(createAction);
+ }
+ }
+ }
+ }
+
+ }
+
+ private void addDeleteItemsAction(IMenuManager manager, Collection<DTreeItem> selectedItems) {
+ deleteItemsAction.setItems(selectedItems);
+ if (deleteItemsAction.canExecute()) {
+ manager.add(deleteItemsAction);
+ }
+ }
+
+ private void createDetailsActions(final DTreeItem currentElement, final SubContributionItem navigate) {
+ if (currentElement.getActualMapping() != null) {
+ final Iterator<RepresentationCreationDescription> it = currentElement.getActualMapping().getDetailDescriptions().iterator();
+ while (it.hasNext()) {
+ final RepresentationCreationDescription desc = it.next();
+ final String precondition = desc.getPrecondition();
+ boolean append = true;
+ if (precondition != null && !StringUtil.isEmpty(precondition.trim())) {
+ append = false;
+ final IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(currentElement.getTarget());
+ try {
+ append = interpreter.evaluateBoolean(currentElement.getTarget(), precondition);
+ } catch (final EvaluationException e) {
+ // do nothing
+ }
+ }
+ if (append) {
+ navigate.setVisible(true);
+ ((IMenuManager) navigate.getInnerItem()).appendToGroup(NEW_REPRESENTATION_GROUP_SEPARATOR, new CreateRepresentationFromRepresentationCreationDescription(desc, currentElement,
+ treeViewManager.getEditingDomain(), treeViewManager.getTreeCommandFactory()));
+ }
+ }
+ }
+ }
+
+ protected Map<TreeMapping, List<AbstractToolAction>> getMappingToCreateActions() {
+ return mappingToCreateActions;
+ }
+
+ public void setMappingToCreateActions(final Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions) {
+ this.mappingToCreateActions = mappingToCreateActions;
+ }
+
+ protected List<AbstractToolAction> getCreateActionsForTree() {
+ return createActionsForTree;
+ }
+
+ public void setCreateActionsForTree(final List<AbstractToolAction> createActionsForTable) {
+ this.createActionsForTree = createActionsForTable;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewer.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewer.java
new file mode 100644
index 0000000000..0274b98e3d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewer.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TreeItem;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.listeners.DTreeItemExpansionChecker;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeViewer;
+
+/**
+ * Sirius {@link AbstractDTreeViewer} for DTree model.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class DTreeViewer extends AbstractDTreeViewer {
+
+ private DTreeItemExpansionChecker dTreeItemExpansionChecker;
+
+ /**
+ * Creates a tree viewer on the given tree control. The viewer has no input,
+ * no content provider, a default label provider, no sorter, and no filters.
+ *
+ * @param parent
+ * the parent control
+ * @param style
+ * the SWT style bits used to create the tree.
+ * @param session
+ * the {@link Session} used by the underlying model
+ */
+ public DTreeViewer(final Composite parent, final int style, final Session session) {
+ super(parent, style);
+ this.dTreeItemExpansionChecker.setPermissionAuthority(session.getModelAccessor().getPermissionAuthority());
+ }
+
+ /**
+ * Overridden to add the {@link DTreeItemExpansionChecker}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected void hookControl(Control control) {
+ dTreeItemExpansionChecker = new DTreeItemExpansionChecker(control);
+ super.hookControl(control);
+ }
+
+ /**
+ * Overridden to fix a behavior difference.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void expandToLevel(Object elementOrTreePath, int level) {
+ int newLevel = level;
+ if (level == ALL_LEVELS) {
+ /*
+ * here we're making sure we'll have the same behavior as in Linux
+ * even on other platforms. We don't want the user to ends up in an
+ * infinite loop because he stroke the "*" key on windows and this
+ * tree is infinite.
+ */
+ newLevel = getCurrentExpandedLevel() + 1;
+ }
+ super.expandToLevel(elementOrTreePath, newLevel);
+ }
+
+ private int getCurrentExpandedLevel() {
+ int maxLevel = 0;
+ for (TreeItem child : getTree().getItems()) {
+ int childValue = doBrowse(child, 1);
+ if (childValue > maxLevel) {
+ maxLevel = childValue;
+ }
+ }
+ return maxLevel;
+ };
+
+ private int doBrowse(TreeItem cur, int currentLevel) {
+ int maxLevel = currentLevel;
+ for (TreeItem child : cur.getItems()) {
+ int childValue = doBrowse(child, currentLevel + 1);
+ if (childValue > maxLevel) {
+ maxLevel = childValue;
+ }
+ }
+ return maxLevel;
+ }
+
+ /**
+ * Overridden to remove the {@link DTreeItemExpansionChecker}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected void handleDispose(DisposeEvent event) {
+ dTreeItemExpansionChecker.dispose();
+ super.handleDispose(event);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
new file mode 100644
index 0000000000..4ebe75c9d2
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
@@ -0,0 +1,493 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.layout.TreeColumnLayout;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerEditor;
+import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeViewerEditor;
+import org.eclipse.jface.viewers.TreeViewerFocusCellManager;
+import org.eclipse.jface.viewers.ViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.ByteArrayTransfer;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
+
+import com.google.common.collect.Lists;
+
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
+import org.eclipse.sirius.common.tools.api.util.Option;
+import org.eclipse.sirius.common.tools.api.util.Options;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.tools.api.command.ICommandFactory;
+import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.business.internal.helper.TreeHelper;
+import org.eclipse.sirius.tree.description.TreeDescription;
+import org.eclipse.sirius.tree.description.TreeItemCreationTool;
+import org.eclipse.sirius.tree.description.TreeItemMapping;
+import org.eclipse.sirius.tree.description.TreeMapping;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.AbstractToolAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.CreateToolItemAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.DeleteTreeItemsAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.actions.EditorCreateTreeItemMenuAction;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.listeners.DTreeViewerListener;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeContentProvider;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeDecoratingLabelProvider;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeItemDropListener;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeItemEditingSupport;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTableViewerManager;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
+import org.eclipse.sirius.ui.tools.internal.editor.DTableColumnViewerEditorActivationStrategy;
+import org.eclipse.sirius.ui.tools.internal.editor.DTableTreeFocusListener;
+import org.eclipse.sirius.ui.tools.internal.views.sessionview.ModelDragTargetAdapter;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+
+/**
+ * This class manages the tree viewer for display the DTree.
+ *
+ * @author nlepine
+ */
+public class DTreeViewerManager extends AbstractDTableViewerManager {
+
+ /** The key for the image which represents a delete action. */
+ public static final String REFRESH_IMG = "tree/refresh";
+
+ /** The key for the image which represents a delete action. */
+ public static final String DELETE_IMG = "tree/delete";
+
+ /** The key for the image which represents a delete action. */
+ public static final String CREATE_TREE_ITEM_IMG = "tree/newTreeItem";
+
+ static {
+ imageRegistry.put(REFRESH_IMG, ImageDescriptor.createFromURL((URL) TreeUIPlugin.INSTANCE.getImage(REFRESH_IMG)));
+ imageRegistry.put(DELETE_IMG, ImageDescriptor.createFromURL((URL) TreeUIPlugin.INSTANCE.getImage(DELETE_IMG)));
+ imageRegistry.put(CREATE_TREE_ITEM_IMG, ImageDescriptor.createFromURL((URL) TreeUIPlugin.INSTANCE.getImage(CREATE_TREE_ITEM_IMG)));
+ }
+
+ private ITreeViewerListener treeViewerListener;
+
+ private final ITreeCommandFactory treeCommandFactory;
+
+ private DTreeContentProvider dTreeContentProvider;
+
+ private DTreeMenuListener actualMenuListener;
+
+ private AdapterFactory adapterFactory;
+
+ private final EditorCreateTreeItemMenuAction createTreeItemMenu = new EditorCreateTreeItemMenuAction();
+
+ /**
+ * The constructor.
+ *
+ * @param parent
+ * The parent composite
+ * @param input
+ * The input DTable
+ * @param editingDomain
+ * The transactional editing domain of this viewer
+ * @param accessor
+ * The accessor for the model
+ * @param tableCommandFactory
+ * The EMF command factory
+ * @param treeEditor
+ * The associated editor
+ */
+ public DTreeViewerManager(final Composite parent, final DTree input, final TransactionalEditingDomain editingDomain, final ModelAccessor accessor, final ICommandFactory tableCommandFactory,
+ final AbstractDTreeEditor treeEditor) {
+ super(parent, input, editingDomain, accessor, tableCommandFactory, treeEditor);
+ this.treeCommandFactory = (ITreeCommandFactory) tableCommandFactory;
+ adapterFactory = TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory();
+ this.createTreeViewer(parent);
+ }
+
+ public static ImageRegistry getImageRegistry() {
+ return imageRegistry;
+ }
+
+ /**
+ * Creates the TreeViewer.
+ *
+ * Problem for action on column header
+ *
+ * @param composite
+ * the Container of the TreeViewer to create
+ */
+ @Override
+ protected void createTreeViewer(final Composite composite) {
+ // Create a composite to hold the children
+ final GridData gridData = new GridData(GridData.FILL_BOTH);
+ composite.setLayoutData(gridData);
+
+ final TreeColumnLayout treeLayout = new TreeColumnLayout();
+ composite.setLayout(treeLayout);
+
+ // Create and setup the TreeViewer
+ final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI;
+
+ treeViewer = new DTreeViewer(composite, style, getSession());
+
+ // Add a focus listener to deactivate the EMF actions on the Tree
+ treeViewer.getTree().addFocusListener(new DTableTreeFocusListener(tableEditor, treeViewer.getTree()));
+ treeViewer.setUseHashlookup(true);
+
+ // tableViewer.setSorter(new
+ // ExampleTaskSorter(ExampleTaskSorter.DESCRIPTION));
+
+ dTreeContentProvider = new DTreeContentProvider(getSession(), this);
+ treeViewer.setContentProvider(dTreeContentProvider);
+
+ // Wrap the LabelProvider in a DecoratingLabelProvider
+ ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator();
+ treeViewer.setLabelProvider(new DTreeDecoratingLabelProvider(adapterFactory, decorator));
+
+ fillMenu();
+ triggerColumnSelectedColumn();
+ initializeEditingSupport();
+ initializeDragAndDropSupport();
+ initializeKeyBindingSupport();
+
+ treeViewerListener = new DTreeViewerListener(getSession());
+ treeViewer.addTreeListener(treeViewerListener);
+
+ // Manage height of the lines, selected colors,
+ triggerCustomDrawingTreeItems();
+
+ // Create a new CellFocusManager
+ final TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(treeViewer, new FocusCellOwnerDrawHighlighter(treeViewer));
+ // Create a TreeViewerEditor with focusable cell
+ TreeViewerEditor.create(treeViewer, focusCellManager, new DTableColumnViewerEditorActivationStrategy(treeViewer), ColumnViewerEditor.TABBING_HORIZONTAL
+ | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
+
+ // The input for the table viewer is the instance of DTable
+ treeViewer.setInput(dRepresentation);
+
+ // Expands the line according to the model
+ treeViewer.setExpandedElements(TreeHelper.getExpandedItems((DTree) dRepresentation).toArray());
+ }
+
+ private void initializeKeyBindingSupport() {
+ treeViewer.getTree().addKeyListener(new KeyListener() {
+ public void keyPressed(final KeyEvent e) {
+ if (e.keyCode == SWT.DEL) {
+ DeleteTreeItemsAction deleteItemsAction = new DeleteTreeItemsAction(getEditingDomain(), getTreeCommandFactory());
+ deleteItemsAction.setItems(getSelectedItems());
+ if (deleteItemsAction.canExecute()) {
+ deleteItemsAction.run();
+ }
+ }
+ }
+ public void keyReleased(final KeyEvent e) {
+ };
+ });
+ }
+
+ private Session getSession() {
+ return SessionManager.INSTANCE.getSession(((DTree) dRepresentation).getTarget());
+ }
+
+ /**
+ * Initializes the Editing Support (allowing direct Edit) to associate to
+ * the current Tree.
+ */
+ protected void initializeEditingSupport() {
+
+ // Step 1 : get the TreeViewerColumn corresponding to this Tree
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.ADD_SWT_COLUMN_KEY);
+
+ Option<ViewerColumn> optionViewerColumn = getViewerColumn();
+ if (optionViewerColumn.some()) {
+ ViewerColumn treeColumn = optionViewerColumn.get();
+
+ // Step 2 : set the Editing support
+ treeColumn.setEditingSupport(new DTreeItemEditingSupport(treeViewer, getEditingDomain(), getAccessor(), getTreeCommandFactory(), this.getEditor()));
+ }
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.ADD_SWT_COLUMN_KEY);
+ }
+
+ /**
+ * Initializes Drag and Drop support for the current DTree.
+ */
+ protected void initializeDragAndDropSupport() {
+ // If copy/paste operations should be supported, may add
+ // " | DND.DROP_COPY" to the supported operations.
+ int supportedOperations = DND.DROP_MOVE | DND.DROP_LINK;
+
+ ISelectionProvider selectionProvider = this.treeViewer;
+ this.treeViewer.addDragSupport(supportedOperations, new ByteArrayTransfer[] { LocalSelectionTransfer.getInstance() }, new ModelDragTargetAdapter(selectionProvider));
+ this.treeViewer.addDropSupport(supportedOperations, new ByteArrayTransfer[] { LocalSelectionTransfer.getInstance() }, new DTreeItemDropListener(this.treeViewer, this.editingDomain,
+ this.treeCommandFactory, this.accessor));
+ }
+
+ /**
+ * Returns the viewer column associated to the treeViewer.
+ *
+ * @return the viewer column of the treeViewer, or Options.newNone() if to
+ * viewer column found.
+ */
+ private Option<ViewerColumn> getViewerColumn() {
+ Option<ViewerColumn> viewerColumn = Options.newNone();
+
+ // We use reflection to access to the ColumnViewer.getViewerColumn(int)
+ // method (package visibility)
+ Class<?> columnViewerClass = ColumnViewer.class;
+ Method method;
+ try {
+ method = columnViewerClass.getDeclaredMethod("getViewerColumn", Integer.TYPE);
+ method.setAccessible(true);
+ Object invoke = method.invoke(treeViewer, 0);
+ if (invoke instanceof ViewerColumn) {
+ viewerColumn = Options.newSome((ViewerColumn) invoke);
+ }
+ } catch (SecurityException e) {
+ // Nothing to do, method will return Options.NONE
+ } catch (NoSuchMethodException e) {
+ // Nothing to do, method will return Options.NONE
+ } catch (IllegalArgumentException e) {
+ // Nothing to do, method will return Options.NONE
+ } catch (InvocationTargetException e) {
+ // Nothing to do, method will return Options.NONE
+ } catch (IllegalAccessException e) {
+ // Nothing to do, method will return Options.NONE
+ }
+
+ return viewerColumn;
+ }
+
+ /**
+ * Initialize a cache and add, if needed, the contextual menu for the table. <BR>
+ * Cached the actions of creation and deletion in order to increase
+ * performance and not calculate it on each contextual menu.<BR>
+ */
+ @Override
+ public void fillMenu() {
+ if (descriptionFileChanged) {
+ descriptionFileChanged = false;
+ final Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions = new HashMap<TreeMapping, List<AbstractToolAction>>();
+ final List<AbstractToolAction> createActionsForTree = new ArrayList<AbstractToolAction>();
+
+ calculateAvailableMenus(mappingToCreateActions, createActionsForTree);
+ mgr.setRemoveAllWhenShown(true);
+ if (actualMenuListener != null) {
+ mgr.removeAll();
+ actualMenuListener.setMappingToCreateActions(mappingToCreateActions);
+ actualMenuListener.setCreateActionsForTree(createActionsForTree);
+ } else {
+ actualMenuListener = new DTreeMenuListener((DTree) dRepresentation, this, mappingToCreateActions, createActionsForTree);
+ mgr.addMenuListener(actualMenuListener);
+ //
+ final Menu menu = mgr.createContextMenu(treeViewer.getControl());
+ treeViewer.getControl().setMenu(menu);
+ // // Add this line to have others contextual menus
+ tableEditor.getSite().registerContextMenu(mgr, treeViewer);
+ }
+ getCreateTreeItemMenu().update(createActionsForTree);
+ }
+ }
+
+ /**
+ * Get the selected {@link DTreeItem item}.
+ *
+ * @return the selected tree items or an empty collection
+ */
+ public Collection<DTreeItem> getSelectedItems() {
+ Collection<DTreeItem> result = Lists.newArrayList();
+ if (treeViewer.getTree().getSelectionCount() > 0) {
+ for (TreeItem item : treeViewer.getTree().getSelection()) {
+ Object data = item.getData();
+ if (data instanceof DTreeItem) {
+ result.add((DTreeItem) data);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Create the menus according to the {@link TreeMapping} and the associated
+ * {@link CreateTool} and {@link DeleteTool}.
+ *
+ */
+ private void calculateAvailableMenus(final Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions, final List<AbstractToolAction> createActionsForTree) {
+
+ final TreeDescription treeDescription = ((DTree) dRepresentation).getDescription();
+
+ if (treeDescription != null) {
+ // Actions on lines
+ calculateAvailableMenusForLine(treeDescription.getSubItemMappings(), mappingToCreateActions, new ArrayList<TreeItemMapping>());
+
+ // Actions on table
+ final EList<? extends TreeItemCreationTool> createLineTools = treeDescription.getCreateTreeItem();
+ for (final TreeItemCreationTool createTool : createLineTools) {
+ final CreateToolItemAction createLineAction = new CreateToolItemAction(createTool, getEditingDomain(), getTreeCommandFactory());
+ createLineAction.setTable((DTree) dRepresentation);
+ createActionsForTree.add(createLineAction);
+ }
+ }
+
+ }
+
+ /**
+ * Create the menus according to the {@link LineMapping} and the associated
+ * {@link CreateTool} and {@link DeleteTool}.
+ *
+ * @param lineMappings
+ * List of {@link LineMapping}
+ * @param mappingToCreateActions
+ * A map which associates {@link TreeMapping} with the
+ * corresponding list of {@link AbstractToolAction} (
+ * {@link CreateLineAction} or {@link CreateTargetColumnAction})
+ */
+ private void calculateAvailableMenusForLine(final EList<TreeItemMapping> lineMappings, final Map<TreeMapping, List<AbstractToolAction>> mappingToCreateActions,
+ final List<TreeItemMapping> processedLineMappings) {
+ for (final TreeItemMapping treeItemMapping : lineMappings) {
+ if (treeItemMapping != null && !mappingToCreateActions.keySet().contains(treeItemMapping)) {
+ final EList<? extends TreeItemCreationTool> createTools = treeItemMapping.getCreate();
+ List<AbstractToolAction> existingCreateTools = mappingToCreateActions.get(treeItemMapping);
+ if (existingCreateTools == null) {
+ existingCreateTools = new ArrayList<AbstractToolAction>();
+ }
+ for (final TreeItemCreationTool createTool : createTools) {
+ existingCreateTools.add(new CreateToolItemAction(createTool, getEditingDomain(), getTreeCommandFactory()));
+ }
+ mappingToCreateActions.put(treeItemMapping, existingCreateTools);
+ }
+ if (treeItemMapping != null && !processedLineMappings.contains(treeItemMapping)) {
+ processedLineMappings.add(treeItemMapping);
+ calculateAvailableMenusForLine(treeItemMapping.getAllSubMappings(), mappingToCreateActions, processedLineMappings);
+ }
+ }
+ }
+
+ /**
+ * Add a listener on the tree to listen the mouseDouwn or the key left-right
+ * arrows and store the activeColumn
+ */
+ private void triggerColumnSelectedColumn() {
+ treeViewer.getTree().addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseDown(final MouseEvent event) {
+ int x = 0;
+ for (int i = 0; i < treeViewer.getTree().getColumnCount(); i++) {
+ x += treeViewer.getTree().getColumn(i).getWidth();
+ if (event.x <= x) {
+ activeColumn = i;
+ break;
+ }
+ }
+ }
+
+ });
+ treeViewer.getTree().addKeyListener(new KeyListener() {
+ public void keyPressed(final KeyEvent e) {
+ if (e.keyCode == SWT.ARROW_LEFT && activeColumn != 0) {
+ activeColumn--;
+ treeViewer.getTree().showColumn(treeViewer.getTree().getColumn(activeColumn));
+ } else if (e.keyCode == SWT.ARROW_RIGHT && activeColumn != treeViewer.getTree().getColumnCount() - 1) {
+ activeColumn++;
+ treeViewer.getTree().showColumn(treeViewer.getTree().getColumn(activeColumn));
+ }
+ }
+
+ public void keyReleased(final KeyEvent e) {
+ };
+ });
+
+ }
+
+ /**
+ * Return the TableCommandFactory.
+ *
+ * @return the TableCommandFactory
+ */
+ public ITreeCommandFactory getTreeCommandFactory() {
+ return treeCommandFactory;
+ }
+
+ /**
+ * Check the tree.
+ *
+ * @param tree
+ * the tree to test
+ * @return true if the tree is equals to the dTree of this manager, false
+ * otherwise
+ */
+ public boolean isSameTree(final DTree tree) {
+ return ((DTree) dRepresentation).equals(tree);
+ }
+
+ /**
+ * Changed descriptionFileChanged state.
+ *
+ * @param modified
+ * Indicates whether the odesign file has changed since the last
+ * load menus
+ */
+ @Override
+ public void setDescriptionFileChanged(final boolean modified) {
+ descriptionFileChanged = modified;
+ }
+
+ /**
+ * Return the menu which is display in the toolBar.
+ *
+ * @return the menu for create lines on the root
+ */
+ public EditorCreateTreeItemMenuAction getCreateTreeItemMenu() {
+ return createTreeItemMenu;
+ }
+
+ /**
+ * Release resources.
+ */
+ @Override
+ public void dispose() {
+ treeViewer.removeTreeListener(treeViewerListener);
+ treeViewerListener = null;
+ dTreeContentProvider.dispose();
+ dTreeContentProvider = null;
+ super.dispose();
+ createTreeItemMenu.dispose();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/RefreshAtOpeningActivator.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/RefreshAtOpeningActivator.java
new file mode 100644
index 0000000000..94265e0853
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/RefreshAtOpeningActivator.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor;
+
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * IPartListener to allows update of the DTree model after tree dialect editor
+ * opening. Done here because it is call even with IMemento.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class RefreshAtOpeningActivator implements IPartListener {
+
+ private DTreeEditor dTreeEditor;
+
+ /**
+ * Default constructor.
+ *
+ * @param dTreeEditor
+ * the {@link DTreeEditor}
+ */
+ public RefreshAtOpeningActivator(DTreeEditor dTreeEditor) {
+ this.dTreeEditor = dTreeEditor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IPartListener#partActivated(IWorkbenchPart)
+ */
+ public void partActivated(IWorkbenchPart part) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IPartListener#partBroughtToTop(IWorkbenchPart)
+ */
+ public void partBroughtToTop(IWorkbenchPart part) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IPartListener#partClosed(IWorkbenchPart)
+ */
+ public void partClosed(IWorkbenchPart part) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IPartListener#partDeactivated(IWorkbenchPart)
+ */
+ public void partDeactivated(IWorkbenchPart part) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IPartListener#partOpened(IWorkbenchPart)
+ */
+ public void partOpened(IWorkbenchPart part) {
+ // Activation of the refresh of the DTree property page
+ dTreeEditor.enablePropertiesUpdate(true);
+ dTreeEditor.forceRefreshProperties();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolAction.java
new file mode 100644
index 0000000000..e398e7bba3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolAction.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.description.TreeItemTool;
+
+/**
+ * An abstract class for all actions which launch tool (DeleteTool, CreateTool).
+ *
+ * @author nlepine
+ */
+public class AbstractToolAction extends Action {
+ TransactionalEditingDomain editingDomain;
+
+ ITreeCommandFactory treeCommandFactory;
+
+ /**
+ * The tool corresponding to this action.
+ */
+ TreeItemTool tool;
+
+ /**
+ * Creates a new action with the given text.
+ *
+ * @param text
+ * the action's text, or <code>null</code> if there is no text
+ * @param editingDomain
+ * The transactional editing domain
+ * @param treeCommandFactory
+ * The EMF command factory
+ * @param treeTool
+ * The tool corresponding to this action
+ *
+ */
+ public AbstractToolAction(final String text, final TransactionalEditingDomain editingDomain, final ITreeCommandFactory treeCommandFactory, final TreeItemTool treeTool) {
+ super(text);
+ this.editingDomain = editingDomain;
+ this.treeCommandFactory = treeCommandFactory;
+ this.tool = treeTool;
+ }
+
+ /**
+ * Creates a new action with the given text and style.
+ *
+ * @param text
+ * the action's text, or <code>null</code> if there is no text
+ * @param image
+ * the action's image, or <code>null</code> if there is no image
+ * @param editingDomain
+ * The transactional editing domain
+ * @param treeCommandFactory
+ * The EMF command factory
+ * @param treeTool
+ * The tool corresponding to this action
+ */
+ public AbstractToolAction(final String text, final ImageDescriptor image, final TransactionalEditingDomain editingDomain, final ITreeCommandFactory treeCommandFactory, final TreeItemTool treeTool) {
+ super(text, image);
+ this.editingDomain = editingDomain;
+ this.treeCommandFactory = treeCommandFactory;
+ this.tool = treeTool;
+ }
+
+ /**
+ * return The transactional editing domain.
+ *
+ * @return the editingDomain
+ */
+ protected TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ /**
+ * Return the EMF command factory.
+ *
+ * @return the treeCommandFactory
+ */
+ protected ITreeCommandFactory getITreeCommandFactory() {
+ return treeCommandFactory;
+ }
+
+ /**
+ * The default implementation of this <code>AbstractToolAction</code> method
+ * return false. Subclasses should override this method.
+ *
+ * @return true if this action can be execute, false otherwise
+ */
+ public boolean canExecute() {
+ return false;
+ }
+
+ protected TreeItemTool getTool() {
+ return tool;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolItemAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolItemAction.java
new file mode 100644
index 0000000000..7756248363
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/AbstractToolItemAction.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.description.TreeItemTool;
+
+/**
+ * An abstract class for all actions on {@link DLine}.
+ *
+ * @author nlepine
+ */
+public abstract class AbstractToolItemAction extends AbstractToolAction {
+
+ /**
+ * The line concerned with this action
+ */
+ private DTreeItem line;
+
+ /**
+ * Creates a new action with the given text and the given line.
+ *
+ * @param text
+ * the action's text, or <code>null</code> if there is no text
+ * @param editingDomain
+ * The transactional editing domain
+ * @param treeCommandFactory
+ * The EMF command factory
+ * @param treeTool
+ * The tool corresponding to this action
+ */
+ public AbstractToolItemAction(final String text, final TransactionalEditingDomain editingDomain, final ITreeCommandFactory treeCommandFactory, final TreeItemTool treeTool) {
+ super(text, editingDomain, treeCommandFactory, treeTool);
+ }
+
+ /**
+ * Creates a new action with the given text and style.
+ *
+ * @param text
+ * the action's text, or <code>null</code> if there is no text
+ * @param image
+ * the action's image, or <code>null</code> if there is no image
+ * @param editingDomain
+ * The transactional editing domain
+ * @param treeCommandFactory
+ * The EMF command factory
+ * @param treeTool
+ * The tool corresponding to this action
+ */
+ public AbstractToolItemAction(final String text, final ImageDescriptor image, final TransactionalEditingDomain editingDomain, final ITreeCommandFactory treeCommandFactory,
+ final TreeItemTool treeTool) {
+ super(text, image, editingDomain, treeCommandFactory, treeTool);
+ }
+
+ /**
+ * Return the line.
+ *
+ * @return the line
+ */
+ public DTreeItem getTreeItem() {
+ return line;
+ }
+
+ /**
+ * Set the line on which the tool of this action applied.
+ *
+ * @param line
+ * the line to set
+ */
+ public void setLine(final DTreeItem line) {
+ this.line = line;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateRepresentationFromRepresentationCreationDescription.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateRepresentationFromRepresentationCreationDescription.java
new file mode 100644
index 0000000000..c8979d7c80
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateRepresentationFromRepresentationCreationDescription.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.common.ui.SiriusTransPlugin;
+import org.eclipse.sirius.DRepresentationElement;
+import org.eclipse.sirius.business.api.dialect.command.CreateRepresentationCommand;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.description.DescriptionPackage;
+import org.eclipse.sirius.description.RepresentationDescription;
+import org.eclipse.sirius.description.tool.RepresentationCreationDescription;
+import org.eclipse.sirius.description.tool.ToolPackage;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
+import org.eclipse.sirius.ui.tools.api.image.ImagesPath;
+
+/**
+ * Create a new Representation from a {@link RepresentationCreationDescription}.
+ *
+ * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a>
+ */
+public class CreateRepresentationFromRepresentationCreationDescription extends Action {
+
+ private static final AdapterFactory ADAPTER_FACTORY = DialectUIManager.INSTANCE.createAdapterFactory();
+
+ private final RepresentationCreationDescription desc;
+
+ private final DRepresentationElement target;
+
+ private final TransactionalEditingDomain editingDomain;
+
+ private final ITreeCommandFactory treeCommandFactory;
+
+ /**
+ * Build the action.
+ *
+ * @param desc
+ * {@link RepresentationCreationDescription} to use.
+ * @param target
+ * element on which the user requested the creation of a new
+ * representation.
+ * @param editingDomain
+ * current {@link org.eclipse.emf.edit.domain.EditingDomain}.
+ * @param tableCommandFactory
+ * The {@link ITableCommandFactory}.
+ */
+ public CreateRepresentationFromRepresentationCreationDescription(final RepresentationCreationDescription desc, final DRepresentationElement target, final TransactionalEditingDomain editingDomain,
+ final ITreeCommandFactory tableCommandFactory) {
+ this.desc = desc;
+ this.target = target;
+ this.editingDomain = editingDomain;
+ ImageDescriptor imageDescriptor = null;
+ RepresentationDescription representationDescription = desc.getRepresentationDescription();
+ if (representationDescription != null) {
+ // Search the icon for this representation description
+ final IItemLabelProvider labelProvider = (IItemLabelProvider) CreateRepresentationFromRepresentationCreationDescription.ADAPTER_FACTORY.adapt(representationDescription,
+ IItemLabelProvider.class);
+ if (labelProvider != null) {
+ imageDescriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(labelProvider.getImage(representationDescription));
+ }
+ }
+ if (imageDescriptor != null) {
+ setImageDescriptor(imageDescriptor);
+ } else {
+ setImageDescriptor(SiriusTransPlugin.getBundledImageDescriptor(ImagesPath.CREATE_VIEW_ICON));
+ }
+ this.treeCommandFactory = tableCommandFactory;
+ }
+
+ @Override
+ public String getText() {
+ return new StringBuffer("New detail : ").append(desc.getName()).toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ final CompoundCommand compoundCommand = new CompoundCommand();
+
+ final IInterpreter interpreter = InterpreterUtil.getInterpreter(target.getTarget());
+ // default name
+ String name = "new " + desc.getName();
+ if (!StringUtil.isEmpty(desc.getTitleExpression())) {
+ try {
+ name = interpreter.evaluateString(target.getTarget(), desc.getTitleExpression());
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(desc, ToolPackage.eINSTANCE.getRepresentationCreationDescription_TitleExpression(), e);
+ }
+ } else if (desc.getRepresentationDescription() != null && !StringUtil.isEmpty(desc.getRepresentationDescription().getTitleExpression())) {
+ try {
+ name = interpreter.evaluateString(target.getTarget(), desc.getRepresentationDescription().getTitleExpression());
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(desc.getRepresentationDescription(), DescriptionPackage.eINSTANCE.getRepresentationDescription_TitleExpression(), e);
+ }
+ }
+
+ try {
+ name = treeCommandFactory.getUserInterfaceCallBack().askForDetailName(name, desc.getRepresentationDescription().getEndUserDocumentation());
+
+ if (desc.getInitialOperation() != null && desc.getInitialOperation().getFirstModelOperations() != null) {
+ final Command emfCommandTool = treeCommandFactory.buildDoExecuteDetailsOperation(target, desc, name);
+ compoundCommand.append(emfCommandTool);
+ }
+ final CreateRepresentationCommand command = treeCommandFactory.buildCreateRepresentationFromDescription(desc, target, name);
+ compoundCommand.append(command);
+ editingDomain.getCommandStack().execute(compoundCommand);
+
+ final Session session = SessionManager.INSTANCE.getSession(target.getTarget());
+
+ DialectUIManager.INSTANCE.openEditor(session, command.getCreatedRepresentation());
+ } catch (final InterruptedException e) {
+ // the user pressed "cancel", let's do nothing
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateToolItemAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateToolItemAction.java
new file mode 100644
index 0000000000..27ffc00f74
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/CreateToolItemAction.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import com.google.common.collect.Iterators;
+
+import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterSiriusVariables;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
+import org.eclipse.sirius.description.tool.CreateInstance;
+import org.eclipse.sirius.description.tool.ToolPackage;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItemContainer;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.business.internal.helper.TreeHelper;
+import org.eclipse.sirius.tree.description.TreeItemCreationTool;
+import org.eclipse.sirius.tree.description.TreeItemMapping;
+import org.eclipse.sirius.tree.description.TreeItemTool;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.command.CreateLineCommandFromToolRecordingCommand;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.MetaClassNotFoundException;
+
+/**
+ * Action to launch the createTool of the treeItemContainer (tree or tree item).
+ *
+ * @author nlepine
+ */
+public class CreateToolItemAction extends AbstractToolItemAction {
+ DTree tree;
+
+ /**
+ * Constructor.
+ *
+ * @param createTool
+ * The tool to do some other actions
+ * @param editingDomain
+ * The transactional editing domain
+ * @param tableCommandFactory
+ * The EMF command factory
+ */
+ public CreateToolItemAction(final TreeItemCreationTool createTool, final TransactionalEditingDomain editingDomain, final ITreeCommandFactory tableCommandFactory) {
+ super(new IdentifiedElementQuery(createTool).getLabel(), CreateToolItemAction.findImageDescriptor(createTool), editingDomain, tableCommandFactory, createTool);
+ }
+
+ private static ImageDescriptor findImageDescriptor(TreeItemCreationTool createTool) {
+
+ ImageDescriptor descriptor = DTreeViewerManager.getImageRegistry().getDescriptor(DTreeViewerManager.CREATE_TREE_ITEM_IMG);
+ EObject created = null;
+
+ Iterator<CreateInstance> createInstances = Iterators.filter(createTool.eAllContents(), CreateInstance.class);
+ while (created == null && createInstances.hasNext()) {
+ CreateInstance map = createInstances.next();
+ created = CreateToolItemAction.tryToInstanciateType(createTool, created, map.getTypeName());
+ }
+
+ Iterator<TreeItemMapping> it = createTool.getMapping().iterator();
+ while (created == null && it.hasNext()) {
+ TreeItemMapping map = it.next();
+ created = CreateToolItemAction.tryToInstanciateType(createTool, created, map.getDomainClass());
+ }
+
+ if (created != null) {
+ final IItemLabelProvider labelProvider = (IItemLabelProvider) TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory().adapt(created, IItemLabelProvider.class);
+ if (labelProvider != null) {
+ ImageDescriptor semanticDescriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(labelProvider.getImage(created));
+ if (semanticDescriptor != null) {
+ descriptor = semanticDescriptor;
+ }
+
+ }
+ }
+
+ return descriptor;
+ }
+
+ private static EObject tryToInstanciateType(TreeItemCreationTool createTool, EObject created, String map) {
+ EObject result = created;
+ if (!StringUtil.isEmpty(map)) {
+ try {
+ final EObject anInstance = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(createTool).createInstance(map);
+ result = anInstance;
+ } catch (final MetaClassNotFoundException e) {
+ /*
+ * silent catch, it's just a bit more magic, if we're able to
+ * retrieve the right type then we'll do.
+ */
+ }
+
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ super.run();
+ getEditingDomain().getCommandStack().execute(new CreateLineCommandFromToolRecordingCommand(getEditingDomain(), getText(), getTreeItem(), tree, treeCommandFactory, getCreationTool()));
+ }
+
+ private TreeItemCreationTool getCreationTool() {
+ TreeItemCreationTool tool = null;
+ final TreeItemTool tableTool = getTool();
+ if (tableTool instanceof TreeItemCreationTool) {
+ tool = (TreeItemCreationTool) tableTool;
+ }
+ return tool;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.table.ui.tools.internal.editor.action.AbstractToolAction#canExecute()
+ */
+ @Override
+ public boolean canExecute() {
+ boolean canExecute = true;
+ if (getCreationTool() != null) {
+ if (getCreationTool().getFirstModelOperation() == null) {
+ canExecute = false;
+ } else {
+ if (getCreationTool().getPrecondition() != null && !StringUtil.isEmpty(getCreationTool().getPrecondition().trim())) {
+ IInterpreter interpreter = null;
+ try {
+ if (getTreeItem() != null) {
+ interpreter = InterpreterUtil.getInterpreter(getTreeItem().getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.ROOT, TreeHelper.getTree(getTreeItem()).getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.ELEMENT, getTreeItem().getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER, ((DTreeItemContainer) getTreeItem().eContainer()).getTarget());
+ canExecute = interpreter.evaluateBoolean(getTreeItem().getTarget(), getCreationTool().getPrecondition());
+ } else {
+ interpreter = InterpreterUtil.getInterpreter(getTable().getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.ROOT, getTable().getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.ELEMENT, getTable().getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER, null);
+ canExecute = interpreter.evaluateBoolean(getTable().getTarget(), getCreationTool().getPrecondition());
+ }
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(getCreationTool(), ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition(), e);
+ }
+ interpreter.unSetVariable(IInterpreterSiriusVariables.ROOT);
+ interpreter.unSetVariable(IInterpreterSiriusVariables.ELEMENT);
+ interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER);
+ }
+ }
+ }
+ return canExecute;
+ }
+
+ /**
+ * Return the table.
+ *
+ * @return the table
+ */
+ public DTree getTable() {
+ return tree;
+ }
+
+ /**
+ * Set the table on which the tool of this action applied.
+ *
+ * @param table
+ * the table to set
+ */
+ public void setTable(final DTree table) {
+ this.tree = table;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/DeleteTreeItemsAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/DeleteTreeItemsAction.java
new file mode 100644
index 0000000000..be36baf71f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/DeleteTreeItemsAction.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+
+import com.google.common.collect.Lists;
+
+import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.business.internal.metamodel.query.DTreeItemInternalQuery;
+import org.eclipse.sirius.tree.description.TreeItemDeletionTool;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+
+/**
+ * This action delete the line (the corresponding semantic element).
+ *
+ * @author nlepine
+ */
+public class DeleteTreeItemsAction extends Action {
+ private static final String DELETE_ITEM = "Delete tree item";
+
+ private static final String DELETE_ITEMS = DELETE_ITEM + "s";
+
+ private static final String TOOLTIP_ITEM = "Delete the target semantic element";
+
+ private static final String TOOLTIP_ITEMS = TOOLTIP_ITEM + "s";
+
+ private final ITreeCommandFactory treeCommandFactory;
+
+ private final TransactionalEditingDomain editingDomain;
+
+ private final Collection<DTreeItem> items = Lists.newArrayList();
+
+ /**
+ * Constructor. The deleteTool can be null if there is nothing specific to
+ * do (only the delete of the line). <BR>
+ * When a {@link DeleteTool} is specified the normal delete is not done.
+ *
+ * @param editingDomain
+ * The transactional editing domain
+ * @param treeCommandFactory
+ * The EMF command factory
+ *
+ */
+ public DeleteTreeItemsAction(final TransactionalEditingDomain editingDomain, final ITreeCommandFactory treeCommandFactory) {
+ super(DELETE_ITEM, DTreeViewerManager.getImageRegistry().getDescriptor(DTreeViewerManager.DELETE_IMG));
+ this.editingDomain = editingDomain;
+ this.treeCommandFactory = treeCommandFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ super.run();
+
+ CompoundCommand cc = new CompoundCommand();
+ for (DTreeItem item : items) {
+ cc.append(new DeleteTreeElementRecordingCommand(getEditingDomain(), getText(), item));
+ }
+
+ getEditingDomain().getCommandStack().execute(cc);
+
+ items.clear();
+ }
+
+ private TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ private TreeItemDeletionTool getDeleteTool(DTreeItem treeItem) {
+ TreeItemDeletionTool tool = null;
+ if (treeItem != null && treeItem.getActualMapping() != null) {
+ tool = treeItem.getActualMapping().getDelete();
+ }
+ return tool;
+ }
+
+ /**
+ * Set the tree items to delete.
+ *
+ * @param itemsToDelete
+ * the items to delete.
+ */
+ public void setItems(Collection<DTreeItem> itemsToDelete) {
+ items.clear();
+ if (itemsToDelete != null) {
+ items.addAll(itemsToDelete);
+ }
+
+ if (items.size() == 1) {
+ setText(DELETE_ITEM);
+ setToolTipText(TOOLTIP_ITEM);
+
+ TreeItemDeletionTool deleteTool = getDeleteTool(items.iterator().next());
+ if (deleteTool != null) {
+ setText(new IdentifiedElementQuery(deleteTool).getLabel());
+ setToolTipText(deleteTool.getDocumentation());
+ }
+ } else if (items.size() > 1) {
+ setText(DELETE_ITEMS);
+ setToolTipText(TOOLTIP_ITEMS);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.sirius.tree.ui.tools.internal.editor.action.AbstractToolAction#canExecute()
+ */
+ public boolean canExecute() {
+ boolean canExecute = !items.isEmpty();
+
+ for (DTreeItem itemToDelete : items) {
+ canExecute = canExecute && new DTreeItemInternalQuery(itemToDelete).canBeDeleted();
+
+ if (!canExecute) {
+ break;
+ }
+ }
+
+ return canExecute;
+ }
+
+ private class DeleteTreeElementRecordingCommand extends RecordingCommand {
+
+ private final DTreeItem item;
+
+ public DeleteTreeElementRecordingCommand(TransactionalEditingDomain domain, String label, DTreeItem item) {
+ super(domain, label);
+ this.item = item;
+ }
+
+ @Override
+ protected void doExecute() {
+ treeCommandFactory.buildDeleteTreeElement(item).execute();
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorCreateTreeItemMenuAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorCreateTreeItemMenuAction.java
new file mode 100644
index 0000000000..9117a825de
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorCreateTreeItemMenuAction.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+
+/**
+ * This implementation is used to create the structure viewer's
+ * "Create Tree Item" action.
+ *
+ * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a>
+ */
+public class EditorCreateTreeItemMenuAction extends Action implements IMenuCreator {
+ /** The Id of this action. */
+ public static final String ID = "CreateTreeItemMenu";
+
+ /** Menu manager for this action. */
+ private final MenuManager menuManager = new MenuManager();
+
+ /** The last action launch from this menu. */
+ private Action lastCreateTreeItemAction;
+
+ /** List of the current available actions for this menu. */
+ private final List<CreateToolItemAction> createTreeItemActionsForTree = new ArrayList<CreateToolItemAction>();
+
+ // menu item selection listener: listens to selection events
+ private final Listener menuItemListener = new Listener() {
+ public void handleEvent(final Event event) {
+ if (SWT.Selection == event.type && !event.widget.isDisposed()) {
+ final ActionContributionItem item = (ActionContributionItem) event.widget.getData();
+ setLastAction((CreateToolItemAction) item.getAction());
+ }
+ }
+ };
+
+ /**
+ * This default constructor will instantiate an action given the
+ * {@link #BUNDLE bundle} resources prefixed by &quot;action.save&quot;.
+ */
+ public EditorCreateTreeItemMenuAction() {
+ super("Create root tree items", DTreeViewerManager.getImageRegistry().getDescriptor(DTreeViewerManager.CREATE_TREE_ITEM_IMG));
+ setId(ID);
+ setMenuCreator(this);
+ setEnabled(false);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ if (lastCreateTreeItemAction != null && lastCreateTreeItemAction.isEnabled()) {
+ lastCreateTreeItemAction.run();
+ }
+ }
+
+ /**
+ * This will add the given action to this action's menu.
+ *
+ * @param action
+ * {@link Action} to add to this action's menu.
+ */
+ public void addActionToMenu(final Action action) {
+ final ActionContributionItem contribution = new ActionContributionItem(action);
+ menuManager.add(contribution);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#dispose()
+ */
+ public void dispose() {
+ if (menuManager.getMenu() != null) {
+ final MenuItem[] menuItems = menuManager.getMenu().getItems();
+ for (MenuItem menuItem : menuItems) {
+ if (menuItem.getStyle() == SWT.SEPARATOR) {
+ continue;
+ }
+ menuItem.removeListener(SWT.Selection, menuItemListener);
+ }
+ menuManager.getMenu().dispose();
+ }
+ menuManager.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control)
+ */
+ public Menu getMenu(final Control parent) {
+ // Creates the menu if needed, or removes all elements except for the
+ // save action
+ if (menuManager.getMenu() == null) {
+ menuManager.createContextMenu(parent);
+ update();
+ }
+
+ final MenuItem[] menuItems = menuManager.getMenu().getItems();
+ for (MenuItem menuItem : menuItems) {
+ if (menuItem.getStyle() == SWT.SEPARATOR) {
+ continue;
+ }
+ menuItem.addListener(SWT.Selection, menuItemListener);
+ }
+
+ return menuManager.getMenu();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu)
+ */
+ public Menu getMenu(final Menu parent) {
+ return null;
+ }
+
+ /**
+ * The change is applied on the next getMenu.
+ *
+ * @param createActionsForTable
+ * List of <{@link AbstractToolAction}
+ */
+ public void update(final List<AbstractToolAction> createActionsForTable) {
+ getCreateTreeItemActionsForTree().clear();
+ menuManager.removeAll();
+ // Add all create line tool
+ for (final AbstractToolAction toolAction : createActionsForTable) {
+ if (toolAction instanceof CreateToolItemAction) {
+ getCreateTreeItemActionsForTree().add((CreateToolItemAction) toolAction);
+ }
+ }
+ update();
+ }
+
+ /**
+ * The change is applied on the next getMenu.
+ */
+ protected void update() {
+ setEnabled(!getCreateTreeItemActionsForTree().isEmpty());
+
+ menuManager.removeAll();
+ // Add all create line tool on the table
+ for (final CreateToolItemAction createLineAction : getCreateTreeItemActionsForTree()) {
+ if (createLineAction.canExecute()) {
+ menuManager.add(createLineAction);
+ }
+ }
+ }
+
+ public void setLastAction(final CreateToolItemAction createLineAction) {
+ lastCreateTreeItemAction = createLineAction;
+ }
+
+ /**
+ * Return the available createTreeItem actions.
+ *
+ * @return the createTreeItemActionsForTable
+ */
+ protected List<CreateToolItemAction> getCreateTreeItemActionsForTree() {
+ return createTreeItemActionsForTree;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorRefreshAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorRefreshAction.java
new file mode 100644
index 0000000000..000678f4f0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/EditorRefreshAction.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.dialect.command.RefreshRepresentationsCommand;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeEditor;
+import org.eclipse.sirius.ui.business.api.action.RefreshActionListenerRegistry;
+
+/**
+ * This action refresh the content of the tree.
+ *
+ * @author nlepine
+ */
+public class EditorRefreshAction implements IEditorActionDelegate {
+ /**
+ * This records the editor or view with which the action is currently
+ * associated.
+ */
+ protected IWorkbenchPart workbenchPart;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction,
+ * org.eclipse.ui.IEditorPart)
+ */
+ public void setActiveEditor(final IAction action, final IEditorPart targetEditor) {
+ setActiveWorkbenchPart(targetEditor);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+ public void run(final IAction action) {
+ if (workbenchPart instanceof DTreeEditor) {
+ final IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(final IProgressMonitor monitor) {
+ final DTreeEditor treeEditor = (DTreeEditor) workbenchPart;
+ treeEditor.enablePropertiesUpdate(false);
+ RefreshActionListenerRegistry.INSTANCE.notifyRepresentationIsAboutToBeRefreshed(treeEditor.getTreeModel());
+ treeEditor.getEditingDomain().getCommandStack().execute(new RefreshRepresentationsCommand(treeEditor.getEditingDomain(), monitor, treeEditor.getTreeModel()));
+ treeEditor.enablePropertiesUpdate(true);
+ }
+ };
+ final Shell activeShell = workbenchPart.getSite().getShell();
+ final ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(activeShell);
+ try {
+ monitorDialog.run(false, false, op);
+ } catch (final InvocationTargetException e) {
+ MessageDialog.openError(activeShell, "Error", e.getTargetException().getMessage());
+ SiriusPlugin.getDefault().error("Error while refreshing tree", e);
+ } catch (final InterruptedException e) {
+ MessageDialog.openInformation(activeShell, "Cancelled", e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(final IAction action, final ISelection selection) {
+ }
+
+ /**
+ * Set the workbench part.
+ *
+ * @param aWorkbenchPart
+ * the new workbench part
+ */
+ public void setActiveWorkbenchPart(final IWorkbenchPart aWorkbenchPart) {
+ this.workbenchPart = aWorkbenchPart;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/OpenRepresentationAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/OpenRepresentationAction.java
new file mode 100644
index 0000000000..77404b6636
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/OpenRepresentationAction.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorPart;
+
+import org.eclipse.sirius.DRepresentation;
+import org.eclipse.sirius.business.api.dialect.DialectManager;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
+import org.eclipse.sirius.ui.business.api.session.IEditingSession;
+import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
+
+public final class OpenRepresentationAction extends Action {
+
+ private final DRepresentation representation;
+
+ private final Session session;
+
+ private TransactionalEditingDomain editingDomain;
+
+ /**
+ * Constructor.
+ *
+ * @param text
+ * the action's text, or <code>null</code> if there is no text
+ * @param image
+ * the action's image, or <code>null</code> if there is no image
+ * @param representation
+ * the representation to open.
+ * @param session
+ * the session in which to open it.
+ */
+ public OpenRepresentationAction(String text, ImageDescriptor image, DRepresentation representation, Session session) {
+ super(text, image);
+ this.representation = representation;
+ this.session = session;
+ this.editingDomain = session.getTransactionalEditingDomain();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param representation
+ * the representation to open.
+ * @param session
+ * the session in which to open it.
+ */
+ public OpenRepresentationAction(DRepresentation representation, Session session) {
+ super();
+ this.representation = representation;
+ this.session = session;
+ this.editingDomain = session.getTransactionalEditingDomain();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ super.run();
+ editingDomain.getCommandStack().execute(new AttachEditorRecordingCommand(editingDomain));
+ }
+
+ private class AttachEditorRecordingCommand extends RecordingCommand {
+
+ public AttachEditorRecordingCommand(TransactionalEditingDomain domain) {
+ super(domain);
+ }
+
+ @Override
+ protected void doExecute() {
+ final IEditingSession ui = SessionUIManager.INSTANCE.getUISession(session);
+ DialectManager.INSTANCE.refresh(representation, new NullProgressMonitor());
+ final IEditorPart part = DialectUIManager.INSTANCE.openEditor(session, representation);
+ if (part != null && ui != null) {
+ ui.attachEditor((DialectEditor) part);
+ }
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/RefreshAction.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/RefreshAction.java
new file mode 100644
index 0000000000..43bd7fc6c0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/actions/RefreshAction.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.LinkedList;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.dialect.command.RefreshRepresentationsCommand;
+import org.eclipse.sirius.tools.api.command.SiriusCommand;
+import org.eclipse.sirius.tree.DTreeElement;
+import org.eclipse.sirius.tree.business.internal.helper.RefreshTreeElementTask;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeEditor;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+import org.eclipse.sirius.ui.business.api.action.RefreshActionListenerRegistry;
+
+/**
+ * This action refresh the entire tree or the tree items elements selected.
+ *
+ * @author nlepine
+ */
+public class RefreshAction extends Action implements IObjectActionDelegate {
+ private static final String DEFAULT_NAME = "Refresh Tree Element";
+
+ DTreeEditor treeEditor;
+
+ private ISelection selection;
+
+ private LinkedList<Object> minimizedSelection;
+
+ /**
+ * Default constructor.
+ *
+ * @param treeEditor
+ * the tree editor
+ */
+ public RefreshAction(final DTreeEditor treeEditor) {
+ super(DEFAULT_NAME, DTreeViewerManager.getImageRegistry().getDescriptor(DTreeViewerManager.REFRESH_IMG));
+ this.treeEditor = treeEditor;
+ minimizedSelection = new LinkedList<Object>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ this.selection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getSelection();
+ if (this.selection instanceof IStructuredSelection) {
+ final IStructuredSelection structuredSelection = (IStructuredSelection) this.selection;
+ minimizedSelection = new LinkedList<Object>(Arrays.asList(structuredSelection.toArray()));
+
+ }
+ final IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(final IProgressMonitor monitor) {
+ final SiriusCommand result = new SiriusCommand(treeEditor.getEditingDomain());
+ Iterable<DTreeElement> elements = Iterables.filter(minimizedSelection, DTreeElement.class);
+ result.getTasks().add(new RefreshTreeElementTask(Lists.newArrayList(elements), treeEditor.getEditingDomain(), monitor));
+ treeEditor.getEditingDomain().getCommandStack().execute(result);
+ }
+ };
+ run(op);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction,
+ * org.eclipse.ui.IWorkbenchPart)
+ */
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+ public void run(IAction action) {
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(final IProgressMonitor monitor) {
+ TransactionalEditingDomain domain = treeEditor.getEditingDomain();
+ domain.getCommandStack().execute(new RefreshRepresentationsCommand(domain, monitor, treeEditor.getTreeModel()));
+ }
+ };
+ RefreshActionListenerRegistry.INSTANCE.notifyRepresentationIsAboutToBeRefreshed(treeEditor.getTreeModel());
+ run(op);
+ }
+
+ private void run(final IRunnableWithProgress op) {
+ final Shell activeShell = treeEditor.getSite().getShell();
+ final ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(activeShell);
+ try {
+ treeEditor.enablePropertiesUpdate(false);
+ monitorDialog.run(true, false, op);
+ } catch (final InvocationTargetException e) {
+ MessageDialog.openError(activeShell, "Error", e.getTargetException().getMessage());
+ SiriusPlugin.getDefault().error("Error while refreshing tree", e);
+ } catch (final InterruptedException e) {
+ MessageDialog.openInformation(activeShell, "Cancelled", e.getMessage());
+ } finally {
+ treeEditor.enablePropertiesUpdate(true);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void selectionChanged(IAction action, ISelection sel) {
+ this.selection = sel;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeItemExpansionChecker.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeItemExpansionChecker.java
new file mode 100644
index 0000000000..cbea6d8362
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeItemExpansionChecker.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.listeners;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TreeItem;
+
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.TreePackage;
+import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority;
+
+/**
+ * {@link Listener} to prevents expansion/collapse {@link Event} while
+ * {@link IPermissionAuthority} disallow
+ * {@link TreePackage#DTREE_ITEM__EXPANDED} change.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class DTreeItemExpansionChecker implements Listener {
+
+ private IPermissionAuthority permissionAuthority;
+
+ private Control control;
+
+ /**
+ * Default constructor.
+ *
+ * @param control
+ * the {@link Control} to listen
+ */
+ public DTreeItemExpansionChecker(Control control) {
+ this.control = control;
+ control.getDisplay().addFilter(SWT.Expand, this);
+ control.getDisplay().addFilter(SWT.Collapse, this);
+ }
+
+ public void setPermissionAuthority(IPermissionAuthority permissionAuthority) {
+ this.permissionAuthority = permissionAuthority;
+ }
+
+ /**
+ * Overridden to handle {@link SWT#Collapse} and {@link SWT#Expand} events.
+ *
+ * {@inheritDoc}
+ */
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Collapse:
+ handleTreeCollapse(event);
+ break;
+ case SWT.Expand:
+ handleTreeExpand(event);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ /**
+ * Handle the undo of the swt TreeItem collapse if the current
+ * {@link IPermissionAuthority} disallow it.
+ */
+ private void handleTreeCollapse(Event event) {
+ if (!isEventForDTreeItemExpandable(event)) {
+ event.type = SWT.None;
+ final TreeItem treeItem = (TreeItem) event.item;
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ treeItem.setExpanded(true);
+ }
+
+ });
+
+ }
+ }
+
+ /**
+ * Handle the undo the swt TreeItem expansion if the current
+ * {@link IPermissionAuthority} disallow it.
+ */
+ private void handleTreeExpand(Event event) {
+ if (!isEventForDTreeItemExpandable(event)) {
+ event.type = SWT.None;
+ final TreeItem treeItem = (TreeItem) event.item;
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ treeItem.setExpanded(false);
+ }
+
+ });
+ }
+ }
+
+ /**
+ * Tells if the specified {@link Event} is a event of a {@link TreeItem}
+ * collapse/expansion which should be allowed by the current
+ * {@link IPermissionAuthority}.
+ *
+ * @param event
+ * the specified {@link Event}
+ * @return true if the specified {@link Event} is allowed by the current
+ * {@link IPermissionAuthority}, false else
+ */
+ private boolean isEventForDTreeItemExpandable(Event event) {
+ boolean isEventForDTreeItemExpandable = true;
+ if (event.item instanceof TreeItem) {
+ TreeItem treeItem = (TreeItem) event.item;
+ Object data = treeItem.getData();
+ if (data instanceof DTreeItem) {
+ DTreeItem dTreeItem = (DTreeItem) data;
+ boolean canEditFeature = permissionAuthority != null && permissionAuthority.canEditFeature(dTreeItem, TreePackage.Literals.DTREE_ITEM__EXPANDED.getName());
+ isEventForDTreeItemExpandable = canEditFeature;
+ }
+ }
+ return isEventForDTreeItemExpandable;
+ }
+
+ /**
+ * remove THis {@link DTreeItemExpansionChecker} as {@link Listener} of the
+ * Tree.
+ */
+ public void dispose() {
+ control.getDisplay().removeFilter(SWT.Expand, this);
+ control.getDisplay().removeFilter(SWT.Collapse, this);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeViewerListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeViewerListener.java
new file mode 100644
index 0000000000..8e7cf8a1fb
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/listeners/DTreeViewerListener.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.listeners;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.tools.api.command.SiriusCommand;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.interaction.DTreeItemUserInteraction;
+import org.eclipse.sirius.tree.business.internal.dialect.common.viewpoint.GlobalContext;
+import org.eclipse.sirius.tree.business.internal.helper.RefreshTreeElementTask;
+
+/**
+ * A {@link ITreeViewerListener} to update the DTree model when a SWT TreeItem
+ * is collapsed/expanded.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class DTreeViewerListener implements ITreeViewerListener {
+
+ private Session session;
+
+ private TransactionalEditingDomain domain;
+
+ /**
+ * Default constructor.
+ *
+ * @param session
+ * {@link Session}
+ */
+ public DTreeViewerListener(Session session) {
+ this.session = session;
+ this.domain = session.getTransactionalEditingDomain();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void treeExpanded(final TreeExpansionEvent event) {
+ if (event.getElement() instanceof DTreeItem) {
+ DTreeItem dTreeItem = (DTreeItem) event.getElement();
+ if (!dTreeItem.isExpanded()) {
+ CommandStack commandStack = domain.getCommandStack();
+ CompoundCommand expandDTreeItemCmd = new CompoundCommand("Expand " + dTreeItem.getName() + " tree item");
+ expandDTreeItemCmd.append(new TreeFoldingRecordingCommand(session, event, true));
+ final SiriusCommand result = new SiriusCommand(domain);
+ result.getTasks().add(new RefreshTreeElementTask((DTreeItem) event.getElement(), domain));
+ expandDTreeItemCmd.append(result);
+ commandStack.execute(expandDTreeItemCmd);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void treeCollapsed(final TreeExpansionEvent event) {
+ if (event.getElement() instanceof DTreeItem) {
+ DTreeItem dTreeItem = (DTreeItem) event.getElement();
+ if (dTreeItem.isExpanded()) {
+ CommandStack commandStack = domain.getCommandStack();
+ CompoundCommand expandDTreeItemCmd = new CompoundCommand("Collapse " + dTreeItem.getName() + " tree item");
+ expandDTreeItemCmd.append(new TreeFoldingRecordingCommand(session, event, false));
+ commandStack.execute(expandDTreeItemCmd);
+ }
+ }
+ }
+
+ /**
+ * EMF Command to synchronize the DTree according to a
+ * {@link TreeExpansionEvent}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban
+ * Dugueperoux</a>
+ */
+ class TreeFoldingRecordingCommand extends RecordingCommand {
+
+ private Session session;
+
+ private TreeExpansionEvent event;
+
+ private boolean expand;
+
+ public TreeFoldingRecordingCommand(Session session, TreeExpansionEvent event, boolean expand) {
+ super(session.getTransactionalEditingDomain());
+ this.session = session;
+ this.event = event;
+ this.expand = expand;
+ }
+
+ @Override
+ protected void doExecute() {
+ GlobalContext ctx = new GlobalContext(session.getModelAccessor(), session);
+ if (expand) {
+ new DTreeItemUserInteraction((DTreeItem) event.getElement(), ctx).expand();
+ } else {
+ new DTreeItemUserInteraction((DTreeItem) event.getElement(), ctx).collapse();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/preferences/SiriusPreferenceChangeListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/preferences/SiriusPreferenceChangeListener.java
new file mode 100644
index 0000000000..e26183771d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/preferences/SiriusPreferenceChangeListener.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2012 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.preferences;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+
+import org.eclipse.sirius.business.api.preferences.DesignerPreferencesKeys;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+
+/**
+ * Listener of the
+ * {@link org.eclipse.sirius.table.ui.tools.internal.editor.AbstractDTableEditor}
+ * preferences.
+ *
+ * @author mporhel
+ *
+ */
+public class SiriusPreferenceChangeListener implements IPreferenceChangeListener {
+
+ ITreeCommandFactory factory;
+
+ /**
+ * Build a new listener.
+ *
+ * @param factory
+ * editor's command factory.
+ */
+ public SiriusPreferenceChangeListener(final ITreeCommandFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.Preferences.IPreferenceChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PreferenceChangeEvent)
+ */
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if (DesignerPreferencesKeys.PREF_AUTO_REFRESH.name().equals(event.getKey()) && event.getNewValue() instanceof String && !event.getNewValue().equals(event.getOldValue())) {
+ factory.setAutoRefreshDTree(Boolean.parseBoolean((String) event.getNewValue()));
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeColumnLabelProvider.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeColumnLabelProvider.java
new file mode 100644
index 0000000000..37670a2901
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeColumnLabelProvider.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import java.io.File;
+import java.net.MalformedURLException;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.sirius.common.tools.api.resource.FileProvider;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.BasicLabelStyle;
+import org.eclipse.sirius.FontFormat;
+import org.eclipse.sirius.RGBValues;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.ui.tools.api.color.VisualBindingManager;
+import org.eclipse.sirius.ui.tools.api.provider.DSemanticTargetBasedLabelProvider;
+
+/**
+ * Label provider for all the tree item.
+ *
+ * @author <a href="mailto:nathalie.lepine@obeo.fr">Nathalie Lepine</a>
+ */
+public class DTreeColumnLabelProvider extends DSemanticTargetBasedLabelProvider {
+
+ /**
+ * Default constructor.
+ *
+ * @param adapterFactoryLabelProvider
+ * Provider which to delegate label and image resolution.
+ */
+ public DTreeColumnLabelProvider(final AdapterFactory adapterFactoryLabelProvider) {
+ super(adapterFactoryLabelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getBackground(java.lang.Object)
+ */
+ @Override
+ public Color getBackground(final Object element) {
+ Color result = null;
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ if (item.getOwnedStyle() != null) {
+ final RGBValues rgb = item.getOwnedStyle().getBackgroundColor();
+ if (rgb != null) {
+ result = VisualBindingManager.getDefault().getColorFromRGBValues(rgb);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getFont(java.lang.Object)
+ */
+ @Override
+ public Font getFont(final Object element) {
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ if (item.getOwnedStyle() != null) {
+ final int size = item.getOwnedStyle().getLabelSize();
+ FontFormat labelFormat = null;
+ if (item.getOwnedStyle().getLabelFormat() != null) {
+ labelFormat = item.getOwnedStyle().getLabelFormat();
+ } else {
+ labelFormat = FontFormat.NORMAL_LITERAL;
+ }
+ return VisualBindingManager.getDefault().getFontFromLabelFormatAndSize(labelFormat, size);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getForeground(java.lang.Object)
+ */
+ @Override
+ public Color getForeground(final Object element) {
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ if (item.getOwnedStyle() != null && item.getOwnedStyle().getLabelColor() != null) {
+ final RGBValues rgb = item.getOwnedStyle().getLabelColor();
+ if (rgb != null) {
+ return VisualBindingManager.getDefault().getLabelColorFromRGBValues(rgb);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(final Object element) {
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ if (item.getOwnedStyle() != null && item.getOwnedStyle().isShowIcon()) {
+ Image labelImage = null;
+
+ if (StringUtil.isEmpty(item.getOwnedStyle().getIconPath())) {
+ labelImage = super.getImage(element);
+ } else {
+ labelImage = getCustomImage(item.getOwnedStyle());
+ }
+ return labelImage;
+ }
+ }
+ return null;
+ }
+
+ private Image getCustomImage(BasicLabelStyle bls) {
+ Image customImage = null;
+ if (bls != null && !StringUtil.isEmpty(bls.getIconPath())) {
+ ImageDescriptor descriptor = null;
+ String iconPath = bls.getIconPath();
+ final File imageFile = FileProvider.getDefault().getFile(new Path(iconPath));
+ if (imageFile != null && imageFile.exists() && imageFile.canRead()) {
+ try {
+ descriptor = ImageDescriptor.createFromURL(imageFile.toURI().toURL());
+ } catch (MalformedURLException e) {
+ // log a waring later.
+ }
+ }
+
+ if (descriptor == null) {
+ SiriusPlugin.getDefault().warning("Icon file \"" + iconPath + "\" not found", null);
+ descriptor = ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ customImage = TreeUIPlugin.getImage(descriptor);
+ }
+ return customImage;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(final Object element) {
+ String result = StringUtil.EMPTY_STRING;
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ if (item != null) {
+ result = item.getName();
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java
new file mode 100644
index 0000000000..c4e6585b7c
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.collect.Iterables;
+
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
+import org.eclipse.sirius.RGBValues;
+import org.eclipse.sirius.SiriusPackage;
+import org.eclipse.sirius.business.api.helper.SiriusUtil;
+import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.TreeItemStyle;
+import org.eclipse.sirius.tree.TreePackage;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewer;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+
+/**
+ * This class is an EMF Adapter which listen change in the model to update a
+ * {@link org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewer}.
+ *
+ * @author nlepine
+ *
+ */
+public class DTreeContentAdapter extends ResourceSetListenerImpl {
+
+ private DTreeViewerManager dTreeViewerManager;
+
+ /** The structured viewer to update. */
+ private DTreeViewer dTreeViewer;
+
+ /**
+ * Creates a new tree content adapter with the given session.
+ *
+ * @param dTreeViewerManager
+ * the structured viewer to update
+ */
+ public DTreeContentAdapter(DTreeViewerManager dTreeViewerManager) {
+ this.dTreeViewerManager = dTreeViewerManager;
+ this.dTreeViewer = (DTreeViewer) dTreeViewerManager.getTreeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.transaction.ResourceSetListenerImpl#isPostcommitOnly()
+ */
+ @Override
+ public boolean isPostcommitOnly() {
+ return true;
+ }
+
+ private boolean isCustom(Notification notif) {
+ return notif.getEventType() == -1;
+ }
+
+ private void notifyChanged(final Notification notification) {
+ if (dTreeViewer == null || dTreeViewer.getControl() == null || dTreeViewer.getControl().isDisposed()) {
+ if (notification.getNotifier() instanceof EObject) {
+ final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(notification.getNotifier());
+ if (domain != null) {
+ domain.removeResourceSetListener(this);
+ }
+ }
+ return;
+ }
+
+ final Object notifier = notification.getNotifier();
+
+ if (notifier instanceof Resource) {
+ final Resource resource = (Resource) notifier;
+
+ // Indicates that at least one description file has changed or was
+ // reloaded
+ if (SiriusUtil.DESCRIPTION_MODEL_EXTENSION.equals(resource.getURI().fileExtension())) {
+ if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__IS_MODIFIED || notification.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED) {
+ dTreeViewerManager.setDescriptionFileChanged(true);
+ }
+ }
+ }
+
+ if (isChangeAboutDTreeModel(notification)) {
+ if (notifier instanceof DTree) {
+ handleDTreeNotification(notification, (DTree) notifier);
+ } else if (notifier instanceof DTreeItem) {
+ handleDTreeItemNotification(notification, (DTreeItem) notifier);
+ } else if (notifier instanceof TreeItemStyle) {
+ handleDTreeItemNotification(notification, (TreeItemStyle) notifier);
+ } else if (notifier instanceof RGBValues) {
+ handleDTreItemNotification(notification, (RGBValues) notifier);
+ }
+ }
+ }
+
+ /**
+ * Checks if the specified {@link Notification} is about a change a a
+ * {@link DTree}.
+ *
+ * @param notification
+ * the specified {@link Notification}
+ * @return true if the specified {@link Notification} is about a change a a
+ * {@link DTree}, false else
+ */
+ private boolean isChangeAboutDTreeModel(final Notification notification) {
+ boolean isImpactingNotification = false;
+ Object notifier = notification.getNotifier();
+ if (notifier instanceof EObject) {
+ EObject eObject = (EObject) notifier;
+ while (eObject != null && !isImpactingNotification) {
+ if (eObject instanceof DTree) {
+ isImpactingNotification = true;
+ } else {
+ eObject = eObject.eContainer();
+ }
+ }
+ }
+ return isImpactingNotification;
+ }
+
+ /**
+ * @param n
+ * @param notifier
+ */
+ private void handleDTreeNotification(final Notification n, final DTree tree) {
+ final int featureID = n.getFeatureID(DTree.class);
+
+ switch (featureID) {
+ case TreePackage.DTREE__OWNED_TREE_ITEMS:
+ case TreePackage.DTREE__TARGET:
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.REFRESH_SWT_TABLE_KEY);
+ refreshViewer(tree);
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.REFRESH_SWT_TABLE_KEY);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * @param n
+ * @param notifier
+ */
+ private void handleDTreeItemNotification(final Notification n, final DTreeItem dTreeItem) {
+ final int featureID = n.getFeatureID(DTreeItem.class);
+
+ switch (featureID) {
+ case TreePackage.DTREE_ITEM__NAME:
+ case TreePackage.DTREE_ITEM__OWNED_STYLE:
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ updateViewer(dTreeItem);
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ break;
+ case TreePackage.DTREE_ITEM__OWNED_TREE_ITEMS:
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.REFRESH_SWT_LINE_KEY);
+ refreshViewer(dTreeItem);
+ // The refresh doesn't update swt TreeItem expansion then we must do
+ // it
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (dTreeViewer != null && dTreeViewer.getControl() != null && !dTreeViewer.getControl().isDisposed()) {
+ dTreeViewer.setExpandedState(dTreeItem, dTreeItem.isExpanded());
+ }
+ }
+ });
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.REFRESH_SWT_LINE_KEY);
+ break;
+ case TreePackage.DTREE_ITEM__EXPANDED:
+ if (n.getNewValue() instanceof Boolean) {
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.CHANGE_SWT_LINE_COLAPSE_STATE_KEY);
+ final boolean expanded = n.getNewBooleanValue();
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (dTreeViewer != null && dTreeViewer.getControl() != null && !dTreeViewer.getControl().isDisposed()) {
+ dTreeViewer.setExpandedState(dTreeItem, expanded);
+ }
+ }
+ });
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.CHANGE_SWT_LINE_COLAPSE_STATE_KEY);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * @param n
+ * @param notifier
+ */
+ private void handleDTreeItemNotification(final Notification n, final TreeItemStyle notifier) {
+ final int featureID = n.getFeatureID(TreeItemStyle.class);
+
+ switch (featureID) {
+ case TreePackage.TREE_ITEM_STYLE__BACKGROUND_COLOR:
+ case TreePackage.TREE_ITEM_STYLE__LABEL_COLOR:
+ case TreePackage.TREE_ITEM_STYLE__LABEL_FORMAT:
+ case TreePackage.TREE_ITEM_STYLE__LABEL_SIZE:
+ case TreePackage.TREE_ITEM_STYLE__SHOW_ICON:
+ final DTreeItem treeItem = (DTreeItem) notifier.eContainer();
+ if (treeItem != null) {
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ updateViewer(treeItem);
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void handleDTreItemNotification(Notification notification, RGBValues notifier) {
+ final int featureID = notification.getFeatureID(TreeItemStyle.class);
+
+ switch (featureID) {
+ case SiriusPackage.RGB_VALUES__BLUE:
+ case SiriusPackage.RGB_VALUES__GREEN:
+ case SiriusPackage.RGB_VALUES__RED:
+ EObject notifierContainer = notifier.eContainer();
+ if (notifierContainer instanceof TreeItemStyle) {
+ TreeItemStyle treeItemStyle = (TreeItemStyle) notifierContainer;
+ EObject treeitemStyleContainer = treeItemStyle.eContainer();
+ if (treeitemStyleContainer != null) {
+ DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ updateViewer(treeitemStyleContainer);
+ DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.UPDATE_SWT_LINE_KEY);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void refreshViewer(final Object object) {
+ if (object != null) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (dTreeViewer != null && dTreeViewer.getControl() != null && !dTreeViewer.getControl().isDisposed()) {
+ dTreeViewer.refresh(object, true);
+ }
+ }
+ });
+ }
+ }
+
+ private void updateViewer(final Object object) {
+ if (object != null) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (dTreeViewer != null && dTreeViewer.getControl() != null && !dTreeViewer.getControl().isDisposed()) {
+ dTreeViewer.update(object, null);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.transaction.ResourceSetListenerImpl#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)
+ */
+ @Override
+ public void resourceSetChanged(ResourceSetChangeEvent event) {
+ super.resourceSetChanged(event);
+ for (Notification notif : Iterables.filter(event.getNotifications(), Notification.class)) {
+ if (!isCustom(notif)) {
+ notifyChanged(notif);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java
new file mode 100644
index 0000000000..85c14beafc
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.DTreeItemContainer;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+
+/**
+ * The provider for the content of the tree.
+ *
+ * @author nlepine
+ */
+public class DTreeContentProvider implements ITreeContentProvider {
+
+ private Session session;
+
+ /** The EMF adapter */
+ private DTreeContentAdapter dTreeContentAdapter;
+
+ /**
+ * Creates a tree with the given session.
+ *
+ * @param session
+ * the session.
+ * @param dTreeViewerManager
+ * the manager of the structured viewer to update
+ */
+ public DTreeContentProvider(final Session session, DTreeViewerManager dTreeViewerManager) {
+ this.session = session;
+ this.dTreeContentAdapter = new DTreeContentAdapter(dTreeViewerManager);
+ this.session.getTransactionalEditingDomain().addResourceSetListener(dTreeContentAdapter);
+ }
+
+ /**
+ * Returns the elements to display in the viewer (only the visible one).
+ *
+ * @param inputElement
+ * the input element
+ * @return the array of elements to display in the viewer
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(final Object inputElement) {
+ if (inputElement instanceof DTree) {
+ final List<DTreeItem> visibleLines = getVisibleLines((DTree) inputElement);
+ return visibleLines.toArray();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#inputChanged(Viewer,
+ * Object, Object)
+ */
+ public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(final Object parentElement) {
+ Object[] result = null;
+ if (parentElement instanceof DTree) {
+ final List<DTreeItem> visibleLines = getVisibleLines((DTree) parentElement);
+ result = visibleLines.toArray();
+ } else if (parentElement instanceof DTreeItem) {
+ final List<DTreeItem> visibleLines = getVisibleLines((DTreeItem) parentElement);
+ result = visibleLines.toArray();
+ }
+ return result;
+ }
+
+ /**
+ * Returns the visible items of the given <@link DTreeItemContainer
+ * lineContainer>.
+ * <p>
+ *
+ * @param treeItemContainer
+ * the line container
+ * @return a list of visible lines
+ */
+ private List<DTreeItem> getVisibleLines(final DTreeItemContainer treeItemContainer) {
+ return treeItemContainer.getOwnedTreeItems();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(final Object element) {
+ if (element instanceof DTreeItem) {
+ final DTreeItem line = (DTreeItem) element;
+ return line.eContainer();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(final Object element) {
+ final Object[] children = getChildren(element);
+ return children != null && children.length > 0;
+ }
+
+ /**
+ * Disposes of this content provider.
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ session.getTransactionalEditingDomain().removeResourceSetListener(dTreeContentAdapter);
+ dTreeContentAdapter = null;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeDecoratingLabelProvider.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeDecoratingLabelProvider.java
new file mode 100644
index 0000000000..b259c4d684
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeDecoratingLabelProvider.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Inherits {@link DTreeColumnLabelProvider} to decorate DTreeItem.
+ *
+ * @author edugueperoux
+ */
+public class DTreeDecoratingLabelProvider extends DTreeColumnLabelProvider {
+
+ private ILabelDecorator decorator;
+
+ /**
+ * Default constructor.
+ *
+ * @param adapterFactoryLabelProvider
+ * Provider which to delegate label and image resolution
+ * @param decorator
+ * {@link ILabelDecorator} to decorate the {@link Image} returned
+ * by {@link DTreeDecoratingLabelProvider#getImage(Object)}
+ */
+ public DTreeDecoratingLabelProvider(AdapterFactory adapterFactoryLabelProvider, ILabelDecorator decorator) {
+ super(adapterFactoryLabelProvider);
+ this.decorator = decorator;
+ }
+
+ /**
+ * Overridden to decorate with a image to notify the user of lock status.
+ *
+ * {@inheritDoc}
+ */
+ public Image getImage(Object element) {
+ Image image = super.getImage(element);
+ if (decorator != null) {
+ Image decorated = decorator.decorateImage(image, element);
+ if (decorated != null) {
+ return decorated;
+ }
+ }
+ return image;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDragListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDragListener.java
new file mode 100644
index 0000000000..2f72800227
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDragListener.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
+
+import com.google.common.collect.Sets;
+
+import org.eclipse.sirius.tree.DTreeItem;
+
+//FIXME Alex Lagarde
+/**
+ * .
+ *
+ * @author alagarde
+ */
+public class DTreeItemDragListener extends DragSourceAdapter implements DragSourceListener {
+
+ private ISelectionProvider selectionProvider;
+
+ /**
+ * Construct a new instance.
+ *
+ * @param selectionProvider
+ * the selection provider
+ */
+ public DTreeItemDragListener(ISelectionProvider selectionProvider) {
+ this.selectionProvider = selectionProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.dnd.DragSourceAdapter#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragFinished(DragSourceEvent event) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.dnd.DragSourceAdapter#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void dragSetData(DragSourceEvent event) {
+ // We set the data of the drag to all selected DTreeItem (if any)
+ ISelection selection = this.selectionProvider.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Set<DTreeItem> dragData = Sets.newLinkedHashSet();
+ Iterator<Object> selectionIterator = ((IStructuredSelection) selection).iterator();
+ while (selectionIterator.hasNext()) {
+ Object selectedElement = selectionIterator.next();
+ if (selectedElement instanceof DTreeItem) {
+ dragData.add((DTreeItem) selectedElement);
+ }
+ }
+ LocalSelectionTransfer.getInstance().setSelection(this.selectionProvider.getSelection());
+ event.data = dragData;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.dnd.DragSourceAdapter#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragStart(DragSourceEvent event) {
+ event.doit = !this.selectionProvider.getSelection().isEmpty();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDropListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDropListener.java
new file mode 100644
index 0000000000..2fa20cd287
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemDropListener.java
@@ -0,0 +1,518 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterSiriusVariables;
+import org.eclipse.sirius.common.tools.api.util.Option;
+import org.eclipse.sirius.common.tools.api.util.Options;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.DSemanticDecorator;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerInterpreter;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.description.tool.ToolPackage;
+import org.eclipse.sirius.tree.DTree;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.DTreeItemContainer;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.description.TreeDragSource;
+import org.eclipse.sirius.tree.description.TreeItemContainerDropTool;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority;
+
+/**
+ * Drop Listener used to validate and perform Drag and Drop operations on
+ * DTreeItems.
+ *
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public class DTreeItemDropListener extends ViewerDropAdapter implements DropTargetListener {
+ /**
+ * Start of the error message when more than one drop description
+ * corresponds to a drop element.
+ */
+ private static final String MORE_THAN_ONE_DROP_DESCRIPTION_ERROR_MSG = "There are more than one drop description that match the dropped element";
+
+ private TransactionalEditingDomain domain;
+
+ private ModelAccessor accessor;
+
+ private ITreeCommandFactory commandFactory;
+
+ /**
+ * A cache memorizing the sources of the current dragAndDrop.
+ */
+ private final Set<DSemanticDecorator> droppedData = Sets.newLinkedHashSet();
+
+ /**
+ * A cache memorizing the semantic sources of the current dragAndDrop.
+ */
+ private final Map<EObject, TreeItemContainerDropTool> semanticDroppedData = Maps.newLinkedHashMap();
+
+ /**
+ * The cache value of the DnD target.
+ */
+ private DTreeItemContainer dropTarget;
+
+ /**
+ * The preceding siblings of the current DnD operation.
+ */
+ private final Collection<DTreeItem> precedingSiblings = Lists.newArrayList();
+
+ /**
+ * Creates a new DTreeItemDropListener.
+ *
+ * @param viewer
+ * the viewer on which this ViewerDropListener will be installed
+ * @param domain
+ * the Editing domain in which execute the DnD actions
+ * @param treeCommandFactory
+ * the Tree command factory to use
+ * @param accessor
+ * the model accessor to use
+ */
+ public DTreeItemDropListener(Viewer viewer, TransactionalEditingDomain domain, ITreeCommandFactory treeCommandFactory, ModelAccessor accessor) {
+ super(viewer);
+ this.domain = domain;
+ this.commandFactory = treeCommandFactory;
+ this.accessor = accessor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object,
+ * int, org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ public boolean validateDrop(Object target, int operation, TransferData transferType) {
+ resetContext();
+ computeContext(target, operation, transferType);
+
+ boolean valid = validateContext();
+
+ if (!valid) {
+ resetContext();
+ }
+
+ return valid;
+ }
+
+ private void resetContext() {
+ dropTarget = null;
+ precedingSiblings.clear();
+ droppedData.clear();
+ semanticDroppedData.clear();
+ }
+
+ private void computeContext(Object target, int operation, TransferData transferType) {
+ // Result are stored to avoid unnecessary computation of
+ // the TreeItems when performing drag
+
+ // Step A : get the correct target and preceding siblings
+ computeDropTargetAndPrecedingSiblings(target);
+
+ // Step B : get the sources of the drop by checking
+ // the local selection transfer
+ computeDraggedDataFromLocalSelectionTransfer();
+
+ }
+
+ /**
+ * Computes the actual Target of the DnD and the preceding siblings
+ * variables , according to the current Location value :
+ * <ul>
+ * <li>if the currentLocation is LOCATION_BEFORE : then the target of the
+ * DnD is the container of the default target. Preceding siblings will be
+ * all TreeItems contained by this container and located before the current
+ * target.</li>
+ * <li>if the currentLocation is LOCATION_AFTER : then the target of the DnD
+ * is the container of the default target. Preceding siblings will be all
+ * TreeItems contained by this container and located before the current
+ * target, including the current target.</li>
+ * <li>for all other values of currentLocation, then the target of the DnD
+ * is the current target, and the precedingSiblings will be all TreeItmes
+ * contained in the current target.</li>
+ * <li>if the target of the DnD is null, then the real container is the tree
+ * itself.</li>
+ * </ul>
+ *
+ * @param target
+ * the current DnD target (calculated by SWT)
+ * @return the actual Target of the DnD
+ */
+ private void computeDropTargetAndPrecedingSiblings(Object target) {
+ int currentLocation = getCurrentLocation();
+
+ Object mouseTarget = target;
+ if (mouseTarget == null) {
+ // receiver is tree
+ mouseTarget = getViewer().getInput();
+ currentLocation = LOCATION_ON;
+ }
+
+ if (mouseTarget instanceof DTreeItem) {
+ DTreeItem itemMouseTarget = (DTreeItem) mouseTarget;
+
+ // If the cursor is between 2 treeItems,
+ // the dropTarget should be the container
+ if ((currentLocation == LOCATION_BEFORE) || (currentLocation == LOCATION_AFTER)) {
+ if (itemMouseTarget.eContainer() instanceof DTreeItemContainer) {
+ dropTarget = (DTreeItemContainer) itemMouseTarget.eContainer();
+ }
+ } else {
+ dropTarget = (DTreeItem) mouseTarget;
+ }
+ } else if (mouseTarget instanceof DTree) {
+ dropTarget = (DTree) mouseTarget;
+ }
+
+ precedingSiblings.clear();
+ if (dropTarget != null) {
+ List<DTreeItem> ownedTreeItems = dropTarget.getOwnedTreeItems();
+
+ // The preceding sliblings are all TreeItems contained
+ // before the current dropTarget.
+ if ((currentLocation == LOCATION_BEFORE) || (currentLocation == LOCATION_AFTER)) {
+ if (mouseTarget instanceof DTreeItem) {
+ DTreeItem ticMouseTarget = (DTreeItem) mouseTarget;
+ int dropTargetIndex = ownedTreeItems.indexOf(ticMouseTarget);
+ if (dropTargetIndex > 0) {
+ precedingSiblings.addAll(ownedTreeItems.subList(0, dropTargetIndex));
+ }
+
+ // If the items are dropped after the dropTarget
+ if (currentLocation == LOCATION_AFTER) {
+ // Then the current drop Target must be considered as a
+ // preceding slibling
+ precedingSiblings.add(ticMouseTarget);
+ }
+ }
+ } else {
+ // If the sources are dropped directly on a tree item container
+ // the we consider that all children of the drop target are
+ // preceding siblings of this target.
+ precedingSiblings.addAll(dropTarget.getOwnedTreeItems());
+ }
+ }
+ }
+
+ /**
+ * Compute the sources of the drag and drop from the local selection
+ * transfer's selection (for example the Model Explorer View).
+ *
+ */
+ private void computeDraggedDataFromLocalSelectionTransfer() {
+ ISelection selection = LocalSelectionTransfer.getInstance().getSelection();
+
+ droppedData.clear();
+ semanticDroppedData.clear();
+
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection sel = (IStructuredSelection) selection;
+
+ Iterable<DSemanticDecorator> dSelection = Iterables.filter(sel.toList(), DSemanticDecorator.class);
+ if (!Iterables.isEmpty(dSelection)) {
+ for (DSemanticDecorator semDec : dSelection) {
+ droppedData.add(semDec);
+ semanticDroppedData.put(semDec.getTarget(), null);
+ }
+ } else {
+ for (EObject eobject : Iterables.filter(sel.toList(), EObject.class)) {
+ semanticDroppedData.put(eobject, null);
+ }
+ }
+ }
+ }
+
+ private boolean validateContext() {
+ boolean valid = false;
+
+ // Check 1 : Graphical considerations
+ // Check 1.1 : the target must be a treeItem and the selection not empty
+ if (dropTarget != null && !semanticDroppedData.isEmpty()) {
+ // Look for a tool for each dropped semantic element
+
+ // Check 1.2 : the sources must no contain the target
+ valid = !sourceIsTargetContainer();
+ if (valid) {
+ // Check 2 : ensure that the target of the DnD can be edited
+ valid = canEditSemanticDecorator(dropTarget);
+
+ // Check 3 : For each source of the DnD
+ // a DnD tool must be defined and applicable
+ if (!droppedData.isEmpty()) {
+ // Check 3.1 : dropping viewpoint elements : more variables
+ // and tool BOTH or TREE
+ for (DSemanticDecorator dSem : droppedData) {
+ valid = valid && canEditSemanticDecorator(dSem);
+
+ EObject oldContainer = null;
+ if (dSem.eContainer() instanceof DSemanticDecorator) {
+ oldContainer = ((DSemanticDecorator) dSem.eContainer()).getTarget();
+ }
+ Option<TreeItemContainerDropTool> dropTool = getBestDropDescription(dSem.getTarget(), oldContainer, TreeDragSource.TREE, dSem);
+ if (dropTool.some()) {
+ semanticDroppedData.put(dSem.getTarget(), dropTool.get());
+ } else {
+ valid = false;
+ }
+
+ if (!valid) {
+ break;
+ }
+ }
+ } else {
+ // Check 3.2 : dropping semantic elements : variables and
+ // tool BOTH or PROJECT_EXPLORER
+ for (EObject droppedElement : Lists.newArrayList(semanticDroppedData.keySet())) {
+ valid = valid && canEditEObject(droppedElement);
+
+ Option<TreeItemContainerDropTool> dropTool = getBestDropDescription(droppedElement, null, TreeDragSource.PROJECT_EXPLORER, null);
+
+ if (dropTool.some()) {
+ semanticDroppedData.put(droppedElement, dropTool.get());
+ } else {
+ valid = false;
+ }
+
+ if (!valid) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return valid;
+ }
+
+ /**
+ * Indicates if one of the dragged sources is a container of the target.
+ *
+ * @param dragSources
+ * the dragged element
+ * @param dropTarget
+ * the drop target
+ * @return true if one of the dragged sources is a container of the target,
+ * false otherwise
+ */
+ private boolean sourceIsTargetContainer() {
+ Object targetContainer = dropTarget;
+ while (targetContainer instanceof DTreeItem) {
+ if (droppedData.contains(targetContainer)) {
+ return true;
+ }
+ targetContainer = ((DTreeItem) targetContainer).getContainer();
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
+ */
+ @Override
+ public boolean performDrop(Object data) {
+ boolean dropped = false;
+ if (dropTarget != null) {
+ // Step 1 : create a command containing all semantic
+ // instructions
+ // associated to the DnD tools
+ Command dndCommand = buildCommand();
+
+ // Step 2 : execute the created command
+ if (dndCommand.canExecute()) {
+ domain.getCommandStack().execute(dndCommand);
+ dropped = true;
+ }
+ }
+ resetContext();
+ return dropped;
+
+ }
+
+ private CompoundCommand buildCommand() {
+ CompoundCommand dndCommand = new CompoundCommand("Drag And Drop");
+ if (!droppedData.isEmpty()) {
+ for (DSemanticDecorator semDec : droppedData) {
+ EObject droppedElement = semDec.getTarget();
+ TreeItemContainerDropTool tool = semanticDroppedData.get(droppedElement);
+ if (tool == null) {
+ dndCommand.append(UnexecutableCommand.INSTANCE);
+ }
+ dndCommand.append(commandFactory.buildDropItemFromTool(semDec, dropTarget, precedingSiblings, tool));
+ }
+ } else {
+ for (Entry<EObject, TreeItemContainerDropTool> entry : semanticDroppedData.entrySet()) {
+ if (entry.getValue() == null) {
+ dndCommand.append(UnexecutableCommand.INSTANCE);
+ }
+ dndCommand.append(commandFactory.buildDropItemFromTool(entry.getKey(), dropTarget, precedingSiblings, entry.getValue()));
+ }
+ }
+ return dndCommand;
+ }
+
+ /**
+ * Indicates whether the given DSemanticDecorator (TreeItem or DTree) can be
+ * edited or not, using the Permission Authority and the CanEdit feature.
+ *
+ * @param decorator
+ * the item to determine if it is editable or not
+ * @return true if the given DSemanticDecorator and its target can be
+ * edited, false otherwise
+ */
+ protected boolean canEditSemanticDecorator(DSemanticDecorator decorator) {
+ // Permission Authority must allow edition of the DTreeItem and its
+ // semantic target
+
+ IPermissionAuthority authority = accessor != null ? accessor.getPermissionAuthority() : null;
+ boolean canEdit = authority != null && authority.canEditInstance(decorator.getTarget());
+ canEdit = canEdit && authority.canEditInstance(decorator);
+
+ return canEdit;
+ }
+
+ /**
+ * Indicates whether the given object can be edited or not, using the
+ * Permission Authority and the CanEdit feature.
+ *
+ * @param obj
+ * the item to determine if it is editable or not
+ * @return true if the given object can be edited, false otherwise
+ */
+ protected boolean canEditEObject(EObject obj) {
+ // Permission Authority must allow edition of the DTreeItem and its
+ // semantic target
+
+ IPermissionAuthority authority = accessor != null ? accessor.getPermissionAuthority() : null;
+ boolean canEdit = authority != null && authority.canEditInstance(obj);
+
+ return canEdit;
+ }
+
+ /**
+ * Return the best drop description.
+ *
+ * @param description
+ * .
+ * @param droppedElement
+ * The semantic dropped element
+ * @param oldContainer
+ * The old semantic container, can be null (for instance if drop
+ * comes from project explorer)
+ * @param newContainer
+ * The new semantic container
+ * @param newViewContainer
+ * The new view container
+ * @param dragSource
+ * the drag source.
+ * @param droppedSemanticDecorator
+ * The graphical dropped element (Optional).
+ * @return he best drop description
+ */
+ private Option<TreeItemContainerDropTool> getBestDropDescription(final EObject droppedElement, final EObject oldContainer, final TreeDragSource dragSource,
+ final DSemanticDecorator droppedSemanticDecorator) {
+
+ final IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(droppedElement);
+ if (oldContainer != null) {
+ interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_OLD, oldContainer);
+ }
+ interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_NEW, dropTarget.getTarget());
+ interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_VIEW_NEW, dropTarget);
+ interpreter.setVariable(IInterpreterSiriusVariables.ELEMENT, droppedElement);
+ if (droppedSemanticDecorator != null) {
+ interpreter.setVariable(IInterpreterSiriusVariables.VIEW, droppedSemanticDecorator);
+ }
+ RuntimeLoggerInterpreter safeInterpreter = RuntimeLoggerManager.INSTANCE.decorate(interpreter);
+
+ TreeItemContainerDropTool bestDropDescription = null;
+
+ /* find valid candidates */
+ for (TreeItemContainerDropTool dropTool : getDropTools(dragSource)) {
+ if (checkPrecondition(dropTool, safeInterpreter, droppedElement)) {
+ if (bestDropDescription == null) {
+ bestDropDescription = dropTool;
+ } else {
+ SiriusPlugin.getDefault().warning(
+ MORE_THAN_ONE_DROP_DESCRIPTION_ERROR_MSG + " : " + droppedElement + " (" + bestDropDescription.getName() + " and " + dropTool.getName() + ").", new RuntimeException());
+ break;
+ }
+ }
+ }
+
+ // Clean variables
+ if (oldContainer != null) {
+ interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_OLD);
+ }
+ interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_NEW);
+ interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_VIEW_NEW);
+ interpreter.unSetVariable(IInterpreterSiriusVariables.ELEMENT);
+ if (droppedSemanticDecorator != null) {
+ interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
+ }
+
+ return Options.newSome(bestDropDescription);
+ }
+
+ private boolean checkPrecondition(TreeItemContainerDropTool dropTool, RuntimeLoggerInterpreter safeInterpreter, EObject droppedElement) {
+ final String precondition = dropTool.getPrecondition();
+ if (precondition != null && !StringUtil.isEmpty(precondition.trim())) {
+ return safeInterpreter.evaluateBoolean(droppedElement, dropTool, ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition());
+ }
+ return true;
+ }
+
+ private Iterable<TreeItemContainerDropTool> getDropTools(final TreeDragSource dragSource) {
+ Predicate<TreeItemContainerDropTool> checkedDragSource = new Predicate<TreeItemContainerDropTool>() {
+ public boolean apply(TreeItemContainerDropTool input) {
+ return input.getDragSource() == TreeDragSource.BOTH || input.getDragSource() == dragSource;
+ }
+ };
+
+ Collection<TreeItemContainerDropTool> availableTools = Lists.newArrayList();
+ if (dropTarget instanceof DTree) {
+ availableTools.addAll(((DTree) dropTarget).getDescription().getDropTools());
+ } else if (dropTarget instanceof DTreeItem) {
+ availableTools.addAll(((DTreeItem) dropTarget).getActualMapping().getDropTools());
+ }
+
+ return Iterables.filter(availableTools, checkedDragSource);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditingSupport.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditingSupport.java
new file mode 100644
index 0000000000..ef51bdb06d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditingSupport.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Tree;
+
+import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.description.TreeItemEditionTool;
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority;
+
+/**
+ * Support for editing DTreeItems of a DTree.
+ *
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public class DTreeItemEditingSupport extends EditingSupport {
+
+ /**
+ * The transactional editing domain of this viewer.
+ */
+ private final TransactionalEditingDomain editingDomain;
+
+ /**
+ * The model accessor to use for get and modify model elements.
+ */
+ private final ModelAccessor accessor;
+
+ /**
+ * The command Factory to use for building tools commands.
+ */
+ private final ITreeCommandFactory treeCommandFactory;
+
+ /**
+ * The managed TreeEditor.
+ */
+ private final AbstractDTreeEditor treeEditor;
+
+ /**
+ * Creates a new editing support for editing DTreeItems of a DTree.
+ *
+ * @param viewer
+ * The treeViewer for this editingSupport
+ * @param editingDomain
+ * The transactional editing domain of this viewer
+ * @param accessor
+ * The accessor for the model
+ * @param treeCommandFactory
+ * the command Factory to use for building tools commands
+ * @param abstractDTreeEditor
+ * The associated editor
+ */
+ public DTreeItemEditingSupport(final TreeViewer viewer, final TransactionalEditingDomain editingDomain, final ModelAccessor accessor, final ITreeCommandFactory treeCommandFactory,
+ final AbstractDTreeEditor abstractDTreeEditor) {
+ super(viewer);
+ this.editingDomain = editingDomain;
+ this.accessor = accessor;
+ this.treeCommandFactory = treeCommandFactory;
+ this.treeEditor = abstractDTreeEditor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
+ */
+ @Override
+ protected boolean canEdit(final Object element) {
+
+ if (element instanceof DTreeItem) {
+ final DTreeItem item = (DTreeItem) element;
+ boolean canEdit = false;
+ IInterpreter interpreter = null;
+ // If the DTreeItem to edit is associated to a canEdit expression
+ // if (item.getUpdater() != null && item.getUpdater().getCanEdit()
+ // != null && item.getUpdater().getCanEdit().length() > 0) {
+ // interpreter = InterpreterUtil.getInterpreter(item.getTarget());
+ // try {
+ // // The evaluation of this expression must return true
+ // canEdit = interpreter.evaluateBoolean(item.getTarget(),
+ // item.getUpdater().getCanEdit());
+ // } catch (final EvaluationException e) {
+ // RuntimeLoggerManager.INSTANCE.error(item.getUpdater(),
+ // DescriptionPackage.eINSTANCE.getTreeItemUpdater_CanEdit(), e);
+ // }
+ // }
+ // If the Edition tool has a precondition
+ if (item.getUpdater() != null && item.getUpdater().getDirectEdit() != null) {
+ canEdit = true;
+ if (!StringUtil.isEmpty(item.getUpdater().getDirectEdit().getPrecondition())) {
+ if (interpreter == null) {
+ interpreter = InterpreterUtil.getInterpreter(item.getTarget());
+ }
+ String precondition = item.getUpdater().getDirectEdit().getPrecondition();
+ try {
+ canEdit = interpreter.evaluateBoolean(item.getTarget(), precondition);
+ } catch (final EvaluationException e) {
+ RuntimeLoggerManager.INSTANCE.error(item.getUpdater().getDirectEdit(), org.eclipse.sirius.description.tool.ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition(),
+ e);
+ }
+
+ }
+ }
+
+ // DTreeItem also must be editable
+ return canEdit && getAuthority().canEditInstance(item);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.EditingSupport#getCellEditor(java.lang.Object)
+ */
+ @Override
+ protected CellEditor getCellEditor(final Object element) {
+ if (element instanceof DTreeItem) {
+ DTreeItem editedItem = (DTreeItem) element;
+ final boolean directEdit = editedItem.getUpdater() != null && editedItem.getUpdater().getDirectEdit() != null;
+ return getBestCellEditor(editedItem.getTarget(), directEdit);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
+ */
+ @Override
+ protected Object getValue(final Object element) {
+ Object result = null;
+ if (element instanceof DTreeItem) {
+ result = ((DTreeItem) element).getName();
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object,
+ * java.lang.Object)
+ */
+ @Override
+ protected void setValue(final Object element, final Object value) {
+ if (element instanceof DTreeItem) {
+ final DTreeItem treeItem = (DTreeItem) element;
+
+ if (value != null) {
+ final Object finalValue = value;
+ if (treeItem.getUpdater() != null && treeItem.getUpdater().getDirectEdit() != null) {
+ // Specific set : we use the DirectEditTool defined on this
+ // DTreeItem to modify semantic elements
+ specificSetValue(treeItem, finalValue);
+ } else {
+ // Normal set : we only change the DTreeItem name
+ standardSetValue(treeItem, finalValue);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Only changes the name of the given DTreeItem.
+ *
+ * @param itemToSet
+ * the edited DTreeItem
+ * @param value
+ * the new value for this DTreeItem
+ */
+ private void standardSetValue(final DTreeItem itemToSet, final Object value) {
+ // We simply change the name of the given itemToSet
+ final DTreeItem treeItem = itemToSet;
+ if (value instanceof String) {
+ getEditingDomain().getCommandStack().execute(new StandardSetValueRecordingCommand(getEditingDomain(), "Direct Edit on " + itemToSet.getName(), treeItem, value));
+ }
+ }
+
+ /**
+ * Set the value by calling the defined Edition Tool.
+ *
+ * @param editedTreeItem
+ * The DTreeItem to set
+ * @param value
+ * the new value
+ *
+ */
+ private void specificSetValue(final DTreeItem editedTreeItem, final Object value) {
+ treeEditor.enablePropertiesUpdate(false);
+ // We use the command Factory to create the command corresponding to the
+ // Editing Tool
+ final TreeItemEditionTool editTool = editedTreeItem.getUpdater().getDirectEdit();
+ if (editTool.getFirstModelOperation() != null) {
+ getEditingDomain().getCommandStack().execute(treeCommandFactory.buildDirectEditLabelFromTool(editedTreeItem, editTool, (String) value));
+ }
+ // We allow properties update so that the treeItem is correctly
+ // refreshed
+ treeEditor.enablePropertiesUpdate(true);
+ treeEditor.forceRefreshProperties();
+ }
+
+ /**
+ * Chooses the best CellEditor depending on the type of value to edit
+ *
+ * @param element
+ * The current edited element
+ * @param directEdit
+ * true if this cell has a direct edit tool, false otherwise
+ * @return An adapted cell Editor
+ */
+ private CellEditor getBestCellEditor(final EObject element, final boolean directEdit) {
+ final Tree tree = ((TreeViewer) getViewer()).getTree();
+ final TextCellEditor textEditor = new TextCellEditor(tree) {
+ /**
+ * {@inheritDoc} We override the doSetFocus for clearing the
+ * selection for the direct edition of the cell.
+ *
+ * @see org.eclipse.jface.viewers.TextCellEditor#doSetFocus()
+ */
+ @Override
+ protected void doSetFocus() {
+ super.doSetFocus();
+ if (text != null) {
+ text.clearSelection();
+ }
+ }
+ };
+ textEditor.getControl().addFocusListener(new DTreeItemEditorFocusListener(this.treeEditor, textEditor));
+ return textEditor;
+ }
+
+ /**
+ * Return the transactional editing domain.
+ *
+ * @return the transactional editing domain
+ */
+ public TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ /**
+ * @return The permission authority
+ */
+ private IPermissionAuthority getAuthority() {
+ return getAccessor().getPermissionAuthority();
+ }
+
+ /**
+ * @return the accessor
+ */
+ private ModelAccessor getAccessor() {
+ return accessor;
+ }
+
+ private class StandardSetValueRecordingCommand extends RecordingCommand {
+
+ private DTreeItem treeItem;
+
+ private Object value;
+
+ public StandardSetValueRecordingCommand(TransactionalEditingDomain domain, String label, DTreeItem treeItem, Object value) {
+ super(domain, label);
+ this.treeItem = treeItem;
+ this.value = value;
+ }
+
+ @Override
+ protected void doExecute() {
+ treeItem.setName((String) value);
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditorFocusListener.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditorFocusListener.java
new file mode 100644
index 0000000000..2b31f59359
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeItemEditorFocusListener.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.ui.actions.ActionFactory;
+
+import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
+
+/**
+ * A focusListener which replaces the EMF copy/cut/paste actions with standard
+ * actions.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class DTreeItemEditorFocusListener implements FocusListener {
+ /**
+ * Action to cut the content of the cell in the clipboard.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+ private class StandardCutAction extends Action {
+ TextCellEditor textCellEditor;
+
+ /**
+ * The default constructor.
+ *
+ * @param textCellEditor
+ * The current cell editor
+ */
+ public StandardCutAction(final TextCellEditor textCellEditor) {
+ this.textCellEditor = textCellEditor;
+ }
+
+ @Override
+ public void run() {
+ textCellEditor.performCut();
+ }
+ }
+
+ /**
+ * Action to copy the content of the cell in the clipboard.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+ private class StandardCopyAction extends Action {
+ TextCellEditor textCellEditor;
+
+ /**
+ * The default constructor.
+ *
+ * @param textCellEditor
+ * The current cell editor
+ */
+ public StandardCopyAction(final TextCellEditor textCellEditor) {
+ this.textCellEditor = textCellEditor;
+ }
+
+ @Override
+ public void run() {
+ textCellEditor.performCopy();
+ }
+ }
+
+ /**
+ * Action to paste the content of the cell in the clipboard.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+ private class StandardPasteAction extends Action {
+ TextCellEditor textCellEditor;
+
+ /**
+ * The default constructor.
+ *
+ * @param textCellEditor
+ * The current cell editor
+ */
+ public StandardPasteAction(final TextCellEditor textCellEditor) {
+ this.textCellEditor = textCellEditor;
+ }
+
+ @Override
+ public void run() {
+ textCellEditor.performPaste();
+ }
+ }
+
+ AbstractDTreeEditor treeEditor;
+
+ TextCellEditor textCellEditor;
+
+ IAction emfCutAction;
+
+ IAction emfCopyAction;
+
+ IAction emfPasteAction;
+
+ IAction standardCut;
+
+ IAction standardCopy;
+
+ IAction standardPaste;
+
+ /**
+ * The default constructor.
+ *
+ * @param treeEditor
+ * The current tree editor
+ * @param textCellEditor
+ * The current Editor associated to the TreeItem being edited
+ */
+ public DTreeItemEditorFocusListener(final AbstractDTreeEditor treeEditor, final TextCellEditor textCellEditor) {
+ this.treeEditor = treeEditor;
+ this.textCellEditor = textCellEditor;
+ emfCutAction = treeEditor.getActionBars().getGlobalActionHandler(ActionFactory.CUT.getId());
+ emfCopyAction = treeEditor.getActionBars().getGlobalActionHandler(ActionFactory.COPY.getId());
+ emfPasteAction = treeEditor.getActionBars().getGlobalActionHandler(ActionFactory.PASTE.getId());
+
+ standardCut = new StandardCutAction(textCellEditor);
+ standardCopy = new StandardCopyAction(textCellEditor);
+ standardPaste = new StandardPasteAction(textCellEditor);
+ }
+
+ /**
+ * We reset the actions with the EMF actions.<BR> {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusLost(final FocusEvent e) {
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(), emfCutAction);
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), emfCopyAction);
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(), emfPasteAction);
+ treeEditor.getActionBars().updateActionBars();
+ }
+
+ /**
+ * We override the EMF actions with the standard action.<BR> {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusGained(final FocusEvent e) {
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(), standardCut);
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), standardCopy);
+ treeEditor.getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(), standardPaste);
+ treeEditor.getActionBars().updateActionBars();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreePopupMenuContributionSupport.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreePopupMenuContributionSupport.java
new file mode 100644
index 0000000000..529e254d79
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreePopupMenuContributionSupport.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 THALES GLOBAL SERVICES.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tree.ui.tools.internal.editor.provider;
+
+import java.util.Iterator;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import com.google.common.collect.Iterators;
+
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.SiriusPlugin;
+import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
+import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
+import org.eclipse.sirius.description.tool.CreateInstance;
+import org.eclipse.sirius.description.tool.ExternalJavaAction;
+import org.eclipse.sirius.description.tool.ExternalJavaActionCall;
+import org.eclipse.sirius.description.tool.MenuItemDescription;
+import org.eclipse.sirius.description.tool.OperationAction;
+import org.eclipse.sirius.description.tool.ToolPackage;
+import org.eclipse.sirius.tools.api.ui.ExternalJavaActionProvider;
+import org.eclipse.sirius.tools.api.ui.IExternalJavaAction;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.business.api.command.ITreeCommandFactory;
+import org.eclipse.sirius.tree.business.api.query.TreePopupMenuQuery;
+import org.eclipse.sirius.tree.description.TreePopupMenu;
+import org.eclipse.sirius.tree.ui.provider.TreeUIPlugin;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.MetaClassNotFoundException;
+
+/**
+ * A Class that will populate a {@link DTreeItem}'s contextual menu using all
+ * the {@link org.eclipse.sirius.description.tool.PopupMenu}s defined with its associate
+ * {@link org.eclipse.sirius.tree.description.TreeItemMapping}.
+ *
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public final class TreePopupMenuContributionSupport {
+
+ /**
+ * The editing domain.
+ */
+ protected TransactionalEditingDomain domain;
+
+ /**
+ * The factory to use to create tree-related commands.
+ */
+ protected ITreeCommandFactory treeCommandFactory;
+
+ /**
+ * Creates a new TreePopupMenuContributionSupport.
+ *
+ * @param transactionalEditingDomain
+ * the domain to use for executing contributed actions
+ * @param treeCommandFactory
+ * the command factory to use
+ */
+ public TreePopupMenuContributionSupport(TransactionalEditingDomain transactionalEditingDomain, ITreeCommandFactory treeCommandFactory) {
+ this.domain = transactionalEditingDomain;
+ this.treeCommandFactory = treeCommandFactory;
+ }
+
+ /**
+ * Adds all menus and actions defined for the given {@link DTreeItem} to the
+ * given contextual menu.
+ *
+ * @param menu
+ * the contextual menu about to be shown
+ * @param selectedItem
+ * the selected {@link DTreeItem} from which getting the
+ * additional menus and actions
+ */
+ public void contributeToPopupMenu(final IMenuManager menu, DTreeItem selectedItem) {
+ EList<TreePopupMenu> popupMenus = selectedItem.getActualMapping().getPopupMenus();
+ IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(selectedItem.getTarget());
+ boolean haveCreatedAtLeastOnePopupMenu = false;
+ if (interpreter == null || popupMenus.isEmpty()) {
+ return;
+ }
+
+ // For each defined popupMenu
+ for (TreePopupMenu popupMenu : popupMenus) {
+ // If the defined popupMenu is applicable (i.e. has a "true"
+ // precondition)
+ final Boolean menuPrecondition;
+ if (StringUtil.isEmpty(popupMenu.getPrecondition())) {
+ menuPrecondition = true;
+ } else {
+ menuPrecondition = RuntimeLoggerManager.INSTANCE.decorate(interpreter).evaluateBoolean(selectedItem.getTarget(), popupMenu,
+ ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition());
+ }
+
+ if (menuPrecondition) {
+
+ // We create a subMenu
+ final MenuManager subMenu = new MenuManager(new IdentifiedElementQuery(popupMenu).getLabel(), new IdentifiedElementQuery(popupMenu).getLabel().toLowerCase());
+ // and populate it with all menu contributions contained it this
+ // popupMenu
+ buildActionsFromTreePopupMenu(subMenu, selectedItem, popupMenu, interpreter);
+
+ // If at least one action has been added to the subMenu, we make
+ // it visible
+ if (subMenu.getSize() > 0) {
+ haveCreatedAtLeastOnePopupMenu = true;
+ subMenu.setParent(menu);
+ menu.add(subMenu);
+ subMenu.setVisible(true);
+ }
+ }
+ }
+ if (haveCreatedAtLeastOnePopupMenu) {
+ menu.add(new Separator());
+ }
+
+ }
+
+ /**
+ * Builds all the Actions specified in the given popupMenu and adds them to
+ * the given subMenu
+ *
+ * @param subMenu
+ * the subMenu in which create the actions
+ * @param selectedItem
+ * the {@link DTreeItem} from which the contextual menu is
+ * computed
+ * @param popupMenu
+ * the popupMenu containing the Actions to create
+ * @param domain
+ */
+ private void buildActionsFromTreePopupMenu(IMenuManager subMenu, DTreeItem selectedItem, TreePopupMenu popupMenu, IInterpreter interpreter) {
+ // For each menu contribution associated to the given popupMenu
+ for (MenuItemDescription candidateMenuItem : new TreePopupMenuQuery(popupMenu).getMenuItems()) {
+ // If the menu item is applicable (i.e. has a "true"
+ // precondition)
+ final Boolean menuItemPrecondition;
+ if (StringUtil.isEmpty(candidateMenuItem.getPrecondition())) {
+ menuItemPrecondition = true;
+ } else {
+ menuItemPrecondition = RuntimeLoggerManager.INSTANCE.decorate(interpreter).evaluateBoolean(selectedItem.getTarget(), candidateMenuItem,
+ ToolPackage.eINSTANCE.getAbstractToolDescription_Precondition());
+ }
+
+ if (menuItemPrecondition) {
+ // We build a jface Action from this menu item
+ final IAction action = buildActionFromMenuItemDescription(candidateMenuItem, selectedItem);
+ if (action != null) {
+ subMenu.add(action);
+ }
+ }
+ }
+ }
+
+ /**
+ * Builds a JFace Action from the given {@link MenuItemDescription}, which
+ * target is the given selected {@link DTreeItem}.
+ *
+ * @param candidateMenuItem
+ * the {@link MenuItemDescription} to create an Action from
+ * @param selectedItem
+ * the selected {@link DTreeItem}
+ * @return a JFace Action created from the given {@link MenuItemDescription}
+ */
+ private IAction buildActionFromMenuItemDescription(MenuItemDescription candidateMenuItem, DTreeItem selectedItem) {
+ IAction result = null;
+ // The Menu Item Description can be :
+ // An External Java Action
+ if (candidateMenuItem instanceof ExternalJavaAction) {
+ final ExternalJavaAction javaAction = (ExternalJavaAction) candidateMenuItem;
+ if (!StringUtil.isEmpty(javaAction.getId())) {
+ result = buildJavaAction(javaAction, selectedItem, new IdentifiedElementQuery(javaAction).getLabel(), javaAction.getIcon());
+ }
+ } else {
+ // An External Java Action call
+ if (candidateMenuItem instanceof ExternalJavaActionCall) {
+ final ExternalJavaAction javaAction = ((ExternalJavaActionCall) candidateMenuItem).getAction();
+ if (javaAction != null && !StringUtil.isEmpty(javaAction.getId())) {
+ String iconPath = ((ExternalJavaActionCall) candidateMenuItem).getIcon();
+ if (StringUtil.isEmpty(iconPath)) {
+ iconPath = javaAction.getIcon();
+ }
+ result = buildJavaAction(javaAction, selectedItem, new IdentifiedElementQuery(candidateMenuItem).getLabel(), iconPath);
+ }
+ // An Operation Action
+ } else {
+ if (candidateMenuItem instanceof OperationAction) {
+ final OperationAction operation = (OperationAction) candidateMenuItem;
+ if (operation.getInitialOperation().getFirstModelOperations() != null) {
+ result = buildOperationAction(operation, selectedItem);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Builds a JFace Action from the given {@link ExternalJavaAction}, which
+ * target is the given selected {@link DTreeItem}.
+ *
+ * @param javaActionItem
+ * the ExternalJavaAction action to create an Action from
+ * @param selectedItem
+ * the selected {@link DTreeItem}
+ * @param nameOfTheAction
+ * the name to associate with the created action
+ * @param iconPath
+ * the path of the icon to associate with the created action
+ * @return a JFace Action created from the given {@link ExternalJavaAction}
+ */
+ private IAction buildJavaAction(ExternalJavaAction javaActionItem, DTreeItem selectedItem, String nameOfTheAction, String iconPath) {
+ // Step 1 : getting the java Action
+ final IExternalJavaAction javaAction = ExternalJavaActionProvider.INSTANCE.getJavaActionById(javaActionItem.getId());
+
+ if (javaAction != null) {
+ // Step 2 : building the command from this java Action
+ final Command command = this.treeCommandFactory.buildJavaActionFromTool(javaActionItem, selectedItem, javaAction);
+
+ if (command.canExecute()) {
+ // Step 3 : getting the icon to associate with the action to
+ // create
+ ImageDescriptor imageDescriptor = null;
+ if (!StringUtil.isEmpty(iconPath)) {
+ imageDescriptor = TreeUIPlugin.findImageDescriptor(iconPath);
+ }
+ // Step 4 : creating an action that will call the builded
+ // command
+ return new Action(nameOfTheAction, imageDescriptor) {
+
+ @Override
+ public void run() {
+ super.run();
+ domain.getCommandStack().execute(command);
+ }
+ };
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Builds a JFace Action from the given {@link OperationAction}, which
+ * target is the given selected {@link DTreeItem}.
+ *
+ * @param operationAction
+ * the operation action to create an Action from
+ * @param selectedItem
+ * the selected {@link DTreeItem}
+ * @return a JFace Action created from the given {@link OperationAction}
+ */
+ private IAction buildOperationAction(final OperationAction operationAction, DTreeItem selectedItem) {
+ // Step 1 : getting the icon to associate with the action to create
+ ImageDescriptor imageDescriptor = null;
+ if (!StringUtil.isEmpty(operationAction.getIcon())) {
+ imageDescriptor = TreeUIPlugin.findImageDescriptor(operationAction.getIcon());
+ } else {
+ // no icon is specified, let's provide a semantic icon as a default
+ // if we can find a create instance task.
+ imageDescriptor = TreePopupMenuContributionSupport.findImageDescriptor(operationAction);
+ }
+
+ // Step 2 : building the command from this OperationAction
+ final Command operationActionCommand = treeCommandFactory.buildOperationActionFromTool(operationAction, selectedItem);
+
+ if (operationActionCommand.canExecute()) {
+ // Step 3 : creating an action that will call the builded
+ // command
+ return new Action(new IdentifiedElementQuery(operationAction).getLabel(), imageDescriptor) {
+ @Override
+ public void run() {
+ super.run();
+ domain.getCommandStack().execute(operationActionCommand);
+ }
+ };
+ }
+ return null;
+ }
+
+ private static ImageDescriptor findImageDescriptor(OperationAction createTool) {
+
+ ImageDescriptor descriptor = DTreeViewerManager.getImageRegistry().getDescriptor(DTreeViewerManager.CREATE_TREE_ITEM_IMG);
+ EObject created = null;
+
+ Iterator<CreateInstance> createInstances = Iterators.filter(createTool.eAllContents(), CreateInstance.class);
+ while (created == null && createInstances.hasNext()) {
+ CreateInstance map = createInstances.next();
+ created = TreePopupMenuContributionSupport.tryToInstanciateType(createTool, created, map.getTypeName());
+ }
+
+ if (created != null) {
+ final IItemLabelProvider labelProvider = (IItemLabelProvider) TreeUIPlugin.getPlugin().getItemProvidersAdapterFactory().adapt(created, IItemLabelProvider.class);
+ if (labelProvider != null) {
+ ImageDescriptor semanticDescriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(labelProvider.getImage(created));
+ if (semanticDescriptor != null) {
+ descriptor = semanticDescriptor;
+ }
+
+ }
+ }
+
+ return descriptor;
+ }
+
+ private static EObject tryToInstanciateType(OperationAction createTool, EObject created, String map) {
+ EObject result = created;
+ if (!StringUtil.isEmpty(map)) {
+ try {
+ final EObject anInstance = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(createTool).createInstance(map);
+ result = anInstance;
+ } catch (final MetaClassNotFoundException e) {
+ /*
+ * silent catch, it's just a bit more magic, if we're able to
+ * retrieve the right type then we'll do.
+ */
+ }
+
+ }
+ return result;
+ }
+}

Back to the top