--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ * Semantum Oy - issue #4384\r
+ *******************************************************************************/\r
+package org.simantics.ui.workbench;\r
+\r
+import java.util.function.Supplier;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.ui.IActionBars;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorSite;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.part.EditorPart;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ParametrizedRead;\r
+import org.simantics.db.event.ChangeListener;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * ResourceEditorPart is a base implementation for editors that support\r
+ * {@link ResourceEditorInput} style inputs for working on top of the Simantics\r
+ * graph database.\r
+ * \r
+ * <p>\r
+ * If you want your ResourceEditorPart implementation to receive notifications\r
+ * for all graph change events through the {@link ChangeListener} interface,\r
+ * just implement it and it will be automatically invoked by this base\r
+ * implementation.\r
+ * </p>\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public abstract class ResourceEditorPart extends EditorPart implements IResourceEditorPart {\r
+\r
+ protected boolean disposed = false;\r
+ protected ResourceEditorSupport support;\r
+\r
+ /**\r
+ * Override to define your own input resource editor input validator that\r
+ * the view uses by default in {@link #init(IEditorSite, IEditorInput)}.\r
+ * \r
+ * @return\r
+ */\r
+ protected ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {\r
+ init(site, input, getInputValidator());\r
+ }\r
+ \r
+ protected void createSupport(ParametrizedRead<IResourceEditorInput, Boolean> inputValidator) throws PartInitException {\r
+ support = new ResourceEditorSupport(this, inputValidator);\r
+ }\r
+\r
+ protected void init(IEditorSite site, IEditorInput input,\r
+ ParametrizedRead<IResourceEditorInput, Boolean> inputValidator) throws PartInitException {\r
+ if (!(input instanceof IResourceEditorInput))\r
+ throw new PartInitException("Invalid input: must be IResourceEditorInput");\r
+\r
+ setSite(site);\r
+ setInput(input);\r
+ createSupport(inputValidator);\r
+\r
+ // Set initial part name according to the name given by IEditorInput\r
+ setPartName(getEditorInput().getName());\r
+\r
+ Session session = SimanticsUI.peekSession();\r
+ if (session != null) {\r
+ Supplier<Boolean> disposedCallback = () -> disposed;\r
+ session.asyncRequest(\r
+ new TitleRequest(site.getId(), getResourceInput()),\r
+ new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback));\r
+ session.asyncRequest(\r
+ new ToolTipRequest(site.getId(), getResourceInput()),\r
+ new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback));\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ disposed = true;\r
+ support.dispose();\r
+ super.dispose();\r
+ }\r
+\r
+ protected void activateValidation() {\r
+ support.activateValidation();\r
+ }\r
+\r
+ public ISessionContext getSessionContext() {\r
+ return support.getSessionContext();\r
+ }\r
+\r
+ public Session getSession() {\r
+ return support.getSession();\r
+ }\r
+\r
+ /**\r
+ * A resource editor does not need to perform any save operations since the\r
+ * graph model is global and different parts of it need not be saved\r
+ * separately.\r
+ * \r
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)\r
+ */\r
+ @Override\r
+ public void doSave(IProgressMonitor monitor) {\r
+ //System.out.println("[ResourceEditorPart] doSave: " + getPartName());\r
+ }\r
+\r
+ @Override\r
+ public void doSaveAs() {\r
+ //System.out.println("[ResourceEditorPart] doSaveAs: " + getPartName());\r
+ }\r
+\r
+ /**\r
+ * A resource editor should never be dirty since its purpose is to reflect\r
+ * the current state of the graph model.\r
+ * \r
+ * @see org.eclipse.ui.part.EditorPart#isDirty()\r
+ */\r
+ @Override\r
+ public boolean isDirty() {\r
+ //System.out.println("[ResourceEditorPart] isDirty: " + getPartName());\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public boolean isSaveAsAllowed() {\r
+ // Graph edits are always immediately sent to "UndoCore" which means\r
+ // that resource graph editors do not support save-features as such.\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public IResourceEditorInput getResourceInput() {\r
+ return (IResourceEditorInput) getEditorInput();\r
+ }\r
+\r
+ //-------\r
+ // UTILS\r
+ //-------\r
+\r
+ public IStatusLineManager getStatusLineManager() {\r
+ IActionBars bars = getEditorSite().getActionBars();\r
+ IStatusLineManager mgr = bars.getStatusLineManager();\r
+ return mgr;\r
+ }\r
+\r
+ /**\r
+ * @param message <code>null</code> to remove message\r
+ */\r
+ public void setStatusMessage(String message) {\r
+ getStatusLineManager().setMessage(message);\r
+ }\r
+\r
+ /**\r
+ * @param message <code>null</code> to remove message\r
+ */\r
+ public void setStatusErrorMessage(String message) {\r
+ getStatusLineManager().setErrorMessage(message);\r
+ }\r
+\r
+ protected Resource getInputResource() {\r
+ return getResourceInput().getResource();\r
+ }\r
+\r
+ protected String getInputName() {\r
+ return getEditorInput().getName();\r
+ }\r
+\r
+ protected String getTitleText() {\r
+ return getInputName();\r
+ }\r
+\r
+ protected String getTitleTooltip() {\r
+ return getInputName();\r
+ }\r
+\r
+ protected void updateTitle() {\r
+ setPartName(getTitleText());\r
+ setTitleToolTip(getTitleTooltip());\r
+ }\r
+\r
+ /**\r
+ * A utility method for easier invocation of Runnables asynchronously in the\r
+ * SWT UI thread.\r
+ * \r
+ * @param run\r
+ */\r
+ protected void asyncExec(Runnable run) {\r
+ getSite().getShell().getDisplay().asyncExec(run);\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getAdapter(Class<T> adapter) {\r
+ if (adapter == Session.class)\r
+ return (T) getSession();\r
+ return super.getAdapter(adapter);\r
+ }\r
+\r
+}\r