X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.browsing.ui.swt%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fswt%2FGraphExplorerViewBase.java;fp=bundles%2Forg.simantics.browsing.ui.swt%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fswt%2FGraphExplorerViewBase.java;h=f748656a5ba10f484a1dd9701f7c4f24b185c7b7;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerViewBase.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerViewBase.java new file mode 100644 index 000000000..f748656a5 --- /dev/null +++ b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerViewBase.java @@ -0,0 +1,544 @@ +/******************************************************************************* + * 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.browsing.ui.swt; + +import java.util.Map; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.simantics.browsing.ui.Column; +import org.simantics.browsing.ui.GraphExplorer; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.common.views.IViewArguments; +import org.simantics.browsing.ui.graph.impl.SessionContextInputSource; +import org.simantics.db.Session; +import org.simantics.db.common.request.Queries; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.management.ISessionContextChangedListener; +import org.simantics.db.management.ISessionContextProvider; +import org.simantics.db.management.SessionContextChangedEvent; +import org.simantics.project.IProject; +import org.simantics.project.ProjectKeys; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.dnd.BasicDragSource; +import org.simantics.ui.dnd.SessionContainer; +import org.simantics.ui.workbench.IPropertyPage; +import org.simantics.utils.ObjectUtils; +import org.simantics.utils.datastructures.Function; +import org.simantics.utils.datastructures.disposable.DisposeState; +import org.simantics.utils.datastructures.hints.HintListenerAdapter; +import org.simantics.utils.datastructures.hints.HintTracker; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.datastructures.hints.IHintTracker; +import org.simantics.utils.ui.LayoutUtils; + +/** + * An abstract base Eclipse workbench ViewPart for use in situations where a + * tree-based GraphExplorer graph model browser is needed. + * + *
+ * Override to customize behavior: + *
+ * You can invoke the following methods from within + * {@link #createControls(Composite)} to customize how the view keeps track of + * the active ISessionContext and how the view resolves the input object of the + * GraphExplorer control. + *
null
+ * to indicate that there is no input and nothing should be shown.
+ */
+ @Override
+ public Object get(ISessionContext ctx) {
+ if (ctx == null)
+ return GraphExplorer.EMPTY_INPUT;
+
+ String inputId = getViewArguments().get(IViewArguments.INPUT);
+ if (inputId != null) {
+ try {
+ return ctx.getSession().syncRequest(Queries.resource(inputId));
+ } catch (DatabaseException e) {
+ // Ok, the view argument was invalid. Just continue to the next
+ // method.
+ }
+ }
+
+ Object input = GraphExplorer.EMPTY_INPUT;
+ IProject project2 = ctx.getHint(ProjectKeys.KEY_PROJECT);
+ if (project2 != null)
+ input = project2.get();
+ return input;
+ }
+
+ @Override
+ public IWorkbenchPart getProvider() {
+ return null;
+ }
+
+ }
+
+ protected LocalResourceManager resourceManager;
+
+ protected ISelectionListener workbenchSelectionListener;
+
+ protected Composite parent;
+
+ protected GraphExplorer explorer;
+
+ protected IMenuManager menuManager;
+
+ private MaprestoreState(IMemento)
in OntologyExplorer. Must be unique
+// * within a workbench part.
+// *
+// * @return a unique name for this particular graph explorer view used for
+// * saving and restoring the state of this view part
+// */
+// public String getExplorerName() {
+// return "GraphExplorerViewBase";
+// }
+
+ protected Column[] getColumns() {
+ return null;
+ }
+
+ /**
+ * Override this method to add controls to the view part. This is invoked
+ * before attaching the view part to a database session.
+ *
+ * @param parent
+ */
+ protected void createControls(Composite parent) {
+
+ parent.setLayout(LayoutUtils.createNoBorderGridLayout(1, false));
+
+ // Initialize explorer control.
+ explorer = createExplorerControl(parent);
+
+ ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);
+ Control control = explorer.getControl();
+
+ Column[] columns = getColumns();
+ if(columns != null)
+ explorer.setColumns(columns);
+
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(control);
+
+ // Initialize context menu if an initializer is provided.
+ IContextMenuInitializer cmi = getContextMenuInitializer();
+ if (cmi != null) {
+ menuManager = cmi.createContextMenu(control, selectionProvider, getSite());
+ }
+
+ // Initialize DND.
+ dragSource = createDragSource(explorer);
+
+ // Listeners are only added once per listener, not every time the
+ // session context changes.
+ addListeners(explorer, menuManager);
+ }
+
+ /**
+ * Override this method and provide a proper context menu initializer if you
+ * want to have this base class initialize one for you.
+ *
+ * @return the initializer to be used by {@link #createControls(Composite)}
+ */
+ protected IContextMenuInitializer getContextMenuInitializer() {
+ String contextMenuId = getContextMenuId();
+ if(contextMenuId != null) {
+ return new ContextMenuInitializer(contextMenuId);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return the ID of the context menu to initialize for this this graph
+ * explorer view or null
to not initialize a context
+ * menu
+ */
+ protected String getContextMenuId() {
+ return null;
+ }
+
+ protected int getStyle() {
+ return SWT.MULTI;
+ }
+
+ /**
+ * @param parent
+ * @return
+ */
+ protected GraphExplorer createExplorerControl(Composite parent) {
+ return GraphExplorerFactory.getInstance()
+ .selectionDataResolver(new DefaultSelectionDataResolver())
+ .create(parent, getStyle());
+ }
+
+ /**
+ * Override to customize drag source initialization. This default
+ * implementation creates a {@link BasicDragSource}. The drag source is
+ * initialized when the active database session is set.
+ *
+ * @param explorer
+ * @return the object representing the drag source. If the object implements
+ * {@link SessionContainer}, its
+ * {@link SessionContainer#setSession(Session)} will be invoked
+ * every time the active database session changes.
+ */
+ protected Object createDragSource(GraphExplorer explorer) {
+ ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);
+ Control control = explorer.getControl();
+ return new BasicDragSource(selectionProvider, control, null);
+ }
+
+ protected void setupDragSource(Session session) {
+ if (dragSource instanceof SessionContainer) {
+ ((SessionContainer) dragSource).setSession(session);
+ }
+ }
+
+ /**
+ * Override to customize the addition of listeners a newly created
+ * GraphExplorer.
+ *
+ * @param explorer
+ */
+ protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {
+ addSelectionInputListeners(explorer, menuManager);
+ }
+
+ protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {
+ // Consider ENTER presses to simulate mouse left button double clicks
+ explorer.addListener(new DefaultKeyListener(contextProvider, explorer, new Functionnull
if there is no session
+ */
+ protected void initializeExplorer(final GraphExplorer explorer, ISessionContext context) {
+ setupDragSource((context != null) ? context.getSession() : null);
+ }
+
+ // Needed for preventing unnecessary re-initialization of the explorer with the same input.
+ private Object currentInput;
+
+ protected boolean isImportantInput(Object previousInput, Object input) {
+ return !ObjectUtils.objectEquals(previousInput, input);
+ }
+
+ /**
+ * Invoke this to reinitialize the explorer and reset its input. The input
+ * will be resolved from the specified ISessionContext based on the
+ * {@link SessionContextInputSource} that is currently in use. If the input
+ * is identical to the previous input, nothing will be done.
+ *
+ * @param context
+ */
+ protected final boolean applySessionContext(ISessionContext context) {
+ // If control is not alive anymore, do nothing.
+// System.out.println(this + ": applySessionContext(" + context + "), explorer=" + explorer);
+ if (disposeState != DisposeState.Alive)
+ return false;
+
+ this.sessionContext = context;
+ Object input = inputSource.get(context);
+ if (!isImportantInput(currentInput, input))
+ return false;
+
+// System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");
+ initializeExplorer(explorer, context);
+// System.out.println(this + ": setRoot(" + input + ")");
+ explorer.setRoot(input);
+
+ currentInput = input;
+
+ // Start tracking the session context.
+ //
+ // If this is not the same session that is currently tracked, it will
+ // cause IHintListeners of the sessionContextTracker to fire.
+ // For this we need the above input equality (identity) checking.
+ // This is here just to make sure that we are tracking the correct
+ // session context.
+ sessionContextTracker.track(sessionContext);
+
+ return true;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Object getAdapter(Class adapter) {
+
+ if (GraphExplorer.class == adapter)
+ return explorer;
+ else if(ISessionContextProvider.class == adapter)
+ return getSessionContextProvider();
+ else if(IPropertyPage.class == adapter)
+ return getPropertyPage();
+
+ return super.getAdapter(adapter);
+
+ }
+
+ protected IPropertyPage getPropertyPage() {
+ return null;
+ }
+
+
+
+}