Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Barbin2015-07-27 09:40:34 +0000
committerLaurent Redor2015-08-14 07:15:25 +0000
commitbf04a73d6efa05ddc069c6e518b3331f69dda132 (patch)
treea2cdebbc777bd118b0e7c4e68953a145184fa8b1
parentd9bfff3b9751c874ef604a6013b18d0478c055d7 (diff)
downloadorg.eclipse.sirius-bf04a73d6efa05ddc069c6e518b3331f69dda132.tar.gz
org.eclipse.sirius-bf04a73d6efa05ddc069c6e518b3331f69dda132.tar.xz
org.eclipse.sirius-bf04a73d6efa05ddc069c6e518b3331f69dda132.zip
[460610] Adds a selection listener for the bidirectional feature
* Modifies the SessionLinkHelper to select one or several elements when a selection is active * The SiriusCommonContentProvider installs the propertyListener on the link with editor property Bug: 460610 Change-Id: I52d938cdc5f0e24230f01593090aa33a1a19d07b Signed-off-by: Florian Barbin <florian.barbin@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.html1
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile1
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.html18
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.textile2
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SessionLinkHelper.java69
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SiriusCommonContentProvider.java48
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/modelexplorer/SiriusDialectLinkWithEditorSelectionListener.java321
7 files changed, 408 insertions, 52 deletions
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
index e01d52181c..58da2e3baf 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
@@ -71,6 +71,7 @@
<em>Snap to Shapes</em> are now automatically disabled on Sequence diagrams. As indicated in the user documentation, to work correctly, Sirius sequence diagrams must have a tight control on where the graphical elements are placed on the diagram and on their synchronization with the underlying semantic model. see
<a href="./user/sequences/Sequence%20Diagrams.html#introduction">documentation</a> for details. Previously, the user has to explicitely disable the snap features.
</li>
+ <li><span class="label label-info">Modified</span> The Link with Editor behavior has changed. The link with editor was previously unidirectional from the Common Navigator (Model Explorer view or Project view) toward the active representation. By now, when selecting one or several elements in the representation, the corresponding semantic elements are selected in the Common Navigator.</li>
</ul>
<h3 id="SpecifierVisibleChanges">Specifier-Visible Changes</h3>
<ul>
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
index 448ee0e3e3..d2875a91c2 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
@@ -10,6 +10,7 @@ h3. User-Visible Changes
* <span class="label label-success">Added</span> A new feature allows to snap to all shapes (instead of just to snap to brother shapes). The <kdb>F4</kdb> shortcut key activates this mode when you resize a node, move a node or move a bendpoint of edge, see "documentation":./user/diagrams/Diagrams.html#snap_to_shapes for details.
* <span class="label label-info">Modified</span> The _Snap to Grid_ and _Snap to Shapes_ are now automatically disabled on Sequence diagrams. As indicated in the user documentation, to work correctly, Sirius sequence diagrams must have a tight control on where the graphical elements are placed on the diagram and on their synchronization with the underlying semantic model. see "documentation":./user/sequences/Sequence%20Diagrams.html#introduction for details. Previously, the user has to explicitely disable the snap features.
+* <span class="label label-info">Modified</span> The Link with Editor behavior has changed. The link with editor was previously unidirectional from the Common Navigator (Model Explorer view or Project view) toward the active representation. By now, when selecting one or several elements in the representation, the corresponding semantic elements are selected in the Common Navigator.
h3. Specifier-Visible Changes
diff --git a/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.html b/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.html
index 2f69ab1af5..7973aae608 100644
--- a/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.html
+++ b/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.html
@@ -134,7 +134,7 @@
<em>dialect</em> is a kind of representation supported by Sirius. Out of the box, Sirius supports three dialects: diagrams, tables, and trees. Sequence diagrams and cross-tables, which are special kinds of diagrams (resp. tables) can also be considered of as dialects, although technically they are not.
</li>
<li>a
- <em>representation</em> is a particular diagram, table, or tree which you created on your semantic model. It is simply a more general term than &#171;diagram&#187; which is also usable for other dialects.
+ <em>representation</em> is a particular diagram, table, or tree which you created on your semantic model. It is simply a more general term than &#8220;diagram&#8221; which is also usable for other dialects.
</li>
<li>a
<em>representation file</em> is a file in which Sirius stores all informations related to which representations you created, what appears on them, the positions and colors of the elements, etc. This files have a
@@ -161,7 +161,7 @@
<p>Representation files are now automatically migrated when opened. This migration is transparent for the end-user. While a representation file is not saved, the automatic migration will be replayed at the next opening.</p>
<h3 id="UICHanges">User Interface Changes</h3>
<p>You will notice some radical changes in the user interface. The most important change is the disappearance of the
- <em>Model Content</em> view. It has been replaced with a streamlined UI which integrates directly into the Eclipse explorer view. The notion of &#171;Local Session&#187; has disappeared from the user interface; its management has been made as transparent as possible so you do not have to deal with it except in some very specific circumstances.
+ <em>Model Content</em> view. It has been replaced with a streamlined UI which integrates directly into the Eclipse explorer view. The notion of &#8220;Local Session&#8221; has disappeared from the user interface; its management has been made as transparent as possible so you do not have to deal with it except in some very specific circumstances.
</p>
<p>The recommended way to use Sirius is now to use the new notion of
<em>Modeling Project</em> described below. If you already have existing Sirius representation files (
@@ -179,7 +179,7 @@
<li>A
<a href="#ModelExplorer">
<em>Model Explorer</em>
- </a>, which is the main UI to interact with your models. (For users of previous versions, this explorer includes directly all the features which were found in the &#171;Model Content&#187; view before).
+ </a>, which is the main UI to interact with your models. (For users of previous versions, this explorer includes directly all the features which were found in the &#8220;Model Content&#8221; view before).
</li>
<li>An
<em>Outline</em> view, which provides a structural overview of the document or model currently opened. For diagrams, it shows a miniature view of the whole diagram on which you can easily navigate to other parts of the diagram for large ones.
@@ -209,15 +209,15 @@
</p>
<img border="0" src="images/model_explorer_view.png"/>
<p>In the example above, the
- <code>example</code> modeling project (note the blue &#171;M&#187; decorator on the project icon) contains a single semantic model, the
+ <code>example</code> modeling project (note the blue &#8220;M&#8221; decorator on the project icon) contains a single semantic model, the
<code>example.ecore</code> file, and a single representation file
<code>representations.aird</code>. Both can be expanded directly from inside the
<em>Model Explorer</em> view, to discover the structure of the semantic model and the graphical representations which already exist.
</p>
<p>The
- <em>Model Explorer</em> supports the &#171;Link with Editor&#187; feature, which can be enabled by pressing the icon in the top right corner of the view (the one with two horizontal arrows, pressed in the screenshot above). When this mode is enabled, if you have a representation opened, clicking anywhere on it will automatically select the corresponding representation inside the
- <em>Model Explorer</em> (expanding the project and files if necessary). Conversely, if you select a semantic element from one of your semantic models in the
- <em>Model Explorer</em> view and if this element is represented somewhere on the opened editor, it will be automatically selected. This can be very useful when you have many projects and representation or large representations to avoid getting lost.
+ <em>Model Explorer</em> supports the &#8220;Link with Editor&#8221; feature, which can be enabled by pressing the icon in the top right corner of the view (the one with two horizontal arrows, pressed in the screenshot above). When this mode is enabled, if you have a representation opened, clicking anywhere on it will automatically select the corresponding semantic element(s) inside the
+ <em>Model Explorer</em> (expanding the project and files if necessary). Conversely, if you select one or several semantic element(s) from one of your semantic models in the
+ <em>Model Explorer</em> view and if these elements are represented somewhere on the opened editor, they will be automatically selected. This can be very useful when you have many projects and representation or large representations to avoid getting lost.
</p>
<p>The
<em>Model Explorer</em> also supports filtering of elements from inside
@@ -225,7 +225,7 @@
<code>Element</code> in the search box, only the model elements whose name starts with
<code>Element</code> will be shown. You can use the
<code>*</code> and
- <code>?</code> special characters in your search string to mean respectively &#171;any text&#187; (including none) and &#171;any single character&#187;. For example the search string
+ <code>?</code> special characters in your search string to mean respectively &#8220;any text&#8221; (including none) and &#8220;any single character&#8221;. For example the search string
<code>*Element</code> will show all elements whose name
<em>contains</em> the string
<code>Element</code> anywhere.
@@ -280,7 +280,7 @@
<em>New &gt; Modeling Project</em>.
</p>
<img border="0" src="images/new_project1.png"/>
- <p>A wizard opens, asking for a mandatory project name. Entering an invalid project name will result in an error message. By default, the modeling project will be created in the workspace&#8217;s location, but this can be changed: just uncheck &#171;Use default location&#187; and enter the path to the location where you want your modeling project to be created.</p>
+ <p>A wizard opens, asking for a mandatory project name. Entering an invalid project name will result in an error message. By default, the modeling project will be created in the workspace&#8217;s location, but this can be changed: just uncheck &#8220;Use default location&#8221; and enter the path to the location where you want your modeling project to be created.</p>
<img border="0" src="images/new_project2.png"/>
<p>When you are done, click
<em>Finish</em> to actually create the modeling project. It will appear in the
diff --git a/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.textile b/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.textile
index 0ee7f10615..8544cc3ff8 100644
--- a/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/user/general/Modeling Project.textile
@@ -65,7 +65,7 @@ For instance, inside the _Model Explorer_, semantic models and representation fi
In the example above, the @example@ modeling project (note the blue "M" decorator on the project icon) contains a single semantic model, the @example.ecore@ file, and a single representation file @representations.aird@. Both can be expanded directly from inside the _Model Explorer_ view, to discover the structure of the semantic model and the graphical representations which already exist.
-The _Model Explorer_ supports the "Link with Editor" feature, which can be enabled by pressing the icon in the top right corner of the view (the one with two horizontal arrows, pressed in the screenshot above). When this mode is enabled, if you have a representation opened, clicking anywhere on it will automatically select the corresponding representation inside the _Model Explorer_ (expanding the project and files if necessary). Conversely, if you select a semantic element from one of your semantic models in the _Model Explorer_ view and if this element is represented somewhere on the opened editor, it will be automatically selected. This can be very useful when you have many projects and representation or large representations to avoid getting lost.
+The _Model Explorer_ supports the "Link with Editor" feature, which can be enabled by pressing the icon in the top right corner of the view (the one with two horizontal arrows, pressed in the screenshot above). When this mode is enabled, if you have a representation opened, clicking anywhere on it will automatically select the corresponding semantic element(s) inside the _Model Explorer_ (expanding the project and files if necessary). Conversely, if you select one or several semantic element(s) from one of your semantic models in the _Model Explorer_ view and if these elements are represented somewhere on the opened editor, they will be automatically selected. This can be very useful when you have many projects and representation or large representations to avoid getting lost.
The _Model Explorer_ also supports filtering of elements from inside _Modeling Projects_ (and only these elements): if you enter some text in the search box at the top of the view, the view will filter out all the elements which do not match your text. For example if you enter @Element@ in the search box, only the model elements whose name starts with @Element@ will be shown. You can use the @*@ and @?@ special characters in your search string to mean respectively "any text" (including none) and "any single character". For example the search string @*Element@ will show all elements whose name _contains_ the string @Element@ anywhere.
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SessionLinkHelper.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SessionLinkHelper.java
index de1d444676..8f0407be42 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SessionLinkHelper.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SessionLinkHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 THALES GLOBAL SERVICES.
+ * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES 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
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.sirius.ui.tools.internal.views.common.navigator;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -26,7 +27,6 @@ import org.eclipse.sirius.ui.business.api.session.SessionEditorInput;
import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
import org.eclipse.sirius.ui.tools.internal.views.common.item.RepresentationItemImpl;
import org.eclipse.sirius.viewpoint.DRepresentation;
-import org.eclipse.sirius.viewpoint.DRepresentationElement;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
@@ -36,14 +36,14 @@ import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.navigator.ILinkHelper;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
/**
* The current link helper is able to activate an opened editor on the selected
* representation in a common viewer.
*
- * For an EObject selection, the selection in the activated editor is updated
- * with
+ * For one or several EObject selection in the Common Navigator, the selection
+ * is now handled by the
+ * <code>SiriusDialectLinkWithEditorSelectionListener</code>.
*
* @author mporhel
*
@@ -54,26 +54,39 @@ public class SessionLinkHelper implements ILinkHelper {
*/
@Override
public IStructuredSelection findSelection(IEditorInput anInput) {
- Object foundElement = null;
+ IStructuredSelection returnSelection = null;
IFile file = ResourceUtil.getFile(anInput);
if (file != null) {
- foundElement = file;
+ returnSelection = new StructuredSelection(file);
}
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart editor = page.findEditor(anInput);
- if (editor != null) {
+ if (editor instanceof DialectEditor) {
+
+ Collection<DSemanticDecorator> semanticDecorators = DialectUIManager.INSTANCE.getSelection((DialectEditor) editor);
- // It is possible to get the representation, the associated semantic
- // element or even the semantic selection.
- // The choice was made to select representation.
- Object editorRepresentation = getEditorRepresentation(anInput, editor);
- if (editorRepresentation != null) {
- foundElement = editorRepresentation;
+ // When the focus is set back on the representation by selecting
+ // a representation element, we select the corresponding target
+ // instead of the representation node.
+ if (!semanticDecorators.isEmpty()) {
+ List<EObject> elements = new ArrayList<EObject>();
+ for (DSemanticDecorator currentDecorator : semanticDecorators) {
+ elements.add(currentDecorator.getTarget());
+ }
+ returnSelection = new StructuredSelection(elements);
+ } else {
+ // It is possible to get the representation, the associated
+ // semantic element or even the semantic selection. The choice
+ // was made to select representation.
+ Object editorRepresentation = getEditorRepresentation(anInput, editor);
+ if (editorRepresentation != null) {
+ returnSelection = new StructuredSelection(editorRepresentation);
+ }
}
}
- return foundElement == null ? StructuredSelection.EMPTY : new StructuredSelection(foundElement);
+ return returnSelection == null ? StructuredSelection.EMPTY : returnSelection;
}
private Object getEditorRepresentation(IEditorInput anInput, IEditorPart editor) {
@@ -113,11 +126,6 @@ public class SessionLinkHelper implements ILinkHelper {
}
}
}
- } else if (activeEditor instanceof DialectEditor && activeEditor.getEditorInput() instanceof SessionEditorInput && aSelection.getFirstElement() instanceof EObject) {
- aPage.bringToTop(activeEditor);
- DialectEditor dialectEditor = (DialectEditor) activeEditor;
- List<DRepresentationElement> vpSelection = getRepresentationsForElement(dialectEditor.getRepresentation(), aSelection.toList());
- DialectUIManager.INSTANCE.setSelection(dialectEditor, vpSelection);
}
}
@@ -134,25 +142,4 @@ public class SessionLinkHelper implements ILinkHelper {
}
return rep;
}
-
- /**
- * Get the representation element from the semantic one.
- *
- * @param representation
- * the representation
- * @param selection
- * the semantic element
- * @return the first representation element which has as target the semantic
- * element given as parameter
- */
- protected final List<DRepresentationElement> getRepresentationsForElement(final DRepresentation representation, final List<?> selection) {
- List<DRepresentationElement> result = Lists.newArrayList();
- if (representation != null) {
- for (final DRepresentationElement element : representation.getRepresentationElements()) {
- if (selection != null && selection.contains(element.getTarget()))
- result.add(element);
- }
- }
- return result;
- }
}
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SiriusCommonContentProvider.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SiriusCommonContentProvider.java
index c7eed3dc2a..d075717a57 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SiriusCommonContentProvider.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/common/navigator/SiriusCommonContentProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES 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
@@ -57,6 +57,7 @@ import org.eclipse.sirius.ui.tools.internal.views.common.item.AnalysisResourceIt
import org.eclipse.sirius.ui.tools.internal.views.common.item.ControlledRoot;
import org.eclipse.sirius.ui.tools.internal.views.common.item.InternalCommonItem;
import org.eclipse.sirius.ui.tools.internal.views.common.item.ProjectDependenciesItemImpl;
+import org.eclipse.sirius.ui.tools.internal.views.modelexplorer.SiriusDialectLinkWithEditorSelectionListener;
import org.eclipse.sirius.viewpoint.DAnalysisSessionEObject;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
@@ -64,6 +65,8 @@ import org.eclipse.sirius.viewpoint.description.Viewpoint;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMemento;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.ICommonContentProvider;
import org.eclipse.ui.progress.UIJob;
@@ -105,6 +108,8 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
private ITreeViewerListener expandListener;
+ private SiriusDialectLinkWithEditorSelectionListener linkWithEditorSelectionListener;
+
/**
* Constructor.
*/
@@ -158,6 +163,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public Object[] getChildren(Object parentElement) {
Collection<Object> allChildren = Lists.newArrayList();
@@ -203,6 +209,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
// modeling projects, all aird for modeling ones, semantic file for
// transient sessions.
List<Session> openedSessions = Lists.newArrayList(Iterables.filter(FileSessionFinder.getSelectedSessions(Collections.singletonList(parentFile)), new Predicate<Session>() {
+ @Override
public boolean apply(Session input) {
return input.isOpen();
}
@@ -305,6 +312,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public Object getParent(Object element) {
Object parent = null;
@@ -390,6 +398,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public boolean hasChildren(Object element) {
if (element instanceof IFile) {
// Show expansion arrows during session load.
@@ -404,6 +413,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
@@ -411,6 +421,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (defaultContentProvider != null) {
defaultContentProvider.inputChanged(viewer, oldInput, newInput);
@@ -419,11 +430,27 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
if (viewer != myViewer) {
removeDoubleClickListener();
removeExpandListener();
+ if (linkWithEditorSelectionListener != null) {
+ linkWithEditorSelectionListener.dispose();
+ }
myViewer = viewer;
addDoubleClickListener();
addExpandListener();
+ createLWESelectionListener();
+ }
+ }
+
+ /**
+ * Creates and initializes the
+ * {@link SiriusDialectLinkWithEditorSelectionListener}.
+ */
+ private void createLWESelectionListener() {
+ if (myViewer instanceof CommonViewer) {
+ CommonNavigator commonNavigator = ((CommonViewer) myViewer).getCommonNavigator();
+ linkWithEditorSelectionListener = new SiriusDialectLinkWithEditorSelectionListener(commonNavigator);
+ linkWithEditorSelectionListener.init();
}
}
@@ -454,12 +481,14 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public void init(ICommonContentExtensionSite aConfig) {
}
/**
* {@inheritDoc}
*/
+ @Override
public void dispose() {
removeDoubleClickListener();
removeExpandListener();
@@ -479,6 +508,8 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
SessionManager.INSTANCE.removeSessionsListener(sessionManagerListener);
sessionManagerListener = null;
}
+ linkWithEditorSelectionListener.dispose();
+ linkWithEditorSelectionListener = null;
}
/**
@@ -550,6 +581,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
*/
private void updateViewer(final Collection<?> toUpdate) {
Runnable updateViewer = new Runnable() {
+ @Override
public void run() {
if (myViewer instanceof StructuredViewer && toUpdate != null && !toUpdate.isEmpty()) {
((StructuredViewer) myViewer).update(toUpdate.toArray(), null);
@@ -573,6 +605,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
*/
private void refreshViewer(final Collection<?> toRefresh) {
Runnable refreshViewer = new Runnable() {
+ @Override
public void run() {
try {
if (myViewer instanceof StructuredViewer && toRefresh != null && !toRefresh.isEmpty()) {
@@ -707,6 +740,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
private void postAsyncUpdate(final Display display) {
if (updateJob == null) {
updateJob = new UIJob(display, "Async viewer updates") {
+ @Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (isViewerBusy()) {
schedule(100);
@@ -750,6 +784,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public void saveState(IMemento aMemento) {
// Do nothing
}
@@ -757,6 +792,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public void restoreState(IMemento aMemento) {
// Do nothing
}
@@ -812,23 +848,28 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
* Session Manager Listener.
*/
private class CommonSessionManagerListener implements SessionManagerListener {
+ @Override
public void notifyAddSession(Session newSession) {
/* does nothing. */
}
+ @Override
public void notifyRemoveSession(Session removedSession) {
removeRefreshViewerTriggers(removedSession);
refreshViewer(removedSession);
}
+ @Override
public void viewpointSelected(Viewpoint selectedSirius) {
/* does nothing. */
}
+ @Override
public void viewpointDeselected(Viewpoint deselectedSirius) {
// does nothing.
}
+ @Override
public void notify(Session updated, int notification) {
switch (notification) {
case SessionListener.REPRESENTATION_CHANGE:
@@ -864,6 +905,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
/**
* {@inheritDoc}
*/
+ @Override
public boolean apply(Session input) {
return new URIQuery(input.getSessionResource().getURI()).isInMemoryURI();
}
@@ -885,10 +927,12 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
return session;
}
+ @Override
public void resourceSetChanged(ResourceSetChangeEvent event) {
Collection<Notification> notifications = Lists.newArrayList(Iterables.filter(Iterables.filter(event.getNotifications(), Notification.class), new RefreshViewerTriggerScope(session)));
Function<Notification, Object> notifToNotifier = new Function<Notification, Object>() {
+ @Override
public Object apply(Notification from) {
return from.getNotifier();
}
@@ -931,6 +975,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
return false;
}
+ @Override
public boolean isPostcommitOnly() {
return true;
}
@@ -954,6 +999,7 @@ public class SiriusCommonContentProvider implements ICommonContentProvider {
}
}
+ @Override
public boolean apply(Notification notification) {
Object notifier = notification.getNotifier();
boolean result = false;
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/modelexplorer/SiriusDialectLinkWithEditorSelectionListener.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/modelexplorer/SiriusDialectLinkWithEditorSelectionListener.java
new file mode 100644
index 0000000000..fd20ef9ed8
--- /dev/null
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/internal/views/modelexplorer/SiriusDialectLinkWithEditorSelectionListener.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.ui.tools.internal.views.modelexplorer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
+import org.eclipse.sirius.viewpoint.DRepresentation;
+import org.eclipse.sirius.viewpoint.DRepresentationElement;
+import org.eclipse.sirius.viewpoint.DSemanticDecorator;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+import com.google.common.collect.Lists;
+
+/**
+ * This listener provides the synchronized behavior between the dialect selected
+ * element(s) and the given CommonNavigator. As a {@link IPropertyListener}, it
+ * will listen to the property <code>IS_LINKING_ENABLED_PROPERTY</code>. If the
+ * "link with editor" is activated, it will register itself as a
+ * {@link IPartListener2}. If a new {@link DialectEditor} is opened (or closed),
+ * it will register (or remove) itself as a {@link ISelectionChangedListener} to
+ * update the {@link CommonNavigator} according to the selection.</br>
+ * When the "link with editor" is deactivated, it will remove itself from all
+ * {@link DialectEditor} selectionListeners and from IPartListeners.
+ *
+ * @author Florian Barbin
+ *
+ */
+public class SiriusDialectLinkWithEditorSelectionListener implements ISelectionChangedListener, IPropertyListener, IPartListener2 {
+
+ private CommonNavigator navigator;
+
+ private IPartService partService;
+
+ private Collection<DialectEditor> registeredEditors;
+
+ /**
+ * Default constructor.
+ *
+ * @param navigator
+ * the common navigator.
+ */
+ public SiriusDialectLinkWithEditorSelectionListener(CommonNavigator navigator) {
+ this.navigator = navigator;
+ this.registeredEditors = new ArrayList<DialectEditor>();
+
+ }
+
+ /**
+ * Initialize the Selection Listener.
+ */
+ public void init() {
+ this.navigator.addPropertyListener(this);
+ partService = getPartService();
+
+ // If the linking is already activated at the initialization, we
+ // register the IPartListener2 and the ISelectionChangedListener on each
+ // opened DialectEditor.
+ if (this.navigator.isLinkingEnabled()) {
+ enableSelectionListener();
+ }
+ }
+
+ /**
+ * Removes this listener from IPartService and all editors where it is
+ * registered.
+ */
+ public void dispose() {
+ disableSelectionListener();
+ navigator = null;
+ partService = null;
+ }
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+ if (selection instanceof IStructuredSelection) {
+
+ // If the selection come from the navigator, we select the
+ // corresponding representations elements.
+ if (event.getSource().equals(navigator.getCommonViewer())) {
+
+ IWorkbenchPage page = EclipseUIUtil.getActivePage();
+ IEditorPart activeEditor = page.getActiveEditor();
+ if (activeEditor instanceof DialectEditor) {
+ page.bringToTop(activeEditor);
+ DialectEditor dialectEditor = (DialectEditor) activeEditor;
+ List<DRepresentationElement> representationElements = getRepresentationElements(dialectEditor.getRepresentation(), ((IStructuredSelection) selection).toList());
+ DialectUIManager.INSTANCE.setSelection(dialectEditor, representationElements);
+ }
+ } else {
+ Set<EObject> targets = getTargetsFromSelection((IStructuredSelection) selection);
+ if (!targets.isEmpty()) {
+ Set<Object> currentSelection = getCurrentNavigatorSelection();
+ // If the current navigator selection is the same than the
+ // representation one, we do nothing to avoid loops.
+ if (!targets.equals(currentSelection)) {
+ navigator.selectReveal(new StructuredSelection(targets.toArray()));
+ }
+ }
+ }
+ }
+ }
+
+ private List<DRepresentationElement> getRepresentationElements(final DRepresentation representation, final List<?> selection) {
+ List<DRepresentationElement> result = Lists.newArrayList();
+ if (representation != null) {
+ for (final DRepresentationElement element : representation.getRepresentationElements()) {
+ if (selection != null && selection.contains(element.getTarget()))
+ result.add(element);
+ }
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Set<Object> getCurrentNavigatorSelection() {
+
+ Set<Object> selection = new HashSet<Object>();
+ ISelection iSelection = navigator.getCommonViewer().getSelection();
+ if (iSelection instanceof IStructuredSelection) {
+ selection.addAll(((IStructuredSelection) iSelection).toList());
+ }
+ return selection;
+ }
+
+ /**
+ * When the IS_LINKING_ENABLED_PROPERTY changes, we activate or deactivate
+ * this listener.
+ */
+ @Override
+ public void propertyChanged(Object source, int propId) {
+ if (propId == CommonNavigator.IS_LINKING_ENABLED_PROPERTY) {
+ // if the link with editor property has changed, we install or
+ // remove the synchronizer according to the new value.
+ if (navigator.isLinkingEnabled()) {
+ enableSelectionListener();
+ } else {
+ disableSelectionListener();
+ }
+ }
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPartReference partRef) {
+ }
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ }
+
+ /**
+ * When a {@link DialectEditor} is closed, we remove this instance from
+ * {@link ISelectionChangedListener}s.
+ */
+ @Override
+ public void partClosed(IWorkbenchPartReference partRef) {
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part instanceof DialectEditor && registeredEditors.contains(part)) {
+ removeSelectionListener((DialectEditor) part);
+ registeredEditors.remove(part);
+ }
+ }
+
+ @Override
+ public void partDeactivated(IWorkbenchPartReference partRef) {
+ }
+
+ /**
+ * When a {@link DialectEditor} is opened, we register this instance as a
+ * {@link ISelectionChangedListener}.
+ */
+ @Override
+ public void partOpened(IWorkbenchPartReference partRef) {
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part instanceof DialectEditor && !registeredEditors.contains(part)) {
+ addSelectionListener((DialectEditor) part);
+ registeredEditors.add((DialectEditor) part);
+ }
+ }
+
+ @Override
+ public void partHidden(IWorkbenchPartReference partRef) {
+ }
+
+ @Override
+ public void partVisible(IWorkbenchPartReference partRef) {
+ }
+
+ @Override
+ public void partInputChanged(IWorkbenchPartReference partRef) {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private Set<EObject> getTargetsFromSelection(IStructuredSelection iStructuredSelection) {
+ Set<EObject> targets = new HashSet<EObject>();
+ for (Iterator<Object> iterator = iStructuredSelection.iterator(); iterator.hasNext(); /**/) {
+ Object element = iterator.next();
+ DSemanticDecorator decorator = null;
+ if (element instanceof DSemanticDecorator) {
+ decorator = (DSemanticDecorator) element;
+ } else if (element instanceof IAdaptable) {
+ decorator = (DSemanticDecorator) ((IAdaptable) element).getAdapter(DSemanticDecorator.class);
+ }
+
+ if (decorator != null) {
+ // If the selection is the representation, we want to select the
+ // representation node and not its semantic element.
+ if (decorator instanceof DRepresentation) {
+ targets.add(decorator);
+ } else {
+ targets.add(decorator.getTarget());
+ }
+ }
+
+ }
+ return targets;
+ }
+
+ /**
+ * Adds this instance as a {@link ISelectionChangedListener} on the given
+ * editor.
+ *
+ * @param editor
+ * the {@link DialectEditor}.
+ */
+ private void addSelectionListener(DialectEditor editor) {
+ ISelectionProvider selectionProvider = editor.getEditorSite().getSelectionProvider();
+ selectionProvider.addSelectionChangedListener(this);
+ }
+
+ private IPartService getPartService() {
+ IViewSite site = navigator.getViewSite();
+ if (site != null) {
+ return (IPartService) site.getService(IPartService.class);
+ }
+ return null;
+ }
+
+ /**
+ * Registers this instance as a {@link IPartListener2} and as a
+ * {@link ISelectionChangedListener} on each opened {@link DialectEditor}.
+ */
+ private void enableSelectionListener() {
+ if (partService != null) {
+ // We register this listener on the current viewer to have a
+ // bidirectional selection.
+ navigator.getCommonViewer().addSelectionChangedListener(this);
+ partService.addPartListener(this);
+ IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
+ for (IEditorReference editorReference : editorReferences) {
+ IEditorPart editorPart = editorReference.getEditor(false);
+ if (editorPart instanceof DialectEditor) {
+ addSelectionListener((DialectEditor) editorPart);
+ registeredEditors.add((DialectEditor) editorPart);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes this instance from the {@link IPartListener2}s and from all
+ * {@link DialectEditor} selectionListeners.
+ */
+ private void disableSelectionListener() {
+ if (partService != null) {
+ navigator.getCommonViewer().removeSelectionChangedListener(this);
+ partService.removePartListener(this);
+ for (DialectEditor dialectEditor : registeredEditors) {
+ removeSelectionListener(dialectEditor);
+ }
+ registeredEditors.clear();
+ }
+ }
+
+ /**
+ * Removes this instance from the given editor selection listeners.
+ *
+ * @param dialectEditor
+ * the {@link DialectEditor}.
+ */
+ private void removeSelectionListener(DialectEditor dialectEditor) {
+ ISelectionProvider selectionProvider = dialectEditor.getEditorSite().getSelectionProvider();
+ selectionProvider.removeSelectionChangedListener(this);
+ }
+
+}

Back to the top