]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.browsing.ui.platform/src/org/simantics/browsing/ui/platform/GraphExplorerView.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.browsing.ui.platform / src / org / simantics / browsing / ui / platform / GraphExplorerView.java
diff --git a/bundles/org.simantics.browsing.ui.platform/src/org/simantics/browsing/ui/platform/GraphExplorerView.java b/bundles/org.simantics.browsing.ui.platform/src/org/simantics/browsing/ui/platform/GraphExplorerView.java
new file mode 100644 (file)
index 0000000..477d681
--- /dev/null
@@ -0,0 +1,417 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.browsing.ui.platform;\r
+\r
+import java.lang.reflect.Constructor;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IConfigurationElement;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DragSource;\r
+import org.eclipse.swt.dnd.DragSourceListener;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetAdapter;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.FileTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.osgi.framework.Bundle;\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.EvaluatorData;\r
+import org.simantics.browsing.ui.common.EvaluatorDataImpl;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\r
+import org.simantics.browsing.ui.common.processors.ComparableFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.ComparableSelectorQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.FilterSelectionRequestQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.ImageDecoratorFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.ImagerFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.LabelDecoratorFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.LabelerFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.UserSelectedComparableFactoryQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.UserSelectedViewpointFactoryQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.ViewpointFactoryResolver;\r
+import org.simantics.browsing.ui.common.views.IFilterAreaProvider;\r
+import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource;\r
+import org.simantics.browsing.ui.graph.impl.Evaluators;\r
+import org.simantics.browsing.ui.graph.impl.GraphExplorerHints;\r
+import org.simantics.browsing.ui.graph.impl.InheritsQueryProcessor;\r
+import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource;\r
+import org.simantics.browsing.ui.graph.impl.RelatedObjectsQueryProcessor;\r
+import org.simantics.browsing.ui.swt.ComparatorSelector;\r
+import org.simantics.browsing.ui.swt.FilterArea;\r
+import org.simantics.browsing.ui.swt.GraphExplorerViewBase;\r
+import org.simantics.browsing.ui.swt.StandardContextTypesQueryProcessor;\r
+import org.simantics.browsing.ui.swt.TypesQueryProcessor;\r
+import org.simantics.browsing.ui.swt.ViewpointSelector;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.selectionview.StandardPropertyPage;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+import org.simantics.ui.dnd.LocalSelectionDragSourceListener;\r
+import org.simantics.ui.dnd.NoImageDragSourceEffect;\r
+import org.simantics.ui.workbench.IPropertyPage;\r
+import org.simantics.utils.datastructures.hints.HintContext;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.LayoutUtils;\r
+\r
+/**\r
+ * Override:\r
+ * <ul>\r
+ * <li>{@link #createAuxiliaryControls(Composite, Control)} to customize the\r
+ * creation of auxiliary controls around the graph explorer control, such as\r
+ * comparator/viewpoint selectors and filter area.</li>\r
+ * <li>{@link #getUiContexts()} to specify which\r
+ * <code>org.eclipse.ui.context</code> extension point contexts should be\r
+ * activated for this view site. May be empty.</li>\r
+ * <li>{@link #getBrowseContexts()} to specify how the view\r
+ * content/label/decoration production should be configured. May be empty, in\r
+ * which case the browser will show nothing.</li>\r
+ * <li>{@link #getContextMenuId()} to specify the ID of the context menu to be\r
+ * create for this view part and registered with the workbench. May be\r
+ * <code>null</code>, in which case a context menu will not be created nor\r
+ * registered with the workbench.</li>\r
+ * </ul>\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ * @deprecated in favor of org.simantics.views.swt.ModelledView\r
+ * \r
+ **/\r
+public class GraphExplorerView extends GraphExplorerViewBase {\r
+\r
+    protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor;\r
+    protected UserSelectedViewpointFactoryQueryProcessor  userSelectedViewpointFactoryQueryProcessor;\r
+    protected FilterSelectionRequestQueryProcessor        filterSelectionRequestQueryProcessor;\r
+    protected FilterArea                                  filterArea;\r
+    protected IHintContext                                factoryHints = new HintContext();\r
+    protected EvaluatorData                               evaluatorData;\r
+\r
+    protected Set<String>                                 browseContexts = Collections.emptySet();\r
+    protected String                                      contextMenuId;\r
+    protected Set<String>                                 uiContexts = Collections.emptySet();\r
+    protected String                                      propertyPageContributor;\r
+    protected String                                      propertyPageClassName;\r
+    protected Set<String>                                 propertyBrowseContexts = Collections.emptySet();\r
+\r
+    protected boolean                                     hideComparatorSelector = false;\r
+    protected boolean                                     hideViewpointSelector = false;\r
+    protected boolean                                     hideFilter = false;\r
+\r
+    @Override\r
+    public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) {\r
+        super.setInitializationData(cfig, propertyName, data);\r
+        if (data instanceof String) {\r
+            Set<String> browseContexts = new HashSet<String>();\r
+            Set<String> uiContexts = new HashSet<String>();\r
+            Set<String> propertyBrowseContexts = new HashSet<String>();\r
+\r
+            String[] parameters = ((String) data).split(";");\r
+\r
+            IContextService service = (IContextService) PlatformUI.getWorkbench().getService(IContextService.class);\r
+            Set<String> definedContexts = new HashSet<String>();\r
+            for (Object cid : service.getDefinedContextIds())\r
+                definedContexts.add((String) cid);\r
+\r
+            for (String parameter : parameters) {\r
+                String[] keyValue = parameter.split("=");\r
+                if (keyValue.length > 2) {\r
+                    ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);\r
+                    continue;\r
+                }\r
+                String key = keyValue[0];\r
+                String value = keyValue.length > 1 ? keyValue[1] : "";\r
+\r
+                if ("browseContext".equals(key)) {\r
+                    browseContexts.add(value);\r
+                } else if ("contextMenuId".equals(key)) {\r
+                    this.contextMenuId = value;\r
+                } else if ("uiContext".equals(key)) {\r
+                    if (!definedContexts.contains(value)) {\r
+                        ErrorLogger.defaultLogWarning("Parameter '" + parameter + "' references a non-existent Eclipse UI context '" + value + "'. Complete view argument: " + data, null);\r
+                        continue;\r
+                    }\r
+                    uiContexts.add(value);\r
+                } else if ("propertyBrowseContext".equals(key)) {\r
+                    propertyBrowseContexts.add(value);\r
+                } else if ("propertyPageClass".equals(key)) {\r
+                    this.propertyPageContributor = cfig.getContributor().getName();\r
+                    this.propertyPageClassName = value;\r
+                } else if ("hideComparatorSelector".equals(key)) {\r
+                    this.hideComparatorSelector = true;\r
+                } else if ("hideViewpointSelector".equals(key)) {\r
+                    this.hideViewpointSelector = true;\r
+                } else if ("hideFilter".equals(key)) {\r
+                    this.hideFilter = true;\r
+                }\r
+            }\r
+\r
+            this.browseContexts = browseContexts;\r
+            this.uiContexts = uiContexts;\r
+            this.propertyBrowseContexts = propertyBrowseContexts;\r
+        }\r
+    }\r
+\r
+    public GraphExplorer getExplorer() {\r
+       return explorer;\r
+    }\r
+    \r
+    public <T> T getBrowseContext() {\r
+       return evaluatorData.getBrowseContext();\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Override this to specify which browse contexts are considered active for\r
+     * this browser. This information is read only once during view\r
+     * initialization, no change listening is implemented.\r
+     * \r
+     * @return\r
+     */\r
+    protected Set<String> getBrowseContexts() {\r
+        return browseContexts;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.simantics.browsing.ui.swt.GraphExplorerViewBase#getContextMenuId()\r
+     */\r
+    @Override\r
+    protected String getContextMenuId() {\r
+        return contextMenuId;\r
+    }\r
+\r
+    /**\r
+     * @return the set of <code>org.eclipse.ui.context</code> contexts to\r
+     *         activate for this view site\r
+     */\r
+    protected Set<String> getUiContexts() {\r
+        return uiContexts;\r
+    }\r
+\r
+    @Override\r
+    protected IPropertyPage getPropertyPage() {\r
+        if (propertyPageContributor != null && propertyPageClassName != null) {\r
+            try {\r
+                Bundle b = Platform.getBundle(propertyPageContributor);\r
+                if (b == null) {\r
+                    ErrorLogger.defaultLogError("property page '" + propertyPageClassName + "' contributor bundle '"\r
+                            + propertyPageContributor + "' was not found in the platform.", null);\r
+                    return null;\r
+                }\r
+                Class<?> clazz = b.loadClass(propertyPageClassName);\r
+                if (!IPropertyPage.class.isAssignableFrom(clazz)) {\r
+                    ErrorLogger.defaultLogError("property page class '" + propertyPageClassName + "' is not assignable to "\r
+                            + IPropertyPage.class + ".", null);\r
+                    return null;\r
+                }\r
+                Constructor<?> ctor = clazz.getConstructor(IWorkbenchPartSite.class);\r
+                return (IPropertyPage) ctor.newInstance(getSite());\r
+            } catch (Exception e) {\r
+                ErrorLogger.defaultLogError("Failed to instantiate IPropertyPage implementation '" + propertyPageClassName\r
+                        + "' from bundle '" + propertyPageContributor + "'. See exception for details.", e);\r
+                // Something failed, don't try to instantiate the property page anymore.\r
+                propertyPageClassName = null;\r
+            }\r
+        } else if (!propertyBrowseContexts.isEmpty()) {\r
+            return new StandardPropertyPage(getSite(), new HashSet<String>(propertyBrowseContexts));\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    protected void createControls(Composite parent) {\r
+        super.createControls(parent);\r
+\r
+        Control control = explorer.getControl();\r
+\r
+        userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor();\r
+        userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor();\r
+        filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor();\r
+\r
+        createAuxiliaryControls(parent, control);\r
+\r
+        setupDropTarget(control);\r
+        setWorkbenchListeners();\r
+        activateUiContexts();\r
+    }\r
+\r
+    protected void createAuxiliaryControls(Composite parent, Control explorerControl) {\r
+        parent.setLayout(LayoutUtils.createNoBorderGridLayout(3, false));\r
+\r
+        if (!hideComparatorSelector) {\r
+            ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, parent, SWT.READ_ONLY);\r
+            comparatorSelector.moveAbove(explorerControl);\r
+        }\r
+\r
+        if (!hideViewpointSelector) {\r
+            ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, parent, SWT.READ_ONLY);\r
+            viewpointSelector.moveAbove(explorerControl);\r
+        }\r
+\r
+        if (!hideFilter) {\r
+            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.READ_ONLY);\r
+            filterArea.moveAbove(explorerControl);\r
+        }\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).span(3,1).applyTo(explorerControl);\r
+    }\r
+\r
+    protected void setupDropTarget(Control control) {\r
+        DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
+        target.setTransfer(getAcceptedDataTypes());\r
+        target.addDropListener(new DropTargetAdapter() {\r
+            Tree tree = (Tree) explorer.getControl();\r
+\r
+            @Override\r
+            public void dragEnter(DropTargetEvent event) {\r
+                event.detail = DND.DROP_COPY;\r
+            }\r
+\r
+            @Override\r
+            public void drop(DropTargetEvent event) {\r
+                TreeItem item = tree.getItem(tree.toControl(event.x, event.y));\r
+                if (item != null)\r
+                    handleDrop(event.data, (NodeContext) item.getData());\r
+                else\r
+                    handleDrop(event.data, null);\r
+            }\r
+        });\r
+    }\r
+\r
+    protected void activateUiContexts() {\r
+        Collection<String> contexts = getUiContexts();\r
+        if (!contexts.isEmpty()) {\r
+            IContextService cs = (IContextService) getSite().getService(IContextService.class);\r
+            for (String context : contexts)\r
+                cs.activateContext(context);\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if (adapter == IFilterAreaProvider.class)\r
+            return filterArea;\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        //System.out.println(this + ".GraphExplorerViewBase2.dispose()");\r
+        removeWorkbenchListeners();\r
+        userSelectedComparableFactoryQueryProcessor = null;\r
+        userSelectedViewpointFactoryQueryProcessor = null;\r
+        filterSelectionRequestQueryProcessor = null;\r
+        super.dispose();\r
+    }\r
+\r
+    @Override\r
+    protected final void initializeExplorer(GraphExplorer explorer, ISessionContext context) {\r
+        if (explorer.isDisposed())\r
+            return;\r
+\r
+        super.initializeExplorer(explorer, context);\r
+\r
+        Session session = context != null ? context.getSession() : null;\r
+\r
+        if (session != null) {\r
+            evaluatorData = createEvaluatorData(session);\r
+            factoryHints.setHint(GraphExplorerHints.KEY_SESSION_CONTEXT, context);\r
+            explorer.setDataSource(new AsyncReadGraphDataSource(session));\r
+            explorer.setDataSource(new ReadGraphDataSource(session));\r
+        }\r
+        else {\r
+            evaluatorData = new EvaluatorDataImpl();\r
+            explorer.removeDataSource(AsyncReadGraph.class);\r
+            explorer.removeDataSource(ReadGraph.class);\r
+            factoryHints.removeHint(GraphExplorerHints.KEY_SESSION_CONTEXT);\r
+        }\r
+\r
+        explorer.setProcessor(new ComparableFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ViewpointFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new LabelerFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ImagerFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new LabelDecoratorFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ImageDecoratorFactoryResolver(evaluatorData));\r
+        explorer.setPrimitiveProcessor(new TypesQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new InheritsQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor());\r
+\r
+        if(!hideViewpointSelector) {\r
+               explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor);\r
+               explorer.setProcessor(new ComparableSelectorQueryProcessor());\r
+        }\r
+        if(!hideComparatorSelector) {\r
+               explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor);\r
+        }\r
+        explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
+\r
+        initializeExplorerWithEvaluator(explorer, context, evaluatorData);\r
+    }\r
+\r
+    protected void initializeExplorerWithEvaluator(GraphExplorer explorer, ISessionContext context, EvaluatorData data) {\r
+    }\r
+\r
+    protected EvaluatorData createEvaluatorData(Session session) {\r
+        return Evaluators.load(session, getBrowseContexts(), resourceManager);\r
+    }\r
+\r
+    protected Transfer[] getAcceptedDataTypes() {\r
+        return new Transfer[] {  LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() };\r
+    }\r
+\r
+    protected void handleDrop(Object data, NodeContext target) {\r
+        if (target != null) {\r
+            Object input = target.getConstant(BuiltinKeys.INPUT);\r
+            //System.out.println("DROPPED " + data + " ON " + target);\r
+            if (input instanceof IDropTargetNode)\r
+                ((IDropTargetNode) input).drop(data);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Object createDragSource(GraphExplorer explorer) {\r
+        ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
+\r
+        DragSourceListener listener = new LocalSelectionDragSourceListener(selectionProvider);\r
+\r
+        Control control = explorer.getControl();\r
+        DragSource source = new DragSource(control, DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);\r
+        source.setTransfer(new Transfer[] {LocalObjectTransfer.getTransfer()});\r
+        source.addDragListener(listener);\r
+        source.setDragSourceEffect(new NoImageDragSourceEffect(control));\r
+\r
+        return listener;\r
+    }\r
+\r
+    public EvaluatorData getEvaluatorData() {\r
+        return evaluatorData;\r
+    }\r
+\r
+}\r