X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2FResourceEditorPart.java;h=ca06a5d7b5d538c9091fb8b71d7f45d26ad906d3;hp=56c26e8b26b49e3fe333382b6722809ca42bc432;hb=20c2fa2629081d808fe313e387951f69111236b6;hpb=969bd23cab98a79ca9101af33334000879fb60c5
diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorPart.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorPart.java
index 56c26e8b2..ca06a5d7b 100644
--- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorPart.java
+++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorPart.java
@@ -1,216 +1,258 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2013 Association for Decentralized Information Management
- * in Industry THTH ry.
- * 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:
- * VTT Technical Research Centre of Finland - initial API and implementation
- * Semantum Oy - issue #4384
- *******************************************************************************/
-package org.simantics.ui.workbench;
-
-import java.util.function.Supplier;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.EditorPart;
-import org.simantics.db.Resource;
-import org.simantics.db.Session;
-import org.simantics.db.common.request.ParametrizedRead;
-import org.simantics.db.event.ChangeListener;
-import org.simantics.db.management.ISessionContext;
-import org.simantics.ui.SimanticsUI;
-
-/**
- * ResourceEditorPart is a base implementation for editors that support
- * {@link ResourceEditorInput} style inputs for working on top of the Simantics
- * graph database.
- *
- *
- * If you want your ResourceEditorPart implementation to receive notifications
- * for all graph change events through the {@link ChangeListener} interface,
- * just implement it and it will be automatically invoked by this base
- * implementation.
- *
- *
- * @author Tuukka Lehtonen
- */
-public abstract class ResourceEditorPart extends EditorPart implements IResourceEditorPart {
-
- protected boolean disposed = false;
- protected ResourceEditorSupport support;
-
- /**
- * Override to define your own input resource editor input validator that
- * the view uses by default in {@link #init(IEditorSite, IEditorInput)}.
- *
- * @return
- */
- protected ParametrizedRead getInputValidator() {
- return null;
- }
-
- @Override
- public void init(IEditorSite site, IEditorInput input) throws PartInitException {
- init(site, input, getInputValidator());
- }
-
- protected void createSupport(ParametrizedRead inputValidator) throws PartInitException {
- support = new ResourceEditorSupport(this, inputValidator);
- }
-
- protected void init(IEditorSite site, IEditorInput input,
- ParametrizedRead inputValidator) throws PartInitException {
- if (!(input instanceof IResourceEditorInput))
- throw new PartInitException("Invalid input: must be IResourceEditorInput");
-
- setSite(site);
- setInput(input);
- createSupport(inputValidator);
-
- // Set initial part name according to the name given by IEditorInput
- setPartName(getEditorInput().getName());
-
- Session session = SimanticsUI.peekSession();
- if (session != null) {
- Supplier disposedCallback = () -> disposed;
- session.asyncRequest(
- new TitleRequest(site.getId(), getResourceInput()),
- new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback));
- session.asyncRequest(
- new ToolTipRequest(site.getId(), getResourceInput()),
- new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback));
- }
- }
-
- @Override
- public void dispose() {
- disposed = true;
- support.dispose();
- super.dispose();
- }
-
- protected void activateValidation() {
- support.activateValidation();
- }
-
- public ISessionContext getSessionContext() {
- return support.getSessionContext();
- }
-
- public Session getSession() {
- return support.getSession();
- }
-
- /**
- * A resource editor does not need to perform any save operations since the
- * graph model is global and different parts of it need not be saved
- * separately.
- *
- * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
- */
- @Override
- public void doSave(IProgressMonitor monitor) {
- //System.out.println("[ResourceEditorPart] doSave: " + getPartName());
- }
-
- @Override
- public void doSaveAs() {
- //System.out.println("[ResourceEditorPart] doSaveAs: " + getPartName());
- }
-
- /**
- * A resource editor should never be dirty since its purpose is to reflect
- * the current state of the graph model.
- *
- * @see org.eclipse.ui.part.EditorPart#isDirty()
- */
- @Override
- public boolean isDirty() {
- //System.out.println("[ResourceEditorPart] isDirty: " + getPartName());
- return false;
- }
-
- @Override
- public boolean isSaveAsAllowed() {
- // Graph edits are always immediately sent to "UndoCore" which means
- // that resource graph editors do not support save-features as such.
- return false;
- }
-
- @Override
- public IResourceEditorInput getResourceInput() {
- return (IResourceEditorInput) getEditorInput();
- }
-
- //-------
- // UTILS
- //-------
-
- public IStatusLineManager getStatusLineManager() {
- IActionBars bars = getEditorSite().getActionBars();
- IStatusLineManager mgr = bars.getStatusLineManager();
- return mgr;
- }
-
- /**
- * @param message null
to remove message
- */
- public void setStatusMessage(String message) {
- getStatusLineManager().setMessage(message);
- }
-
- /**
- * @param message null
to remove message
- */
- public void setStatusErrorMessage(String message) {
- getStatusLineManager().setErrorMessage(message);
- }
-
- protected Resource getInputResource() {
- return getResourceInput().getResource();
- }
-
- protected String getInputName() {
- return getEditorInput().getName();
- }
-
- protected String getTitleText() {
- return getInputName();
- }
-
- protected String getTitleTooltip() {
- return getInputName();
- }
-
- protected void updateTitle() {
- setPartName(getTitleText());
- setTitleToolTip(getTitleTooltip());
- }
-
- /**
- * A utility method for easier invocation of Runnables asynchronously in the
- * SWT UI thread.
- *
- * @param run
- */
- protected void asyncExec(Runnable run) {
- getSite().getShell().getDisplay().asyncExec(run);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public T getAdapter(Class adapter) {
- if (adapter == Session.class)
- return (T) getSession();
- return super.getAdapter(adapter);
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - issue #4384
+ * Semantum Oy - issue #7737
+ *******************************************************************************/
+package org.simantics.ui.workbench;
+
+import java.util.function.Supplier;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
+import org.eclipse.ui.part.EditorPart;
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.request.ParametrizedRead;
+import org.simantics.db.management.ISessionContext;
+
+/**
+ * ResourceEditorPart is a base implementation for editors that support
+ * {@link ResourceEditorInput} style inputs for working on top of the Simantics
+ * graph database.
+ *
+ *
+ * If you want your ResourceEditorPart implementation to receive notifications
+ * for all graph change events through the {@link ChangeListener} interface,
+ * just implement it and it will be automatically invoked by this base
+ * implementation.
+ *
+ *
+ * @author Tuukka Lehtonen
+ * @author Jani Simomaa
+ */
+public abstract class ResourceEditorPart extends EditorPart implements IResourceEditorPart {
+
+ protected boolean disposed = false;
+ protected ResourceEditorSupport support;
+
+ /**
+ * Override to define your own input resource editor input validator that
+ * the view uses by default in {@link #init(IEditorSite, IEditorInput)}.
+ *
+ * @return
+ */
+ protected ParametrizedRead getInputValidator() {
+ return null;
+ }
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ init(site, input, getInputValidator());
+ }
+
+ protected void createSupport(ParametrizedRead inputValidator) throws PartInitException {
+ support = new ResourceEditorSupport(this, inputValidator);
+ }
+
+ protected void init(IEditorSite site, IEditorInput input,
+ ParametrizedRead inputValidator) throws PartInitException {
+ if (!(input instanceof IResourceEditorInput))
+ throw new PartInitException("Invalid input: must be IResourceEditorInput");
+
+ setSite(site);
+ setInput(input);
+ createSupport(inputValidator);
+
+ // Set initial part name according to the name given by IEditorInput
+ setPartName(getEditorInput().getName());
+
+ Session session = Simantics.peekSession();
+ if (session != null) {
+ Supplier disposedCallback = () -> disposed;
+ session.asyncRequest(
+ new TitleRequest(site.getId(), getResourceInput()),
+ new TitleUpdater(site.getShell().getDisplay(), this::safeSetPartName, disposedCallback));
+ session.asyncRequest(
+ new ToolTipRequest(site.getId(), getResourceInput()),
+ new TitleUpdater(site.getShell().getDisplay(), this::safeSetTitleToolTip, disposedCallback));
+ }
+ }
+
+ /**
+ * Safely sets part name for parts whose IEditorInput is not yet disposed (e.g.
+ * removed from database)
+ *
+ * @param partName
+ */
+ protected void safeSetPartName(String partName) {
+ if (!disposed && checkCompatibilityPartNotBeingDisposed()) { // this is to fix bug https://gitlab.simantics.org/simantics/platform/issues/117
+ setPartName(partName);
+ }
+ }
+
+ @SuppressWarnings("restriction")
+ private boolean checkCompatibilityPartNotBeingDisposed() {
+ IWorkbenchPartSite site = getSite();
+ if (site instanceof PartSite) {
+ PartSite partSite = (PartSite) getSite();
+ Object object = partSite.getModel().getObject();
+ if (object instanceof CompatibilityEditor) {
+ CompatibilityEditor editor = (CompatibilityEditor) object;
+ return !editor.isBeingDisposed();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Safely sets title tooltip for parts whose IEditorInput is not yet disposed (e.g.
+ * removed from database)
+ *
+ * @param toolTip
+ */
+ protected void safeSetTitleToolTip(String toolTip) {
+ if (!disposed) {
+ setTitleToolTip(toolTip);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ disposed = true;
+ support.dispose();
+ super.dispose();
+ }
+
+ protected void activateValidation() {
+ support.activateValidation();
+ }
+
+ public ISessionContext getSessionContext() {
+ return support.getSessionContext();
+ }
+
+ public Session getSession() {
+ return support.getSession();
+ }
+
+ /**
+ * A resource editor does not need to perform any save operations since the
+ * graph model is global and different parts of it need not be saved
+ * separately.
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ //System.out.println("[ResourceEditorPart] doSave: " + getPartName());
+ }
+
+ @Override
+ public void doSaveAs() {
+ //System.out.println("[ResourceEditorPart] doSaveAs: " + getPartName());
+ }
+
+ /**
+ * A resource editor should never be dirty since its purpose is to reflect
+ * the current state of the graph model.
+ *
+ * @see org.eclipse.ui.part.EditorPart#isDirty()
+ */
+ @Override
+ public boolean isDirty() {
+ //System.out.println("[ResourceEditorPart] isDirty: " + getPartName());
+ return false;
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ // Graph edits are always immediately sent to "UndoCore" which means
+ // that resource graph editors do not support save-features as such.
+ return false;
+ }
+
+ @Override
+ public IResourceEditorInput getResourceInput() {
+ return (IResourceEditorInput) getEditorInput();
+ }
+
+ //-------
+ // UTILS
+ //-------
+
+ public IStatusLineManager getStatusLineManager() {
+ IActionBars bars = getEditorSite().getActionBars();
+ IStatusLineManager mgr = bars.getStatusLineManager();
+ return mgr;
+ }
+
+ /**
+ * @param message null
to remove message
+ */
+ public void setStatusMessage(String message) {
+ getStatusLineManager().setMessage(message);
+ }
+
+ /**
+ * @param message null
to remove message
+ */
+ public void setStatusErrorMessage(String message) {
+ getStatusLineManager().setErrorMessage(message);
+ }
+
+ protected Resource getInputResource() {
+ return getResourceInput().getResource();
+ }
+
+ protected String getInputName() {
+ return getEditorInput().getName();
+ }
+
+ protected String getTitleText() {
+ return getInputName();
+ }
+
+ protected String getTitleTooltip() {
+ return getInputName();
+ }
+
+ protected void updateTitle() {
+ setPartName(getTitleText());
+ setTitleToolTip(getTitleTooltip());
+ }
+
+ /**
+ * A utility method for easier invocation of Runnables asynchronously in the
+ * SWT UI thread.
+ *
+ * @param run
+ */
+ protected void asyncExec(Runnable run) {
+ getSite().getShell().getDisplay().asyncExec(run);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T getAdapter(Class adapter) {
+ if (adapter == Session.class)
+ return (T) getSession();
+ return super.getAdapter(adapter);
+ }
+
+}