]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.ui/src/org/simantics/ui/workbench/GraphAccessViewPart.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / workbench / GraphAccessViewPart.java
diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/GraphAccessViewPart.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/GraphAccessViewPart.java
new file mode 100644 (file)
index 0000000..843786a
--- /dev/null
@@ -0,0 +1,301 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 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
+ *******************************************************************************/\r
+package org.simantics.ui.workbench;\r
+\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IActionBars;\r
+import org.eclipse.ui.IMemento;\r
+import org.eclipse.ui.IViewSite;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.event.ChangeEvent;\r
+import org.simantics.db.event.ChangeListener;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.service.GraphChangeListenerSupport;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * This class acts as a base class for ViewParts that to access the semantic\r
+ * graph from ProCore via {@link Session} and {@link Graph}.\r
+ * \r
+ * <p>\r
+ * This class contains the vitals for setting up a the editor for ProCore\r
+ * access. It also contains some support for dynamically allocating persistent\r
+ * (via the viewpart memento) ResourceInput instances for the viewpart's\r
+ * use, i.e. with OntologyExplorer controls.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * To use this class all you need to do is call super.createPartControl in your\r
+ * own createPartControl implementation. This will make sure a {@link Graph}\r
+ * will be available directly after that for initializing the UI and its\r
+ * contents.\r
+ * </p>\r
+ * \r
+ * <pre>\r
+ *       class MyViewPart extends GraphAccessViewPart\r
+ *           public void createPartControl(Composite parent) {\r
+ *               super.createPartControl(parent);\r
+ * \r
+ *               // Initialize UI controls.\r
+ *               // Initialize &quot;controllers&quot; based on the &quot;model&quot; (graph structure).\r
+ *               // Initialize &quot;view&quot; structures from the &quot;controllers&quot;\r
+ *               // Reflect &quot;model&quot; state into &quot;view&quot;\r
+ *               reload();\r
+ *           }\r
+ * \r
+ *           public void reload(Graph g) {\r
+ *               // Reflect the current graph model state in the UI...\r
+ *           }\r
+ *       }\r
+ * </pre>\r
+ * \r
+ * <p>\r
+ * To open a GraphAccessViewPart use\r
+ * <code>WorkbenchUtils.activateView(view id)</code>.\r
+ * </p>\r
+ * \r
+ * TODO: support changing active database session ?\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public abstract class GraphAccessViewPart extends ViewPart {\r
+\r
+    private IMemento          memento;\r
+\r
+    private ChangeListener    graphChangeListener;\r
+\r
+    protected ISessionContext sessionContext;\r
+\r
+    protected Session         session;\r
+\r
+    @SuppressWarnings("unchecked")\r
+       @Override\r
+    public <A> A getAdapter(Class<A> adapter) {\r
+        // NOTE: the Session is instantiated at createPartControl time!\r
+        if (adapter == Session.class)\r
+            return (A) getSession();\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+    // ----------------------------------------------------------------------\r
+    // Getters\r
+\r
+    public IStatusLineManager getStatusLineManager() {\r
+        IViewSite site = getViewSite();\r
+        IActionBars bars = site.getActionBars();\r
+        IStatusLineManager mgr = bars.getStatusLineManager();\r
+        // if (mgr instanceof SubStatusLineManager)\r
+        // ((SubStatusLineManager)mgr).setVisible(true);\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
+    public IMemento getLastMemento() {\r
+        return memento;\r
+    }\r
+\r
+    public IMemento consumeLastMemento() {\r
+        IMemento m = memento;\r
+        memento = null;\r
+        return m;\r
+    }\r
+\r
+    // ----------------------------------------------------------------------\r
+    // Event handlers & initialisation\r
+\r
+    /**\r
+     * Default implementation of createPartControl. Merely calls\r
+     * {@link #initialize()} to initialize the graph access. To make your\r
+     * ViewPart do anything meaningful, you must override this method. But\r
+     * remember to call super before trying to use the graph.\r
+     * \r
+     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)\r
+     */\r
+    @Override\r
+    public void createPartControl(Composite parent) {\r
+        initialize();\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        cleanup();\r
+        super.dispose();\r
+    }\r
+\r
+    @Override\r
+    public void init(IViewSite site) throws PartInitException {\r
+        super.init(site);\r
+    }\r
+\r
+    @Override\r
+    public void init(IViewSite site, IMemento memento) throws PartInitException {\r
+        super.init(site, memento);\r
+        this.memento = memento;\r
+    }\r
+\r
+    protected ISessionContext getSessionContext() {\r
+        return sessionContext;\r
+    }\r
+\r
+    protected Session getSession() {\r
+        return session;\r
+    }\r
+\r
+    protected void initializeSession() {\r
+        sessionContext = SimanticsUI.getSessionContext();\r
+        if (sessionContext == null)\r
+            throw new IllegalStateException("no active session context");\r
+        session = sessionContext.getSession();\r
+    }\r
+\r
+    /**\r
+     * Initializes graph data access and view resource ID input structures.\r
+     * \r
+     * <p>\r
+     * This method is automatically called by\r
+     * {@link #createPartControl(Composite)}. Override to perform own\r
+     * graph-related initializations but be absolutely sure to call super the\r
+     * first thing. Clients must not directly call this method.\r
+     * </p>\r
+     */\r
+    protected void initialize() {\r
+        initializeSession();\r
+\r
+        graphChangeListener = getGraphChangeListener();\r
+        if (graphChangeListener != null) {\r
+            GraphChangeListenerSupport support = session.getService(GraphChangeListenerSupport.class);\r
+            support.addListener(graphChangeListener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Override this and return <code>null</code> to prevent a\r
+     * {@link GraphChangeListener} from being added automatically.\r
+     * \r
+     * @return\r
+     */\r
+    protected ChangeListener getGraphChangeListener() {\r
+        return new ChangeListenerImpl();\r
+    }\r
+\r
+    /**\r
+     */\r
+    protected void cleanup() {\r
+        if (session != null) {\r
+            Session s = session;\r
+            session = null;\r
+\r
+            if (graphChangeListener != null) {\r
+                GraphChangeListenerSupport support = s.getService(GraphChangeListenerSupport.class);\r
+                support.removeListener(graphChangeListener);\r
+                graphChangeListener = null;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * The ProCore update notification listener for all GraphAccessViewPart\r
+     * instances. Calls\r
+     * {@link ResourceInputViewPart#update(GraphChangeEvent)} default\r
+     * implementation of which merely invokes\r
+     * {@link ResourceInputViewPart#reload()} for which overriding is\r
+     * allowed.\r
+     */\r
+    class ChangeListenerImpl implements ChangeListener {\r
+        public void graphChanged(ChangeEvent e) throws DatabaseException {\r
+            // System.out.println(GraphAccessViewPart.this.getClass().getName()\r
+            // + " receives update.");\r
+            update(e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This method is called when an update event is received from the Graph of\r
+     * this {@link ResourceInputViewPart}.\r
+     * \r
+     * This base implementation stupidly calls {@link #reload()} on every\r
+     * committed transaction or undo point change.\r
+     * \r
+     * @param event\r
+     *            the received change event\r
+     */\r
+    protected void update(ChangeEvent event) throws DatabaseException {\r
+        getSession().asyncRequest(new ReadRequest() {\r
+            @Override\r
+            public void run(ReadGraph g) {\r
+                reload(g);\r
+            }\r
+        });\r
+    }\r
+\r
+    // ----------------------------------------------------------------------\r
+    // Event utilities\r
+\r
+    public void updateTitle() {\r
+        // setPartName must not be called with a null name!\r
+        String partName = getTitleText();\r
+        if (partName != null) {\r
+            setPartName(partName);\r
+        }\r
+        // Tooltip may be null, which clears the tooltip.\r
+        setTitleToolTip(getTitleTooltip());\r
+    }\r
+\r
+    // ----------------------------------------------------------------------\r
+    // (Re-)Implement these if necessary:\r
+\r
+    /**\r
+     * Returns null by default which makes {@link #updateTitle()} not set the\r
+     * part name programmatically, i.e. the plugin-defined view name will stay.\r
+     * \r
+     * @return\r
+     */\r
+    protected String getTitleText() {\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Return null by default which makes {@link #updateTitle()} clear the\r
+     * tooltip.\r
+     * \r
+     * @return\r
+     */\r
+    protected String getTitleTooltip() {\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Reload the UI because there are changes in the data model that have not\r
+     * been reflected to the UI.\r
+     */\r
+    public abstract void reload(ReadGraph g);\r
+\r
+}\r