diff options
Diffstat (limited to 'plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse')
13 files changed, 2579 insertions, 2657 deletions
diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/CustomCommonViewer.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/CustomCommonViewer.java index 106d5c979ec..398f0364ec2 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/CustomCommonViewer.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/CustomCommonViewer.java @@ -1,155 +1,155 @@ -/*****************************************************************************
- * Copyright (c) 2010 CEA LIST.
- *
- *
- * 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:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.views.modelexplorer;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.jface.viewers.ColumnViewerEditor;
-import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
-import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
-import org.eclipse.jface.viewers.FocusCellHighlighter;
-import org.eclipse.jface.viewers.IElementComparer;
-import org.eclipse.jface.viewers.TreeViewerEditor;
-import org.eclipse.jface.viewers.TreeViewerFocusCellManager;
-import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EObjectTreeElement;
-import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EReferenceTreeElement;
-import org.eclipse.papyrus.views.modelexplorer.matching.HashCodeCalculus;
-import org.eclipse.papyrus.views.modelexplorer.matching.IMatchingItem;
-import org.eclipse.papyrus.views.modelexplorer.matching.IReferencable;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.internal.navigator.dnd.NavigatorDnDService;
-import org.eclipse.ui.navigator.CommonDragAdapter;
-import org.eclipse.ui.navigator.CommonDropAdapter;
-import org.eclipse.ui.navigator.CommonViewer;
-
-/**
- * this class was created in order to access to the drop adapter
- *
- */
-@SuppressWarnings("restriction")
-public class CustomCommonViewer extends CommonViewer {
- protected CommonDropAdapter dropAdapter;
-
- public CustomCommonViewer(String aViewerId, Composite aParent, int aStyle) {
- super(aViewerId, aParent, aStyle);
- // TODO Auto-generated constructor stub
- setComparer(new IElementComparer() {
-
- public int hashCode(Object element) {
- if (element instanceof EObjectTreeElement) {
- EObject eObject = ((EObjectTreeElement) element).getEObject();
- return HashCodeCalculus.getHashCode(eObject);
- }
-
- if (element instanceof EReferenceTreeElement) {
- EObject eParent = ((EReferenceTreeElement) element).getParent().getEObject();
- EReference eref = ((EReferenceTreeElement) element).getEReference();
- return HashCodeCalculus.getHashCode(eParent, eref);
- }
- if (element instanceof IReferencable) {
- IReferencable ref = (IReferencable) element;
- return ref.getElementBehind().hashCode();
- }
- if (element instanceof IMatchingItem) {
- IMatchingItem matchItem = (IMatchingItem) element;
- return matchItem.matchingItemHashcode();
- }
- return element.hashCode();
- }
-
- public boolean equals(Object a, Object b) {
- if (a instanceof IMatchingItem) {
- return ((IMatchingItem) a).matchingItemEquals(b);
- }
-
- if (b != null) {
- return b.equals(a);
- }
- return false;
- }
- });
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void initDragAndDrop() {
- dropAdapter = null;
- int operations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
-
- CommonDragAdapter dragAdapter = createDragAdapter();
- addDragSupport(operations, dragAdapter.getSupportedDragTransfers(), dragAdapter);
- dropAdapter = createDropAdapter();
- addDropSupport(operations, dropAdapter.getSupportedDropTransfers(), dropAdapter);
-
- NavigatorDnDService dnd = (NavigatorDnDService) getNavigatorContentService().getDnDService();
- dnd.setDropAdaptor(dropAdapter);
- }
-
- /**
- * get the listener in order to parameterize during the runtime the drop
- *
- * @return the dropadapter
- */
- public CommonDropAdapter getDropAdapter() {
- return dropAdapter;
- }
-
- /**
- * Overridden to disable cell editor activation by single click, it can be activated by double click instead.
- */
- @Override
- protected ColumnViewerEditor createViewerEditor() {
- // instantiate abstract focus cell high-lighter as dummy object for focus manager. The sub class
- // FocusCellOwnerDrawHighlighter would break multi-selections in Papyrus, see bug 419591.
- // (but we need to create a high-lighter, since the focus cell manager does not accept null pointer. The
- // TreeViewerEditor could work without focusCellManager, but would ignore keyboard events in this case.)
- FocusCellHighlighter fch = new FocusCellHighlighter(this) {
- };
- TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(
- this, fch);
-
-
-
- TreeViewerEditor.create(this, focusCellManager, new ColumnViewerEditorActivationStrategy(this) {
- @Override
- protected boolean isEditorActivationEvent(
- ColumnViewerEditorActivationEvent event) {
- // activation will uses F2 (also used by rename-popup, but not taken into account by the latter
- // for model elements for which a direct-editor exists)
- return event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED &&
- event.keyCode == SWT.F2;
- }
- }, ColumnViewerEditor.KEYBOARD_ACTIVATION);
- ColumnViewerEditor editor = this.getColumnViewerEditor();
-
- return editor;
- }
-
- /**
- * @see org.eclipse.ui.navigator.CommonViewer#dispose()
- *
- */
- @Override
- public void dispose() {
- //Remove the custom column viewer editor which causes NPE after dispose
- //ViewerEditor cannot be nulled or disposed, so we just recreate a default one
- setColumnViewerEditor(super.createViewerEditor());
- super.dispose();
- }
-
+/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * 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: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.views.modelexplorer; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.FocusCellHighlighter; +import org.eclipse.jface.viewers.IElementComparer; +import org.eclipse.jface.viewers.TreeViewerEditor; +import org.eclipse.jface.viewers.TreeViewerFocusCellManager; +import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EObjectTreeElement; +import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EReferenceTreeElement; +import org.eclipse.papyrus.views.modelexplorer.matching.HashCodeCalculus; +import org.eclipse.papyrus.views.modelexplorer.matching.IMatchingItem; +import org.eclipse.papyrus.views.modelexplorer.matching.IReferencable; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.internal.navigator.dnd.NavigatorDnDService; +import org.eclipse.ui.navigator.CommonDragAdapter; +import org.eclipse.ui.navigator.CommonDropAdapter; +import org.eclipse.ui.navigator.CommonViewer; + +/** + * this class was created in order to access to the drop adapter + * + */ +@SuppressWarnings("restriction") +public class CustomCommonViewer extends CommonViewer { + protected CommonDropAdapter dropAdapter; + + public CustomCommonViewer(String aViewerId, Composite aParent, int aStyle) { + super(aViewerId, aParent, aStyle); + // TODO Auto-generated constructor stub + setComparer(new IElementComparer() { + + public int hashCode(Object element) { + if (element instanceof EObjectTreeElement) { + EObject eObject = ((EObjectTreeElement) element).getEObject(); + return HashCodeCalculus.getHashCode(eObject); + } + + if (element instanceof EReferenceTreeElement) { + EObject eParent = ((EReferenceTreeElement) element).getParent().getEObject(); + EReference eref = ((EReferenceTreeElement) element).getEReference(); + return HashCodeCalculus.getHashCode(eParent, eref); + } + if (element instanceof IReferencable) { + IReferencable ref = (IReferencable) element; + return ref.getElementBehind().hashCode(); + } + if (element instanceof IMatchingItem) { + IMatchingItem matchItem = (IMatchingItem) element; + return matchItem.matchingItemHashcode(); + } + return element.hashCode(); + } + + public boolean equals(Object a, Object b) { + if (a instanceof IMatchingItem) { + return ((IMatchingItem) a).matchingItemEquals(b); + } + + if (b != null) { + return b.equals(a); + } + return false; + } + }); + } + + /** + * {@inheritDoc} + */ + @Override + protected void initDragAndDrop() { + dropAdapter = null; + int operations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + + CommonDragAdapter dragAdapter = createDragAdapter(); + addDragSupport(operations, dragAdapter.getSupportedDragTransfers(), dragAdapter); + dropAdapter = createDropAdapter(); + addDropSupport(operations, dropAdapter.getSupportedDropTransfers(), dropAdapter); + + NavigatorDnDService dnd = (NavigatorDnDService) getNavigatorContentService().getDnDService(); + dnd.setDropAdaptor(dropAdapter); + } + + /** + * get the listener in order to parameterize during the runtime the drop + * + * @return the dropadapter + */ + public CommonDropAdapter getDropAdapter() { + return dropAdapter; + } + + /** + * Overridden to disable cell editor activation by single click, it can be activated by double click instead. + */ + @Override + protected ColumnViewerEditor createViewerEditor() { + // instantiate abstract focus cell high-lighter as dummy object for focus manager. The sub class + // FocusCellOwnerDrawHighlighter would break multi-selections in Papyrus, see bug 419591. + // (but we need to create a high-lighter, since the focus cell manager does not accept null pointer. The + // TreeViewerEditor could work without focusCellManager, but would ignore keyboard events in this case.) + FocusCellHighlighter fch = new FocusCellHighlighter(this) { + }; + TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager( + this, fch); + + + + TreeViewerEditor.create(this, focusCellManager, new ColumnViewerEditorActivationStrategy(this) { + @Override + protected boolean isEditorActivationEvent( + ColumnViewerEditorActivationEvent event) { + // activation will uses F2 (also used by rename-popup, but not taken into account by the latter + // for model elements for which a direct-editor exists) + return event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && + event.keyCode == SWT.F2; + } + }, ColumnViewerEditor.KEYBOARD_ACTIVATION); + ColumnViewerEditor editor = this.getColumnViewerEditor(); + + return editor; + } + + /** + * @see org.eclipse.ui.navigator.CommonViewer#dispose() + * + */ + @Override + public void dispose() { + //Remove the custom column viewer editor which causes NPE after dispose + //ViewerEditor cannot be nulled or disposed, so we just recreate a default one + setColumnViewerEditor(super.createViewerEditor()); + super.dispose(); + } + }
\ No newline at end of file diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java index 142bf96f65f..ca198787830 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java @@ -1,6 +1,6 @@ /***************************************************************************** * Copyright (c) 2014 Christian W. Damus and others. - * + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,7 @@ * * Contributors: * Christian W. Damus - Initial API and implementation - * + * *****************************************************************************/ package org.eclipse.papyrus.views.modelexplorer; diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPropertySheetPage.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPropertySheetPage.java index 295302b58a1..3bd40a67c97 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPropertySheetPage.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPropertySheetPage.java @@ -1,6 +1,6 @@ /***************************************************************************** * Copyright (c) 2014 CEA LIST, Christian W. Damus, and others. - * + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,7 @@ * Contributors: * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation * Christian W. Damus - bug 454536 - * + * *****************************************************************************/ package org.eclipse.papyrus.views.modelexplorer; @@ -41,7 +41,7 @@ import com.google.common.collect.Iterators; /** * Specific PropertySheetPage for Model Explorer view to contribute to Undo/Redo Edit menu. - * + * * @author Gabriel Pascual * */ @@ -125,7 +125,7 @@ class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage implements /** * Queries whether the current selection includes any element from a resource in the context of the specified {@code context} that is being unloaded. - * + * * @param context * the service registry context of an editor that is being unloaded * @return whether any currently presented input element has already been unloaded (is now a proxy) or is in the given {@code context} diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerView.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerView.java index be0f262467d..f62485ecdc4 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerView.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerView.java @@ -1,1319 +1,1241 @@ -/*****************************************************************************
- * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- * Christian W. Damus (CEA) - post refreshes for transaction commit asynchronously (CDO)
- * Christian W. Damus (CEA) - bug 429826
- * Christian W. Damus (CEA) - bug 434635
- * Christian W. Damus (CEA) - bug 437217
- * Christian W. Damus (CEA) - bug 441857
- * Christian W. Damus - bug 450235
- * Christian W. Damus - bug 451683
- *
- *****************************************************************************/
-package org.eclipse.papyrus.views.modelexplorer;
-
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.core.commands.operations.IUndoContext;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.edit.domain.EditingDomain;
-import org.eclipse.emf.edit.domain.IEditingDomainProvider;
-import org.eclipse.emf.transaction.ResourceSetChangeEvent;
-import org.eclipse.emf.transaction.ResourceSetListener;
-import org.eclipse.emf.transaction.ResourceSetListenerImpl;
-import org.eclipse.emf.transaction.Transaction;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.jface.util.Policy;
-import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerColumn;
-import org.eclipse.jface.window.ToolTip;
-import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor;
-import org.eclipse.papyrus.infra.core.editor.IReloadableEditor;
-import org.eclipse.papyrus.infra.core.editor.reload.EditorReloadAdapter;
-import org.eclipse.papyrus.infra.core.editor.reload.EditorReloadEvent;
-import org.eclipse.papyrus.infra.core.editor.reload.TreeViewerContext;
-import org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener;
-import org.eclipse.papyrus.infra.core.lifecycleevents.ISaveAndDirtyService;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyListener;
-import org.eclipse.papyrus.infra.core.resource.ModelSet;
-import org.eclipse.papyrus.infra.core.resource.ReadOnlyEvent;
-import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel;
-import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager;
-import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
-import org.eclipse.papyrus.infra.core.sasheditor.editor.IPageLifeCycleEventsListener;
-import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
-import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
-import org.eclipse.papyrus.infra.emf.providers.SemanticFromModelExplorer;
-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
-import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
-import org.eclipse.papyrus.infra.services.navigation.service.NavigableElement;
-import org.eclipse.papyrus.infra.services.navigation.service.NavigationService;
-import org.eclipse.papyrus.infra.widgets.editors.SelectionMenu;
-import org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement;
-import org.eclipse.papyrus.views.modelexplorer.SharedModelExplorerState.StateChangedEvent;
-import org.eclipse.papyrus.views.modelexplorer.listener.DoubleClickListener;
-import org.eclipse.papyrus.views.modelexplorer.matching.IMatchingItem;
-import org.eclipse.papyrus.views.modelexplorer.matching.LinkItemMatchingItem;
-import org.eclipse.papyrus.views.modelexplorer.matching.ModelElementItemMatchingItem;
-import org.eclipse.papyrus.views.modelexplorer.matching.ReferencableMatchingItem;
-import org.eclipse.swt.SWT;
-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.events.MouseMoveListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-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.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IPropertyListener;
-import org.eclipse.ui.ISaveablePart;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IViewSite;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.navigator.CommonNavigator;
-import org.eclipse.ui.navigator.CommonViewer;
-import org.eclipse.ui.navigator.CommonViewerSorter;
-import org.eclipse.ui.navigator.IExtensionActivationListener;
-import org.eclipse.ui.navigator.ILinkHelper;
-import org.eclipse.ui.navigator.INavigatorContentService;
-import org.eclipse.ui.navigator.LinkHelperService;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.views.properties.IPropertySheetPage;
-import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
-import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
-
-import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/**
- * Papyrus Model Explorer associated to one {@link IMultiDiagramEditor}.
- * This ModelExplorer is linked to one single {@link IMultiDiagramEditor}. It doesn't change its
- * source when the current Editor change. To allow to explore different Model, use a {@link ModelExplorerPageBookView}.
- *
- */
-public class ModelExplorerView extends CommonNavigator implements IRevealSemanticElement, IEditingDomainProvider, IPageLifeCycleEventsListener {
-
- private SharedModelExplorerState sharedState;
-
- private SharedModelExplorerState.StateChangedListener sharedStateListener;
-
- /**
- * The context of the LabelProviderService used by this view
- *
- * @see {@link LabelProviderService}
- */
- public static final String LABEL_PROVIDER_SERVICE_CONTEXT = "org.eclipse.papyrus.views.modelexplorer.labelProvider.context";
-
- /**
- * The {@link ServicesRegistry} associated to the Editor. This view is associated to the
- * ServicesRegistry rather than to the EditorPart.
- */
- private ServicesRegistry serviceRegistry;
-
- /** The save aservice associated to the editor. */
- private ISaveAndDirtyService saveAndDirtyService;
-
- /** {@link IUndoContext} used to tag command in the commandStack. */
- private IUndoContext undoContext;
-
- /** editing domain used to read/write the model */
- private TransactionalEditingDomain editingDomain;
-
- /** Flag to avoid reentrant call to refresh. */
- private AtomicBoolean isRefreshing = new AtomicBoolean(false);
-
- /**
- * A listener on page (all editors) selection change. This listener is set
- * in {@link ModelExplorerView#init(IViewSite)}. It should be dispose to remove
- * hook to the Eclipse page.
- */
- private ISelectionListener pageSelectionListener = new ISelectionListener() {
-
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
- handleSelectionChangedFromDiagramEditor(part, selection);
- }
- };
-
- /**
- * Listener on {@link ISaveAndDirtyService#addInputChangedListener(IEditorInputChangedListener)}
- */
- protected IEditorInputChangedListener editorInputChangedListener = new IEditorInputChangedListener() {
-
- /**
- * This method is called when the editor input is changed from the ISaveAndDirtyService.
- *
- * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#editorInputChanged(org.eclipse.ui.part.FileEditorInput)
- *
- * @param fileEditorInput
- */
- public void editorInputChanged(FileEditorInput fileEditorInput) {
- // Change the editor input.
- setPartName(fileEditorInput.getName());
- }
-
- /**
- * The isDirty flag has changed, reflect its new value
- *
- * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#isDirtyChanged()
- *
- */
- public void isDirtyChanged() {
- firePropertyChange(IEditorPart.PROP_DIRTY);
- }
- };
-
- /** The {@link IPropertySheetPage} this model explorer will use. */
- private final List<IPropertySheetPage> propertySheetPages = new LinkedList<IPropertySheetPage>();
-
- /**
- *
- * Constructor.
- *
- * @param part
- * The part associated to this ModelExplorer
- */
- public ModelExplorerView(IMultiDiagramEditor part) {
-
- if (part == null) {
- throw new IllegalArgumentException("A part should be provided.");
- }
-
- init(part);
-
- IReloadableEditor.Adapter.getAdapter(part).addEditorReloadListener(new EditorReloadAdapter() {
-
- @Override
- public void editorAboutToReload(EditorReloadEvent event) {
- // Stash expansion and selection state of the common viewer
- event.putContext(new ModelExplorerTreeViewerContext(getCommonViewer()));
-
- deactivate();
- }
-
- @Override
- public void editorReloaded(EditorReloadEvent event) {
- init(event.getEditor());
-
- activate();
-
- initCommonViewer(getCommonViewer());
-
- // Restore expansion and selection state of the common viewer
- ((TreeViewerContext<?>) event.getContext()).restore(getCommonViewer());
- }
- });
- }
-
- private void init(IMultiDiagramEditor editor) {
- // Try to get the ServicesRegistry
- serviceRegistry = editor.getServicesRegistry();
- if (serviceRegistry == null) {
- throw new IllegalArgumentException("The editor should have a ServiceRegistry.");
- }
-
- // Get required services from ServicesRegistry
- try {
- saveAndDirtyService = serviceRegistry.getService(ISaveAndDirtyService.class);
- undoContext = serviceRegistry.getService(IUndoContext.class);
- } catch (ServiceException e) {
- Activator.log.error(e);
- }
- }
-
- /**
- * Handle a selection change in the editor.
- *
- * @param part
- * @param selection
- */
- private void handleSelectionChangedFromDiagramEditor(IWorkbenchPart part, ISelection selection) {
- // Handle selection from diagram editor
- if (isLinkingEnabled()) {
- if (part instanceof IEditorPart) {
- if (selection instanceof IStructuredSelection) {
- Iterator<?> selectionIterator = ((IStructuredSelection) selection).iterator();
- ArrayList<Object> semanticElementList = new ArrayList<Object>();
- while (selectionIterator.hasNext()) {
- Object currentSelection = selectionIterator.next();
- Object semanticElement = EMFHelper.getEObject(currentSelection);
- if (semanticElement != null) {
- semanticElementList.add(semanticElement);
- }
-
- }
- revealSemanticElement(semanticElementList);
-
- }
-
- }
-
- // Selections from the Model Explorer result in a part from the ModelExplorerPageBookView instance which is not an IEditorPart
- if (part instanceof ModelExplorerPageBookView && !selection.isEmpty()) {
- if (selection instanceof IStructuredSelection) {
- // Extracted from org.eclipse.ui.internal.navigator.actions.LinkEditorAction activateEditorJob
- // the problem was that multi-element selections were disabled as only selections of 1 could clear the condition size()==1
- IStructuredSelection sSelection = (IStructuredSelection) selection;
- LinkHelperService linkService = getLinkHelperService();
- ILinkHelper[] helpers = linkService.getLinkHelpersFor(sSelection.getFirstElement()); // LinkHelper in org.eclipse.papyrus.views.modelexplorer
- if (helpers.length > 0) {
- helpers[0].activateEditor(part.getSite().getPage(), sSelection);
- }
- }
- }
- }
- }
-
- /**
- * look for the path the list of element (comes from the content provider) to go the eObject
- *
- * @param eobject
- * that we look for.
- * @param objects
- * a list of elements where eobject can be wrapped.
- * @return the list of modelElementItem ( from the root to the element that wrap the eobject)
- */
- protected List<Object> searchPath(EObject eobject, List<Object> objects) {
- SemanticFromModelExplorer semanticGetter = new SemanticFromModelExplorer();
- List<Object> path = new ArrayList<Object>();
- ITreeContentProvider contentProvider = (ITreeContentProvider) getCommonViewer().getContentProvider();
- // IPageMngr iPageMngr = EditorUtils.getIPageMngr();
- IPageManager iPageMngr;
- try {
- iPageMngr = ServiceUtils.getInstance().getIPageManager(serviceRegistry);
- } catch (ServiceException e) {
- // This shouldn't happen.
- return Collections.emptyList();
- }
- Object[] result = iPageMngr.allPages().toArray();
- List<Object> editors = Arrays.asList(result);
-
-
- for (Object o : objects) {
- // Search matches in this level
- if (!editors.contains(o)) {
- if (eobject.equals(EMFHelper.getEObject(o))) {
- path.add(o);
- return path;
- }
- }
-
- // Find childs only for feature container
- for (int i = 0; i < contentProvider.getChildren(o).length; i++) {
- Object treeItem = contentProvider.getChildren(o)[i];
-
- List<Object> tmppath = new ArrayList<Object>();
- Object element = semanticGetter.getSemanticElement(treeItem);
- if (element != null) {
- if (element instanceof EReference) {
- if (((EReference) element).isContainment() && (!((EReference) element).isDerived())) {
- List<Object> childs = new ArrayList<Object>();
- childs.add(treeItem);
- tmppath = searchPath(eobject, childs);
- }
- }
-
- else {
- if (element instanceof EObject) {
- List<Object> childs = new ArrayList<Object>();
- childs.add(treeItem);
- tmppath = searchPath(eobject, childs);
- }
- }
- }
-
- // if tmppath contains the wrapped eobject we have find the good path
- if (tmppath.size() > 0) {
- if (eobject.equals((EMFHelper.getEObject((tmppath.get(tmppath.size() - 1)))))) {
- path.add(o);
- path.addAll(tmppath);
- return path;
- }
- }
- }
- }
-
- return new ArrayList<Object>();
- }
-
-
- /**
- * {@inheritDoc}
- */
- // FIXME Use of internal class (NavigatorContentService) - in the hope that the bug gets fixed soon.
- @Override
- protected CommonViewer createCommonViewerObject(Composite aParent) {
- CommonViewer viewer = new CustomCommonViewer(getViewSite().getId(), aParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-
- initCommonViewer(viewer);
-
- viewer.getNavigatorContentService().getActivationService().addExtensionActivationListener(new IExtensionActivationListener() {
-
- public void onExtensionActivation(String aViewerId, String[] theNavigatorExtensionIds, boolean isActive) {
- sharedState.updateNavigatorContentExtensions(theNavigatorExtensionIds, isActive);
- }
- });
-
- ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE);
-
- return viewer;
- }
-
- private void installEMFFacetTreePainter(Tree tree) {
- // Install the EMFFacet Custom Tree Painter
- // org.eclipse.papyrus.infra.emf.Activator.getDefault().getCustomizationManager().installCustomPainter(tree);
-
- // The EMF Facet MeasureItem Listener is incompatible with the NavigatorDecoratingLabelProvider. Remove it.
- // Symptoms: ModelElementItems with an EMF Facet Overlay have a small selection size
- // Removal also fixes bug 400012: no scrollbar although tree is larger than visible area
- Collection<Listener> listenersToRemove = new LinkedList<Listener>();
- for (Listener listener : tree.getListeners(SWT.MeasureItem)) {
- if (listener.getClass().getName().contains("org.eclipse.papyrus.emf.facet.infra.browser.uicore.internal.CustomTreePainter")) {
- listenersToRemove.add(listener);
- }
- }
-
- for (Listener listener : listenersToRemove) {
- tree.removeListener(SWT.MeasureItem, listener);
- }
- }
-
- private void initCommonViewer(CommonViewer viewer) {
- // enable tool-tips
- // workaround for bug 311827: the Common Viewer always uses NavigatorDecoratingLabelProvider
- // as a wrapper for the LabelProvider provided by the application. The NavigatorDecoratingLabelProvider
- // does not delegate tooltip related functions but defines them as empty.
-
- Object input = getInitialInput();
- ILabelProvider labelProvider = null;
-
- if (input instanceof ServicesRegistry) {
- ServicesRegistry registry = (ServicesRegistry) input;
- try {
- labelProvider = registry.getService(LabelProviderService.class).getLabelProvider(LABEL_PROVIDER_SERVICE_CONTEXT);
- } catch (ServiceException ex) {
- Activator.log.error(ex);
- }
-
- labelProvider = new DecoratingLabelProviderWTooltips(labelProvider, (ServicesRegistry) input);
- }
-
- if (labelProvider == null) {
- labelProvider = new LabelProvider();
- }
-
- viewer.setLabelProvider(labelProvider); // add for decorator and tooltip support
- }
-
- @Override
- public void createPartControl(Composite aParent) {
- super.createPartControl(aParent);
-
- getCommonViewer().setSorter(null);
- ((CustomCommonViewer) getCommonViewer()).getDropAdapter().setFeedbackEnabled(true);
- getCommonViewer().addDoubleClickListener(new DoubleClickListener(new Supplier<ServicesRegistry>() {
- public ServicesRegistry get() {
- return serviceRegistry;
- }
- }));
-
- Tree tree = getCommonViewer().getTree();
-
- tree.addKeyListener(new KeyListener() {
-
- public void keyReleased(KeyEvent e) {
- if (e.keyCode == SWT.ALT) {
- exitItem();
- }
- }
-
- public void keyPressed(KeyEvent e) {
- if (e.keyCode != SWT.ALT) {
- return;
- }
-
- Tree tree = getCommonViewer().getTree();
-
- // Generate a basic mouse event
- Event event = new Event();
- event.widget = tree;
- event.stateMask = SWT.ALT;
-
- Point absoluteTreeLocation = tree.toDisplay(new Point(0, 0));
-
- event.x = tree.getDisplay().getCursorLocation().x - absoluteTreeLocation.x;
- event.y = tree.getDisplay().getCursorLocation().y - absoluteTreeLocation.y;
-
- MouseEvent mouseEvent = new MouseEvent(event);
- if (isEnterState(mouseEvent)) {
- enterItem(currentItem);
- }
- }
- });
-
- tree.addMouseListener(new MouseAdapter() {
-
- @Override
- public void mouseUp(MouseEvent e) {
- if ((e.stateMask & SWT.ALT) == 0) {
- return;
- }
-
- TreeItem currentItem = getTreeItem(e);
- if (currentItem != null) {
- Object data = currentItem.getData();
- try {
- NavigationService service = serviceRegistry.getService(NavigationService.class);
- List<NavigableElement> navigableElements = service.getNavigableElements(data);
-
- // TODO: Implement a priority on NavigableElements and navigate the element with the highest priority
- for (NavigableElement navigableElement : navigableElements) {
- if (navigableElement.isEnabled()) {
- service.navigate(navigableElement);
- }
- }
- } catch (ServiceException ex) {
- Activator.log.error(ex);
- }
- }
- }
- });
-
- tree.addMouseMoveListener(new MouseMoveListener() {
-
- public void mouseMove(MouseEvent e) {
-
- if (isExitState(e)) {
- exitItem();
- }
-
- if (isEnterState(e)) {
- enterItem(currentItem);
- }
-
- }
-
- });
-
- installEMFFacetTreePainter(tree);
- try {
- ISashWindowsContainer sashWindowsContainer = serviceRegistry.getService(ISashWindowsContainer.class);
- sashWindowsContainer.addPageLifeCycleListener(this);
- } catch (ServiceException ex) {
- // Ignore
- }
-
- if (sharedState != null) {
- initSharedState(sharedState);
- }
- }
-
- @Override
- protected CommonViewer createCommonViewer(Composite aParent) {
- CommonViewer viewer = super.createCommonViewer(aParent);
- ViewerColumn column = (ViewerColumn) viewer.getTree().getData(Policy.JFACE + ".columnViewer");
- column.setEditingSupport(new DirectEditorEditingSupport(viewer));
- return viewer;
- }
-
-
- TreeItem currentItem;
-
- SelectionMenu selectionMenu;
-
- private boolean isExitState(MouseEvent e) {
- if (currentItem == null) {
- return false;
- }
-
- TreeItem item = getTreeItem(e);
- if (item == null) {
- return true;
- }
-
- if (item != currentItem) {
- return true;
- }
-
- if ((e.stateMask & SWT.ALT) == 0) {
- return true;
- }
-
- return false;
- }
-
- private boolean isEnterState(MouseEvent e) {
- TreeItem item = getTreeItem(e);
- if (item == currentItem) {
- return false;
- }
-
- if (item == null) {
- return false;
- }
-
- if ((e.stateMask & SWT.ALT) == 0) {
- return false;
- }
-
- currentItem = item;
-
- return true;
- }
-
- private void disposeCurrentMenu() {
- if (selectionMenu != null) {
- selectionMenu.dispose();
- selectionMenu = null;
- }
- }
-
- private void exitItem() {
- currentItem = null;
- disposeCurrentMenu();
- }
-
- private void enterItem(TreeItem item) {
- try {
- final NavigationService navigation = serviceRegistry.getService(NavigationService.class);
- disposeCurrentMenu();
- selectionMenu = navigation.createNavigationList(item.getData(), item.getParent());
- if (selectionMenu == null) {
- return;
- }
-
- selectionMenu.addSelectionChangedListener(new ISelectionChangedListener() {
-
- public void selectionChanged(SelectionChangedEvent event) {
- if (event.getSelection().isEmpty()) {
- return;
- }
- Object selectedElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
- if (selectedElement instanceof NavigableElement) {
- NavigableElement navigableElement = (NavigableElement) selectedElement;
- if (navigableElement.isEnabled()) {
- navigation.navigate((NavigableElement) selectedElement);
- exitItem();
- }
- }
- }
- });
- } catch (ServiceException ex) {
- Activator.log.error(ex);
- }
- }
-
- private TreeItem getTreeItem(MouseEvent e) {
- return ((Tree) e.widget).getItem(new Point(e.x, e.y));
- }
-
-
- /**
- * Return the control used to render this View
- *
- * @see org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.IPageBookNestableViewPart#getControl()
- *
- * @return the main control of the navigator viewer
- */
- public Control getControl() {
- return getCommonViewer().getControl();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void init(IViewSite site, IMemento aMemento) throws PartInitException {
- super.init(site, aMemento);
-
- activate();
-
- // Self-listen for property changes
- addPropertyListener(new IPropertyListener() {
-
- public void propertyChanged(Object source, int propId) {
- switch (propId) {
- case IS_LINKING_ENABLED_PROPERTY:
- // Propagate to other instances
- sharedState.setLinkingEnabled(isLinkingEnabled());
- break;
- }
- }
- });
- }
-
- /**
- * {@link ResourceSetListener} to listen and react to changes in the
- * resource set.
- */
- private final ResourceSetListener resourceSetListener = new ResourceSetListenerImpl() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void resourceSetChanged(ResourceSetChangeEvent event) {
- super.resourceSetChanged(event);
- handleResourceSetChanged(event);
- }
- };
-
- /** cache variable with last transaction which triggered a refresh */
- private Transaction lastTrans = null;
-
- /**
- * Run in a UI thread to avoid non UI thread exception.
- *
- * @param event
- */
- private void handleResourceSetChanged(ResourceSetChangeEvent event) {
- // avoid refreshing N times for the same transaction (called for each object in resource)
- Transaction curTrans = event.getTransaction();
- if (lastTrans != null && lastTrans.equals(curTrans)) {
- return;
- }
- lastTrans = curTrans;
-
- scheduleRefresh();
- }
-
- private Runnable refreshRunnable;
-
- /**
- * Thread-safe
- * Schedule a runnable which will refresh the view if necessary
- */
- protected void scheduleRefresh() {
- final Runnable schedule;
-
- synchronized (this) {
- if (refreshRunnable == null) {
- // No refresh is yet pending. Schedule one
- schedule = createRefreshRunnable();
- refreshRunnable = schedule;
- } else {
- schedule = null;
- }
- }
-
- if (schedule != null) {
- Control control = getControl();
- Display display = ((control == null) || control.isDisposed()) ? null : control.getDisplay();
-
- if (display != null) {
- // Don't need to schedule a refresh if we have no control or it's disposed
- display.asyncExec(schedule);
- }
- }
- }
-
- private Runnable createRefreshRunnable() {
- return new Runnable() {
-
- public void run() {
- // Only run if I'm still pending
- synchronized (ModelExplorerView.this) {
- if (refreshRunnable != this) {
- return;
- }
-
- refreshRunnable = null;
- }
-
- refreshInUIThread();
- }
- };
- }
-
- /**
- * Thread-safe method to hurry up a pending refresh of the Model Explorer view (if any), synchronously.
- * When this method returns, then either the explorer has been refreshed or it doesn't need to be.
- */
- protected void syncRefresh() {
- final Runnable pending;
-
- synchronized (this) {
- pending = refreshRunnable;
- }
-
- if (pending != null) {
- Control control = getControl();
- Display display = ((control == null) || control.isDisposed()) ? null : control.getDisplay();
-
- if (display != null) {
- // Don't need to execute a refresh if we have no control or it's disposed
- display.syncExec(pending);
- }
- }
- }
-
- /**
- * refresh the view.
- */
- protected void refreshInUIThread() {
- // Need to refresh, even if (temporarily) invisible
- // (Better alternative?: store refresh event and execute once visible again)
- if (getControl().isDisposed()) {
- return;
- }
-
- // avoid reentrant call
- // Refresh only of we are not already refreshing.
- if (isRefreshing.compareAndSet(false, true)) {
- if (!getCommonViewer().isBusy()) {
- getCommonViewer().refresh();
- }
-
- isRefreshing.set(false);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object getInitialInput() {
-
- if (serviceRegistry != null) {
- return serviceRegistry;
- } else {
- return super.getInitialInput();
- }
-
- }
-
- /**
- * Activate specified Part.
- */
- private void activate() {
- try {
- this.editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
-
- // Set Viewer input if it already exist
- if (getCommonViewer() != null) {
- getCommonViewer().setInput(serviceRegistry);
- }
- editingDomain.addResourceSetListener(resourceSetListener);
- IReadOnlyHandler2 readOnlyHandler = AdapterUtils.adapt(editingDomain, IReadOnlyHandler2.class, null);
- if (readOnlyHandler != null) {
- readOnlyHandler.addReadOnlyListener(createReadOnlyListener());
- }
- } catch (ServiceException e) {
- // Can't get EditingDomain, skip
- }
-
- // listen to change events
- getSite().getPage().addSelectionListener(pageSelectionListener);
-
- // Listen to isDirty flag
- saveAndDirtyService.addInputChangedListener(editorInputChangedListener);
-
- if (this.getCommonViewer() != null) {
- // Force a refresh
- Display display = getControl().getDisplay();
- if (display == Display.getCurrent()) {
- refreshInUIThread();
- } else {
- // Hmm. We should be on the UI thread
- Activator.log.warn("Model Explorer activated on a non-UI thread."); //$NON-NLS-1$
- scheduleRefresh();
- }
- }
- }
-
- /**
- * Deactivate the Model Explorer.
- */
- private void deactivate() {
- // deactivate global handler
- if (Activator.log.isDebugEnabled()) {
- Activator.log.debug("deactivate ModelExplorerView"); //$NON-NLS-1$
- }
-
- try {
- ISashWindowsContainer sashWindowsContainer = serviceRegistry.getService(ISashWindowsContainer.class);
- if (sashWindowsContainer != null) {
- sashWindowsContainer.removePageLifeCycleListener(this);
- }
- } catch (ServiceException ex) {
- // Ignore
- }
-
- // Stop listening on change events
- getSite().getPage().removeSelectionListener(pageSelectionListener);
- // Stop Listening to isDirty flag
- saveAndDirtyService.removeInputChangedListener(editorInputChangedListener);
-
- if (editingDomain != null) {
- editingDomain.removeResourceSetListener(resourceSetListener);
- editingDomain = null;
- }
-
- saveAndDirtyService = null;
- undoContext = null;
- editingDomain = null;
- editingDomain = null;
- lastTrans = null;
- }
-
- /**
- * Invoked internally to clear the common viewer's associate listener in order to promote garbage collection.
- */
- void aboutToDispose() {
- final CommonViewer viewer = getCommonViewer();
- if ((viewer.getTree() != null) && !viewer.getTree().isDisposed()) {
- viewer.setInput(null);
-
- // Kick the NavigatorContentService to clear the cache in its StructuredViewerManager that leaks all of our tree elements
- INavigatorContentService contentService = getNavigatorContentService();
- if (contentService instanceof IExtensionActivationListener) {
- ((IExtensionActivationListener) getNavigatorContentService()).onExtensionActivation(contentService.getViewerId(), new String[0], false);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void dispose() {
-
- // Stop if we are already disposed
- if (isDisposed()) {
- return;
- }
-
- if ((sharedStateListener != null) && (sharedState != null)) {
- sharedState.removeListener(sharedStateListener);
- }
-
- if (getSite() != null) {
- getSite().getPage().removeSelectionListener(pageSelectionListener);
- }
-
- deactivate();
-
- for (IPropertySheetPage propertySheetPage : this.propertySheetPages) {
- propertySheetPage.dispose();
- }
-
- propertySheetPages.clear();
-
- pageSelectionListener = null;
-
- super.dispose();
-
- // Clean up properties to help GC
-
- }
-
- /**
- * Return true if the component is already disposed.
- *
- * @return
- */
- public boolean isDisposed() {
- // use editorPart as flag
- return saveAndDirtyService == null;
- }
-
- /**
- * Retrieves the {@link IPropertySheetPage} that his Model Explorer uses.
- *
- * @return
- */
- private IPropertySheetPage getPropertySheetPage() {
- try {
- final IMultiDiagramEditor multiDiagramEditor = ServiceUtils.getInstance().getService(IMultiDiagramEditor.class, serviceRegistry);
-
- if (multiDiagramEditor != null) {
- if (multiDiagramEditor instanceof ITabbedPropertySheetPageContributor) {
- ITabbedPropertySheetPageContributor contributor = (ITabbedPropertySheetPageContributor) multiDiagramEditor;
- IPropertySheetPage propertySheetPage = new TabbedPropertySheetPage(contributor);
- this.propertySheetPages.add(propertySheetPage);
- return propertySheetPage;
- }
- }
- } catch (ServiceException ex) {
- Activator.log.error(ex);
- }
- return null;
- }
-
- /**
- * in order to see element if the property view
- */
- @Override
- @SuppressWarnings("rawtypes")
- public Object getAdapter(Class adapter) {
- if (IPropertySheetPage.class.equals(adapter)) {
- return getPropertySheetPage();
- }
-
- if (IUndoContext.class == adapter) {
- // Return the IUndoContext of associated model.
- return undoContext;
- }
-
- if (ISaveablePart.class.equals(adapter)) {
- try {
- return serviceRegistry.getService(IMultiDiagramEditor.class);
- } catch (ServiceException ex) {
- Activator.log.error(ex);
- }
- return saveAndDirtyService;
- }
-
- if (ServicesRegistry.class == adapter) {
- return serviceRegistry;
- }
-
- return super.getAdapter(adapter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @return the EditingDomain used by the properties view
- */
- public EditingDomain getEditingDomain() {
- return editingDomain;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void selectReveal(ISelection selection) {
- syncRefresh();
- if (getCommonViewer() != null) {
- getCommonViewer().setSelection(selection, true);
- }
- }
-
- public void revealSemanticElement(List<?> elementList) {
- // Ensure that the ModelExplorer is refreshed before
- // trying to display an element. Useful if the element has just been created,
- // and the model explorer has not yet been refreshed
- syncRefresh();
- reveal(elementList, getCommonViewer());
- }
-
- /**
- * Expands the given CommonViewer to reveal the given elements
- *
- * @param elementList
- * The elements to reveal
- * @param commonViewer
- * The CommonViewer they are to be revealed in
- */
- public static void reveal(Iterable<?> elementList, final CommonViewer commonViewer) {
- ArrayList<IMatchingItem> matchingItemsToSelect = new ArrayList<IMatchingItem>();
- // filter out non EMF objects
- Iterable<EObject> list = Iterables.filter(elementList, EObject.class);
-
- for (EObject currentEObject : list) {
- matchingItemsToSelect.add(new ModelElementItemMatchingItem(currentEObject));
-
- // the content provider exist?
- if (commonViewer.getContentProvider() != null) {
- // retrieve the ancestors to reveal them
- // and allow the selection of the object
- ArrayList<EObject> parents = new ArrayList<EObject>();
- EObject tmp = currentEObject.eContainer();
- while (tmp != null) {
- parents.add(tmp);
- tmp = tmp.eContainer();
- }
-
- Iterable<EObject> reverseParents = Lists.reverse(parents);
-
- // reveal the resource if necessary
- Resource r = null;
- if (!parents.isEmpty()) {
- r = parents.get(parents.size() - 1).eResource();
- } else {
- r = currentEObject.eResource();
- }
-
- if (r != null) {
- final ResourceSet rs = r.getResourceSet();
- final Resource resource = r;
- if (rs instanceof ModelSet && AdditionalResourcesModel.isAdditionalResource((ModelSet) rs, r.getURI())) {
- commonViewer.getControl().getDisplay().syncExec(new Runnable() {
-
- public void run() {
- commonViewer.expandToLevel(new ReferencableMatchingItem(rs), 1);
- commonViewer.expandToLevel(new ReferencableMatchingItem(resource), 1);
- }
- });
-
- }
- }
-
- /*
- * reveal the ancestors tree using expandToLevel on each of them
- * in the good order. This is a lot faster than going through the whole tree
- * using getChildren of the ContentProvider since our Viewer uses a Hashtable
- * to keep track of the revealed elements.
- *
- * However we need to use a dedicated MatchingItem to do the matching,
- * and a specific comparer in our viewer so than the equals of MatchingItem is
- * used in priority.
- *
- * Please refer to MatchingItem for more infos.
- */
- EObject previousParent = null;
- for (EObject parent : reverseParents) {
- if (parent.eContainingFeature() != null && previousParent != null) {
- commonViewer.expandToLevel(new LinkItemMatchingItem(previousParent, parent.eContainmentFeature()), 1);
- }
-
- final IMatchingItem itemToExpand = new ModelElementItemMatchingItem(parent);
-
- commonViewer.getControl().getDisplay().syncExec(new Runnable() {
-
- public void run() {
- commonViewer.expandToLevel(itemToExpand, 1);
- }
- });
-
- previousParent = parent;
- }
-
- final IMatchingItem itemToExpand = new LinkItemMatchingItem(currentEObject.eContainer(), currentEObject.eContainmentFeature());
-
- commonViewer.getControl().getDisplay().syncExec(new Runnable() {
-
- public void run() {
- commonViewer.expandToLevel(itemToExpand, 1);
- }
- });
- }
- }
-
- selectReveal(new StructuredSelection(matchingItemsToSelect), commonViewer);
- }
-
- /**
- * Selects the given ISelection in the given CommonViwer
- *
- * @param structuredSelection
- * The ISelection to select
- * @param commonViewer
- * The ComonViewer to select it in
- */
- public static void selectReveal(final ISelection structuredSelection, final Viewer commonViewer) {
- Display.getDefault().syncExec(new Runnable() {
-
- public void run() {
- commonViewer.setSelection(structuredSelection, true);
- }
- });
- }
-
- /**
- * Selects and, if possible, reveals the given ISelection in the given CommonViwer
- *
- * @param selection
- * The ISelection to select
- * @param viewer
- * The ComonViewer to select it in
- */
- public static void reveal(final ISelection selection, final CommonViewer viewer) {
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection structured = (IStructuredSelection) selection;
- reveal(Lists.newArrayList(structured.iterator()), viewer);
- } else {
- viewer.getControl().getDisplay().syncExec(new Runnable() {
-
- public void run() {
- viewer.setSelection(selection);
- }
- });
- }
- }
-
- public void pageOpened(IPage page) {
- refreshTree();
- }
-
- public void pageClosed(IPage page) {
- refreshTree();
- }
-
- private void refreshTree() {
- Display.getDefault().asyncExec(new Runnable() {
-
- public void run() {
- if (getCommonViewer().getControl() == null || getCommonViewer().getControl().isDisposed()) {
- return;
- }
- getCommonViewer().refresh(true);
- // Force redraw to refresh facet overlay
- getCommonViewer().getTree().redraw();
- }
- });
- }
-
- public void pageChanged(IPage newPage) {
- // Nothing
- }
-
- public void pageActivated(IPage page) {
- // Nothing
- }
-
- public void pageDeactivated(IPage page) {
- // Nothing
- }
-
- public void pageAboutToBeOpened(IPage page) {
- // Nothing
- }
-
- public void pageAboutToBeClosed(IPage page) {
- // Nothing
- }
-
- private IReadOnlyListener createReadOnlyListener() {
- return new IReadOnlyListener() {
-
- public void readOnlyStateChanged(ReadOnlyEvent event) {
- switch (event.getEventType()) {
- case ReadOnlyEvent.RESOURCE_READ_ONLY_STATE_CHANGED:
- scheduleRefresh();
- break;
- case ReadOnlyEvent.OBJECT_READ_ONLY_STATE_CHANGED:
- CommonViewer viewer = getCommonViewer();
- if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) {
- viewer.refresh(event.getObject());
- }
- break;
- default:
- Activator.log.warn("Unsupported read-only event type: " + event.getEventType());
- break;
- }
- }
- };
- }
-
- void setSharedState(SharedModelExplorerState state) {
- if (this.sharedState != null) {
- this.sharedState.removeListener(getSharedStateListener());
- }
-
- this.sharedState = state;
-
- if (state != null) {
- state.addListener(getSharedStateListener());
- initSharedState(state);
- }
- }
-
- void initSharedState(SharedModelExplorerState state) {
- setLinkingEnabled(state.isLinkingEnabled());
- setAlphaSorted(state.isAlphaSorted());
- }
-
- void setAlphaSorted(boolean sorted) {
- CommonViewer viewer = getCommonViewer();
- if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) {
- if (sorted) {
- viewer.setSorter(new CommonViewerSorter());
- if (viewer instanceof CustomCommonViewer) {
- ((CustomCommonViewer) viewer).getDropAdapter().setFeedbackEnabled(false);
- }
- } else {
- viewer.setSorter(null);
- if (viewer instanceof CustomCommonViewer) {
- ((CustomCommonViewer) viewer).getDropAdapter().setFeedbackEnabled(true);
- }
- }
- }
- }
-
- SharedModelExplorerState.StateChangedListener getSharedStateListener() {
- if (sharedStateListener == null) {
- sharedStateListener = new SharedModelExplorerState.StateChangedListener() {
-
- private volatile Runnable contentUpdate;
-
- public void sharedStateChanged(StateChangedEvent event) {
- switch (event.getEventType()) {
- case StateChangedEvent.LINKING_ENABLED:
- setLinkingEnabled(event.getSource().isLinkingEnabled());
- break;
- case StateChangedEvent.ALPHA_SORTED:
- setAlphaSorted(event.getSource().isAlphaSorted());
- break;
- case StateChangedEvent.CONTENT_EXTENSIONS:
- if (contentUpdate == null) {
- getCommonViewer().getControl().getDisplay().asyncExec(getContentUpdate());
- }
- break;
- }
- }
-
- private Runnable getContentUpdate() {
- if (contentUpdate == null) {
- contentUpdate = new Runnable() {
-
- public void run() {
- CommonViewer viewer = getCommonViewer();
- if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) {
- viewer.getNavigatorContentService().getActivationService().activateExtensions(sharedState.getNavigatorContentExtensions(), true);
- }
-
- // I am no longer pending
- contentUpdate = null;
- }
- };
- }
- return contentUpdate;
- }
- };
- }
-
- return sharedStateListener;
- }
+/***************************************************************************** + * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * Christian W. Damus (CEA) - post refreshes for transaction commit asynchronously (CDO) + * Christian W. Damus (CEA) - bug 429826 + * Christian W. Damus (CEA) - bug 434635 + * Christian W. Damus (CEA) - bug 437217 + * Christian W. Damus (CEA) - bug 441857 + * Christian W. Damus - bug 450235 + * Christian W. Damus - bug 451683 + * + *****************************************************************************/ +package org.eclipse.papyrus.views.modelexplorer; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.core.commands.operations.IUndoContext; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.domain.IEditingDomainProvider; +import org.eclipse.emf.transaction.ResourceSetChangeEvent; +import org.eclipse.emf.transaction.ResourceSetListener; +import org.eclipse.emf.transaction.ResourceSetListenerImpl; +import org.eclipse.emf.transaction.Transaction; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.jface.util.Policy; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerColumn; +import org.eclipse.jface.window.ToolTip; +import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor; +import org.eclipse.papyrus.infra.core.editor.IReloadableEditor; +import org.eclipse.papyrus.infra.core.editor.reload.EditorReloadAdapter; +import org.eclipse.papyrus.infra.core.editor.reload.EditorReloadEvent; +import org.eclipse.papyrus.infra.core.editor.reload.TreeViewerContext; +import org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener; +import org.eclipse.papyrus.infra.core.lifecycleevents.ISaveAndDirtyService; +import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2; +import org.eclipse.papyrus.infra.core.resource.IReadOnlyListener; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.resource.ReadOnlyEvent; +import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel; +import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager; +import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage; +import org.eclipse.papyrus.infra.core.sasheditor.editor.IPageLifeCycleEventsListener; +import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AdapterUtils; +import org.eclipse.papyrus.infra.core.utils.ServiceUtils; +import org.eclipse.papyrus.infra.emf.providers.SemanticFromModelExplorer; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; +import org.eclipse.papyrus.infra.services.navigation.service.NavigableElement; +import org.eclipse.papyrus.infra.services.navigation.service.NavigationMenu; +import org.eclipse.papyrus.infra.services.navigation.service.NavigationService; +import org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement; +import org.eclipse.papyrus.views.modelexplorer.SharedModelExplorerState.StateChangedEvent; +import org.eclipse.papyrus.views.modelexplorer.listener.DoubleClickListener; +import org.eclipse.papyrus.views.modelexplorer.matching.IMatchingItem; +import org.eclipse.papyrus.views.modelexplorer.matching.LinkItemMatchingItem; +import org.eclipse.papyrus.views.modelexplorer.matching.ModelElementItemMatchingItem; +import org.eclipse.papyrus.views.modelexplorer.matching.ReferencableMatchingItem; +import org.eclipse.swt.SWT; +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.events.MouseMoveListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +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.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.ISaveablePart; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.navigator.CommonNavigator; +import org.eclipse.ui.navigator.CommonViewer; +import org.eclipse.ui.navigator.CommonViewerSorter; +import org.eclipse.ui.navigator.IExtensionActivationListener; +import org.eclipse.ui.navigator.ILinkHelper; +import org.eclipse.ui.navigator.INavigatorContentService; +import org.eclipse.ui.navigator.LinkHelperService; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.views.properties.IPropertySheetPage; +import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor; +import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +/** + * Papyrus Model Explorer associated to one {@link IMultiDiagramEditor}. + * This ModelExplorer is linked to one single {@link IMultiDiagramEditor}. It doesn't change its + * source when the current Editor change. To allow to explore different Model, use a {@link ModelExplorerPageBookView}. + * + */ +public class ModelExplorerView extends CommonNavigator implements IRevealSemanticElement, IEditingDomainProvider, IPageLifeCycleEventsListener { + + private SharedModelExplorerState sharedState; + + private SharedModelExplorerState.StateChangedListener sharedStateListener; + + /** + * The context of the LabelProviderService used by this view + * + * @see {@link LabelProviderService} + */ + public static final String LABEL_PROVIDER_SERVICE_CONTEXT = "org.eclipse.papyrus.views.modelexplorer.labelProvider.context"; + + /** + * The {@link ServicesRegistry} associated to the Editor. This view is associated to the + * ServicesRegistry rather than to the EditorPart. + */ + private ServicesRegistry serviceRegistry; + + /** The save aservice associated to the editor. */ + private ISaveAndDirtyService saveAndDirtyService; + + /** {@link IUndoContext} used to tag command in the commandStack. */ + private IUndoContext undoContext; + + /** editing domain used to read/write the model */ + private TransactionalEditingDomain editingDomain; + + /** Flag to avoid reentrant call to refresh. */ + private AtomicBoolean isRefreshing = new AtomicBoolean(false); + + /** Currently selected tree item */ + private TreeItem currentItem; + + /** Navigation menu for selected tree item */ + private NavigationMenu navigationMenu; + + /** + * A listener on page (all editors) selection change. This listener is set + * in {@link ModelExplorerView#init(IViewSite)}. It should be dispose to remove + * hook to the Eclipse page. + */ + private ISelectionListener pageSelectionListener = new ISelectionListener() { + + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + handleSelectionChangedFromDiagramEditor(part, selection); + } + }; + + /** + * Listener on {@link ISaveAndDirtyService#addInputChangedListener(IEditorInputChangedListener)} + */ + protected IEditorInputChangedListener editorInputChangedListener = new IEditorInputChangedListener() { + + /** + * This method is called when the editor input is changed from the ISaveAndDirtyService. + * + * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#editorInputChanged(org.eclipse.ui.part.FileEditorInput) + * + * @param fileEditorInput + */ + public void editorInputChanged(FileEditorInput fileEditorInput) { + // Change the editor input. + setPartName(fileEditorInput.getName()); + } + + /** + * The isDirty flag has changed, reflect its new value + * + * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#isDirtyChanged() + * + */ + public void isDirtyChanged() { + firePropertyChange(IEditorPart.PROP_DIRTY); + } + }; + + /** The {@link IPropertySheetPage} this model explorer will use. */ + private final List<IPropertySheetPage> propertySheetPages = new LinkedList<IPropertySheetPage>(); + + /** + * + * Constructor. + * + * @param part + * The part associated to this ModelExplorer + */ + public ModelExplorerView(IMultiDiagramEditor part) { + + if (part == null) { + throw new IllegalArgumentException("A part should be provided."); + } + + init(part); + + IReloadableEditor.Adapter.getAdapter(part).addEditorReloadListener(new EditorReloadAdapter() { + + @Override + public void editorAboutToReload(EditorReloadEvent event) { + // Stash expansion and selection state of the common viewer + event.putContext(new ModelExplorerTreeViewerContext(getCommonViewer())); + + deactivate(); + } + + @Override + public void editorReloaded(EditorReloadEvent event) { + init(event.getEditor()); + + activate(); + + initCommonViewer(getCommonViewer()); + + // Restore expansion and selection state of the common viewer + ((TreeViewerContext<?>) event.getContext()).restore(getCommonViewer()); + } + }); + } + + private void init(IMultiDiagramEditor editor) { + // Try to get the ServicesRegistry + serviceRegistry = editor.getServicesRegistry(); + if (serviceRegistry == null) { + throw new IllegalArgumentException("The editor should have a ServiceRegistry."); + } + + // Get required services from ServicesRegistry + try { + saveAndDirtyService = serviceRegistry.getService(ISaveAndDirtyService.class); + undoContext = serviceRegistry.getService(IUndoContext.class); + } catch (ServiceException e) { + Activator.log.error(e); + } + } + + /** + * Handle a selection change in the editor. + * + * @param part + * @param selection + */ + private void handleSelectionChangedFromDiagramEditor(IWorkbenchPart part, ISelection selection) { + // Handle selection from diagram editor + if (isLinkingEnabled()) { + if (part instanceof IEditorPart) { + if (selection instanceof IStructuredSelection) { + Iterator<?> selectionIterator = ((IStructuredSelection) selection).iterator(); + ArrayList<Object> semanticElementList = new ArrayList<Object>(); + while (selectionIterator.hasNext()) { + Object currentSelection = selectionIterator.next(); + Object semanticElement = EMFHelper.getEObject(currentSelection); + if (semanticElement != null) { + semanticElementList.add(semanticElement); + } + + } + revealSemanticElement(semanticElementList); + + } + + } + + // Selections from the Model Explorer result in a part from the ModelExplorerPageBookView instance which is not an IEditorPart + if (part instanceof ModelExplorerPageBookView && !selection.isEmpty()) { + if (selection instanceof IStructuredSelection) { + // Extracted from org.eclipse.ui.internal.navigator.actions.LinkEditorAction activateEditorJob + // the problem was that multi-element selections were disabled as only selections of 1 could clear the condition size()==1 + IStructuredSelection sSelection = (IStructuredSelection) selection; + LinkHelperService linkService = getLinkHelperService(); + ILinkHelper[] helpers = linkService.getLinkHelpersFor(sSelection.getFirstElement()); // LinkHelper in org.eclipse.papyrus.views.modelexplorer + if (helpers.length > 0) { + helpers[0].activateEditor(part.getSite().getPage(), sSelection); + } + } + } + } + } + + /** + * look for the path the list of element (comes from the content provider) to go the eObject + * + * @param eobject + * that we look for. + * @param objects + * a list of elements where eobject can be wrapped. + * @return the list of modelElementItem ( from the root to the element that wrap the eobject) + */ + protected List<Object> searchPath(EObject eobject, List<Object> objects) { + SemanticFromModelExplorer semanticGetter = new SemanticFromModelExplorer(); + List<Object> path = new ArrayList<Object>(); + ITreeContentProvider contentProvider = (ITreeContentProvider) getCommonViewer().getContentProvider(); + // IPageMngr iPageMngr = EditorUtils.getIPageMngr(); + IPageManager iPageMngr; + try { + iPageMngr = ServiceUtils.getInstance().getIPageManager(serviceRegistry); + } catch (ServiceException e) { + // This shouldn't happen. + return Collections.emptyList(); + } + Object[] result = iPageMngr.allPages().toArray(); + List<Object> editors = Arrays.asList(result); + + + for (Object o : objects) { + // Search matches in this level + if (!editors.contains(o)) { + if (eobject.equals(EMFHelper.getEObject(o))) { + path.add(o); + return path; + } + } + + // Find childs only for feature container + for (int i = 0; i < contentProvider.getChildren(o).length; i++) { + Object treeItem = contentProvider.getChildren(o)[i]; + + List<Object> tmppath = new ArrayList<Object>(); + Object element = semanticGetter.getSemanticElement(treeItem); + if (element != null) { + if (element instanceof EReference) { + if (((EReference) element).isContainment() && (!((EReference) element).isDerived())) { + List<Object> childs = new ArrayList<Object>(); + childs.add(treeItem); + tmppath = searchPath(eobject, childs); + } + } + + else { + if (element instanceof EObject) { + List<Object> childs = new ArrayList<Object>(); + childs.add(treeItem); + tmppath = searchPath(eobject, childs); + } + } + } + + // if tmppath contains the wrapped eobject we have find the good path + if (tmppath.size() > 0) { + if (eobject.equals((EMFHelper.getEObject((tmppath.get(tmppath.size() - 1)))))) { + path.add(o); + path.addAll(tmppath); + return path; + } + } + } + } + + return new ArrayList<Object>(); + } + + + /** + * {@inheritDoc} + */ + // FIXME Use of internal class (NavigatorContentService) - in the hope that the bug gets fixed soon. + @Override + protected CommonViewer createCommonViewerObject(Composite aParent) { + CommonViewer viewer = new CustomCommonViewer(getViewSite().getId(), aParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + + initCommonViewer(viewer); + + viewer.getNavigatorContentService().getActivationService().addExtensionActivationListener(new IExtensionActivationListener() { + + public void onExtensionActivation(String aViewerId, String[] theNavigatorExtensionIds, boolean isActive) { + sharedState.updateNavigatorContentExtensions(theNavigatorExtensionIds, isActive); + } + }); + + ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE); + + return viewer; + } + + private void installEMFFacetTreePainter(Tree tree) { + // Install the EMFFacet Custom Tree Painter + // org.eclipse.papyrus.infra.emf.Activator.getDefault().getCustomizationManager().installCustomPainter(tree); + + // The EMF Facet MeasureItem Listener is incompatible with the NavigatorDecoratingLabelProvider. Remove it. + // Symptoms: ModelElementItems with an EMF Facet Overlay have a small selection size + // Removal also fixes bug 400012: no scrollbar although tree is larger than visible area + Collection<Listener> listenersToRemove = new LinkedList<Listener>(); + for (Listener listener : tree.getListeners(SWT.MeasureItem)) { + if (listener.getClass().getName().contains("org.eclipse.papyrus.emf.facet.infra.browser.uicore.internal.CustomTreePainter")) { + listenersToRemove.add(listener); + } + } + + for (Listener listener : listenersToRemove) { + tree.removeListener(SWT.MeasureItem, listener); + } + } + + private void initCommonViewer(CommonViewer viewer) { + // enable tool-tips + // workaround for bug 311827: the Common Viewer always uses NavigatorDecoratingLabelProvider + // as a wrapper for the LabelProvider provided by the application. The NavigatorDecoratingLabelProvider + // does not delegate tooltip related functions but defines them as empty. + + Object input = getInitialInput(); + ILabelProvider labelProvider = null; + + if (input instanceof ServicesRegistry) { + ServicesRegistry registry = (ServicesRegistry) input; + try { + labelProvider = registry.getService(LabelProviderService.class).getLabelProvider(LABEL_PROVIDER_SERVICE_CONTEXT); + } catch (ServiceException ex) { + Activator.log.error(ex); + } + + labelProvider = new DecoratingLabelProviderWTooltips(labelProvider, (ServicesRegistry) input); + } + + if (labelProvider == null) { + labelProvider = new LabelProvider(); + } + + viewer.setLabelProvider(labelProvider); // add for decorator and tooltip support + } + + @Override + public void createPartControl(Composite aParent) { + super.createPartControl(aParent); + + getCommonViewer().setSorter(null); + ((CustomCommonViewer) getCommonViewer()).getDropAdapter().setFeedbackEnabled(true); + getCommonViewer().addDoubleClickListener(new DoubleClickListener(new Supplier<ServicesRegistry>() { + public ServicesRegistry get() { + return serviceRegistry; + } + })); + + try { + navigationMenu = serviceRegistry.getService(NavigationService.class).createNavigationList(); + if (navigationMenu != null) { + navigationMenu.setServicesRegistry(serviceRegistry); + navigationMenu.setParentShell(this.getControl().getShell()); + } + } catch (ServiceException e) { + Activator.log.error(e); + } + + Tree tree = getCommonViewer().getTree(); + + tree.addKeyListener(new KeyListener() { + + public void keyReleased(KeyEvent e) { + if (navigationMenu != null) { + if (e.keyCode == SWT.ALT) { + navigationMenu.exitItem(); + } + } + } + + public void keyPressed(KeyEvent e) { + if (e.keyCode != SWT.ALT) { + return; + } + + if (navigationMenu != null) { + Tree tree = getCommonViewer().getTree(); + + // Generate a basic mouse event + Event event = new Event(); + event.widget = tree; + event.stateMask = SWT.ALT; + + Point absoluteTreeLocation = tree.toDisplay(new Point(0, 0)); + + event.x = tree.getDisplay().getCursorLocation().x - absoluteTreeLocation.x; + event.y = tree.getDisplay().getCursorLocation().y - absoluteTreeLocation.y; + + MouseEvent mouseEvent = new MouseEvent(event); + navigationMenu.handleRequest(mouseEvent, getTreeItem(mouseEvent)); + } + } + }); + + tree.addMouseListener(new MouseAdapter() { + + @Override + public void mouseUp(MouseEvent e) { + if ((e.stateMask & SWT.ALT) == 0) { + return; + } + + TreeItem currentItem = getTreeItem(e); + if (currentItem != null) { + Object data = currentItem.getData(); + try { + NavigationService service = serviceRegistry.getService(NavigationService.class); + List<NavigableElement> navigableElements = service.getNavigableElements(data); + + // TODO: Implement a priority on NavigableElements and navigate the element with the highest priority + for (NavigableElement navigableElement : navigableElements) { + if (navigableElement.isEnabled()) { + service.navigate(navigableElement); + } + } + } catch (ServiceException ex) { + Activator.log.error(ex); + } + } + } + }); + + tree.addMouseMoveListener(new MouseMoveListener() { + + public void mouseMove(MouseEvent e) { + if (navigationMenu != null) { + navigationMenu.handleRequest(e, getTreeItem(e)); + } + } + + }); + + installEMFFacetTreePainter(tree); + try { + ISashWindowsContainer sashWindowsContainer = serviceRegistry.getService(ISashWindowsContainer.class); + sashWindowsContainer.addPageLifeCycleListener(this); + } catch (ServiceException ex) { + // Ignore + } + + if (sharedState != null) { + initSharedState(sharedState); + } + } + + @Override + protected CommonViewer createCommonViewer(Composite aParent) { + CommonViewer viewer = super.createCommonViewer(aParent); + ViewerColumn column = (ViewerColumn) viewer.getTree().getData(Policy.JFACE + ".columnViewer"); + column.setEditingSupport(new DirectEditorEditingSupport(viewer)); + return viewer; + } + + private TreeItem getTreeItem(MouseEvent e) { + return ((Tree) e.widget).getItem(new Point(e.x, e.y)); + } + + + /** + * Return the control used to render this View + * + * @see org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.IPageBookNestableViewPart#getControl() + * + * @return the main control of the navigator viewer + */ + public Control getControl() { + return getCommonViewer().getControl(); + } + + /** + * {@inheritDoc} + */ + @Override + public void init(IViewSite site, IMemento aMemento) throws PartInitException { + super.init(site, aMemento); + + activate(); + + // Self-listen for property changes + addPropertyListener(new IPropertyListener() { + + public void propertyChanged(Object source, int propId) { + switch (propId) { + case IS_LINKING_ENABLED_PROPERTY: + // Propagate to other instances + sharedState.setLinkingEnabled(isLinkingEnabled()); + break; + } + } + }); + } + + /** + * {@link ResourceSetListener} to listen and react to changes in the + * resource set. + */ + private final ResourceSetListener resourceSetListener = new ResourceSetListenerImpl() { + + /** + * {@inheritDoc} + */ + @Override + public void resourceSetChanged(ResourceSetChangeEvent event) { + super.resourceSetChanged(event); + handleResourceSetChanged(event); + } + }; + + /** cache variable with last transaction which triggered a refresh */ + private Transaction lastTrans = null; + + /** + * Run in a UI thread to avoid non UI thread exception. + * + * @param event + */ + private void handleResourceSetChanged(ResourceSetChangeEvent event) { + // avoid refreshing N times for the same transaction (called for each object in resource) + Transaction curTrans = event.getTransaction(); + if (lastTrans != null && lastTrans.equals(curTrans)) { + return; + } + lastTrans = curTrans; + + scheduleRefresh(); + } + + private Runnable refreshRunnable; + + /** + * Thread-safe + * Schedule a runnable which will refresh the view if necessary + */ + protected void scheduleRefresh() { + final Runnable schedule; + + synchronized (this) { + if (refreshRunnable == null) { + // No refresh is yet pending. Schedule one + schedule = createRefreshRunnable(); + refreshRunnable = schedule; + } else { + schedule = null; + } + } + + if (schedule != null) { + Control control = getControl(); + Display display = ((control == null) || control.isDisposed()) ? null : control.getDisplay(); + + if (display != null) { + // Don't need to schedule a refresh if we have no control or it's disposed + display.asyncExec(schedule); + } + } + } + + private Runnable createRefreshRunnable() { + return new Runnable() { + + public void run() { + // Only run if I'm still pending + synchronized (ModelExplorerView.this) { + if (refreshRunnable != this) { + return; + } + + refreshRunnable = null; + } + + refreshInUIThread(); + } + }; + } + + /** + * Thread-safe method to hurry up a pending refresh of the Model Explorer view (if any), synchronously. + * When this method returns, then either the explorer has been refreshed or it doesn't need to be. + */ + protected void syncRefresh() { + final Runnable pending; + + synchronized (this) { + pending = refreshRunnable; + } + + if (pending != null) { + Control control = getControl(); + Display display = ((control == null) || control.isDisposed()) ? null : control.getDisplay(); + + if (display != null) { + // Don't need to execute a refresh if we have no control or it's disposed + display.syncExec(pending); + } + } + } + + /** + * refresh the view. + */ + protected void refreshInUIThread() { + // Need to refresh, even if (temporarily) invisible + // (Better alternative?: store refresh event and execute once visible again) + if (getControl().isDisposed()) { + return; + } + + // avoid reentrant call + // Refresh only of we are not already refreshing. + if (isRefreshing.compareAndSet(false, true)) { + if (!getCommonViewer().isBusy()) { + getCommonViewer().refresh(); + } + + isRefreshing.set(false); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected Object getInitialInput() { + + if (serviceRegistry != null) { + return serviceRegistry; + } else { + return super.getInitialInput(); + } + + } + + /** + * Activate specified Part. + */ + private void activate() { + try { + this.editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry); + + // Set Viewer input if it already exist + if (getCommonViewer() != null) { + getCommonViewer().setInput(serviceRegistry); + } + editingDomain.addResourceSetListener(resourceSetListener); + IReadOnlyHandler2 readOnlyHandler = AdapterUtils.adapt(editingDomain, IReadOnlyHandler2.class, null); + if (readOnlyHandler != null) { + readOnlyHandler.addReadOnlyListener(createReadOnlyListener()); + } + } catch (ServiceException e) { + // Can't get EditingDomain, skip + } + + // listen to change events + getSite().getPage().addSelectionListener(pageSelectionListener); + + // Listen to isDirty flag + saveAndDirtyService.addInputChangedListener(editorInputChangedListener); + + if (this.getCommonViewer() != null) { + // Force a refresh + Display display = getControl().getDisplay(); + if (display == Display.getCurrent()) { + refreshInUIThread(); + } else { + // Hmm. We should be on the UI thread + Activator.log.warn("Model Explorer activated on a non-UI thread."); //$NON-NLS-1$ + scheduleRefresh(); + } + } + } + + /** + * Deactivate the Model Explorer. + */ + private void deactivate() { + // deactivate global handler + if (Activator.log.isDebugEnabled()) { + Activator.log.debug("deactivate ModelExplorerView"); //$NON-NLS-1$ + } + + try { + ISashWindowsContainer sashWindowsContainer = serviceRegistry.getService(ISashWindowsContainer.class); + if (sashWindowsContainer != null) { + sashWindowsContainer.removePageLifeCycleListener(this); + } + } catch (ServiceException ex) { + // Ignore + } + + // Stop listening on change events + getSite().getPage().removeSelectionListener(pageSelectionListener); + // Stop Listening to isDirty flag + saveAndDirtyService.removeInputChangedListener(editorInputChangedListener); + + if (editingDomain != null) { + editingDomain.removeResourceSetListener(resourceSetListener); + editingDomain = null; + } + + saveAndDirtyService = null; + undoContext = null; + editingDomain = null; + editingDomain = null; + lastTrans = null; + } + + /** + * Invoked internally to clear the common viewer's associate listener in order to promote garbage collection. + */ + void aboutToDispose() { + final CommonViewer viewer = getCommonViewer(); + if ((viewer.getTree() != null) && !viewer.getTree().isDisposed()) { + viewer.setInput(null); + + // Kick the NavigatorContentService to clear the cache in its StructuredViewerManager that leaks all of our tree elements + INavigatorContentService contentService = getNavigatorContentService(); + if (contentService instanceof IExtensionActivationListener) { + ((IExtensionActivationListener) getNavigatorContentService()).onExtensionActivation(contentService.getViewerId(), new String[0], false); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void dispose() { + + // Stop if we are already disposed + if (isDisposed()) { + return; + } + + if ((sharedStateListener != null) && (sharedState != null)) { + sharedState.removeListener(sharedStateListener); + } + + if (getSite() != null) { + getSite().getPage().removeSelectionListener(pageSelectionListener); + } + + deactivate(); + + for (IPropertySheetPage propertySheetPage : this.propertySheetPages) { + propertySheetPage.dispose(); + } + + propertySheetPages.clear(); + + pageSelectionListener = null; + + super.dispose(); + + // Clean up properties to help GC + + } + + /** + * Return true if the component is already disposed. + * + * @return + */ + public boolean isDisposed() { + // use editorPart as flag + return saveAndDirtyService == null; + } + + /** + * Retrieves the {@link IPropertySheetPage} that his Model Explorer uses. + * + * @return + */ + private IPropertySheetPage getPropertySheetPage() { + try { + final IMultiDiagramEditor multiDiagramEditor = ServiceUtils.getInstance().getService(IMultiDiagramEditor.class, serviceRegistry); + + if (multiDiagramEditor != null) { + if (multiDiagramEditor instanceof ITabbedPropertySheetPageContributor) { + ITabbedPropertySheetPageContributor contributor = (ITabbedPropertySheetPageContributor) multiDiagramEditor; + IPropertySheetPage propertySheetPage = new TabbedPropertySheetPage(contributor); + this.propertySheetPages.add(propertySheetPage); + return propertySheetPage; + } + } + } catch (ServiceException ex) { + Activator.log.error(ex); + } + return null; + } + + /** + * in order to see element if the property view + */ + @Override + @SuppressWarnings("rawtypes") + public Object getAdapter(Class adapter) { + if (IPropertySheetPage.class.equals(adapter)) { + return getPropertySheetPage(); + } + + if (IUndoContext.class == adapter) { + // Return the IUndoContext of associated model. + return undoContext; + } + + if (ISaveablePart.class.equals(adapter)) { + try { + return serviceRegistry.getService(IMultiDiagramEditor.class); + } catch (ServiceException ex) { + Activator.log.error(ex); + } + return saveAndDirtyService; + } + + if (ServicesRegistry.class == adapter) { + return serviceRegistry; + } + + return super.getAdapter(adapter); + } + + /** + * {@inheritDoc} + * + * @return the EditingDomain used by the properties view + */ + public EditingDomain getEditingDomain() { + return editingDomain; + } + + /** + * {@inheritDoc} + */ + @Override + public void selectReveal(ISelection selection) { + syncRefresh(); + if (getCommonViewer() != null) { + getCommonViewer().setSelection(selection, true); + } + } + + public void revealSemanticElement(List<?> elementList) { + // Ensure that the ModelExplorer is refreshed before + // trying to display an element. Useful if the element has just been created, + // and the model explorer has not yet been refreshed + syncRefresh(); + reveal(elementList, getCommonViewer()); + } + + /** + * Expands the given CommonViewer to reveal the given elements + * + * @param elementList + * The elements to reveal + * @param commonViewer + * The CommonViewer they are to be revealed in + */ + public static void reveal(Iterable<?> elementList, final CommonViewer commonViewer) { + ArrayList<IMatchingItem> matchingItemsToSelect = new ArrayList<IMatchingItem>(); + // filter out non EMF objects + Iterable<EObject> list = Iterables.filter(elementList, EObject.class); + + for (EObject currentEObject : list) { + matchingItemsToSelect.add(new ModelElementItemMatchingItem(currentEObject)); + + // the content provider exist? + if (commonViewer.getContentProvider() != null) { + // retrieve the ancestors to reveal them + // and allow the selection of the object + ArrayList<EObject> parents = new ArrayList<EObject>(); + EObject tmp = currentEObject.eContainer(); + while (tmp != null) { + parents.add(tmp); + tmp = tmp.eContainer(); + } + + Iterable<EObject> reverseParents = Lists.reverse(parents); + + // reveal the resource if necessary + Resource r = null; + if (!parents.isEmpty()) { + r = parents.get(parents.size() - 1).eResource(); + } else { + r = currentEObject.eResource(); + } + + if (r != null) { + final ResourceSet rs = r.getResourceSet(); + final Resource resource = r; + if (rs instanceof ModelSet && AdditionalResourcesModel.isAdditionalResource((ModelSet) rs, r.getURI())) { + commonViewer.getControl().getDisplay().syncExec(new Runnable() { + + public void run() { + commonViewer.expandToLevel(new ReferencableMatchingItem(rs), 1); + commonViewer.expandToLevel(new ReferencableMatchingItem(resource), 1); + } + }); + + } + } + + /* + * reveal the ancestors tree using expandToLevel on each of them + * in the good order. This is a lot faster than going through the whole tree + * using getChildren of the ContentProvider since our Viewer uses a Hashtable + * to keep track of the revealed elements. + * + * However we need to use a dedicated MatchingItem to do the matching, + * and a specific comparer in our viewer so than the equals of MatchingItem is + * used in priority. + * + * Please refer to MatchingItem for more infos. + */ + EObject previousParent = null; + for (EObject parent : reverseParents) { + if (parent.eContainingFeature() != null && previousParent != null) { + commonViewer.expandToLevel(new LinkItemMatchingItem(previousParent, parent.eContainmentFeature()), 1); + } + + final IMatchingItem itemToExpand = new ModelElementItemMatchingItem(parent); + + commonViewer.getControl().getDisplay().syncExec(new Runnable() { + + public void run() { + commonViewer.expandToLevel(itemToExpand, 1); + } + }); + + previousParent = parent; + } + + final IMatchingItem itemToExpand = new LinkItemMatchingItem(currentEObject.eContainer(), currentEObject.eContainmentFeature()); + + commonViewer.getControl().getDisplay().syncExec(new Runnable() { + + public void run() { + commonViewer.expandToLevel(itemToExpand, 1); + } + }); + } + } + + selectReveal(new StructuredSelection(matchingItemsToSelect), commonViewer); + } + + /** + * Selects the given ISelection in the given CommonViwer + * + * @param structuredSelection + * The ISelection to select + * @param commonViewer + * The ComonViewer to select it in + */ + public static void selectReveal(final ISelection structuredSelection, final Viewer commonViewer) { + Display.getDefault().syncExec(new Runnable() { + + public void run() { + commonViewer.setSelection(structuredSelection, true); + } + }); + } + + /** + * Selects and, if possible, reveals the given ISelection in the given CommonViwer + * + * @param selection + * The ISelection to select + * @param viewer + * The ComonViewer to select it in + */ + public static void reveal(final ISelection selection, final CommonViewer viewer) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection structured = (IStructuredSelection) selection; + reveal(Lists.newArrayList(structured.iterator()), viewer); + } else { + viewer.getControl().getDisplay().syncExec(new Runnable() { + + public void run() { + viewer.setSelection(selection); + } + }); + } + } + + public void pageOpened(IPage page) { + refreshTree(); + } + + public void pageClosed(IPage page) { + refreshTree(); + } + + private void refreshTree() { + Display.getDefault().asyncExec(new Runnable() { + + public void run() { + if (getCommonViewer().getControl() == null || getCommonViewer().getControl().isDisposed()) { + return; + } + getCommonViewer().refresh(true); + // Force redraw to refresh facet overlay + getCommonViewer().getTree().redraw(); + } + }); + } + + public void pageChanged(IPage newPage) { + // Nothing + } + + public void pageActivated(IPage page) { + // Nothing + } + + public void pageDeactivated(IPage page) { + // Nothing + } + + public void pageAboutToBeOpened(IPage page) { + // Nothing + } + + public void pageAboutToBeClosed(IPage page) { + // Nothing + } + + private IReadOnlyListener createReadOnlyListener() { + return new IReadOnlyListener() { + + public void readOnlyStateChanged(ReadOnlyEvent event) { + switch (event.getEventType()) { + case ReadOnlyEvent.RESOURCE_READ_ONLY_STATE_CHANGED: + scheduleRefresh(); + break; + case ReadOnlyEvent.OBJECT_READ_ONLY_STATE_CHANGED: + CommonViewer viewer = getCommonViewer(); + if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) { + viewer.refresh(event.getObject()); + } + break; + default: + Activator.log.warn("Unsupported read-only event type: " + event.getEventType()); + break; + } + } + }; + } + + void setSharedState(SharedModelExplorerState state) { + if (this.sharedState != null) { + this.sharedState.removeListener(getSharedStateListener()); + } + + this.sharedState = state; + + if (state != null) { + state.addListener(getSharedStateListener()); + initSharedState(state); + } + } + + void initSharedState(SharedModelExplorerState state) { + setLinkingEnabled(state.isLinkingEnabled()); + setAlphaSorted(state.isAlphaSorted()); + } + + void setAlphaSorted(boolean sorted) { + CommonViewer viewer = getCommonViewer(); + if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) { + if (sorted) { + viewer.setSorter(new CommonViewerSorter()); + if (viewer instanceof CustomCommonViewer) { + ((CustomCommonViewer) viewer).getDropAdapter().setFeedbackEnabled(false); + } + } else { + viewer.setSorter(null); + if (viewer instanceof CustomCommonViewer) { + ((CustomCommonViewer) viewer).getDropAdapter().setFeedbackEnabled(true); + } + } + } + } + + SharedModelExplorerState.StateChangedListener getSharedStateListener() { + if (sharedStateListener == null) { + sharedStateListener = new SharedModelExplorerState.StateChangedListener() { + + private volatile Runnable contentUpdate; + + public void sharedStateChanged(StateChangedEvent event) { + switch (event.getEventType()) { + case StateChangedEvent.LINKING_ENABLED: + setLinkingEnabled(event.getSource().isLinkingEnabled()); + break; + case StateChangedEvent.ALPHA_SORTED: + setAlphaSorted(event.getSource().isAlphaSorted()); + break; + case StateChangedEvent.CONTENT_EXTENSIONS: + if (contentUpdate == null) { + getCommonViewer().getControl().getDisplay().asyncExec(getContentUpdate()); + } + break; + } + } + + private Runnable getContentUpdate() { + if (contentUpdate == null) { + contentUpdate = new Runnable() { + + public void run() { + CommonViewer viewer = getCommonViewer(); + if ((viewer != null) && (viewer.getControl() != null) && !viewer.getControl().isDisposed()) { + viewer.getNavigatorContentService().getActivationService().activateExtensions(sharedState.getNavigatorContentExtensions(), true); + } + + // I am no longer pending + contentUpdate = null; + } + }; + } + return contentUpdate; + } + }; + } + + return sharedStateListener; + } }
\ No newline at end of file diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/NavigatorUtils.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/NavigatorUtils.java index b63b4abf38b..9f1257e2ed0 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/NavigatorUtils.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/NavigatorUtils.java @@ -486,10 +486,10 @@ public class NavigatorUtils { T result = null; if (o instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) o; - result = (T) adaptable.getAdapter(theClass); + result = adaptable.getAdapter(theClass); } if (result == null) { - result = (T) Platform.getAdapterManager().getAdapter(o, theClass); + result = Platform.getAdapterManager().getAdapter(o, theClass); } if (result == null && theClass.isInstance(o)) { result = (T) o; diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actionprovider/UndoRedoActionProvider.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actionprovider/UndoRedoActionProvider.java index b968376d08a..a470fd159aa 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actionprovider/UndoRedoActionProvider.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actionprovider/UndoRedoActionProvider.java @@ -1,6 +1,6 @@ /***************************************************************************** * Copyright (c) 2014 CEA LIST, Christian W. Damus, and others. - * + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,7 @@ * Contributors: * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation * Christian W. Damus - bug 450536 - * + * *****************************************************************************/ package org.eclipse.papyrus.views.modelexplorer.actionprovider; @@ -34,7 +34,7 @@ import org.eclipse.ui.operations.UndoActionHandler; /** * Action Provider to provide Redo/Undo action trough workbench menu. - * + * * @author Gabriel Pascual * */ @@ -122,7 +122,7 @@ public class UndoRedoActionProvider extends AbstractCommonActionProvider impleme * <p> * Synchronise handlers after a Command stack's change. * </p> - * + * * @see org.eclipse.emf.common.command.CommandStackListener#commandStackChanged(java.util.EventObject) * * @param event diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actions/GenericTransformer.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actions/GenericTransformer.java index 830db10e477..1265300a6e4 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actions/GenericTransformer.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/actions/GenericTransformer.java @@ -1,443 +1,443 @@ -/***************************************************
- * Copyright (c) 2010 Atos Origin.
-
- *
- * 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:
- * Atos Origin - Initial API and implementation
- *
- ****************************************************/
-package org.eclipse.papyrus.views.modelexplorer.actions;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
-import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gef.commands.CommandStack;
-import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
-import org.eclipse.gef.requests.GroupRequest;
-import org.eclipse.gmf.runtime.common.core.command.CommandResult;
-import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
-import org.eclipse.gmf.runtime.common.ui.services.editor.EditorService;
-import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewRefactorHelper;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
-import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain;
-import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
-import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
-import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest;
-import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
-import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.Edge;
-import org.eclipse.gmf.runtime.notation.LayoutConstraint;
-import org.eclipse.gmf.runtime.notation.Location;
-import org.eclipse.gmf.runtime.notation.Node;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
-import org.eclipse.papyrus.views.modelexplorer.Activator;
-import org.eclipse.papyrus.views.modelexplorer.commands.EObjectInheritanceCopyCommand;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * The Class GenericTransformer. Permits to transform an eobject of eclass to
- * another eclass
- */
-public class GenericTransformer {
-
- /** The factories to create eObjects */
- private static HashMap<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>();
-
- /** extension to recover factories */
- private static final String EXT_FACTORIES = "org.eclipse.emf.edit.itemProviderAdapterFactories";
-
- /** title of the warning dialog */
- private static final String WARNING_TITLE = "Problems during transformation";
-
- /** message of the warning dialog */
- private static final String WARNING_MSG = "It seems the transformation you want to perform can't be executed";
-
- /** command to execute the whole transformation */
- private CompositeCommand globalCommand;
-
- /** element to transform */
- private EObject element;
-
- /** views referencing the element */
- private Set<View> referencingViews = new HashSet<View>();
-
- /** command to execute the model transformation */
- private EObjectInheritanceCopyCommand commandModel;
-
- /** whether the graphical edit parts must also be transformed */
- private boolean graphCopy = true;
-
- /** the command to import new graphical edit parts */
- private ImporterCommand importerCommand;
-
- /**
- * Instantiates a new generic transformer.
- *
- * @param currentNode
- * the current node
- */
- public GenericTransformer(AbstractGraphicalEditPart currentNode) {
- this(currentNode, true);
- }
-
- /**
- * Instantiates a new generic transformer. and specify if we have to perform
- * graphical copy
- *
- * @param currentNode
- * the current node
- * @param graphCopy
- * the graph copy
- */
- public GenericTransformer(AbstractGraphicalEditPart currentNode, boolean graphCopy) {
- this.graphCopy = graphCopy;
- if (currentNode != null) {
- Object model = currentNode.getModel();
- if (model instanceof View) {
- this.element = ((View) model).getElement();
- }
- }
- }
-
- /**
- * Instantiates a new generic transformer.
- *
- * @param currentEobject
- * the current eobject
- */
- public GenericTransformer(EObject currentEobject) {
- this.element = currentEobject;
- }
-
- /**
- * Transform the element to the given eclass.
- *
- * @param eclass
- * the targeted eclass
- */
- public void transform(EClass eclass) {
-
- IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
- IEditorPart editor = page.getActiveEditor();
- CommandStack stack = (CommandStack) editor.getAdapter(CommandStack.class);
- globalCommand = new CompositeCommand("Generic Transformation");
-
- if (graphCopy) {
- if (element != null) {
- EReference[] features = { NotationPackage.eINSTANCE.getView_Element() };
- Collection<?> views = EMFCoreUtil.getReferencers(element, features);
- for (Object view : views) {
- if (view instanceof View) {
- referencingViews.add((View) view);
- }
- }
- }
- }
- if (stack != null) {
- // maybe extension point for stereotypes
- EObject model = (EObject) AdapterFactoryEditingDomain.unwrap(element);
- // get mixed editing domain to do transaction
- TransactionalEditingDomain domain = (TransactionalEditingDomain) EMFHelper.resolveEditingDomain(model);
- commandModel = new EObjectInheritanceCopyCommand(model, eclass, domain);
- globalCommand.add(commandModel);
- if (graphCopy) {
- importerCommand = new ImporterCommand(domain);
- if (importerCommand.canExecute()) {
- globalCommand.add(importerCommand);
- }
-
- }
- if (globalCommand.canExecute()) {
- try {
- // drop caches about input element
- ECrossReferenceAdapter cross = ECrossReferenceAdapter.getCrossReferenceAdapter(element);
- if (cross != null) {
- cross.unsetTarget(element);
- }
- stack.execute(new ICommandProxy(globalCommand));
- } catch (Exception e) {
- MessageDialog.openWarning(Display.getDefault().getActiveShell(), WARNING_TITLE, WARNING_MSG);
- e.printStackTrace();
- }
- } else {
- MessageDialog.openWarning(Display.getDefault().getActiveShell(), WARNING_TITLE, WARNING_MSG);
- }
- }
- }
-
- /**
- * The Class ImporterCommand. permits to add the importer in the compound
- * command
- */
- private class ImporterCommand extends AbstractTransactionalCommand {
-
- /**
- * Constructor.
- *
- * @param domain
- * transactional editing domain
- */
- public ImporterCommand(TransactionalEditingDomain domain) {
- super(domain, "Import graphical nodes", null);
- }
-
- /**
- * Execute the command
- *
- * @param monitor
- * progress monitor
- * @param info
- * the info
- * @return the command result
- * @throws ExecutionException
- */
- @Override
- protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
- graphCopy(null, commandModel.getResultEobject());
- return CommandResult.newOKCommandResult();
- }
-
- /**
- * Graph copy, make a drag and drop of the new object on all diagrams
- *
- * @param diagramDomain
- * the mixed domain
- * @param target
- * the target
- * @param globalCommand2
- * @param graphElement
- * the graph element
- * @param oldLocation
- * the old location
- * @param editpart
- * the editpart
- */
- private void graphCopy(IDiagramEditDomain domain, EObject target) {
- for (View graphElement : referencingViews) {
- View parent = ViewUtil.getContainerView(graphElement);
- if (parent == null || graphElement.getDiagram() == null) {
- // this is an orphaned view. Skip it
- continue;
- }
- IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
- // Get the edit part of the diagram containing the view.
- DiagramEditPart diagramEditPart = null;
- IEditorPart activeEditorPart = page.getActiveEditor();
- if (activeEditorPart instanceof IDiagramWorkbenchPart) {
- if (graphElement.getDiagram().equals(((IDiagramWorkbenchPart) activeEditorPart).getDiagram())) {
- diagramEditPart = ((IDiagramWorkbenchPart) activeEditorPart).getDiagramEditPart();
- }
- }
- if (diagramEditPart == null) {
- // search in other editor parts than the active one
- List<?> editorParts = EditorService.getInstance().getRegisteredEditorParts();
- for (Object editorPart : editorParts) {
- if (editorPart instanceof IDiagramWorkbenchPart) {
- if (graphElement.getDiagram().equals(((IDiagramWorkbenchPart) editorPart).getDiagram())) {
- diagramEditPart = ((IDiagramWorkbenchPart) editorPart).getDiagramEditPart();
- }
- }
- }
- }
-
- if (diagramEditPart != null) {
- EditPart containerPart = (EditPart) diagramEditPart.getViewer().getEditPartRegistry().get(parent);
- // create the new transformed view
- DropObjectsRequest req = new DropObjectsRequest();
- req.setObjects(Collections.singletonList(target));
- if (graphElement instanceof Node) {
- LayoutConstraint constraint = ((Node) graphElement).getLayoutConstraint();
- if (constraint instanceof Location) {
- Location location = (Location) constraint;
- req.setLocation(new Point(location.getX(), location.getY()));
- }
- }
- if (req.getLocation() == null) {
- req.setLocation(new Point());
- }
- Command partCreationCmd = containerPart.getCommand(req);
- partCreationCmd.execute();
- View newView = null;
- if (partCreationCmd instanceof ICommandProxy) {
- CommandResult res = ((ICommandProxy) partCreationCmd).getICommand().getCommandResult();
- Object newValue = res.getReturnValue();
- if (newValue instanceof Collection<?>) {
- for (Object value : (Collection<?>) newValue) {
- if (value instanceof ViewDescriptor) {
- newView = (View) ((ViewDescriptor) value).getAdapter(View.class);
- }
- }
- } else if (newValue instanceof ViewDescriptor) {
- newView = (View) ((ViewDescriptor) newValue).getAdapter(View.class);
- }
- }
- // with ViewRefactorHelper, copy view properties on the old
- // one
- if (newView != null) {
- ViewTransformerHelper helper = new ViewTransformerHelper(diagramEditPart.getDiagramPreferencesHint());
- helper.copyMixedViewFeatures(graphElement, newView);
- }
- // delete the old view
- GroupRequest deleteReq = new GroupRequest(org.eclipse.gef.RequestConstants.REQ_DELETE);
- EditPart oldPart = (EditPart) diagramEditPart.getViewer().getEditPartRegistry().get(graphElement);
- Command partDeletionCmd = oldPart.getCommand(deleteReq);
- partDeletionCmd.execute();
- }
- }
-
- }
-
- }
-
- /**
- * ViewTransformerHelper allow to refactor a view to copy properties from
- * another view
- */
- private static class ViewTransformerHelper extends ViewRefactorHelper {
-
- /**
- * Constructor.
- *
- * @param preferencesHint
- * the diagram preferences hint
- */
- public ViewTransformerHelper(PreferencesHint preferencesHint) {
- super(preferencesHint);
- }
-
- /**
- * Copy common features from a view to another
- *
- * @param oldView
- * the old view to copy from
- * @param newView
- * the new view to copy to
- */
- public void copyMixedViewFeatures(View oldView, View newView) {
- if (oldView instanceof Diagram && newView instanceof Diagram) {
- copyDiagramFeatures((Diagram) oldView, (Diagram) newView);
- } else if (oldView instanceof Node && newView instanceof Node) {
- copyNodeFeatures((Node) oldView, (Node) newView);
- } else if (oldView instanceof Edge && newView instanceof Edge) {
- copyEdgeFeatures((Edge) oldView, (Edge) newView);
- } else {
- copyViewFeatures(oldView, newView);
- }
- }
-
- }
-
- /**
- * Gets all the super types.
- *
- * @param class1
- * the class
- *
- * @return super types
- */
- public static HashSet<EClass> getAllSuperTypes(EClass class1) {
- HashSet<EClass> results = new HashSet<EClass>();
- results.addAll(class1.getEAllSuperTypes());
- return results;
- }
-
- /**
- * Gets the factory from uri.
- *
- * @param uri
- * the uri
- *
- * @return the factory
- */
- public static AdapterFactory getFactory(String uri) {
- AdapterFactory factory = factories.get(uri);
- if (factory == null) {
- IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_FACTORIES);
- for (IConfigurationElement e : extensions) {
- if (uri.equals(e.getAttribute("uri"))) {
- try {
- factory = (AdapterFactory) e.createExecutableExtension("class");
- if (factory != null) {
- factories.put(uri, factory);
- }
- } catch (CoreException e1) {
- // do nothing
- }
- }
- }
- }
- return factory;
- }
-
- /**
- * Checks if a transformation is possible.
- *
- * @param eclass
- * the eclass
- *
- * @return the multi status
- */
- public MultiStatus isTransformationPossible(EClass eclass) {
- MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, 0, "Type incompatibility", null);
- if (element != null) {
- Collection<Setting> usages = EMFHelper.getUsages(element);
- if (usages != null) {
- for (EStructuralFeature.Setting nonNavigableInverseReference : usages) {
- EStructuralFeature structuralFeature = nonNavigableInverseReference.getEStructuralFeature();
- if (!(nonNavigableInverseReference.getEObject() instanceof View)) {
- boolean compatible = EObjectInheritanceCopyCommand.isCompatible(structuralFeature.getEType(), eclass);
- if (!compatible) {
- String econtainer = structuralFeature.eContainer() instanceof EClassifier ? ((EClassifier) structuralFeature.eContainer()).getName() + " ( " + nonNavigableInverseReference.getEObject().toString() + " )" : structuralFeature
- .eContainer().toString();
- Status s = new Status(IStatus.WARNING, Activator.PLUGIN_ID, String.format("an element typed %s references your selection, we can not assign instead of your selection an object typed %s", econtainer, eclass.getName()));
- result.add(s);
- }
- }
- }
- }
- }
- return result;
- }
-
-}
+/*************************************************** + * Copyright (c) 2010 Atos Origin. + + * + * 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: + * Atos Origin - Initial API and implementation + * + ****************************************************/ +package org.eclipse.papyrus.views.modelexplorer.actions; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.commands.CommandStack; +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; +import org.eclipse.gef.requests.GroupRequest; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; +import org.eclipse.gmf.runtime.common.ui.services.editor.EditorService; +import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint; +import org.eclipse.gmf.runtime.diagram.core.util.ViewRefactorHelper; +import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; +import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; +import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; +import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain; +import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor; +import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; +import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.Edge; +import org.eclipse.gmf.runtime.notation.LayoutConstraint; +import org.eclipse.gmf.runtime.notation.Location; +import org.eclipse.gmf.runtime.notation.Node; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.views.modelexplorer.Activator; +import org.eclipse.papyrus.views.modelexplorer.commands.EObjectInheritanceCopyCommand; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + * The Class GenericTransformer. Permits to transform an eobject of eclass to + * another eclass + */ +public class GenericTransformer { + + /** The factories to create eObjects */ + private static HashMap<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>(); + + /** extension to recover factories */ + private static final String EXT_FACTORIES = "org.eclipse.emf.edit.itemProviderAdapterFactories"; + + /** title of the warning dialog */ + private static final String WARNING_TITLE = "Problems during transformation"; + + /** message of the warning dialog */ + private static final String WARNING_MSG = "It seems the transformation you want to perform can't be executed"; + + /** command to execute the whole transformation */ + private CompositeCommand globalCommand; + + /** element to transform */ + private EObject element; + + /** views referencing the element */ + private Set<View> referencingViews = new HashSet<View>(); + + /** command to execute the model transformation */ + private EObjectInheritanceCopyCommand commandModel; + + /** whether the graphical edit parts must also be transformed */ + private boolean graphCopy = true; + + /** the command to import new graphical edit parts */ + private ImporterCommand importerCommand; + + /** + * Instantiates a new generic transformer. + * + * @param currentNode + * the current node + */ + public GenericTransformer(AbstractGraphicalEditPart currentNode) { + this(currentNode, true); + } + + /** + * Instantiates a new generic transformer. and specify if we have to perform + * graphical copy + * + * @param currentNode + * the current node + * @param graphCopy + * the graph copy + */ + public GenericTransformer(AbstractGraphicalEditPart currentNode, boolean graphCopy) { + this.graphCopy = graphCopy; + if (currentNode != null) { + Object model = currentNode.getModel(); + if (model instanceof View) { + this.element = ((View) model).getElement(); + } + } + } + + /** + * Instantiates a new generic transformer. + * + * @param currentEobject + * the current eobject + */ + public GenericTransformer(EObject currentEobject) { + this.element = currentEobject; + } + + /** + * Transform the element to the given eclass. + * + * @param eclass + * the targeted eclass + */ + public void transform(EClass eclass) { + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IEditorPart editor = page.getActiveEditor(); + CommandStack stack = editor.getAdapter(CommandStack.class); + globalCommand = new CompositeCommand("Generic Transformation"); + + if (graphCopy) { + if (element != null) { + EReference[] features = { NotationPackage.eINSTANCE.getView_Element() }; + Collection<?> views = EMFCoreUtil.getReferencers(element, features); + for (Object view : views) { + if (view instanceof View) { + referencingViews.add((View) view); + } + } + } + } + if (stack != null) { + // maybe extension point for stereotypes + EObject model = (EObject) AdapterFactoryEditingDomain.unwrap(element); + // get mixed editing domain to do transaction + TransactionalEditingDomain domain = (TransactionalEditingDomain) EMFHelper.resolveEditingDomain(model); + commandModel = new EObjectInheritanceCopyCommand(model, eclass, domain); + globalCommand.add(commandModel); + if (graphCopy) { + importerCommand = new ImporterCommand(domain); + if (importerCommand.canExecute()) { + globalCommand.add(importerCommand); + } + + } + if (globalCommand.canExecute()) { + try { + // drop caches about input element + ECrossReferenceAdapter cross = ECrossReferenceAdapter.getCrossReferenceAdapter(element); + if (cross != null) { + cross.unsetTarget(element); + } + stack.execute(new ICommandProxy(globalCommand)); + } catch (Exception e) { + MessageDialog.openWarning(Display.getDefault().getActiveShell(), WARNING_TITLE, WARNING_MSG); + e.printStackTrace(); + } + } else { + MessageDialog.openWarning(Display.getDefault().getActiveShell(), WARNING_TITLE, WARNING_MSG); + } + } + } + + /** + * The Class ImporterCommand. permits to add the importer in the compound + * command + */ + private class ImporterCommand extends AbstractTransactionalCommand { + + /** + * Constructor. + * + * @param domain + * transactional editing domain + */ + public ImporterCommand(TransactionalEditingDomain domain) { + super(domain, "Import graphical nodes", null); + } + + /** + * Execute the command + * + * @param monitor + * progress monitor + * @param info + * the info + * @return the command result + * @throws ExecutionException + */ + @Override + protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + graphCopy(null, commandModel.getResultEobject()); + return CommandResult.newOKCommandResult(); + } + + /** + * Graph copy, make a drag and drop of the new object on all diagrams + * + * @param diagramDomain + * the mixed domain + * @param target + * the target + * @param globalCommand2 + * @param graphElement + * the graph element + * @param oldLocation + * the old location + * @param editpart + * the editpart + */ + private void graphCopy(IDiagramEditDomain domain, EObject target) { + for (View graphElement : referencingViews) { + View parent = ViewUtil.getContainerView(graphElement); + if (parent == null || graphElement.getDiagram() == null) { + // this is an orphaned view. Skip it + continue; + } + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + // Get the edit part of the diagram containing the view. + DiagramEditPart diagramEditPart = null; + IEditorPart activeEditorPart = page.getActiveEditor(); + if (activeEditorPart instanceof IDiagramWorkbenchPart) { + if (graphElement.getDiagram().equals(((IDiagramWorkbenchPart) activeEditorPart).getDiagram())) { + diagramEditPart = ((IDiagramWorkbenchPart) activeEditorPart).getDiagramEditPart(); + } + } + if (diagramEditPart == null) { + // search in other editor parts than the active one + List<?> editorParts = EditorService.getInstance().getRegisteredEditorParts(); + for (Object editorPart : editorParts) { + if (editorPart instanceof IDiagramWorkbenchPart) { + if (graphElement.getDiagram().equals(((IDiagramWorkbenchPart) editorPart).getDiagram())) { + diagramEditPart = ((IDiagramWorkbenchPart) editorPart).getDiagramEditPart(); + } + } + } + } + + if (diagramEditPart != null) { + EditPart containerPart = (EditPart) diagramEditPart.getViewer().getEditPartRegistry().get(parent); + // create the new transformed view + DropObjectsRequest req = new DropObjectsRequest(); + req.setObjects(Collections.singletonList(target)); + if (graphElement instanceof Node) { + LayoutConstraint constraint = ((Node) graphElement).getLayoutConstraint(); + if (constraint instanceof Location) { + Location location = (Location) constraint; + req.setLocation(new Point(location.getX(), location.getY())); + } + } + if (req.getLocation() == null) { + req.setLocation(new Point()); + } + Command partCreationCmd = containerPart.getCommand(req); + partCreationCmd.execute(); + View newView = null; + if (partCreationCmd instanceof ICommandProxy) { + CommandResult res = ((ICommandProxy) partCreationCmd).getICommand().getCommandResult(); + Object newValue = res.getReturnValue(); + if (newValue instanceof Collection<?>) { + for (Object value : (Collection<?>) newValue) { + if (value instanceof ViewDescriptor) { + newView = (View) ((ViewDescriptor) value).getAdapter(View.class); + } + } + } else if (newValue instanceof ViewDescriptor) { + newView = (View) ((ViewDescriptor) newValue).getAdapter(View.class); + } + } + // with ViewRefactorHelper, copy view properties on the old + // one + if (newView != null) { + ViewTransformerHelper helper = new ViewTransformerHelper(diagramEditPart.getDiagramPreferencesHint()); + helper.copyMixedViewFeatures(graphElement, newView); + } + // delete the old view + GroupRequest deleteReq = new GroupRequest(org.eclipse.gef.RequestConstants.REQ_DELETE); + EditPart oldPart = (EditPart) diagramEditPart.getViewer().getEditPartRegistry().get(graphElement); + Command partDeletionCmd = oldPart.getCommand(deleteReq); + partDeletionCmd.execute(); + } + } + + } + + } + + /** + * ViewTransformerHelper allow to refactor a view to copy properties from + * another view + */ + private static class ViewTransformerHelper extends ViewRefactorHelper { + + /** + * Constructor. + * + * @param preferencesHint + * the diagram preferences hint + */ + public ViewTransformerHelper(PreferencesHint preferencesHint) { + super(preferencesHint); + } + + /** + * Copy common features from a view to another + * + * @param oldView + * the old view to copy from + * @param newView + * the new view to copy to + */ + public void copyMixedViewFeatures(View oldView, View newView) { + if (oldView instanceof Diagram && newView instanceof Diagram) { + copyDiagramFeatures((Diagram) oldView, (Diagram) newView); + } else if (oldView instanceof Node && newView instanceof Node) { + copyNodeFeatures((Node) oldView, (Node) newView); + } else if (oldView instanceof Edge && newView instanceof Edge) { + copyEdgeFeatures((Edge) oldView, (Edge) newView); + } else { + copyViewFeatures(oldView, newView); + } + } + + } + + /** + * Gets all the super types. + * + * @param class1 + * the class + * + * @return super types + */ + public static HashSet<EClass> getAllSuperTypes(EClass class1) { + HashSet<EClass> results = new HashSet<EClass>(); + results.addAll(class1.getEAllSuperTypes()); + return results; + } + + /** + * Gets the factory from uri. + * + * @param uri + * the uri + * + * @return the factory + */ + public static AdapterFactory getFactory(String uri) { + AdapterFactory factory = factories.get(uri); + if (factory == null) { + IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_FACTORIES); + for (IConfigurationElement e : extensions) { + if (uri.equals(e.getAttribute("uri"))) { + try { + factory = (AdapterFactory) e.createExecutableExtension("class"); + if (factory != null) { + factories.put(uri, factory); + } + } catch (CoreException e1) { + // do nothing + } + } + } + } + return factory; + } + + /** + * Checks if a transformation is possible. + * + * @param eclass + * the eclass + * + * @return the multi status + */ + public MultiStatus isTransformationPossible(EClass eclass) { + MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, 0, "Type incompatibility", null); + if (element != null) { + Collection<Setting> usages = EMFHelper.getUsages(element); + if (usages != null) { + for (EStructuralFeature.Setting nonNavigableInverseReference : usages) { + EStructuralFeature structuralFeature = nonNavigableInverseReference.getEStructuralFeature(); + if (!(nonNavigableInverseReference.getEObject() instanceof View)) { + boolean compatible = EObjectInheritanceCopyCommand.isCompatible(structuralFeature.getEType(), eclass); + if (!compatible) { + String econtainer = structuralFeature.eContainer() instanceof EClassifier ? ((EClassifier) structuralFeature.eContainer()).getName() + " ( " + nonNavigableInverseReference.getEObject().toString() + " )" : structuralFeature + .eContainer().toString(); + Status s = new Status(IStatus.WARNING, Activator.PLUGIN_ID, String.format("an element typed %s references your selection, we can not assign instead of your selection an object typed %s", econtainer, eclass.getName())); + result.add(s); + } + } + } + } + } + return result; + } + +} diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dialog/NavigatorSearchDialog.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dialog/NavigatorSearchDialog.java index 2b349b6cfcc..9ac3d52fb3e 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dialog/NavigatorSearchDialog.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dialog/NavigatorSearchDialog.java @@ -1,441 +1,441 @@ -/*******************************************************************************
- * Copyright (c) 2009 Conselleria de Infraestructuras y Transporte, Generalitat
- * de la Comunitat Valenciana . 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:
- * Francisco Javier Cano Muñoz (Prodevelop) - initial api contribution
- * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Improve the searchText widget
- *
- *
- ******************************************************************************/
-package org.eclipse.papyrus.views.modelexplorer.dialog;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.dialogs.TrayDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
-import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
-import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
-import org.eclipse.papyrus.infra.widgets.editors.StringEditor;
-import org.eclipse.papyrus.views.modelexplorer.LinkNode;
-import org.eclipse.papyrus.views.modelexplorer.ModelExplorerView;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.navigator.CommonNavigator;
-import org.eclipse.ui.navigator.CommonViewer;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/**
- * A dialog that allows searching elements in the Model navigator by name.
- *
- * @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Munoz</a>
- *
- * @author cedric dumoulin
- */
-// @Unused
-// The QuickSearch feature is disabled since the new Search feature is available (0.10)
-public class NavigatorSearchDialog extends TrayDialog {
-
- private ITreeContentProvider contentProvider = null;
-
- private ILabelProvider labelProvider = null;
-
- private Object root = null;
-
- private ISelectionProvider viewer = null;
-
- private List<Object> matchedObjects = Collections.emptyList();
-
- protected int currentIndex = 0;
-
- private Label matchesLabel;
-
- private StringEditor searchText;
-
- private Button backButton;
-
- private Button nextButton;
-
- private Button caseButton;
-
- /**
- *
- * Constructor.
- *
- * @param shell
- * @param modelNavigator
- * @deprecated Use {@link #NavigatorSearchDialog(Shell, TreeViewer)}
- */
- @Deprecated
- public NavigatorSearchDialog(Shell shell, CommonNavigator modelNavigator) {
- super(shell);
- IContentProvider cprovider = modelNavigator.getCommonViewer().getContentProvider();
- if (cprovider instanceof ITreeContentProvider) {
- contentProvider = (ITreeContentProvider) cprovider;
- }
- root = modelNavigator.getCommonViewer().getInput();
- viewer = modelNavigator.getCommonViewer();
- labelProvider = (ILabelProvider) modelNavigator.getCommonViewer().getLabelProvider();
-
- }
-
- /**
- * Constructor.
- *
- * @param shell
- * Shell used to show this Dialog
- * @param viewer
- * @param contentProvider
- * @param labelProvider
- * @param root
- */
- public NavigatorSearchDialog(Shell shell, TreeViewer viewer) {
- super(shell);
- this.viewer = viewer;
- try {
- this.labelProvider = (ILabelProvider) viewer.getLabelProvider();
- this.contentProvider = (ITreeContentProvider) viewer.getContentProvider();
- } catch (ClassCastException e) {
- // Content or label provider are not of appropriate type.
- // let them null
- }
- this.root = viewer.getInput();
- }
-
-
- /**
- * Constructor.
- *
- * @param shell
- * Shell used to show this Dialog
- * @param viewer
- * @param contentProvider
- * @param labelProvider
- * @param root
- */
- public NavigatorSearchDialog(Shell shell, Viewer viewer, ITreeContentProvider contentProvider, ILabelProvider labelProvider, Object root) {
- super(shell);
- this.viewer = viewer;
- this.contentProvider = contentProvider;
- this.labelProvider = labelProvider;
- this.root = root;
- }
-
- /**
- * Sets a new selection for the associated {@link ISelectionProvider} and optionally makes it visible.
- * <p>
- * Subclasses must implement this method.
- * </p>
- *
- * @param selection
- * the new selection
- * @param reveal
- * <code>true</code> if the selection is to be made
- * visible, and <code>false</code> otherwise
- */
- private void fireSetSelection(ISelection selection, boolean reveal) {
- // Note : if we want to force reveal, it is possible to check if
- // selectionProvider instanceof Viewer, and then call selectionProvider.setSelection(selection, true).
- // By default a TreeViewer reveal the selection.
- if (viewer instanceof CommonViewer) {
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection structured = (IStructuredSelection) selection;
- ModelExplorerView.reveal(Iterables.transform(Lists.newArrayList(structured.iterator()), new Function<Object, EObject>() {
-
- public EObject apply(Object arg0) {
- return EMFHelper.getEObject(arg0);
- }
- }), (CommonViewer) viewer);
- }
- } else if (viewer instanceof Viewer) {
- Viewer view = (Viewer) viewer;
- view.setSelection(selection, true);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets
- * .Composite)
- */
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite background = new Composite(parent, SWT.None);
- GridData bgData = new GridData(GridData.FILL_BOTH);
- bgData.minimumWidth = 300;
- background.setLayoutData(bgData);
- GridLayout bgLayout = new GridLayout();
- bgLayout.numColumns = 2;
- background.setLayout(bgLayout);
-
- createSearchTextComposite(background);
-
- getShell().setText("Search");
- return background;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse
- * .swt.widgets.Composite)
- */
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
-
- backButton = createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false);
- nextButton = createButton(parent, IDialogConstants.NEXT_ID, IDialogConstants.NEXT_LABEL, false);
- createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
-
- backButton.setEnabled(false);
- nextButton.setEnabled(false);
-
- nextButton.addSelectionListener(new SelectionListener() {
-
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- public void widgetSelected(SelectionEvent e) {
- if (currentIndex >= matchedObjects.size() - 1) {
- currentIndex = 0;
- } else {
- currentIndex++;
- }
- fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true);
- }
-
- });
-
- backButton.addSelectionListener(new SelectionListener() {
-
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- public void widgetSelected(SelectionEvent e) {
- if (currentIndex <= 0) {
- currentIndex = matchedObjects.size() - 1;
- } else {
- currentIndex--;
- }
- fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true);
- }
-
- });
- }
-
- @Override
- protected boolean isResizable() {
- return true;
- }
-
- private void createSearchTextComposite(Composite background) {
- Label searchLabel = new Label(background, SWT.None);
- searchLabel.setText("Search:");
- searchLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
- searchText = new StringEditor(background, SWT.SEARCH);
- searchText.setFocus();
- searchText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- searchText.addCommitListener(getCommitListener());
- searchText.setValidateOnDelay(true);
-
- caseButton = new Button(background, SWT.CHECK);
- caseButton.setText("Case sensitive?");
- GridData caseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
- caseButtonData.horizontalSpan = 2;
- caseButton.setSelection(false);
- caseButton.setLayoutData(caseButtonData);
- caseButton.addSelectionListener(new SelectionAdapter() {
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- updateMatches();
- }
-
- });
-
- Label resultsLabel = new Label(background, SWT.None);
- resultsLabel.setText("Results:");
- resultsLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
- matchesLabel = new Label(background, SWT.None);
- matchesLabel.setText("No matchings.");
- matchesLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
-
- }
-
- protected void clearMatches() {
- matchedObjects = Collections.emptyList();
- currentIndex = 0;
- backButton.setEnabled(false);
- nextButton.setEnabled(false);
- matchesLabel.setText("");
- }
-
- private void updateMatches() {
- if (contentProvider == null && labelProvider == null) {
- return;
- }
-
- String pattern = (String) searchText.getValue();
- if (pattern.length() == 0) {
- clearMatches();
- return;
- }
-
- if (!caseButton.getSelection()) {
- pattern = pattern.toUpperCase();
- }
-
- launchSearch(pattern, contentProvider.getElements(root));
-
- // Update matches label
- matchesLabel.setText(matchedObjects.size() + " matches found");
-
- // Select first match and update buttons
- if (!matchedObjects.isEmpty()) {
- fireSetSelection(new StructuredSelection(matchedObjects.get(0)), true);
- nextButton.setEnabled(true);
- backButton.setEnabled(true);
- } else {
- nextButton.setEnabled(false);
- backButton.setEnabled(false);
- }
-
- }
-
- protected void launchSearch(final String pattern, final Object[] root) {
- final boolean caseSensitive = caseButton.getSelection();
-
- ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);
- try {
- dialog.run(true, true, new IRunnableWithProgress() {
-
- public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
- matchedObjects = searchPattern(pattern, caseSensitive, Arrays.asList(root), monitor);
- currentIndex = 0;
- }
- });
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- private List<Object> searchPattern(String pattern, boolean caseSensitive, List<Object> objects, IProgressMonitor monitor) {
- if (monitor.isCanceled()) {
- return Collections.emptyList();
- }
-
- List<Object> matches = new ArrayList<Object>();
-
- List<Object> children = new ArrayList<Object>();
- String objectLabel;
-
- for (Object o : objects) {
- // Search matches in this level
- if (!(o instanceof Diagram)) {
- objectLabel = caseSensitive ? labelProvider.getText(o) : labelProvider.getText(o).toUpperCase();
-
- if (objectLabel.contains(pattern)) {
- matches.add(o);
- }
- EObject parentEObj = getAdapter(o, EObject.class);
-
- for (int i = 0; i < contentProvider.getChildren(o).length; i++) {
- Object child = contentProvider.getChildren(o)[i];
- // If child can be adapted into a LinkNode, find its referenced EObjects
- if (getAdapter(child, LinkNode.class) != null) {
- for (Object referencedObject : contentProvider.getChildren(child)) {
- EObject referencedEObject = EMFHelper.getEObject(referencedObject);
- if (referencedEObject != null && (parentEObj == null || parentEObj.equals(referencedEObject.eContainer()))) {
- children.add(referencedObject);
- }
- }
- }
- // If it is an EObject, add it to the list
- else {
- EObject eObject = EMFHelper.getEObject(child);
- if (eObject != null && eObject.eContainer() != null && (parentEObj == null || eObject.eContainer().equals(parentEObj))) {
- children.add(child);
- }
- }
- }
- }
- }
- if (!children.isEmpty()) {
- matches.addAll(searchPattern(pattern, caseSensitive, children, monitor));
- }
-
- return matches;
- }
-
- @SuppressWarnings("unchecked")
- public <T> T getAdapter(Object object, Class<? extends T> toAdapt) {
- T result = null;
- if (object instanceof IAdaptable) {
- IAdaptable adaptable = (IAdaptable) object;
- result = (T) adaptable.getAdapter(toAdapt);
- }
- if (result == null) {
- result = (T) Platform.getAdapterManager().getAdapter(object, toAdapt);
- }
- return result;
- }
-
- protected ICommitListener getCommitListener() {
- return new ICommitListener() {
-
- private String lastValue = "";
-
- public void commit(AbstractEditor editor) {
- String newValue = (String) searchText.getValue();
- if (!lastValue.equals(newValue)) {
- lastValue = newValue;
- updateMatches();
- }
- }
- };
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009 Conselleria de Infraestructuras y Transporte, Generalitat + * de la Comunitat Valenciana . 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: + * Francisco Javier Cano Muñoz (Prodevelop) - initial api contribution + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Improve the searchText widget + * + * + ******************************************************************************/ +package org.eclipse.papyrus.views.modelexplorer.dialog; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor; +import org.eclipse.papyrus.infra.widgets.editors.ICommitListener; +import org.eclipse.papyrus.infra.widgets.editors.StringEditor; +import org.eclipse.papyrus.views.modelexplorer.LinkNode; +import org.eclipse.papyrus.views.modelexplorer.ModelExplorerView; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.navigator.CommonNavigator; +import org.eclipse.ui.navigator.CommonViewer; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +/** + * A dialog that allows searching elements in the Model navigator by name. + * + * @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Munoz</a> + * + * @author cedric dumoulin + */ +// @Unused +// The QuickSearch feature is disabled since the new Search feature is available (0.10) +public class NavigatorSearchDialog extends TrayDialog { + + private ITreeContentProvider contentProvider = null; + + private ILabelProvider labelProvider = null; + + private Object root = null; + + private ISelectionProvider viewer = null; + + private List<Object> matchedObjects = Collections.emptyList(); + + protected int currentIndex = 0; + + private Label matchesLabel; + + private StringEditor searchText; + + private Button backButton; + + private Button nextButton; + + private Button caseButton; + + /** + * + * Constructor. + * + * @param shell + * @param modelNavigator + * @deprecated Use {@link #NavigatorSearchDialog(Shell, TreeViewer)} + */ + @Deprecated + public NavigatorSearchDialog(Shell shell, CommonNavigator modelNavigator) { + super(shell); + IContentProvider cprovider = modelNavigator.getCommonViewer().getContentProvider(); + if (cprovider instanceof ITreeContentProvider) { + contentProvider = (ITreeContentProvider) cprovider; + } + root = modelNavigator.getCommonViewer().getInput(); + viewer = modelNavigator.getCommonViewer(); + labelProvider = (ILabelProvider) modelNavigator.getCommonViewer().getLabelProvider(); + + } + + /** + * Constructor. + * + * @param shell + * Shell used to show this Dialog + * @param viewer + * @param contentProvider + * @param labelProvider + * @param root + */ + public NavigatorSearchDialog(Shell shell, TreeViewer viewer) { + super(shell); + this.viewer = viewer; + try { + this.labelProvider = (ILabelProvider) viewer.getLabelProvider(); + this.contentProvider = (ITreeContentProvider) viewer.getContentProvider(); + } catch (ClassCastException e) { + // Content or label provider are not of appropriate type. + // let them null + } + this.root = viewer.getInput(); + } + + + /** + * Constructor. + * + * @param shell + * Shell used to show this Dialog + * @param viewer + * @param contentProvider + * @param labelProvider + * @param root + */ + public NavigatorSearchDialog(Shell shell, Viewer viewer, ITreeContentProvider contentProvider, ILabelProvider labelProvider, Object root) { + super(shell); + this.viewer = viewer; + this.contentProvider = contentProvider; + this.labelProvider = labelProvider; + this.root = root; + } + + /** + * Sets a new selection for the associated {@link ISelectionProvider} and optionally makes it visible. + * <p> + * Subclasses must implement this method. + * </p> + * + * @param selection + * the new selection + * @param reveal + * <code>true</code> if the selection is to be made + * visible, and <code>false</code> otherwise + */ + private void fireSetSelection(ISelection selection, boolean reveal) { + // Note : if we want to force reveal, it is possible to check if + // selectionProvider instanceof Viewer, and then call selectionProvider.setSelection(selection, true). + // By default a TreeViewer reveal the selection. + if (viewer instanceof CommonViewer) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection structured = (IStructuredSelection) selection; + ModelExplorerView.reveal(Iterables.transform(Lists.newArrayList(structured.iterator()), new Function<Object, EObject>() { + + public EObject apply(Object arg0) { + return EMFHelper.getEObject(arg0); + } + }), (CommonViewer) viewer); + } + } else if (viewer instanceof Viewer) { + Viewer view = (Viewer) viewer; + view.setSelection(selection, true); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets + * .Composite) + */ + @Override + protected Control createDialogArea(Composite parent) { + Composite background = new Composite(parent, SWT.None); + GridData bgData = new GridData(GridData.FILL_BOTH); + bgData.minimumWidth = 300; + background.setLayoutData(bgData); + GridLayout bgLayout = new GridLayout(); + bgLayout.numColumns = 2; + background.setLayout(bgLayout); + + createSearchTextComposite(background); + + getShell().setText("Search"); + return background; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse + * .swt.widgets.Composite) + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + + backButton = createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false); + nextButton = createButton(parent, IDialogConstants.NEXT_ID, IDialogConstants.NEXT_LABEL, false); + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + + backButton.setEnabled(false); + nextButton.setEnabled(false); + + nextButton.addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(SelectionEvent e) { + } + + public void widgetSelected(SelectionEvent e) { + if (currentIndex >= matchedObjects.size() - 1) { + currentIndex = 0; + } else { + currentIndex++; + } + fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true); + } + + }); + + backButton.addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(SelectionEvent e) { + } + + public void widgetSelected(SelectionEvent e) { + if (currentIndex <= 0) { + currentIndex = matchedObjects.size() - 1; + } else { + currentIndex--; + } + fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true); + } + + }); + } + + @Override + protected boolean isResizable() { + return true; + } + + private void createSearchTextComposite(Composite background) { + Label searchLabel = new Label(background, SWT.None); + searchLabel.setText("Search:"); + searchLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + searchText = new StringEditor(background, SWT.SEARCH); + searchText.setFocus(); + searchText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + searchText.addCommitListener(getCommitListener()); + searchText.setValidateOnDelay(true); + + caseButton = new Button(background, SWT.CHECK); + caseButton.setText("Case sensitive?"); + GridData caseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + caseButtonData.horizontalSpan = 2; + caseButton.setSelection(false); + caseButton.setLayoutData(caseButtonData); + caseButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + updateMatches(); + } + + }); + + Label resultsLabel = new Label(background, SWT.None); + resultsLabel.setText("Results:"); + resultsLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + matchesLabel = new Label(background, SWT.None); + matchesLabel.setText("No matchings."); + matchesLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); + + } + + protected void clearMatches() { + matchedObjects = Collections.emptyList(); + currentIndex = 0; + backButton.setEnabled(false); + nextButton.setEnabled(false); + matchesLabel.setText(""); + } + + private void updateMatches() { + if (contentProvider == null && labelProvider == null) { + return; + } + + String pattern = (String) searchText.getValue(); + if (pattern.length() == 0) { + clearMatches(); + return; + } + + if (!caseButton.getSelection()) { + pattern = pattern.toUpperCase(); + } + + launchSearch(pattern, contentProvider.getElements(root)); + + // Update matches label + matchesLabel.setText(matchedObjects.size() + " matches found"); + + // Select first match and update buttons + if (!matchedObjects.isEmpty()) { + fireSetSelection(new StructuredSelection(matchedObjects.get(0)), true); + nextButton.setEnabled(true); + backButton.setEnabled(true); + } else { + nextButton.setEnabled(false); + backButton.setEnabled(false); + } + + } + + protected void launchSearch(final String pattern, final Object[] root) { + final boolean caseSensitive = caseButton.getSelection(); + + ProgressMonitorDialog dialog = new ProgressMonitorDialog(null); + try { + dialog.run(true, true, new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + matchedObjects = searchPattern(pattern, caseSensitive, Arrays.asList(root), monitor); + currentIndex = 0; + } + }); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private List<Object> searchPattern(String pattern, boolean caseSensitive, List<Object> objects, IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Collections.emptyList(); + } + + List<Object> matches = new ArrayList<Object>(); + + List<Object> children = new ArrayList<Object>(); + String objectLabel; + + for (Object o : objects) { + // Search matches in this level + if (!(o instanceof Diagram)) { + objectLabel = caseSensitive ? labelProvider.getText(o) : labelProvider.getText(o).toUpperCase(); + + if (objectLabel.contains(pattern)) { + matches.add(o); + } + EObject parentEObj = getAdapter(o, EObject.class); + + for (int i = 0; i < contentProvider.getChildren(o).length; i++) { + Object child = contentProvider.getChildren(o)[i]; + // If child can be adapted into a LinkNode, find its referenced EObjects + if (getAdapter(child, LinkNode.class) != null) { + for (Object referencedObject : contentProvider.getChildren(child)) { + EObject referencedEObject = EMFHelper.getEObject(referencedObject); + if (referencedEObject != null && (parentEObj == null || parentEObj.equals(referencedEObject.eContainer()))) { + children.add(referencedObject); + } + } + } + // If it is an EObject, add it to the list + else { + EObject eObject = EMFHelper.getEObject(child); + if (eObject != null && eObject.eContainer() != null && (parentEObj == null || eObject.eContainer().equals(parentEObj))) { + children.add(child); + } + } + } + } + } + if (!children.isEmpty()) { + matches.addAll(searchPattern(pattern, caseSensitive, children, monitor)); + } + + return matches; + } + + @SuppressWarnings("unchecked") + public <T> T getAdapter(Object object, Class<? extends T> toAdapt) { + T result = null; + if (object instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) object; + result = adaptable.getAdapter(toAdapt); + } + if (result == null) { + result = Platform.getAdapterManager().getAdapter(object, toAdapt); + } + return result; + } + + protected ICommitListener getCommitListener() { + return new ICommitListener() { + + private String lastValue = ""; + + public void commit(AbstractEditor editor) { + String newValue = (String) searchText.getValue(); + if (!lastValue.equals(newValue)) { + lastValue = newValue; + updateMatches(); + } + } + }; + } + +} diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/AbstractModelExplorerHandler.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/AbstractModelExplorerHandler.java index e58fd269246..cdc02e5420c 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/AbstractModelExplorerHandler.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/AbstractModelExplorerHandler.java @@ -1,163 +1,163 @@ -/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.views.modelexplorer.handler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.Platform;
-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.TreeSelection;
-import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * This provides facilities to get the TransactionEditingDomain and the PageManager from the Model Explorer
- *
- *
- *
- */
-public abstract class AbstractModelExplorerHandler extends AbstractHandler {
-
- /**
- * Returns the
- *
- * @return
- * the current editing domain
- */
- protected TransactionalEditingDomain getEditingDomain() {
- TransactionalEditingDomain editingDomain = null;
- try {
- editingDomain = org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers.getInstance().getTransactionalEditingDomain();
- } catch (ServiceException e) {
- // we are closing the editor, so the model explorer has nothing to display
- // e.printStackTrace();
- }
- return editingDomain;
- }
-
- /**
- * Returns the page manager
- *
- * @return
- * the page manager
- */
- protected IPageManager getPageManager() {
- IPageManager pageManager = null;
- try {
- pageManager = ServiceUtilsForActionHandlers.getInstance().getIPageManager();
- } catch (ServiceException e) {
- // we are closing the editor, so the model explorer has nothing to display
- // e.printStackTrace();
- }
- return pageManager;
- }
-
- /**
- * Adapt the specified object to the requested type, if possible.
- * Return null if the object can't be adapted.
- *
- * @param object
- * @param expectedClassType
- * @return The adapted object, or null.
- */
- @SuppressWarnings("unchecked")
- private <T> T adapt(Object object, Class<T> expectedClassType) {
-
-
- EObject eobject = EMFHelper.getEObject(object);
-
- if (eobject != null && expectedClassType.isInstance(eobject)) {
- return (T) eobject;
- }
-
-
-
- // Try global mechanism
- {
- T ele = (T) Platform.getAdapterManager().getAdapter(object, expectedClassType);
- if (ele != null) {
- return ele;
- }
- // Try as EObject if the expectedClasType is sub-type of EObject.
- if (EObject.class.isAssignableFrom(expectedClassType)) {
- // to EObject
- eobject = (EObject) Platform.getAdapterManager().getAdapter(object, EObject.class);
-
- if (eobject != null && expectedClassType.isInstance(eobject)) {
-
- return (T) eobject;
- }
- }
- }
- // Can't be adapted
- return null;
-
- }
-
- /**
- * Filter the list, and only retain objects that can be adapted to the specified type
- *
- * @param objects
- * @param class1
- * @return
- */
- private <T> List<T> getAllElementAdaptedToType(List<Object> list, Class<T> expectedClassType) {
-
- List<T> res = new ArrayList<T>();
-
- for (Object cur : list) {
-
- T adapted = adapt(cur, expectedClassType);
- if (adapted != null) {
- res.add(adapted);
- }
- }
- return res;
- }
-
- /**
- * Get all selected element of the specified type.
- *
- * @param expectedType
- * @return
- * @throws ExecutionException
- */
- @SuppressWarnings("unchecked")
- protected <T> List<T> getCurrentSelectionAdaptedToType(ExecutionEvent event, Class<T> expectedType) throws ExecutionException {
-
- // Get selection from the workbench
- ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
-
- // Get the selected objects according to the type of the selected
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection structuredSelection = (IStructuredSelection) selection;
- return getAllElementAdaptedToType(structuredSelection.toList(), expectedType);
- } else if (selection instanceof TreeSelection) {
- TreeSelection treeSelection = (TreeSelection) selection;
- return getAllElementAdaptedToType(treeSelection.toList(), expectedType);
-
- }
- return null;
- }
-}
+/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * 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: + * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.views.modelexplorer.handler; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +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.TreeSelection; +import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * This provides facilities to get the TransactionEditingDomain and the PageManager from the Model Explorer + * + * + * + */ +public abstract class AbstractModelExplorerHandler extends AbstractHandler { + + /** + * Returns the + * + * @return + * the current editing domain + */ + protected TransactionalEditingDomain getEditingDomain() { + TransactionalEditingDomain editingDomain = null; + try { + editingDomain = org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers.getInstance().getTransactionalEditingDomain(); + } catch (ServiceException e) { + // we are closing the editor, so the model explorer has nothing to display + // e.printStackTrace(); + } + return editingDomain; + } + + /** + * Returns the page manager + * + * @return + * the page manager + */ + protected IPageManager getPageManager() { + IPageManager pageManager = null; + try { + pageManager = ServiceUtilsForActionHandlers.getInstance().getIPageManager(); + } catch (ServiceException e) { + // we are closing the editor, so the model explorer has nothing to display + // e.printStackTrace(); + } + return pageManager; + } + + /** + * Adapt the specified object to the requested type, if possible. + * Return null if the object can't be adapted. + * + * @param object + * @param expectedClassType + * @return The adapted object, or null. + */ + @SuppressWarnings("unchecked") + private <T> T adapt(Object object, Class<T> expectedClassType) { + + + EObject eobject = EMFHelper.getEObject(object); + + if (eobject != null && expectedClassType.isInstance(eobject)) { + return (T) eobject; + } + + + + // Try global mechanism + { + T ele = Platform.getAdapterManager().getAdapter(object, expectedClassType); + if (ele != null) { + return ele; + } + // Try as EObject if the expectedClasType is sub-type of EObject. + if (EObject.class.isAssignableFrom(expectedClassType)) { + // to EObject + eobject = Platform.getAdapterManager().getAdapter(object, EObject.class); + + if (eobject != null && expectedClassType.isInstance(eobject)) { + + return (T) eobject; + } + } + } + // Can't be adapted + return null; + + } + + /** + * Filter the list, and only retain objects that can be adapted to the specified type + * + * @param objects + * @param class1 + * @return + */ + private <T> List<T> getAllElementAdaptedToType(List<Object> list, Class<T> expectedClassType) { + + List<T> res = new ArrayList<T>(); + + for (Object cur : list) { + + T adapted = adapt(cur, expectedClassType); + if (adapted != null) { + res.add(adapted); + } + } + return res; + } + + /** + * Get all selected element of the specified type. + * + * @param expectedType + * @return + * @throws ExecutionException + */ + @SuppressWarnings("unchecked") + protected <T> List<T> getCurrentSelectionAdaptedToType(ExecutionEvent event, Class<T> expectedType) throws ExecutionException { + + // Get selection from the workbench + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + + // Get the selected objects according to the type of the selected + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + return getAllElementAdaptedToType(structuredSelection.toList(), expectedType); + } else if (selection instanceof TreeSelection) { + TreeSelection treeSelection = (TreeSelection) selection; + return getAllElementAdaptedToType(treeSelection.toList(), expectedType); + + } + return null; + } +} diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/DeleteCommandHandler.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/DeleteCommandHandler.java index 65a418bc1e7..2de12e791ce 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/DeleteCommandHandler.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/DeleteCommandHandler.java @@ -73,7 +73,7 @@ public class DeleteCommandHandler extends AbstractCommandHandler implements IHan /** * Return if the parameter is page. - * + * * @param current * @return */ @@ -97,7 +97,7 @@ public class DeleteCommandHandler extends AbstractCommandHandler implements IHan * elements. * @param selectedElements elements to delete * @return the composite deletion command for current selection - * + * * @TODO : Manage possible Diagrams listed in the selection * * </pre> diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/PasteHandler.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/PasteHandler.java index 5ff9e7ee1bf..ff9e5eae1bf 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/PasteHandler.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/handler/PasteHandler.java @@ -59,7 +59,7 @@ public class PasteHandler extends AbstractCommandHandler { /* * (non-Javadoc) - * + * * @see org.eclipse.papyrus.views.modelexplorer.handler.AbstractCommandHandler#computeEnabled() */ @Override diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/listener/DoubleClickListener.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/listener/DoubleClickListener.java index e08f794eb21..3b2f5c0b1c4 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/listener/DoubleClickListener.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/listener/DoubleClickListener.java @@ -1,122 +1,122 @@ -/*****************************************************************************
- * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- * Christian W. Damus - bug 450235
- *
- *****************************************************************************/
-package org.eclipse.papyrus.views.modelexplorer.listener;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager;
-import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IOpenable;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
-import org.eclipse.papyrus.views.modelexplorer.Activator;
-import org.eclipse.papyrus.views.modelexplorer.Messages;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-
-/**
- * this class is a listener in charge to manage double on element of the model explorer
- *
- */
-public class DoubleClickListener implements IDoubleClickListener {
-
- private final Supplier<ServicesRegistry> servicesRegistry;
-
- /**
- * Initializes me with a fixed service registry.
- *
- * @param servicesRegistry a service registry
- *
- * @deprecated The editor that the Model Explorer views can change dynamically, replacing its service registry. Use the {@link #DoubleClickListener(Supplier)} constructor instead to account for the variability of the registry.
- */
- @Deprecated
- public DoubleClickListener(ServicesRegistry servicesRegistry) {
- this(Suppliers.ofInstance(servicesRegistry));
- }
-
- /**
- * Initializes me with a variable service registry.
- *
- * @param servicesRegistrySupplier a supplier of a dynamically variable service registry
- */
- public DoubleClickListener(Supplier<ServicesRegistry> servicesRegistrySupplier) {
- this.servicesRegistry = servicesRegistrySupplier;
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
- *
- */
- public void doubleClick(DoubleClickEvent event) {
- ISelection selection = event.getSelection();
- final IPageManager pageManager;
- // get the page Manager
- try {
- pageManager = ServiceUtils.getInstance().getIPageManager(servicesRegistry.get());
- } catch (Exception e) {
- Activator.log.error(Messages.DoubleClickListener_Error_NoLoadManagerToOpen, e);
- return;
- }
-
- if (pageManager != null) {
- if (selection instanceof IStructuredSelection) {
- Iterator<?> iter = ((IStructuredSelection) selection).iterator();
- final List<EObject> pagesToOpen = new LinkedList<EObject>();
- EObject pageToSelect = null;
- while (iter.hasNext()) {
- Object currentObject = iter.next();
- EObject diag = EMFHelper.getEObject(currentObject);
-
- if (isPage(diag, pageManager)) {
- // Note that Diagram migration is triggered by the Diagram Editor.
- // Try to open the diagram, even if it is currently invalid. The editor might be able to repair it
- if (pageManager.isOpen(diag)) {
- pageToSelect = diag;
- } else {
- pagesToOpen.add(diag);
- }
- }
- }
-
- if (!pagesToOpen.isEmpty()) {
- for (EObject page : pagesToOpen) {
- pageManager.openPage(page);
- }
- } else if (pageToSelect != null) {
- pageManager.selectPage(pageToSelect);
- }
- }
-
- }
- }
-
- protected boolean isPage(EObject element, IPageManager pageManager) {
- if (pageManager.allPages().contains(element)) {
- return true;
- }
-
- Object openable = Platform.getAdapterManager().getAdapter(element, IOpenable.class);
- return openable instanceof IOpenable;
- }
-}
+/***************************************************************************** + * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * Christian W. Damus - bug 450235 + * + *****************************************************************************/ +package org.eclipse.papyrus.views.modelexplorer.listener; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager; +import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IOpenable; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.ServiceUtils; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.views.modelexplorer.Activator; +import org.eclipse.papyrus.views.modelexplorer.Messages; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; + +/** + * this class is a listener in charge to manage double on element of the model explorer + * + */ +public class DoubleClickListener implements IDoubleClickListener { + + private final Supplier<ServicesRegistry> servicesRegistry; + + /** + * Initializes me with a fixed service registry. + * + * @param servicesRegistry a service registry + * + * @deprecated The editor that the Model Explorer views can change dynamically, replacing its service registry. Use the {@link #DoubleClickListener(Supplier)} constructor instead to account for the variability of the registry. + */ + @Deprecated + public DoubleClickListener(ServicesRegistry servicesRegistry) { + this(Suppliers.ofInstance(servicesRegistry)); + } + + /** + * Initializes me with a variable service registry. + * + * @param servicesRegistrySupplier a supplier of a dynamically variable service registry + */ + public DoubleClickListener(Supplier<ServicesRegistry> servicesRegistrySupplier) { + this.servicesRegistry = servicesRegistrySupplier; + } + + /** + * + * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) + * + */ + public void doubleClick(DoubleClickEvent event) { + ISelection selection = event.getSelection(); + final IPageManager pageManager; + // get the page Manager + try { + pageManager = ServiceUtils.getInstance().getIPageManager(servicesRegistry.get()); + } catch (Exception e) { + Activator.log.error(Messages.DoubleClickListener_Error_NoLoadManagerToOpen, e); + return; + } + + if (pageManager != null) { + if (selection instanceof IStructuredSelection) { + Iterator<?> iter = ((IStructuredSelection) selection).iterator(); + final List<EObject> pagesToOpen = new LinkedList<EObject>(); + EObject pageToSelect = null; + while (iter.hasNext()) { + Object currentObject = iter.next(); + EObject diag = EMFHelper.getEObject(currentObject); + + if (isPage(diag, pageManager)) { + // Note that Diagram migration is triggered by the Diagram Editor. + // Try to open the diagram, even if it is currently invalid. The editor might be able to repair it + if (pageManager.isOpen(diag)) { + pageToSelect = diag; + } else { + pagesToOpen.add(diag); + } + } + } + + if (!pagesToOpen.isEmpty()) { + for (EObject page : pagesToOpen) { + pageManager.openPage(page); + } + } else if (pageToSelect != null) { + pageManager.selectPage(pageToSelect); + } + } + + } + } + + protected boolean isPage(EObject element, IPageManager pageManager) { + if (pageManager.allPages().contains(element)) { + return true; + } + + Object openable = Platform.getAdapterManager().getAdapter(element, IOpenable.class); + return openable instanceof IOpenable; + } +} diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/sorting/DefaultTreeViewerSorting.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/sorting/DefaultTreeViewerSorting.java index 163c6e6e6f2..24d2ac90e1e 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/sorting/DefaultTreeViewerSorting.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/sorting/DefaultTreeViewerSorting.java @@ -37,7 +37,7 @@ public class DefaultTreeViewerSorting implements ITreeViewerSorting { ITreeViewerSorting result = null; if (part != null) { - result = (ITreeViewerSorting) part.getAdapter(ITreeViewerSorting.class); + result = part.getAdapter(ITreeViewerSorting.class); } if (result == null) { |