Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-12-12 18:50:23 +0000
committerChristian W. Damus2014-12-12 20:06:32 +0000
commitd8749d6135abd54e1a9d7d1dddbe455854d56417 (patch)
tree3520a419ed561c96918b6dd3ce694b889a338ff6 /plugins
parent10a26cc0252b3ce11c0c4224edd2a6c51faebd19 (diff)
downloadorg.eclipse.papyrus-d8749d6135abd54e1a9d7d1dddbe455854d56417.tar.gz
org.eclipse.papyrus-d8749d6135abd54e1a9d7d1dddbe455854d56417.tar.xz
org.eclipse.papyrus-d8749d6135abd54e1a9d7d1dddbe455854d56417.zip
454536: [Properties View] Impossible to display the properties pages after reopening of a project
https://bugs.eclipse.org/bugs/show_bug.cgi?id=454536 Ensure that the current selection in the Property sheet is forgotten when closing the model if the selection is from that model. Also ensure that the property sheet always updates to show the current Model Explorer selection when the explorer view is activated (otherwise it may still be showing what was relevant for a previous model editor). Furthermore, when re-using a data source in the property sheet, if that data source contains unloaded objects, then don't reuse it, to ensure that widgets aren't re-used that remember the previous editor's resource-set and other context.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java26
-rw-r--r--plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPageBookView.java69
-rw-r--r--plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPropertySheetPage.java59
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java28
4 files changed, 175 insertions, 7 deletions
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
new file mode 100644
index 00000000000..142bf96f65f
--- /dev/null
+++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/IPageBookViewPageListener.java
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.views.modelexplorer;
+
+import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.MultiViewPageBookView;
+import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.ViewPartPage;
+
+/**
+ * A protocol for notification of page selection change and closing in the Model Explorer view.
+ */
+interface IPageBookViewPageListener {
+ void pageActivated(MultiViewPageBookView pageBookView, ViewPartPage page);
+
+ void pageClosing(MultiViewPageBookView pageBookView, ViewPartPage page);
+}
diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPageBookView.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPageBookView.java
index d73d5150db7..d50febaf273 100644
--- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPageBookView.java
+++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/ModelExplorerPageBookView.java
@@ -21,6 +21,7 @@ package org.eclipse.papyrus.views.modelexplorer;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.resources.IMarker;
import org.eclipse.emf.common.util.URI;
@@ -28,6 +29,7 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.MultiViewPageBookView;
+import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.ViewPartPage;
import org.eclipse.papyrus.views.modelexplorer.sorting.DefaultTreeViewerSorting;
import org.eclipse.papyrus.views.modelexplorer.sorting.ITreeViewerSorting;
import org.eclipse.ui.IMemento;
@@ -37,6 +39,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.part.IPage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
@@ -59,6 +62,8 @@ public class ModelExplorerPageBookView extends MultiViewPageBookView implements
/** The property sheet pages. */
private List<IPropertySheetPage> propertiesSheetPages = new LinkedList<IPropertySheetPage>();
+ private final CopyOnWriteArrayList<IPageBookViewPageListener> pageListeners = new CopyOnWriteArrayList<IPageBookViewPageListener>();
+
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
@@ -157,17 +162,45 @@ public class ModelExplorerPageBookView extends MultiViewPageBookView implements
@Override
public void partClosed(IWorkbenchPart part) {
PageRec rec = getPageRec(part);
- if ((rec != null) && (rec.page instanceof ModelExplorerPage)) {
- ModelExplorerView explorer = (ModelExplorerView) ((ModelExplorerPage) rec.page).getViewer();
+ if (rec != null) {
+ if (rec.page instanceof ModelExplorerPage) {
+ ModelExplorerView explorer = (ModelExplorerView) ((ModelExplorerPage) rec.page).getViewer();
+
+ // Clear the explorer tree input to prompt the CNF to clear caches, promoting garbage collection
+ explorer.aboutToDispose();
+ }
- // Clear the explorer tree input to prompt the CNF to clear caches, promoting garbage collection
- explorer.aboutToDispose();
+ if (rec.page instanceof ViewPartPage) {
+ // Forget the current selection in any property page that is targeting the model that is closing
+ firePageClosing((ViewPartPage) rec.page);
+ }
}
super.partClosed(part);
}
@Override
+ protected void showPageRec(PageRec pageRec) {
+ super.showPageRec(pageRec);
+
+ if (getSite().getPage().getActivePart() == this) {
+ if ((pageRec != null) && (pageRec.page instanceof ViewPartPage)) {
+ firePageActivated((ViewPartPage) pageRec.page);
+ }
+ }
+ }
+
+ @Override
+ public void setFocus() {
+ super.setFocus();
+
+ IPage page = getCurrentPage();
+ if (page instanceof ViewPartPage) {
+ firePageActivated((ViewPartPage) page);
+ }
+ }
+
+ @Override
public void dispose() {
for (IPropertySheetPage page : propertiesSheetPages) {
page.dispose();
@@ -175,4 +208,32 @@ public class ModelExplorerPageBookView extends MultiViewPageBookView implements
propertiesSheetPages.clear();
super.dispose();
}
+
+ void addPageListener(IPageBookViewPageListener listener) {
+ pageListeners.addIfAbsent(listener);
+ }
+
+ void removePageListener(IPageBookViewPageListener listener) {
+ pageListeners.remove(listener);
+ }
+
+ private void firePageActivated(ViewPartPage page) {
+ for (IPageBookViewPageListener next : pageListeners) {
+ try {
+ next.pageActivated(this, page);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in page activation listener.", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private void firePageClosing(ViewPartPage page) {
+ for (IPageBookViewPageListener next : pageListeners) {
+ try {
+ next.pageClosing(this, page);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in page closing listener.", e); //$NON-NLS-1$
+ }
+ }
+ }
}
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 6b64ed8f2e2..295302b58a1 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
@@ -14,16 +14,30 @@
package org.eclipse.papyrus.views.modelexplorer;
+import java.util.Iterator;
+
import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.papyrus.infra.core.operation.DelegatingUndoContext;
+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.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.MultiViewPageBookView;
+import org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.ViewPartPage;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.collect.Iterators;
/**
* Specific PropertySheetPage for Model Explorer view to contribute to Undo/Redo Edit menu.
@@ -31,7 +45,7 @@ import com.google.common.base.Supplier;
* @author Gabriel Pascual
*
*/
-class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage {
+class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage implements IPageBookViewPageListener {
private final ModelExplorerPageBookView modelExplorer;
/** The undo. */
@@ -53,6 +67,7 @@ class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage {
super(modelExplorer);
this.modelExplorer = modelExplorer;
+ modelExplorer.addPageListener(this);
}
/**
@@ -84,6 +99,7 @@ class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage {
*/
@Override
public void dispose() {
+ modelExplorer.removePageListener(this);
if (undo != null) {
undo.dispose();
@@ -94,4 +110,45 @@ class ModelExplorerPropertySheetPage extends TabbedPropertySheetPage {
super.dispose();
}
+
+ public void pageActivated(MultiViewPageBookView pageBookView, ViewPartPage page) {
+ // Ensure that I am showing the up-to-date selection
+ selectionChanged(modelExplorer, pageBookView.getSite().getSelectionProvider().getSelection());
+ }
+
+ public void pageClosing(MultiViewPageBookView pageBookView, ViewPartPage page) {
+ if (isSelectionUnloading((ServicesRegistry) page.getAdapter(ServicesRegistry.class))) {
+ // Forget the selection because it is now invalid and we don't want to show it when next the Model Explorer is activated
+ selectionChanged(modelExplorer, StructuredSelection.EMPTY);
+ }
+ }
+
+ /**
+ * 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}
+ */
+ private boolean isSelectionUnloading(final ServicesRegistry context) {
+ boolean result = false;
+
+ ISelection currentSelection = getCurrentSelection();
+ if (currentSelection instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) currentSelection;
+ result = Iterators.any((Iterator<?>) selection.iterator(), new Predicate<Object>() {
+ public boolean apply(Object input) {
+ try {
+ EObject eObject = EMFHelper.getEObject(input);
+ return (eObject != null) && (eObject.eIsProxy() || (ServiceUtilsForEObject.getInstance().getServiceRegistry(eObject) == context));
+ } catch (ServiceException e) {
+ // We won't try to get the registry for an element that is already unloaded (short-circuit 'or')
+ return false;
+ }
+ }
+ });
+ }
+
+ return result;
+ }
}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java b/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
index f20e3add355..dc26c6eb599 100644
--- a/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
@@ -12,6 +12,7 @@
* Christian W. Damus (CEA) - bug 417409
* Christian W. Damus (CEA) - bug 444227
* Christian W. Damus - bug 450478
+ * Christian W. Damus - bug 454536
*
*****************************************************************************/
package org.eclipse.papyrus.views.properties.runtime;
@@ -20,6 +21,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +31,7 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
import org.eclipse.papyrus.views.properties.Activator;
import org.eclipse.papyrus.views.properties.catalog.PropertiesURIHandler;
import org.eclipse.papyrus.views.properties.contexts.Context;
@@ -194,8 +197,11 @@ public class DefaultDisplayEngine implements DisplayEngine {
DataSource existing = getDataSource(section);
if (!allowDuplicate && (existing != null)) {
- if (conflictingArity(existing.getSelection(), source.getSelection())) {
- // Cannot reuse a multiple-selection data source for single-selection and vice-versa
+ if (isUnloaded(existing) || conflictingArity(existing.getSelection(), source.getSelection())) {
+ // If it's a left-over from an unloaded resource, then rebuild the properties UI because
+ // element-browser widgets and other things may remember the previous (now invalid)
+ // resource-set context. Also, cannot reuse a multiple-selection data source for
+ // single-selection and vice-versa
disposeControls(section);
} else {
// Update the data source and fire the bindings
@@ -220,6 +226,24 @@ public class DefaultDisplayEngine implements DisplayEngine {
return displayedSections.get(section);
}
+ /**
+ * Queries whether any object selected in a data source is unloaded (now an EMF proxy object).
+ *
+ * @param dataSource
+ * a data source
+ * @return whether it contains an unloaded model element
+ */
+ protected boolean isUnloaded(DataSource dataSource) {
+ boolean result = false;
+
+ for (Iterator<?> iter = dataSource.getSelection().iterator(); !result && iter.hasNext();) {
+ EObject next = EMFHelper.getEObject(iter.next());
+ result = (next != null) && ((EObject) next).eIsProxy();
+ }
+
+ return result;
+ }
+
protected boolean conflictingArity(IStructuredSelection selection1, IStructuredSelection selection2) {
return (selection1.size() <= 1) != (selection2.size() <= 1);
}

Back to the top