X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2FGraphAccessViewPart.java;fp=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2FGraphAccessViewPart.java;h=843786a7ccc95ea33458d5faa89c312ef7ea95a9;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..843786a7c --- /dev/null +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/GraphAccessViewPart.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + *******************************************************************************/ +package org.simantics.ui.workbench; + +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.simantics.db.ReadGraph; +import org.simantics.db.Session; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.event.ChangeEvent; +import org.simantics.db.event.ChangeListener; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.service.GraphChangeListenerSupport; +import org.simantics.ui.SimanticsUI; + +/** + * This class acts as a base class for ViewParts that to access the semantic + * graph from ProCore via {@link Session} and {@link Graph}. + * + *

+ * This class contains the vitals for setting up a the editor for ProCore + * access. It also contains some support for dynamically allocating persistent + * (via the viewpart memento) ResourceInput instances for the viewpart's + * use, i.e. with OntologyExplorer controls. + *

+ * + *

+ * To use this class all you need to do is call super.createPartControl in your + * own createPartControl implementation. This will make sure a {@link Graph} + * will be available directly after that for initializing the UI and its + * contents. + *

+ * + *
+ *       class MyViewPart extends GraphAccessViewPart
+ *           public void createPartControl(Composite parent) {
+ *               super.createPartControl(parent);
+ * 
+ *               // Initialize UI controls.
+ *               // Initialize "controllers" based on the "model" (graph structure).
+ *               // Initialize "view" structures from the "controllers"
+ *               // Reflect "model" state into "view"
+ *               reload();
+ *           }
+ * 
+ *           public void reload(Graph g) {
+ *               // Reflect the current graph model state in the UI...
+ *           }
+ *       }
+ * 
+ * + *

+ * To open a GraphAccessViewPart use + * WorkbenchUtils.activateView(view id). + *

+ * + * TODO: support changing active database session ? + * + * @author Tuukka Lehtonen + */ +public abstract class GraphAccessViewPart extends ViewPart { + + private IMemento memento; + + private ChangeListener graphChangeListener; + + protected ISessionContext sessionContext; + + protected Session session; + + @SuppressWarnings("unchecked") + @Override + public A getAdapter(Class adapter) { + // NOTE: the Session is instantiated at createPartControl time! + if (adapter == Session.class) + return (A) getSession(); + return super.getAdapter(adapter); + } + + // ---------------------------------------------------------------------- + // Getters + + public IStatusLineManager getStatusLineManager() { + IViewSite site = getViewSite(); + IActionBars bars = site.getActionBars(); + IStatusLineManager mgr = bars.getStatusLineManager(); + // if (mgr instanceof SubStatusLineManager) + // ((SubStatusLineManager)mgr).setVisible(true); + 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); + } + + public IMemento getLastMemento() { + return memento; + } + + public IMemento consumeLastMemento() { + IMemento m = memento; + memento = null; + return m; + } + + // ---------------------------------------------------------------------- + // Event handlers & initialisation + + /** + * Default implementation of createPartControl. Merely calls + * {@link #initialize()} to initialize the graph access. To make your + * ViewPart do anything meaningful, you must override this method. But + * remember to call super before trying to use the graph. + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + initialize(); + } + + @Override + public void dispose() { + cleanup(); + super.dispose(); + } + + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + } + + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + this.memento = memento; + } + + protected ISessionContext getSessionContext() { + return sessionContext; + } + + protected Session getSession() { + return session; + } + + protected void initializeSession() { + sessionContext = SimanticsUI.getSessionContext(); + if (sessionContext == null) + throw new IllegalStateException("no active session context"); + session = sessionContext.getSession(); + } + + /** + * Initializes graph data access and view resource ID input structures. + * + *

+ * This method is automatically called by + * {@link #createPartControl(Composite)}. Override to perform own + * graph-related initializations but be absolutely sure to call super the + * first thing. Clients must not directly call this method. + *

+ */ + protected void initialize() { + initializeSession(); + + graphChangeListener = getGraphChangeListener(); + if (graphChangeListener != null) { + GraphChangeListenerSupport support = session.getService(GraphChangeListenerSupport.class); + support.addListener(graphChangeListener); + } + } + + /** + * Override this and return null to prevent a + * {@link GraphChangeListener} from being added automatically. + * + * @return + */ + protected ChangeListener getGraphChangeListener() { + return new ChangeListenerImpl(); + } + + /** + */ + protected void cleanup() { + if (session != null) { + Session s = session; + session = null; + + if (graphChangeListener != null) { + GraphChangeListenerSupport support = s.getService(GraphChangeListenerSupport.class); + support.removeListener(graphChangeListener); + graphChangeListener = null; + } + } + } + + /** + * The ProCore update notification listener for all GraphAccessViewPart + * instances. Calls + * {@link ResourceInputViewPart#update(GraphChangeEvent)} default + * implementation of which merely invokes + * {@link ResourceInputViewPart#reload()} for which overriding is + * allowed. + */ + class ChangeListenerImpl implements ChangeListener { + public void graphChanged(ChangeEvent e) throws DatabaseException { + // System.out.println(GraphAccessViewPart.this.getClass().getName() + // + " receives update."); + update(e); + } + } + + /** + * This method is called when an update event is received from the Graph of + * this {@link ResourceInputViewPart}. + * + * This base implementation stupidly calls {@link #reload()} on every + * committed transaction or undo point change. + * + * @param event + * the received change event + */ + protected void update(ChangeEvent event) throws DatabaseException { + getSession().asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph g) { + reload(g); + } + }); + } + + // ---------------------------------------------------------------------- + // Event utilities + + public void updateTitle() { + // setPartName must not be called with a null name! + String partName = getTitleText(); + if (partName != null) { + setPartName(partName); + } + // Tooltip may be null, which clears the tooltip. + setTitleToolTip(getTitleTooltip()); + } + + // ---------------------------------------------------------------------- + // (Re-)Implement these if necessary: + + /** + * Returns null by default which makes {@link #updateTitle()} not set the + * part name programmatically, i.e. the plugin-defined view name will stay. + * + * @return + */ + protected String getTitleText() { + return null; + } + + /** + * Return null by default which makes {@link #updateTitle()} clear the + * tooltip. + * + * @return + */ + protected String getTitleTooltip() { + return null; + } + + /** + * Reload the UI because there are changes in the data model that have not + * been reflected to the UI. + */ + public abstract void reload(ReadGraph g); + +}