--- /dev/null
+/*******************************************************************************\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