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