1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.ui.workbench;
14 import org.eclipse.jface.action.IStatusLineManager;
15 import org.eclipse.swt.widgets.Composite;
16 import org.eclipse.ui.IActionBars;
17 import org.eclipse.ui.IMemento;
18 import org.eclipse.ui.IViewSite;
19 import org.eclipse.ui.PartInitException;
20 import org.eclipse.ui.part.ViewPart;
21 import org.simantics.Simantics;
22 import org.simantics.db.ReadGraph;
23 import org.simantics.db.Session;
24 import org.simantics.db.common.request.ReadRequest;
25 import org.simantics.db.event.ChangeEvent;
26 import org.simantics.db.event.ChangeListener;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.management.ISessionContext;
29 import org.simantics.db.service.GraphChangeListenerSupport;
32 * This class acts as a base class for ViewParts that to access the semantic
33 * graph from ProCore via {@link Session} and {@link Graph}.
36 * This class contains the vitals for setting up a the editor for ProCore
37 * access. It also contains some support for dynamically allocating persistent
38 * (via the viewpart memento) ResourceInput instances for the viewpart's
39 * use, i.e. with OntologyExplorer controls.
43 * To use this class all you need to do is call super.createPartControl in your
44 * own createPartControl implementation. This will make sure a {@link Graph}
45 * will be available directly after that for initializing the UI and its
50 * class MyViewPart extends GraphAccessViewPart
51 * public void createPartControl(Composite parent) {
52 * super.createPartControl(parent);
54 * // Initialize UI controls.
55 * // Initialize "controllers" based on the "model" (graph structure).
56 * // Initialize "view" structures from the "controllers"
57 * // Reflect "model" state into "view"
61 * public void reload(Graph g) {
62 * // Reflect the current graph model state in the UI...
68 * To open a GraphAccessViewPart use
69 * <code>WorkbenchUtils.activateView(view id)</code>.
72 * TODO: support changing active database session ?
74 * @author Tuukka Lehtonen
76 public abstract class GraphAccessViewPart extends ViewPart {
78 private IMemento memento;
80 private ChangeListener graphChangeListener;
82 protected ISessionContext sessionContext;
84 protected Session session;
86 @SuppressWarnings("unchecked")
88 public <A> A getAdapter(Class<A> adapter) {
89 // NOTE: the Session is instantiated at createPartControl time!
90 if (adapter == Session.class)
91 return (A) getSession();
92 return super.getAdapter(adapter);
95 // ----------------------------------------------------------------------
98 public IStatusLineManager getStatusLineManager() {
99 IViewSite site = getViewSite();
100 IActionBars bars = site.getActionBars();
101 IStatusLineManager mgr = bars.getStatusLineManager();
102 // if (mgr instanceof SubStatusLineManager)
103 // ((SubStatusLineManager)mgr).setVisible(true);
108 * @param message <code>null</code> to remove message
110 public void setStatusMessage(String message) {
111 getStatusLineManager().setMessage(message);
115 * @param message <code>null</code> to remove message
117 public void setStatusErrorMessage(String message) {
118 getStatusLineManager().setErrorMessage(message);
121 public IMemento getLastMemento() {
125 public IMemento consumeLastMemento() {
126 IMemento m = memento;
131 // ----------------------------------------------------------------------
132 // Event handlers & initialisation
135 * Default implementation of createPartControl. Merely calls
136 * {@link #initialize()} to initialize the graph access. To make your
137 * ViewPart do anything meaningful, you must override this method. But
138 * remember to call super before trying to use the graph.
140 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
143 public void createPartControl(Composite parent) {
148 public void dispose() {
154 public void init(IViewSite site) throws PartInitException {
159 public void init(IViewSite site, IMemento memento) throws PartInitException {
160 super.init(site, memento);
161 this.memento = memento;
164 protected ISessionContext getSessionContext() {
165 return sessionContext;
168 protected Session getSession() {
172 protected void initializeSession() {
173 sessionContext = Simantics.getSessionContext();
174 if (sessionContext == null)
175 throw new IllegalStateException("no active session context");
176 session = sessionContext.getSession();
180 * Initializes graph data access and view resource ID input structures.
183 * This method is automatically called by
184 * {@link #createPartControl(Composite)}. Override to perform own
185 * graph-related initializations but be absolutely sure to call super the
186 * first thing. Clients must not directly call this method.
189 protected void initialize() {
192 graphChangeListener = getGraphChangeListener();
193 if (graphChangeListener != null) {
194 GraphChangeListenerSupport support = session.getService(GraphChangeListenerSupport.class);
195 support.addListener(graphChangeListener);
200 * Override this and return <code>null</code> to prevent a
201 * {@link GraphChangeListener} from being added automatically.
205 protected ChangeListener getGraphChangeListener() {
206 return new ChangeListenerImpl();
211 protected void cleanup() {
212 if (session != null) {
216 if (graphChangeListener != null) {
217 GraphChangeListenerSupport support = s.getService(GraphChangeListenerSupport.class);
218 support.removeListener(graphChangeListener);
219 graphChangeListener = null;
225 * The ProCore update notification listener for all GraphAccessViewPart
227 * {@link ResourceInputViewPart#update(GraphChangeEvent)} default
228 * implementation of which merely invokes
229 * {@link ResourceInputViewPart#reload()} for which overriding is
232 class ChangeListenerImpl implements ChangeListener {
233 public void graphChanged(ChangeEvent e) throws DatabaseException {
234 // System.out.println(GraphAccessViewPart.this.getClass().getName()
235 // + " receives update.");
241 * This method is called when an update event is received from the Graph of
242 * this {@link ResourceInputViewPart}.
244 * This base implementation stupidly calls {@link #reload()} on every
245 * committed transaction or undo point change.
248 * the received change event
250 protected void update(ChangeEvent event) throws DatabaseException {
251 getSession().asyncRequest(new ReadRequest() {
253 public void run(ReadGraph g) {
259 // ----------------------------------------------------------------------
262 public void updateTitle() {
263 // setPartName must not be called with a null name!
264 String partName = getTitleText();
265 if (partName != null) {
266 setPartName(partName);
268 // Tooltip may be null, which clears the tooltip.
269 setTitleToolTip(getTitleTooltip());
272 // ----------------------------------------------------------------------
273 // (Re-)Implement these if necessary:
276 * Returns null by default which makes {@link #updateTitle()} not set the
277 * part name programmatically, i.e. the plugin-defined view name will stay.
281 protected String getTitleText() {
286 * Return null by default which makes {@link #updateTitle()} clear the
291 protected String getTitleTooltip() {
296 * Reload the UI because there are changes in the data model that have not
297 * been reflected to the UI.
299 public abstract void reload(ReadGraph g);