--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 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.swt.widgets;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.function.Consumer;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.layout.TreeColumnLayout;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.viewers.ColumnWeightData;\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.DragSourceEvent;\r
+import org.eclipse.swt.dnd.DragSourceListener;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.DropTargetListener;\r
+import org.eclipse.swt.dnd.FileTransfer;\r
+import org.eclipse.swt.dnd.TextTransfer;\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.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeColumn;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.Column;\r
+import org.simantics.browsing.ui.ExplorerState;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.GraphExplorer.TransientExplorerState;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.StatePersistor;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.common.EvaluatorData;\r
+import org.simantics.browsing.ui.common.EvaluatorDataImpl;\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.FilterAreaSource;\r
+import org.simantics.browsing.ui.common.views.IFilterArea;\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.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.graph.impl.SessionContextInputSource;\r
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.browsing.ui.swt.Activator;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.ComparatorSelector;\r
+import org.simantics.browsing.ui.swt.ContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.DefaultExplorerSelectionListener;\r
+import org.simantics.browsing.ui.swt.DefaultIsCheckedProcessor2;\r
+import org.simantics.browsing.ui.swt.DefaultKeyListener;\r
+import org.simantics.browsing.ui.swt.DefaultMouseListener;\r
+import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver;\r
+import org.simantics.browsing.ui.swt.FilterArea;\r
+import org.simantics.browsing.ui.swt.GraphExplorerFactory;\r
+import org.simantics.browsing.ui.swt.IContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.RootFilterArea;\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.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ResourceRead;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextChangedListener;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.db.management.SessionContextChangedEvent;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.ui.SimanticsUI;\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.dnd.SessionContainer;\r
+import org.simantics.ui.selection.AnyResource;\r
+import org.simantics.ui.selection.AnyVariable;\r
+import org.simantics.ui.selection.ExplorerColumnContentType;\r
+import org.simantics.ui.selection.ExplorerInputContentType;\r
+import org.simantics.ui.selection.WorkbenchSelectionContentType;\r
+import org.simantics.ui.selection.WorkbenchSelectionElement;\r
+import org.simantics.ui.selection.WorkbenchSelectionUtils;\r
+import org.simantics.utils.ObjectUtils;\r
+import org.simantics.utils.datastructures.BinaryFunction;\r
+import org.simantics.utils.datastructures.Function;\r
+import org.simantics.utils.datastructures.disposable.DisposeState;\r
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
+import org.simantics.utils.datastructures.hints.HintTracker;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintTracker;\r
+\r
+\r
+public class GraphExplorerComposite extends Composite implements Widget, IAdaptable {\r
+\r
+ protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor;\r
+ protected UserSelectedViewpointFactoryQueryProcessor userSelectedViewpointFactoryQueryProcessor;\r
+ protected FilterSelectionRequestQueryProcessor filterSelectionRequestQueryProcessor;\r
+ protected IFilterArea filterArea;\r
+ protected EvaluatorData evaluatorData;\r
+\r
+ protected LocalResourceManager resourceManager;\r
+\r
+ protected ISelectionListener workbenchSelectionListener;\r
+\r
+ private final int style;\r
+\r
+ final private IWorkbenchSite site;\r
+\r
+ protected GraphExplorer explorer;\r
+\r
+ protected IMenuManager menuManager;\r
+\r
+ private final Map<String, Object> args;\r
+\r
+ protected ISessionContextProvider contextProvider;\r
+\r
+ private ISessionContext sessionContext;\r
+\r
+ private Object dragSource;\r
+\r
+ private IHintTracker sessionContextTracker = new SessionContextProjectTracker();\r
+\r
+ private InputSource inputSource = new DirectInputSource();\r
+ private FilterAreaSource filterAreaSource = new SelectionFilterAreaSource();\r
+\r
+ private final TreeColumnLayout ad;\r
+ private String[] editingColumn = ColumnKeys.KEYS_SINGLE;\r
+ \r
+ private StatePersistor persistor = null;\r
+\r
+ private final Composite toolComposite;\r
+ private final Composite toolComposite2;\r
+ private final Composite explorerComposite;\r
+ final private WidgetSupport support;\r
+ private final boolean useNodeBrowseContexts;\r
+ private final boolean useNodeActionContexts;\r
+\r
+ static class SelectionElement extends AdaptableHintContext {\r
+\r
+ final public WorkbenchSelectionElement wse;\r
+ final public Object content;\r
+ final public Resource resource;\r
+ final public Variable variable;\r
+ final public Object input;\r
+ final public TransientExplorerState explorerState;\r
+ \r
+ private WorkbenchSelectionElement extractWse(Object content) {\r
+ if(content instanceof NodeContext) {\r
+ NodeContext context = (NodeContext)content;\r
+ Object input = context.getConstant(NodeType.TYPE);\r
+ if(input instanceof NodeType) \r
+ return ((NodeType)input).getWorkbenchSelectionElement(context);\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ private Resource extractResource(Object content) {\r
+ if(content instanceof NodeContext) {\r
+ NodeContext context = (NodeContext)content;\r
+ Object input = context.getConstant(BuiltinKeys.INPUT);\r
+ if(input instanceof Resource) return (Resource)input;\r
+ if(input instanceof IAdaptable) {\r
+ Resource var = (Resource)((IAdaptable)input).getAdapter(Resource.class);\r
+ if(var != null) return var;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ private Variable extractVariable(Object content) {\r
+ if(content instanceof NodeContext) {\r
+ NodeContext context = (NodeContext)content;\r
+ Object input = context.getConstant(BuiltinKeys.INPUT);\r
+ if(input instanceof Variable) return (Variable)input;\r
+ if(input instanceof IAdaptable) {\r
+ Variable var = (Variable)((IAdaptable)input).getAdapter(Variable.class);\r
+ if(var != null) return var;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ private Object extractInput(Object content) {\r
+ if(content instanceof NodeContext) {\r
+ NodeContext context = (NodeContext)content;\r
+ return context.getConstant(BuiltinKeys.INPUT);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public SelectionElement(GraphExplorer explorer, Key[] keys, Object content) {\r
+ super(keys);\r
+ this.content = content;\r
+ this.wse = extractWse(content);\r
+ this.resource = extractResource(content);\r
+ this.variable = extractVariable(content);\r
+ this.input = extractInput(content);\r
+ this.explorerState = explorer.getTransientState();\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {\r
+\r
+ if(wse != null) {\r
+ T result = wse.getContent(contentType);\r
+ if(result != null) return result;\r
+ }\r
+ \r
+ if(contentType instanceof AnyResource) return (T)resource;\r
+ else if(contentType instanceof AnyVariable) {\r
+ AnyVariable type = (AnyVariable)contentType;\r
+ try {\r
+ \r
+ if(variable != null) return (T)variable;\r
+ \r
+ if(resource == null) return null;\r
+ \r
+ return (T) type.processor.sync(new ResourceRead<Variable>(resource) {\r
+ @Override\r
+ public Variable perform(ReadGraph graph) throws DatabaseException {\r
+ return Variables.getPossibleVariable(graph, resource);\r
+ }\r
+ \r
+ });\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ } else if (contentType instanceof ExplorerInputContentType) {\r
+ return (T)input;\r
+ } else if (contentType instanceof ExplorerColumnContentType) {\r
+ return (T)explorerState.getActiveColumn();\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ @SuppressWarnings("rawtypes")\r
+ @Override\r
+ public Object getAdapter(Class adapter) {\r
+ if(WorkbenchSelectionElement.class == adapter) {\r
+ return wse;\r
+ }\r
+ if(NodeContext.class == adapter) {\r
+ if(content instanceof NodeContext)\r
+ return (NodeContext)content;\r
+ else\r
+ return null;\r
+ }\r
+ return super.getAdapter(adapter);\r
+ }\r
+\r
+ }\r
+ private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {\r
+\r
+ private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN };\r
+ \r
+ @Override\r
+ public Object[] call(GraphExplorer explorer, Object[] objects) {\r
+ Object[] result = new Object[objects.length];\r
+ for (int i = 0; i < objects.length; i++) {\r
+ SelectionElement context = new SelectionElement(explorer, KEYS, objects[i]);\r
+ context.setHint(SelectionHints.KEY_MAIN, objects[i]);\r
+ result[i] = context;\r
+ }\r
+ return result;\r
+ }\r
+\r
+ };\r
+\r
+ private Set<String> browseContexts = null;\r
+\r
+ private DisposeState disposeState = DisposeState.Alive;\r
+\r
+ private boolean created = false;\r
+\r
+ protected String contextMenuId = null;\r
+\r
+ protected Set<String> uiContext = null;\r
+\r
+ protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() {\r
+ @Override\r
+ public void sessionContextChanged(SessionContextChangedEvent event) {\r
+ sessionContext = event.getNewValue();\r
+ sessionContextTracker.track(sessionContext);\r
+ }\r
+ };\r
+\r
+ public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, WidgetSupport support, int style) {\r
+\r
+ super(parent, SWT.NONE);\r
+\r
+ if (args == null)\r
+ args = Collections.emptyMap();\r
+\r
+ this.args = args;\r
+ this.site = site;\r
+ this.style = style;\r
+ this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), this);\r
+\r
+ contextProvider = getSessionContextProvider(site);\r
+\r
+ Integer maxChildren = (Integer)args.get("maxChildren");\r
+\r
+ GridLayoutFactory.fillDefaults().equalWidth(false).numColumns(1).margins(0,0).spacing(0,0).applyTo(this);\r
+\r
+ toolComposite = new Composite(this, SWT.NONE);\r
+// toolComposite.setBackground(toolComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
+// GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite);\r
+ GridLayoutFactory.fillDefaults().applyTo(toolComposite);\r
+\r
+ ad = new TreeColumnLayout();\r
+ explorerComposite = new Composite(this, SWT.NONE);\r
+ explorerComposite.setLayout(ad);\r
+ GridDataFactory.fillDefaults().grab(true, true).minSize(1, 50).applyTo(explorerComposite);\r
+\r
+ if (args.containsKey("treeView") && Boolean.TRUE.equals(args.get("treeView"))) {\r
+ explorer = createExplorerControl2(explorerComposite, maxChildren);\r
+ } else {\r
+ explorer = createExplorerControl(explorerComposite, maxChildren);\r
+ }\r
+ \r
+ if (args.containsKey("useNodeBrowseContexts") && Boolean.TRUE.equals(args.get("useNodeBrowseContexts"))) {\r
+ useNodeBrowseContexts = true;\r
+ } else {\r
+ useNodeBrowseContexts = false;\r
+ }\r
+ \r
+ if (args.containsKey("useNodeActionContexts") && Boolean.TRUE.equals(args.get("useNodeActionContexts"))) {\r
+ useNodeActionContexts = true;\r
+ } else {\r
+ useNodeActionContexts = false;\r
+ }\r
+ \r
+ toolComposite2 = new Composite(this, SWT.NONE);\r
+// toolComposite2.setBackground(toolComposite2.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
+// GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite2);\r
+ GridLayoutFactory.fillDefaults().applyTo(toolComposite2);\r
+\r
+ this.support = support;\r
+\r
+ if (support != null)\r
+ support.register(this);\r
+\r
+ }\r
+\r
+ public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, int style) {\r
+\r
+ this(args, site, parent, null, style);\r
+\r
+ }\r
+\r
+ public ISessionContextProvider getSessionContextProvider(IWorkbenchSite site) {\r
+ if(site != null)\r
+ return SimanticsUI.getSessionContextProvider(site.getWorkbenchWindow());\r
+ else\r
+ return SimanticsUI.getSessionContextProvider();\r
+ }\r
+\r
+ public GraphExplorer getExplorer() {\r
+ return explorer;\r
+ }\r
+\r
+ public Composite getExplorerComposite() {\r
+ return explorerComposite;\r
+ }\r
+\r
+ public <T> T getExplorerControl() {\r
+ return explorer.getControl();\r
+ }\r
+\r
+ public void addListenerToControl(int eventType, Listener listener) {\r
+ ((Tree)explorer.getControl()).addListener(eventType, listener);\r
+ }\r
+\r
+ public void finish() {\r
+ created = true;\r
+ createControls(site);\r
+ attachToSession();\r
+ }\r
+\r
+ IWorkbenchSite getSite() {\r
+ return site;\r
+ }\r
+\r
+ protected void activateUiContexts() {\r
+ Collection<String> contexts = getUiContexts();\r
+ if (contexts == null || contexts.isEmpty())\r
+ return;\r
+ IWorkbenchSite site = getSite();\r
+ if (site != null) {\r
+ IContextService cs = (IContextService) getSite().getService(IContextService.class);\r
+ for (String context : contexts)\r
+ cs.activateContext(context);\r
+ }\r
+ }\r
+\r
+ protected void createControls(IWorkbenchSite site) {\r
+\r
+ // Initialize explorer control.\r
+// GridDataFactory.fillDefaults().grab(true, true).applyTo(explorer.getControl());\r
+\r
+ Control control = explorer.getControl();\r
+\r
+ // Initialize context menu if an initializer is provided.\r
+ IContextMenuInitializer cmi = getContextMenuInitializer();\r
+ if (cmi != null) {\r
+ ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+ menuManager = cmi.createContextMenu(control, selectionProvider, site);\r
+ }\r
+\r
+ // Initialize UI contexts\r
+ activateUiContexts();\r
+\r
+ // Initialize DND.\r
+ dragSource = setupDND(explorer);\r
+\r
+ // Listeners are only added once per listener, not every time the\r
+ // session context changes.\r
+ addListeners(explorer, menuManager);\r
+\r
+ userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor();\r
+ userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor();\r
+ filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor();\r
+ \r
+ explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
+\r
+ boolean hasExtraControls = false;\r
+ boolean hasExtraControls2 = false;\r
+\r
+ Boolean displaySelectors = (Boolean)args.get("displaySelectors");\r
+ if(displaySelectors == null || displaySelectors == true) {\r
+\r
+ @SuppressWarnings("unused")\r
+ ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+// comparatorSelector.moveAbove(control);\r
+\r
+ @SuppressWarnings("unused")\r
+ ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+// viewpointSelector.moveAbove(control);\r
+\r
+ hasExtraControls = true;\r
+\r
+ }\r
+\r
+ Boolean displayFilter = (Boolean)args.get("displayFilter");\r
+ if(displayFilter == null || displayFilter == true) {\r
+\r
+ \r
+ filterArea = filterAreaSource.getFilterArea(toolComposite, explorer);\r
+// filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+ //filterArea.moveAbove(control);\r
+\r
+ hasExtraControls = true;\r
+\r
+ }\r
+\r
+ Boolean displayFilter2 = (Boolean)args.get("displayFilter2");\r
+ if(displayFilter2 != null && displayFilter2 == true) {\r
+\r
+ filterArea = filterAreaSource.getFilterArea(toolComposite2, explorer);\r
+// filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite2, SWT.READ_ONLY);\r
+// //filterArea.moveAbove(control);\r
+\r
+ hasExtraControls2 = true;\r
+\r
+ }\r
+\r
+// filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, this, SWT.READ_ONLY);\r
+// filterArea.moveAbove(control);\r
+\r
+ if(!hasExtraControls)\r
+ GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite);\r
+ if(!hasExtraControls2)\r
+ GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite2);\r
+\r
+ GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control);\r
+\r
+ //tree.getTree().setLayout(new FillLayout()\r
+ //this.setLayout(LayoutUtils.createNoBorderGridLayout(2, false));\r
+\r
+ DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
+ target.setTransfer(getAcceptedDataTypes());\r
+ target.addDropListener(new DropTargetListener() {\r
+\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 dragLeave(DropTargetEvent event) {\r
+ }\r
+\r
+ @Override\r
+ public void dragOperationChanged(DropTargetEvent event) {\r
+ }\r
+\r
+ @Override\r
+ public void dragOver(DropTargetEvent event) {\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
+ Object data = item.getData();\r
+ if (data instanceof NodeContext)\r
+ handleDrop(event.data, (NodeContext) data);\r
+ else if (data instanceof IAdaptable) {\r
+ IAdaptable a = (IAdaptable) data;\r
+ handleDrop(event.data, (NodeContext) a.getAdapter(NodeContext.class));\r
+ }\r
+ } else\r
+ handleDrop(event.data, null);\r
+ }\r
+\r
+ @Override\r
+ public void dropAccept(DropTargetEvent event) {\r
+ }\r
+\r
+ });\r
+\r
+ // Add workbench listeners and make sure they are cleaned up\r
+ setWorkbenchListeners();\r
+ control.addListener(SWT.Dispose, new Listener() {\r
+ @Override\r
+ public void handleEvent(Event event) {\r
+ doDispose();\r
+ }\r
+ });\r
+ }\r
+\r
+ @SuppressWarnings({ "rawtypes", "unchecked" })\r
+ @Override\r
+ public Object getAdapter(Class adapter) {\r
+ if (GraphExplorer.class == adapter)\r
+ return explorer;\r
+ if (EvaluatorData.class == adapter)\r
+ return evaluatorData;\r
+ if (BrowseContext.class == adapter) {\r
+ EvaluatorData ed = evaluatorData;\r
+ return ed != null ? ed.getBrowseContext() : null;\r
+ }\r
+ if (adapter == IFilterAreaProvider.class)\r
+ return filterArea;\r
+ return explorer.getAdapter(adapter);\r
+ }\r
+\r
+ protected void doDispose() {\r
+ //System.out.println(this + ".GraphExplorerComposite.doDispose()");\r
+ removeWorkbenchListeners();\r
+ userSelectedComparableFactoryQueryProcessor = null;\r
+ userSelectedViewpointFactoryQueryProcessor = null;\r
+ filterSelectionRequestQueryProcessor = null;\r
+\r
+ disposeState = DisposeState.Disposing;\r
+ try {\r
+ //System.out.println(this + ".GraphExplorerViewBase.dispose()");\r
+ if (contextProvider != null) {\r
+ contextProvider.removeContextChangedListener(contextChangeListener);\r
+ contextProvider = null;\r
+ }\r
+ sessionContextTracker.untrack();\r
+ resourceManager = null;\r
+ explorer = null;\r
+ sessionContext = null;\r
+ dragSource = null;\r
+// parent = null;\r
+ } finally {\r
+ disposeState = DisposeState.Disposed;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ doDispose();\r
+ super.dispose();\r
+ }\r
+\r
+ protected StatePersistor getStatePersistor() {\r
+ return persistor;\r
+ }\r
+ \r
+ public void setStatePersistor(StatePersistor persistor) {\r
+ this.persistor = persistor;\r
+ }\r
+ \r
+ protected void initializeExplorer(GraphExplorer explorer, ISessionContext context) {\r
+\r
+ if(explorer == null || explorer.isDisposed()) return;\r
+ if(context == null) return;\r
+ if(browseContexts == null) return;\r
+\r
+ Session session = context != null ? context.getSession() : null;\r
+ setupDragSource(session);\r
+\r
+ if (session != null) {\r
+ evaluatorData = createEvaluatorData(session);\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
+ }\r
+\r
+ explorer.setPersistor(getStatePersistor());\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.setProcessor(new DefaultIsCheckedProcessor2(evaluatorData));\r
+ explorer.setPrimitiveProcessor(new TypesQueryProcessor());\r
+ explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor());\r
+ explorer.setPrimitiveProcessor(new InheritsQueryProcessor());\r
+ explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor());\r
+\r
+ explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor);\r
+ explorer.setProcessor(new ComparableSelectorQueryProcessor());\r
+ explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor);\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 context) {\r
+\r
+// Set<String> browseContexts = getArgument("browseContexts");\r
+\r
+ return Evaluators.load(context.getSession(), browseContexts, resourceManager, useNodeBrowseContexts, useNodeActionContexts);\r
+\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
+ }\r
+\r
+ DragSourceListenerFactory dragSourceListenerFactory = new DragSourceListenerFactory() {\r
+\r
+ final Transfer[] transfers = new Transfer[] {LocalObjectTransfer.getTransfer(), TextTransfer.getInstance() };\r
+\r
+ @Override\r
+ public DragSourceListener get(ISelectionProvider selectionProvider) {\r
+\r
+ LocalSelectionDragSourceListener ls = new LocalSelectionDragSourceListener(selectionProvider);\r
+\r
+ return new DragSourceListener() {\r
+ \r
+ @Override\r
+ public void dragStart(DragSourceEvent event) {\r
+ ls.dragStart(event);\r
+ }\r
+ \r
+ @Override\r
+ public void dragSetData(DragSourceEvent event) {\r
+ if(TextTransfer.getInstance().isSupportedType(event.dataType)) {\r
+ try {\r
+ event.data = WorkbenchSelectionUtils.getPossibleJSON(selectionProvider.getSelection());\r
+ } catch (DatabaseException e) {\r
+ event.data = "{ type:\"Exception\" }";\r
+ Logger.defaultLogError(e);\r
+ }\r
+ } else if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {\r
+ ls.dragSetData(event);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void dragFinished(DragSourceEvent event) {\r
+ ls.dragFinished(event);\r
+ }\r
+ };\r
+ }\r
+\r
+ @Override\r
+ public Transfer[] getTransfers() {\r
+ return transfers;\r
+ }\r
+\r
+ };\r
+\r
+ public void setDragSourceListenerFactory(DragSourceListenerFactory dragSourceListenerFactory) {\r
+ this.dragSourceListenerFactory = dragSourceListenerFactory;\r
+ }\r
+\r
+ protected DragSourceListener setupDND(GraphExplorer explorer) {\r
+\r
+ ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+\r
+ DragSourceListener listener = createDragSourceListener(selectionProvider);\r
+\r
+ Control control = explorer.getControl();\r
+ DragSource source = createDragSource(control);\r
+ source.setTransfer(getTransfers());\r
+ source.addDragListener(listener);\r
+ source.setDragSourceEffect(new NoImageDragSourceEffect(control));\r
+\r
+ return listener;\r
+\r
+ }\r
+\r
+ protected DragSourceListener createDragSourceListener(ISelectionProvider selectionProvider) {\r
+ return dragSourceListenerFactory.get(selectionProvider);\r
+ }\r
+\r
+ private int dragStyle = DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;\r
+\r
+ protected void setDragStyle(int style) {\r
+ this.dragStyle = style;\r
+ }\r
+\r
+ protected int getDragStyle() {\r
+ return dragStyle;\r
+ }\r
+\r
+ protected DragSource createDragSource(Control control) {\r
+ return new DragSource(control, getDragStyle());\r
+ }\r
+\r
+ protected Transfer[] getTransfers() {\r
+ return dragSourceListenerFactory.getTransfers();\r
+ }\r
+\r
+ public EvaluatorData getEvaluatorData() {\r
+ return evaluatorData;\r
+ }\r
+\r
+ public interface InputSource {\r
+ /**\r
+ * @param ctx the session context to read the input from. May be\r
+ * <code>null</code> if there is no session.\r
+ * @return the input object of a graph explorer. To indicate no input,\r
+ * use {@link GraphExplorerConstants#EMPTY_INPUT}. Never return\r
+ * <code>null</code>.\r
+ */\r
+ Object get(ISessionContext ctx, Object selection);\r
+ }\r
+ \r
+ public interface FilterSource {\r
+ \r
+ \r
+ \r
+ }\r
+\r
+ /**\r
+ * The default hint tracker that will be active if\r
+ * {@link GraphExplorerComposite#setSessionContextTracker(IHintTracker) is\r
+ * not called.\r
+ */\r
+ public class SessionContextProjectTracker extends HintTracker {\r
+ public SessionContextProjectTracker() {\r
+ IHintListener activeProjectListener = new HintListenerAdapter() {\r
+ @Override\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ applySessionContext(getSessionContext());\r
+ }\r
+ };\r
+ addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);\r
+ }\r
+ }\r
+\r
+ public class DirectInputSource implements InputSource {\r
+ @Override\r
+ public Object get(ISessionContext ctx, Object selection) {\r
+ return selection;\r
+ }\r
+ }\r
+ \r
+ public static class SelectionFilterAreaSource implements FilterAreaSource {\r
+\r
+ @Override\r
+ public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
+ FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
+ return new FilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
+ }\r
+ \r
+ }\r
+\r
+ public static class RootFilterAreaSource implements FilterAreaSource {\r
+\r
+ @Override\r
+ public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
+ FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
+ return new RootFilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
+ }\r
+ \r
+ }\r
+\r
+ protected void setSessionContextTracker(IHintTracker tracker) {\r
+ this.sessionContextTracker = tracker;\r
+ }\r
+\r
+ public void setInputSource(InputSource source) {\r
+ this.inputSource = source;\r
+ }\r
+ \r
+ public void setFilterAreaSource(FilterAreaSource provider) {\r
+ this.filterAreaSource = provider;\r
+ }\r
+\r
+ public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {\r
+ this.selectionTransformation = transformation;\r
+ if(explorer != null) explorer.setSelectionTransformation(transformation);\r
+ }\r
+\r
+ protected Set<String> getBrowseContexts() {\r
+ return browseContexts;\r
+ }\r
+ \r
+ public void setBrowseContexts(Set<String> contexts) {\r
+ this.browseContexts = contexts;\r
+ //initializeExplorer(explorer, getSessionContext());\r
+ }\r
+\r
+ public void setBrowseContexts(String ... contexts) {\r
+ this.browseContexts = new HashSet<String>();\r
+ for(String s : contexts) this.browseContexts.add(s);\r
+ initializeExplorer(explorer, getSessionContext());\r
+ }\r
+\r
+ public void setContextMenuId(String contextMenuId) {\r
+ this.contextMenuId = contextMenuId;\r
+ }\r
+\r
+// protected IContextMenuInitializer getContextMenuInitializer() {\r
+// String contextMenuId = getContextMenuId();\r
+// if(contextMenuId != null) {\r
+// return new ContextMenuInitializer(contextMenuId);\r
+// } else {\r
+// return null;\r
+// }\r
+// }\r
+\r
+ protected String getContextMenuId() {\r
+ return this.contextMenuId;\r
+ }\r
+\r
+ public void setUiContexts(Set<String> uiContext) {\r
+ this.uiContext = uiContext;\r
+ }\r
+\r
+ public Set<String> getUiContexts() {\r
+ return uiContext;\r
+ }\r
+\r
+ protected InputSource getInputSource() {\r
+ return inputSource;\r
+ }\r
+\r
+ protected Map<String, Object> getArguments() {\r
+ return args;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ protected <T> T getArgument(String key) {\r
+ return (T) args.get(key);\r
+ }\r
+\r
+ protected DisposeState getDisposeState() {\r
+ return disposeState;\r
+ }\r
+\r
+ public ISessionContext getSessionContext() {\r
+ return sessionContext;\r
+ }\r
+\r
+ public ISessionContextProvider getSessionContextProvider() {\r
+ return contextProvider;\r
+ }\r
+\r
+ @Override\r
+ public boolean setFocus() {\r
+ if (explorer != null && !explorer.isDisposed())\r
+ explorer.setFocus();\r
+ return true;\r
+ }\r
+\r
+ public void setWorkbenchListeners() {\r
+ if (workbenchSelectionListener == null && getSite() != null) {\r
+ ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
+ getSite().setSelectionProvider(selectionProvider);\r
+\r
+ // Listen to the workbench selection also to propagate it to\r
+ // the explorer also.\r
+ workbenchSelectionListener = new DefaultExplorerSelectionListener(site.getPage().getActivePart(), explorer);\r
+ //System.out.println("ADD WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
+ getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener);\r
+ }\r
+ }\r
+\r
+ protected void removeWorkbenchListeners() {\r
+ //System.out.println("REMOVE WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
+ // Remember to remove the installed workbench selection listener\r
+ if (workbenchSelectionListener != null) {\r
+ getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);\r
+ workbenchSelectionListener = null;\r
+\r
+ ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
+ if(getSite().getSelectionProvider() == selectionProvider) getSite().setSelectionProvider(null);\r
+ \r
+ }\r
+ }\r
+\r
+ protected final void attachToSession() {\r
+\r
+ // Track active ISessionContext changes\r
+ //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());\r
+ contextProvider.addContextChangedListener(contextChangeListener);\r
+\r
+ // Start tracking the current session context for input changes.\r
+ // This will/must cause applySessionContext to get called.\r
+ // Doing the applySessionContext initialization this way\r
+ // instead of directly calling it will also make sure that\r
+ // applySessionContext is only called once when first initialized,\r
+ // and not twice like with the direct invocation.\r
+ this.sessionContext = contextProvider.getSessionContext();\r
+ sessionContextTracker.track(sessionContext);\r
+ }\r
+\r
+ // /////////////////////////////////////////////////////////////////////////\r
+ // Override / implement these:\r
+\r
+// /**\r
+// * Returns an ID that is used for persisting a GraphExplorer instance.\r
+// *\r
+// * Used for </code>restoreState(IMemento)</code> and\r
+// * <code>restoreState(IMemento)</code> in OntologyExplorer. Must be unique\r
+// * within a workbench part.\r
+// *\r
+// * @return a unique name for this particular graph explorer view used for\r
+// * saving and restoring the state of this view part\r
+// */\r
+// public String getExplorerName() {\r
+// return "GraphExplorerViewBase";\r
+// }\r
+\r
+ /**\r
+ * Override this method to add controls to the view part. This is invoked\r
+ * before attaching the view part to a database session.\r
+ * \r
+ * @param parent\r
+ */\r
+ protected void createControls(Composite parent) {\r
+\r
+ }\r
+\r
+ /**\r
+ * Override this method and provide a proper context menu initializer if you\r
+ * want to have this base class initialize one for you.\r
+ * \r
+ * @return the initializer to be used by {@link #createControls(Composite)}\r
+ */\r
+ protected IContextMenuInitializer getContextMenuInitializer() {\r
+ String contextMenuId = getContextMenuId();\r
+ if(contextMenuId != null) {\r
+ return new ContextMenuInitializer(contextMenuId);\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param parent\r
+ * @return\r
+ */\r
+ protected GraphExplorer createExplorerControl(Composite parent, Integer maxChildren) {\r
+ GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
+ if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
+\r
+ GraphExplorer ge = factory\r
+ .selectionDataResolver(new DefaultSelectionDataResolver())\r
+ .selectionTransformation(selectionTransformation)\r
+ .setServiceLocator(site)\r
+ .create(parent, style);\r
+\r
+ return ge;\r
+ }\r
+ \r
+ protected GraphExplorer createExplorerControl2(Composite parent, Integer maxChildren) {\r
+ GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
+ if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
+\r
+ GraphExplorer ge = factory\r
+ .selectionDataResolver(new DefaultSelectionDataResolver())\r
+ .selectionTransformation(selectionTransformation)\r
+ .setServiceLocator(site)\r
+ .create2(parent, style);\r
+\r
+ return ge;\r
+ }\r
+\r
+ protected void setupDragSource(Session session) {\r
+ if (dragSource instanceof SessionContainer) {\r
+ ((SessionContainer) dragSource).setSession(session);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Override to customize the addition of listeners a newly created\r
+ * GraphExplorer.\r
+ * \r
+ * @param explorer\r
+ */\r
+ protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
+ addSelectionInputListeners(explorer, menuManager);\r
+ }\r
+\r
+ protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
+ // Consider ENTER presses to simulate mouse left button double clicks\r
+ explorer.addListener(new DefaultKeyListener(contextProvider, explorer, new Function<String[]>() {\r
+ @Override\r
+ public String[] execute(Object... obj) {\r
+ return getEditingColumn((NodeContext) obj[0]);\r
+ }\r
+ }));\r
+ // Default double click handling\r
+ explorer.addListener(new DefaultMouseListener(explorer));\r
+ }\r
+\r
+ protected String[] getEditingColumn(NodeContext context) {\r
+ return editingColumn;\r
+ }\r
+ \r
+ public void setEditingColumn(String... columnKeysInOrderOfTrial) {\r
+ this.editingColumn = columnKeysInOrderOfTrial;\r
+ }\r
+\r
+ // Needed for preventing unnecessary re-initialization of the explorer with the same input.\r
+ private Object currentInput;\r
+ private Object currentRoot;\r
+\r
+ /**\r
+ * Invoke this to reinitialize the explorer and reset its input. The input\r
+ * will be resolved from the specified ISessionContext based on the\r
+ * {@link SessionContextInputSource} that is currently in use. If the input\r
+ * is identical to the previous input, nothing will be done.\r
+ * \r
+ * @param context\r
+ */\r
+ public final boolean applySessionContext(ISessionContext context) {\r
+\r
+ // If control is not alive anymore, do nothing.\r
+ //System.out.println(this + ": applySessionContext(" + context + "), explorer=" + explorer);\r
+ if (disposeState != DisposeState.Alive)\r
+ return false;\r
+\r
+ //System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");\r
+ initializeExplorer(explorer, context);\r
+\r
+\r
+ // Start tracking the session context.\r
+ //\r
+ // If this is not the same session that is currently tracked, it will\r
+ // cause IHintListeners of the sessionContextTracker to fire.\r
+ // For this we need the above input equality (identity) checking.\r
+ // This is here just to make sure that we are tracking the correct\r
+ // session context.\r
+ sessionContextTracker.track(sessionContext);\r
+\r
+ this.sessionContext = context;\r
+ Object root = inputSource.get(context, currentInput);\r
+ if (ObjectUtils.objectEquals(root, currentRoot))\r
+ return false;\r
+\r
+ currentRoot = root;\r
+\r
+ //System.out.println(this + ": setRoot(" + input + ")");\r
+ explorer.setUIContexts(uiContext);\r
+ explorer.setRoot(root);\r
+\r
+ return true;\r
+\r
+ }\r
+\r
+ protected boolean isImportantInput(Object previousSelection, Object selection) {\r
+ return !ObjectUtils.objectEquals(previousSelection, selection);\r
+ }\r
+\r
+ public void setInput(Object selection, boolean force) {\r
+\r
+ assert(created);\r
+\r
+ if (isDisposed())\r
+ return;\r
+ if (sessionContext == null)\r
+ return;\r
+\r
+ // Check if this is a duplicate of the previous selection to reduce unnecessary flicker.\r
+ if (!force && !isImportantInput(currentInput, selection))\r
+ return;\r
+\r
+ currentInput = selection;\r
+\r
+ Object root = inputSource.get(sessionContext, selection);\r
+\r
+ currentRoot = root;\r
+\r
+ explorer.setUIContexts(uiContext);\r
+\r
+ if (root == null) {\r
+ explorer.setRoot(GraphExplorer.EMPTY_INPUT);\r
+ } else {\r
+ explorer.setRoot(root);\r
+ }\r
+\r
+ }\r
+\r
+ public void setColumnsVisible(boolean visible) {\r
+ explorer.setColumnsVisible(visible);\r
+ }\r
+\r
+ private int getColumnWidth(Column column, ExplorerState state) {\r
+ // Get saved width from the persistor if there is one.\r
+ if (state != null && state.columnWidths != null) {\r
+ Integer width = state.columnWidths.get(column.getLabel());\r
+ if (width != null)\r
+ return width;\r
+ }\r
+ return column.getWidth();\r
+ }\r
+ \r
+ public void setColumns(Column[] columns) {\r
+\r
+ explorer.setColumns(columns, new Consumer<Map<Column, Object>>() {\r
+\r
+ @Override\r
+ public void accept(Map<Column, Object> objects) {\r
+ ExplorerState state = null;\r
+ if (persistor != null) {\r
+ state = persistor.deserialize(\r
+ Platform.getStateLocation(Activator.getDefault().getBundle()).toFile(),\r
+ explorer.getRoot());\r
+ }\r
+\r
+ for(Map.Entry<Column, Object> entry : objects.entrySet()) {\r
+ Column column = entry.getKey();\r
+ TreeColumn treeColumn = (TreeColumn)entry.getValue();\r
+\r
+ if (column.getWidth() < 0) {\r
+ throw new IllegalArgumentException("Column minimum width cannot be < 0, got " + column.getWidth());\r
+ }\r
+\r
+ int width = getColumnWidth(column, state);\r
+ if(column.hasGrab()) {\r
+ \r
+ ad.setColumnData(treeColumn, new ColumnWeightData(column.getWeight(), width));\r
+\r
+ } else {\r
+\r
+ ad.setColumnData(treeColumn, new ColumnWeightData(0, width));\r
+\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ setInput(input, false);\r
+ }\r
+\r
+ public void setMaxChildren(int maxChildren) {\r
+ explorer.setMaxChildren(maxChildren);\r
+ }\r
+ \r
+ public <T> void addListener(ExplorerMouseListenerImpl<T> listener) {\r
+ \r
+ support.register(listener);\r
+ listener.register(explorer);\r
+ explorer.addListener(listener);\r
+ \r
+ }\r
+\r
+// @Override\r
+// public Point computeSize(int wHint, int hHint) {\r
+// Point p = super.computeSize(wHint, hHint);\r
+// System.err.println("graphExplorerComposite.computeSize " + p);\r
+// return p;\r
+// }\r
+// \r
+// @Override\r
+// public Point computeSize(int wHint, int hHint, boolean changed) {\r
+// Point p = super.computeSize(wHint, hHint, changed);\r
+// System.err.println("graphExplorerComposite.computeSize " + p);\r
+// return p;\r
+// }\r
+ \r
+}\r