/******************************************************************************* * 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.Simantics; 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; /** * 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)
.
*
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 = Simantics.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 returnnull
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);
}