X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.views.swt%2Fsrc%2Forg%2Fsimantics%2Fviews%2Fswt%2FSimanticsView.java;h=5a8cd40ed48b2f4b2d8bc65d7b3af5a65ec2b311;hb=a548be86e2719d5a01bcaf55e34185d624d5fbef;hp=6f424c5b07e2a5d9215e85dbf4139ff0133bce9f;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.views.swt/src/org/simantics/views/swt/SimanticsView.java b/bundles/org.simantics.views.swt/src/org/simantics/views/swt/SimanticsView.java index 6f424c5b0..5a8cd40ed 100644 --- a/bundles/org.simantics.views.swt/src/org/simantics/views/swt/SimanticsView.java +++ b/bundles/org.simantics.views.swt/src/org/simantics/views/swt/SimanticsView.java @@ -1,503 +1,503 @@ -/******************************************************************************* - * 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.views.swt; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.jface.action.IMenuManager; -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.dnd.DND; -import org.eclipse.swt.dnd.DragSource; -import org.eclipse.swt.dnd.DragSourceListener; -import org.eclipse.swt.dnd.FileTransfer; -import org.eclipse.swt.dnd.Transfer; -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.IWorkbenchSite; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.contexts.IContextService; -import org.eclipse.ui.part.ViewPart; -import org.simantics.browsing.ui.BuiltinKeys; -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.node.IDropTargetNode; -import org.simantics.browsing.ui.graph.impl.GraphInputSources; -import org.simantics.browsing.ui.graph.impl.SessionContextInputSource; -import org.simantics.browsing.ui.swt.ContextMenuInitializer; -import org.simantics.browsing.ui.swt.DefaultKeyListener; -import org.simantics.browsing.ui.swt.DefaultMouseListener; -import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver; -import org.simantics.browsing.ui.swt.GraphExplorerFactory; -import org.simantics.browsing.ui.swt.IContextMenuInitializer; -import org.simantics.browsing.ui.swt.ViewArgumentUtils; -import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; -import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; -import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; -import org.simantics.db.Disposable; -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.ProjectKeys; -import org.simantics.ui.SimanticsUI; -import org.simantics.ui.dnd.LocalObjectTransfer; -import org.simantics.ui.dnd.LocalSelectionDragSourceListener; -import org.simantics.ui.dnd.NoImageDragSourceEffect; -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.HintContext; -import org.simantics.utils.datastructures.hints.HintListenerAdapter; -import org.simantics.utils.datastructures.hints.HintTracker; -import org.simantics.utils.datastructures.hints.IHintContext; -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; - -/** - * @author Antti Villberg - * @deprecated in favor of org.simantics.views.swt.ModelledView - */ -public abstract class SimanticsView extends ViewPart { - - private final WidgetSupportImpl widgetSupport = createSupport(); - - protected IHintContext factoryHints = new HintContext(); - - protected LocalResourceManager resourceManager; - - protected ISelectionListener workbenchSelectionListener; - - protected Composite parent; - - private Map args; - - private ISessionContextProvider contextProvider; - - private ISessionContext sessionContext; - - protected IMemento memento; - - private IHintTracker sessionContextTracker = new SessionContextProjectTracker(); - - private SessionContextInputSource inputSource = GraphInputSources.projectSource(); - - private DisposeState disposeState = DisposeState.Alive; - - protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() { - @Override - public void sessionContextChanged(SessionContextChangedEvent event) { - sessionContext = event.getNewValue(); - sessionContextTracker.track(sessionContext); - } - }; - - protected Set getBrowseContexts() { - return Collections.emptySet(); - } - - protected WidgetSupportImpl createSupport() { - return new WidgetSupportImpl(); - } - - abstract protected void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support); - - protected void activateUiContexts() { - Collection contexts = getUiContexts(); - if (!contexts.isEmpty()) { - IContextService cs = (IContextService) getSite().getService(IContextService.class); - for (String context : contexts) - cs.activateContext(context); - } - } - - protected Transfer[] getAcceptedDataTypes() { - return new Transfer[] { LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() }; - } - - protected void handleDrop(Object data, NodeContext target) { - if (target != null) { - Object input = target.getConstant(BuiltinKeys.INPUT); - //System.out.println("DROPPED " + data + " ON " + target); - if (input instanceof IDropTargetNode) - ((IDropTargetNode) input).drop(data); - } - } - - protected Object createDragSource(GraphExplorer explorer) { - ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class); - - DragSourceListener listener = new LocalSelectionDragSourceListener(selectionProvider); - - Control control = explorer.getControl(); - DragSource source = new DragSource(control, DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); - source.setTransfer(new Transfer[] {LocalObjectTransfer.getTransfer()}); - source.addDragListener(listener); - source.setDragSourceEffect(new NoImageDragSourceEffect(control)); - - return listener; - } - - /** - * @return the set of org.eclipse.ui.context contexts to - * activate for this view site - */ - protected Set getUiContexts() { - return Collections.emptySet(); - } - - /** - * The default hint tracker that will be active if - * {@link SimanticsViewBase#setSessionContextTracker(IHintTracker) is - * not called. - */ - public class SessionContextProjectTracker extends HintTracker { - public SessionContextProjectTracker() { - IHintListener activeProjectListener = new HintListenerAdapter() { - @Override - public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { - applySessionContext(getSessionContext()); - } - }; - addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener); - } - } - - protected void setSessionContextTracker(IHintTracker tracker) { - this.sessionContextTracker = tracker; - } - - public void setInputSource(SessionContextInputSource source) { - this.inputSource = source; - } - - protected final SessionContextInputSource getInputSource() { - return inputSource; - } - - protected Map getViewArguments() { - return args; - } - - protected DisposeState getDisposeState() { - return disposeState; - } - - public ISessionContext getSessionContext() { - return sessionContext; - } - - public ISessionContextProvider getSessionContextProvider() { - return contextProvider; - } - - @Override - public void createPartControl(Composite parent) { - this.parent = parent; - this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay())); - - contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow()); - - parent.setLayout(LayoutUtils.createNoBorderGridLayout(1, false)); - - setWorkbenchListeners(); - activateUiContexts(); - - createControls(parent, getSite(), getSessionContext(), widgetSupport); - - attachToSession(); - - } - - /** - * Invoked when this viewpart is disposed. Unhooks the view from its - * ISessionContextProvider. Overriding is allowed but super.dispose() must - * be called. - * - * @see org.eclipse.ui.part.WorkbenchPart#dispose() - */ - @Override - public void dispose() { - removeWorkbenchListeners(); - disposeState = DisposeState.Disposing; - try { - if (inputSource instanceof Disposable) { - ((Disposable) inputSource).dispose(); - } - //System.out.println(this + ".GraphExplorerViewBase.dispose()"); - if (contextProvider != null) { - contextProvider.removeContextChangedListener(contextChangeListener); - contextProvider = null; - } - sessionContextTracker.untrack(); - resourceManager.dispose(); - if (widgetSupport instanceof Disposable) - ((Disposable) widgetSupport).dispose(); - resourceManager = null; - args = null; - sessionContext = null; - parent = null; - super.dispose(); - } finally { - disposeState = DisposeState.Disposed; - } - } - - @Override - public void setFocus() { - } - - @Override - public void init(IViewSite site) throws PartInitException { - super.init(site); - this.args = ViewArgumentUtils.parseViewArguments(this); - } - - @Override - public void init(IViewSite site, IMemento memento) throws PartInitException { - super.init(site, memento); - this.args = ViewArgumentUtils.parseViewArguments(this); - this.memento = memento; - } - - @Override - public void saveState(IMemento memento) { - if (this.memento != null) { - memento.putMemento(this.memento); - } -// if (explorer != null) -// explorer.saveState(memento); - } - - protected void setWorkbenchListeners() { - if (workbenchSelectionListener == null) { - -// ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); -// getSite().setSelectionProvider(selectionProvider); - - // Listen to the workbench selection also to propagate it to - // the explorer also. -// workbenchSelectionListener = new DefaultExplorerSelectionListener(this, explorer); -// getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener); - } - } - - protected void removeWorkbenchListeners() { - // Remember to remove the installed workbench selection listener - if (workbenchSelectionListener != null) { - getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener); - workbenchSelectionListener = null; - - getSite().setSelectionProvider(null); - } - } - - protected final void attachToSession() { - // Track active ISessionContext changes - //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow()); - contextProvider.addContextChangedListener(contextChangeListener); - - // Start tracking the current session context for input changes. - // This will/must cause applySessionContext to get called. - // Doing the applySessionContext initialization this way - // instead of directly calling it will also make sure that - // applySessionContext is only called once when first initialized, - // and not twice like with the direct invocation. - this.sessionContext = contextProvider.getSessionContext(); - sessionContextTracker.track(sessionContext); - } - - // ///////////////////////////////////////////////////////////////////////// - // Override / implement these: - - 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)); - - } - - /** - * 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; - } - } - - 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 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 Function() { - @Override - public String[] execute(Object... obj) { - return new String[] { getEditingColumn((NodeContext) obj[0]) }; - } - })); - // Default double click handling - explorer.addListener(new DefaultMouseListener(explorer)); - } - - protected String getEditingColumn(NodeContext context) { - return ColumnKeys.SINGLE; - } - - // 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 + "(SimanticsView).applySessionContext(context=" + context + ")"); - if (disposeState != DisposeState.Alive) - return false; - - if(this.sessionContext == null && context == null) - return false; - - this.sessionContext = context; - Object input = getInputSource().get(context); - //System.out.println(this + "(SimanticsView).applySessionContext(input=" + input + ")"); - 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; - //System.out.println(this + "(SimanticsView).applySessionContext(new input=" + currentInput + ")"); - - widgetSupport.fireInput(context, 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("unchecked") - void searchControl(Control control, Class c, Set result) { - if(c.isInstance(control)) - result.add((T)control); - if(control instanceof Composite) { - for(Control child : ((Composite)control).getChildren()) { - searchControl(child, c, result); - } - } - } - - @SuppressWarnings("unchecked") - @Override - public T getAdapter(Class adapter) { - - if(ISessionContextProvider.class == adapter) - return (T) getSessionContextProvider(); - else if(IPropertyPage.class == adapter) - return (T) getPropertyPage(); - else if(GraphExplorer.class == adapter) { - Set composites = new HashSet<>(); - searchControl(parent, GraphExplorerComposite.class, composites); - if(composites.size() == 1) { - GraphExplorerComposite gec = composites.iterator().next(); - return (T) gec.getExplorer(); - } - return null; - } - - return super.getAdapter(adapter); - - } - - abstract protected IPropertyPage getPropertyPage(); - -// protected IPropertyPage getPropertyPage() { -// return new StandardPropertyPage(getSite(), getBrowseContexts()); -// } - -} +/******************************************************************************* + * 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.views.swt; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.action.IMenuManager; +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.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.Transfer; +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.IWorkbenchSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.part.ViewPart; +import org.simantics.browsing.ui.BuiltinKeys; +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.node.IDropTargetNode; +import org.simantics.browsing.ui.graph.impl.GraphInputSources; +import org.simantics.browsing.ui.graph.impl.SessionContextInputSource; +import org.simantics.browsing.ui.swt.ContextMenuInitializer; +import org.simantics.browsing.ui.swt.DefaultKeyListener; +import org.simantics.browsing.ui.swt.DefaultMouseListener; +import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver; +import org.simantics.browsing.ui.swt.GraphExplorerFactory; +import org.simantics.browsing.ui.swt.IContextMenuInitializer; +import org.simantics.browsing.ui.swt.ViewArgumentUtils; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Disposable; +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.ProjectKeys; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.ui.dnd.LocalSelectionDragSourceListener; +import org.simantics.ui.dnd.NoImageDragSourceEffect; +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.HintContext; +import org.simantics.utils.datastructures.hints.HintListenerAdapter; +import org.simantics.utils.datastructures.hints.HintTracker; +import org.simantics.utils.datastructures.hints.IHintContext; +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; + +/** + * @author Antti Villberg + * @deprecated in favor of org.simantics.views.swt.ModelledView + */ +public abstract class SimanticsView extends ViewPart { + + private final WidgetSupportImpl widgetSupport = createSupport(); + + protected IHintContext factoryHints = new HintContext(); + + protected LocalResourceManager resourceManager; + + protected ISelectionListener workbenchSelectionListener; + + protected Composite parent; + + private Map args; + + private ISessionContextProvider contextProvider; + + private ISessionContext sessionContext; + + protected IMemento memento; + + private IHintTracker sessionContextTracker = new SessionContextProjectTracker(); + + private SessionContextInputSource inputSource = GraphInputSources.projectSource(); + + private DisposeState disposeState = DisposeState.Alive; + + protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() { + @Override + public void sessionContextChanged(SessionContextChangedEvent event) { + sessionContext = event.getNewValue(); + sessionContextTracker.track(sessionContext); + } + }; + + protected Set getBrowseContexts() { + return Collections.emptySet(); + } + + protected WidgetSupportImpl createSupport() { + return new WidgetSupportImpl(); + } + + abstract protected void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support); + + protected void activateUiContexts() { + Collection contexts = getUiContexts(); + if (!contexts.isEmpty()) { + IContextService cs = (IContextService) getSite().getService(IContextService.class); + for (String context : contexts) + cs.activateContext(context); + } + } + + protected Transfer[] getAcceptedDataTypes() { + return new Transfer[] { LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() }; + } + + protected void handleDrop(Object data, NodeContext target) { + if (target != null) { + Object input = target.getConstant(BuiltinKeys.INPUT); + //System.out.println("DROPPED " + data + " ON " + target); + if (input instanceof IDropTargetNode) + ((IDropTargetNode) input).drop(data); + } + } + + protected Object createDragSource(GraphExplorer explorer) { + ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class); + + DragSourceListener listener = new LocalSelectionDragSourceListener(selectionProvider); + + Control control = explorer.getControl(); + DragSource source = new DragSource(control, DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); + source.setTransfer(new Transfer[] {LocalObjectTransfer.getTransfer()}); + source.addDragListener(listener); + source.setDragSourceEffect(new NoImageDragSourceEffect(control)); + + return listener; + } + + /** + * @return the set of org.eclipse.ui.context contexts to + * activate for this view site + */ + protected Set getUiContexts() { + return Collections.emptySet(); + } + + /** + * The default hint tracker that will be active if + * {@link SimanticsViewBase#setSessionContextTracker(IHintTracker) is + * not called. + */ + public class SessionContextProjectTracker extends HintTracker { + public SessionContextProjectTracker() { + IHintListener activeProjectListener = new HintListenerAdapter() { + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + applySessionContext(getSessionContext()); + } + }; + addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener); + } + } + + protected void setSessionContextTracker(IHintTracker tracker) { + this.sessionContextTracker = tracker; + } + + public void setInputSource(SessionContextInputSource source) { + this.inputSource = source; + } + + protected final SessionContextInputSource getInputSource() { + return inputSource; + } + + protected Map getViewArguments() { + return args; + } + + protected DisposeState getDisposeState() { + return disposeState; + } + + public ISessionContext getSessionContext() { + return sessionContext; + } + + public ISessionContextProvider getSessionContextProvider() { + return contextProvider; + } + + @Override + public void createPartControl(Composite parent) { + this.parent = parent; + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay())); + + contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow()); + + parent.setLayout(LayoutUtils.createNoBorderGridLayout(1, false)); + + setWorkbenchListeners(); + activateUiContexts(); + + createControls(parent, getSite(), getSessionContext(), widgetSupport); + + attachToSession(); + + } + + /** + * Invoked when this viewpart is disposed. Unhooks the view from its + * ISessionContextProvider. Overriding is allowed but super.dispose() must + * be called. + * + * @see org.eclipse.ui.part.WorkbenchPart#dispose() + */ + @Override + public void dispose() { + removeWorkbenchListeners(); + disposeState = DisposeState.Disposing; + try { + if (inputSource instanceof Disposable) { + ((Disposable) inputSource).dispose(); + } + //System.out.println(this + ".GraphExplorerViewBase.dispose()"); + if (contextProvider != null) { + contextProvider.removeContextChangedListener(contextChangeListener); + contextProvider = null; + } + sessionContextTracker.untrack(); + resourceManager.dispose(); + if (widgetSupport instanceof Disposable) + ((Disposable) widgetSupport).dispose(); + resourceManager = null; + args = null; + sessionContext = null; + parent = null; + super.dispose(); + } finally { + disposeState = DisposeState.Disposed; + } + } + + @Override + public void setFocus() { + } + + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + this.args = ViewArgumentUtils.parseViewArguments(this); + } + + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + this.args = ViewArgumentUtils.parseViewArguments(this); + this.memento = memento; + } + + @Override + public void saveState(IMemento memento) { + if (this.memento != null) { + memento.putMemento(this.memento); + } +// if (explorer != null) +// explorer.saveState(memento); + } + + protected void setWorkbenchListeners() { + if (workbenchSelectionListener == null) { + +// ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); +// getSite().setSelectionProvider(selectionProvider); + + // Listen to the workbench selection also to propagate it to + // the explorer also. +// workbenchSelectionListener = new DefaultExplorerSelectionListener(this, explorer); +// getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener); + } + } + + protected void removeWorkbenchListeners() { + // Remember to remove the installed workbench selection listener + if (workbenchSelectionListener != null) { + getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener); + workbenchSelectionListener = null; + + getSite().setSelectionProvider(null); + } + } + + protected final void attachToSession() { + // Track active ISessionContext changes + //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow()); + contextProvider.addContextChangedListener(contextChangeListener); + + // Start tracking the current session context for input changes. + // This will/must cause applySessionContext to get called. + // Doing the applySessionContext initialization this way + // instead of directly calling it will also make sure that + // applySessionContext is only called once when first initialized, + // and not twice like with the direct invocation. + this.sessionContext = contextProvider.getSessionContext(); + sessionContextTracker.track(sessionContext); + } + + // ///////////////////////////////////////////////////////////////////////// + // Override / implement these: + + 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)); + + } + + /** + * 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; + } + } + + 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 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 Function() { + @Override + public String[] execute(Object... obj) { + return new String[] { getEditingColumn((NodeContext) obj[0]) }; + } + })); + // Default double click handling + explorer.addListener(new DefaultMouseListener(explorer)); + } + + protected String getEditingColumn(NodeContext context) { + return ColumnKeys.SINGLE; + } + + // 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 + "(SimanticsView).applySessionContext(context=" + context + ")"); + if (disposeState != DisposeState.Alive) + return false; + + if(this.sessionContext == null && context == null) + return false; + + this.sessionContext = context; + Object input = getInputSource().get(context); + //System.out.println(this + "(SimanticsView).applySessionContext(input=" + input + ")"); + 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; + //System.out.println(this + "(SimanticsView).applySessionContext(new input=" + currentInput + ")"); + + widgetSupport.fireInput(context, 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("unchecked") + void searchControl(Control control, Class c, Set result) { + if(c.isInstance(control)) + result.add((T)control); + if(control instanceof Composite) { + for(Control child : ((Composite)control).getChildren()) { + searchControl(child, c, result); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public T getAdapter(Class adapter) { + + if(ISessionContextProvider.class == adapter) + return (T) getSessionContextProvider(); + else if(IPropertyPage.class == adapter) + return (T) getPropertyPage(); + else if(GraphExplorer.class == adapter) { + Set composites = new HashSet<>(); + searchControl(parent, GraphExplorerComposite.class, composites); + if(composites.size() == 1) { + GraphExplorerComposite gec = composites.iterator().next(); + return (T) gec.getExplorer(); + } + return null; + } + + return super.getAdapter(adapter); + + } + + abstract protected IPropertyPage getPropertyPage(); + +// protected IPropertyPage getPropertyPage() { +// return new StandardPropertyPage(getSite(), getBrowseContexts()); +// } + +}