diff options
author | Christian W. Damus | 2014-07-25 19:19:58 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2014-07-25 19:19:58 +0000 |
commit | 43af1aa06fba01ee95ad7b72f07cabf80321bce2 (patch) | |
tree | 244572e62a28ef2180c216b7a9bb445816614cda /plugins/views | |
parent | d558c050796a7e06772835b0b5bb6a936166b0bb (diff) | |
parent | dfde88b139d345b628415dda0769aa87dd7733c6 (diff) | |
download | org.eclipse.papyrus-43af1aa06fba01ee95ad7b72f07cabf80321bce2.tar.gz org.eclipse.papyrus-43af1aa06fba01ee95ad7b72f07cabf80321bce2.tar.xz org.eclipse.papyrus-43af1aa06fba01ee95ad7b72f07cabf80321bce2.zip |
Merge "437217: [Editors] In-place reloading of model resources in the editors https://bugs.eclipse.org/bugs/show_bug.cgi?id=437217"
Diffstat (limited to 'plugins/views')
3 files changed, 287 insertions, 122 deletions
diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerTreeViewerContext.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerTreeViewerContext.java new file mode 100644 index 00000000000..e81398f494a --- /dev/null +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerTreeViewerContext.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2010, 2014 CEA and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * Christian W. Damus (CEA) - adapted from ModelExplorerView::reveal(...) API + * + */ +package org.eclipse.papyrus.views.modelexplorer; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.papyrus.infra.core.editor.reload.EMFTreeViewerContext; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +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 com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + + +/** + * A specialization of the editor re-load tree viewer context that knows how to expand and select nodes + * in the EMF Facet-based Model Explorer view. + */ +class ModelExplorerTreeViewerContext extends EMFTreeViewerContext { + + public ModelExplorerTreeViewerContext(AbstractTreeViewer viewer) { + super(viewer); + } + + public Object deresolveSelectableElement(Object selectableElement) { + return EMFHelper.getEObject(selectableElement); + } + + public Object resolveSelectableElement(Object object) { + return new ModelElementItemMatchingItemWithElement((EObject)object); + } + + @Override + protected void setExpandedElements(AbstractTreeViewer viewer, Collection<?> toExpand) { + // EMF Facet makes expanding tree elements very complicated + if(viewer.getContentProvider() != null) { + for(ModelElementItemMatchingItemWithElement next : Iterables.filter(toExpand, ModelElementItemMatchingItemWithElement.class)) { + + // retrieve the ancestors to reveal them + // and allow the selection of the object + EObject currentEObject = next.element(); + 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())) { + viewer.expandToLevel(new ReferencableMatchingItem(rs), 1); + viewer.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) { + viewer.expandToLevel(new LinkItemMatchingItem(previousParent, parent.eContainmentFeature()), 1); + } + + final IMatchingItem itemToExpand = new ModelElementItemMatchingItem(parent); + viewer.expandToLevel(itemToExpand, 1); + + previousParent = parent; + } + + // expand a reference-link item, if necessary + final IMatchingItem linkItem = new LinkItemMatchingItem(currentEObject.eContainer(), currentEObject.eContainmentFeature()); + viewer.expandToLevel(linkItem, 1); + + // and the actual element + viewer.expandToLevel(next, 1); + } + } + } + + // + // Nested types + // + + static class ModelElementItemMatchingItemWithElement extends ModelElementItemMatchingItem { + + private EObject element; + + ModelElementItemMatchingItemWithElement(EObject element) { + super(element); + + this.element = element; + } + + EObject element() { + return element; + } + } +} 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 7f2a6262cf1..b7f71045b88 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 @@ -12,6 +12,7 @@ * 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
*
*****************************************************************************/
package org.eclipse.papyrus.views.modelexplorer;
@@ -53,6 +54,10 @@ 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;
@@ -127,7 +132,7 @@ import com.google.common.collect.Lists; public class ModelExplorerView extends CommonNavigator implements IRevealSemanticElement, IEditingDomainProvider, IPageLifeCycleEventsListener {
private SharedModelExplorerState sharedState;
-
+
private SharedModelExplorerState.StateChangedListener sharedStateListener;
/**
@@ -138,16 +143,10 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti public static final String LABEL_PROVIDER_SERVICE_CONTEXT = "org.eclipse.papyrus.views.modelexplorer.labelProvider.context";
/**
- * The associated EditorPart
- * The View is associated to the ServicesRegistry rather than to an editor.
- * */
- // private IMultiDiagramEditor editorPart;
-
- /**
* The {@link ServicesRegistry} associated to the Editor. This view is associated to the
* ServicesRegistry rather than to the EditorPart.
*/
- private final ServicesRegistry serviceRegistry;
+ private ServicesRegistry serviceRegistry;
/** The save aservice associated to the editor. */
private ISaveAndDirtyService saveAndDirtyService;
@@ -217,10 +216,37 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti 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 = part.getServicesRegistry();
+ serviceRegistry = editor.getServicesRegistry();
if(serviceRegistry == null) {
- throw new IllegalArgumentException("The part should have a ServiceRegistry.");
+ throw new IllegalArgumentException("The editor should have a ServiceRegistry.");
}
// Get required services from ServicesRegistry
@@ -228,7 +254,7 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti saveAndDirtyService = serviceRegistry.getService(ISaveAndDirtyService.class);
undoContext = serviceRegistry.getService(IUndoContext.class);
} catch (ServiceException e) {
- e.printStackTrace();
+ Activator.log.error(e);
}
}
@@ -341,6 +367,41 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti @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
@@ -375,36 +436,6 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti }
}
contentService.dispose(); // No longer need this
-
- 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);
- }
}
@Override
@@ -625,6 +656,19 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti 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;
+ }
+ }
+ });
}
/**
@@ -753,8 +797,6 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti * Activate specified Part.
*/
private void activate() {
-
-
try {
this.editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
@@ -777,19 +819,6 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti if(this.getCommonViewer() != null) {
syncRefresh();
}
-
- // 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;
- }
- }
- });
}
/**
@@ -801,6 +830,15 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti 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
@@ -811,6 +849,11 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti editingDomain = null;
}
+ saveAndDirtyService = null;
+ undoContext = null;
+ editingDomain = null;
+ editingDomain = null;
+ lastTrans = null;
}
/**
@@ -828,31 +871,19 @@ public class ModelExplorerView extends CommonNavigator implements IRevealSemanti sharedState.removeListener(sharedStateListener);
}
- try {
- ISashWindowsContainer sashWindowsContainer = serviceRegistry.getService(ISashWindowsContainer.class);
- if(sashWindowsContainer != null) {
- sashWindowsContainer.removePageLifeCycleListener(this);
- }
- } catch (ServiceException ex) {
- //Ignore
+ if(getSite() != null) {
+ getSite().getPage().removeSelectionListener(pageSelectionListener);
}
deactivate();
- saveAndDirtyService = null;
- undoContext = null;
- editingDomain = null;
- pageSelectionListener = null;
- editingDomain = null;
- lastTrans = null;
-
for(IPropertySheetPage propertySheetPage : this.propertySheetPages) {
propertySheetPage.dispose();
}
propertySheetPages.clear();
-
+ pageSelectionListener = null;
super.dispose();
diff --git a/plugins/views/validation/org.eclipse.papyrus.views.validation/src/org/eclipse/papyrus/views/validation/internal/providers/ProblemsContentProvider.java b/plugins/views/validation/org.eclipse.papyrus.views.validation/src/org/eclipse/papyrus/views/validation/internal/providers/ProblemsContentProvider.java index 23b5f5c347c..c47c5d83a33 100644 --- a/plugins/views/validation/org.eclipse.papyrus.views.validation/src/org/eclipse/papyrus/views/validation/internal/providers/ProblemsContentProvider.java +++ b/plugins/views/validation/org.eclipse.papyrus.views.validation/src/org/eclipse/papyrus/views/validation/internal/providers/ProblemsContentProvider.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2013 CEA LIST. + * Copyright (c) 2013, 2014 CEA LIST and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,6 +8,8 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Christian W. Damus (CEA) - bug 437217 + * *****************************************************************************/ package org.eclipse.papyrus.views.validation.internal.providers; @@ -31,8 +33,7 @@ import com.google.common.collect.Iterables; /** * This is the ProblemsContentProvider type. Enjoy. */ -public class ProblemsContentProvider - implements IStructuredContentProvider { +public class ProblemsContentProvider implements IStructuredContentProvider { private static final Object[] NONE = {}; @@ -53,31 +54,30 @@ public class ProblemsContentProvider } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - this.viewer = (AbstractTableViewer) viewer; + this.viewer = (AbstractTableViewer)viewer; - if (oldInput instanceof ValidationMarkersService) { - ValidationMarkersService service = (ValidationMarkersService) oldInput; + if(oldInput instanceof ValidationMarkersService) { + ValidationMarkersService service = (ValidationMarkersService)oldInput; unhookMarkers(service); - unhookResourceSet(service.getModelSet() - .getTransactionalEditingDomain()); + + // The old service may have been disposed if its editor was closed + if(service.getModelSet() != null) { + unhookResourceSet(service.getModelSet().getTransactionalEditingDomain()); + } + this.service = null; } - if (newInput instanceof ValidationMarkersService) { - ValidationMarkersService service = (ValidationMarkersService) newInput; + if(newInput instanceof ValidationMarkersService) { + ValidationMarkersService service = (ValidationMarkersService)newInput; this.service = service; hookMarkers(service); - hookResourceSet(service.getModelSet() - .getTransactionalEditingDomain()); + hookResourceSet(service.getModelSet().getTransactionalEditingDomain()); } } public Object[] getElements(Object inputElement) { - return (inputElement instanceof ValidationMarkersService) - ? Iterables.toArray( - ((ValidationMarkersService) inputElement).getMarkers(), - IPapyrusMarker.class) - : NONE; + return (inputElement instanceof ValidationMarkersService) ? Iterables.toArray(((ValidationMarkersService)inputElement).getMarkers(), IPapyrusMarker.class) : NONE; } protected void hookMarkers(ValidationMarkersService service) { @@ -89,19 +89,18 @@ public class ProblemsContentProvider } private IValidationMarkerListener getValidationMarkerListener() { - if (listener == null) { + if(listener == null) { listener = new IValidationMarkerListener() { - public void notifyMarkerChange(IPapyrusMarker marker, - MarkerChangeKind kind) { - if (viewer != null) { - switch (kind) { - case ADDED : - viewer.add(marker); - break; - case REMOVED : - viewer.remove(marker); - break; + public void notifyMarkerChange(IPapyrusMarker marker, MarkerChangeKind kind) { + if(viewer != null) { + switch(kind) { + case ADDED: + viewer.add(marker); + break; + case REMOVED: + viewer.remove(marker); + break; } } } @@ -120,42 +119,36 @@ public class ProblemsContentProvider } private ResourceSetListener getResourceSetListener() { - if (resourceSetListener == null) { + if(resourceSetListener == null) { resourceSetListener = new DemultiplexingListener() { @Override - protected void handleNotification( - TransactionalEditingDomain domain, - Notification notification) { + protected void handleNotification(TransactionalEditingDomain domain, Notification notification) { // handle containment changes of problem elements to update // labels Object feature = notification.getFeature(); - if ((feature instanceof EReference) - && ((EReference) feature).isContainment()) { - - switch (notification.getEventType()) { - case Notification.ADD : - handleContainment((EObject) notification - .getNewValue()); - break; - case Notification.ADD_MANY : - for (Object next : (Collection<?>) notification - .getNewValue()) { - handleContainment((EObject) next); - } - break; - case Notification.SET : - handleContainment((EObject) notification - .getNewValue()); - break; + if((feature instanceof EReference) && ((EReference)feature).isContainment()) { + + switch(notification.getEventType()) { + case Notification.ADD: + handleContainment((EObject)notification.getNewValue()); + break; + case Notification.ADD_MANY: + for(Object next : (Collection<?>)notification.getNewValue()) { + handleContainment((EObject)next); + } + break; + case Notification.SET: + handleContainment((EObject)notification.getNewValue()); + break; } } } private void handleContainment(EObject object) { Object[] markers = service.getMarkers(object).toArray(); - if (markers.length > 0) { + if(markers.length > 0) { viewer.update(markers, null); } } |