]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
Merge "Testing SonarQube with Simantics Platform SDK"
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / widgets / GraphExplorerComposite.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.swt.widgets;\r
13 \r
14 import java.util.Collection;\r
15 import java.util.Collections;\r
16 import java.util.HashSet;\r
17 import java.util.Map;\r
18 import java.util.Set;\r
19 import java.util.function.Consumer;\r
20 \r
21 import org.eclipse.core.runtime.IAdaptable;\r
22 import org.eclipse.core.runtime.Platform;\r
23 import org.eclipse.jface.action.IMenuManager;\r
24 import org.eclipse.jface.layout.GridDataFactory;\r
25 import org.eclipse.jface.layout.GridLayoutFactory;\r
26 import org.eclipse.jface.layout.TreeColumnLayout;\r
27 import org.eclipse.jface.resource.JFaceResources;\r
28 import org.eclipse.jface.resource.LocalResourceManager;\r
29 import org.eclipse.jface.viewers.ColumnWeightData;\r
30 import org.eclipse.jface.viewers.ISelectionProvider;\r
31 import org.eclipse.swt.SWT;\r
32 import org.eclipse.swt.dnd.DND;\r
33 import org.eclipse.swt.dnd.DragSource;\r
34 import org.eclipse.swt.dnd.DragSourceEvent;\r
35 import org.eclipse.swt.dnd.DragSourceListener;\r
36 import org.eclipse.swt.dnd.DropTarget;\r
37 import org.eclipse.swt.dnd.DropTargetEvent;\r
38 import org.eclipse.swt.dnd.DropTargetListener;\r
39 import org.eclipse.swt.dnd.FileTransfer;\r
40 import org.eclipse.swt.dnd.TextTransfer;\r
41 import org.eclipse.swt.dnd.Transfer;\r
42 import org.eclipse.swt.widgets.Composite;\r
43 import org.eclipse.swt.widgets.Control;\r
44 import org.eclipse.swt.widgets.Event;\r
45 import org.eclipse.swt.widgets.Listener;\r
46 import org.eclipse.swt.widgets.Tree;\r
47 import org.eclipse.swt.widgets.TreeColumn;\r
48 import org.eclipse.swt.widgets.TreeItem;\r
49 import org.eclipse.ui.ISelectionListener;\r
50 import org.eclipse.ui.IWorkbenchSite;\r
51 import org.eclipse.ui.contexts.IContextService;\r
52 import org.simantics.browsing.ui.BuiltinKeys;\r
53 import org.simantics.browsing.ui.Column;\r
54 import org.simantics.browsing.ui.ExplorerState;\r
55 import org.simantics.browsing.ui.GraphExplorer;\r
56 import org.simantics.browsing.ui.GraphExplorer.TransientExplorerState;\r
57 import org.simantics.browsing.ui.NodeContext;\r
58 import org.simantics.browsing.ui.StatePersistor;\r
59 import org.simantics.browsing.ui.common.ColumnKeys;\r
60 import org.simantics.browsing.ui.common.EvaluatorData;\r
61 import org.simantics.browsing.ui.common.EvaluatorDataImpl;\r
62 import org.simantics.browsing.ui.common.processors.ComparableFactoryResolver;\r
63 import org.simantics.browsing.ui.common.processors.ComparableSelectorQueryProcessor;\r
64 import org.simantics.browsing.ui.common.processors.FilterSelectionRequestQueryProcessor;\r
65 import org.simantics.browsing.ui.common.processors.ImageDecoratorFactoryResolver;\r
66 import org.simantics.browsing.ui.common.processors.ImagerFactoryResolver;\r
67 import org.simantics.browsing.ui.common.processors.LabelDecoratorFactoryResolver;\r
68 import org.simantics.browsing.ui.common.processors.LabelerFactoryResolver;\r
69 import org.simantics.browsing.ui.common.processors.UserSelectedComparableFactoryQueryProcessor;\r
70 import org.simantics.browsing.ui.common.processors.UserSelectedViewpointFactoryQueryProcessor;\r
71 import org.simantics.browsing.ui.common.processors.ViewpointFactoryResolver;\r
72 import org.simantics.browsing.ui.common.views.FilterAreaSource;\r
73 import org.simantics.browsing.ui.common.views.IFilterArea;\r
74 import org.simantics.browsing.ui.common.views.IFilterAreaProvider;\r
75 import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource;\r
76 import org.simantics.browsing.ui.graph.impl.Evaluators;\r
77 import org.simantics.browsing.ui.graph.impl.InheritsQueryProcessor;\r
78 import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource;\r
79 import org.simantics.browsing.ui.graph.impl.RelatedObjectsQueryProcessor;\r
80 import org.simantics.browsing.ui.graph.impl.SessionContextInputSource;\r
81 import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
82 import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
83 import org.simantics.browsing.ui.swt.Activator;\r
84 import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
85 import org.simantics.browsing.ui.swt.ComparatorSelector;\r
86 import org.simantics.browsing.ui.swt.ContextMenuInitializer;\r
87 import org.simantics.browsing.ui.swt.DefaultExplorerSelectionListener;\r
88 import org.simantics.browsing.ui.swt.DefaultIsCheckedProcessor2;\r
89 import org.simantics.browsing.ui.swt.DefaultKeyListener;\r
90 import org.simantics.browsing.ui.swt.DefaultMouseListener;\r
91 import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver;\r
92 import org.simantics.browsing.ui.swt.FilterArea;\r
93 import org.simantics.browsing.ui.swt.GraphExplorerFactory;\r
94 import org.simantics.browsing.ui.swt.IContextMenuInitializer;\r
95 import org.simantics.browsing.ui.swt.RootFilterArea;\r
96 import org.simantics.browsing.ui.swt.StandardContextTypesQueryProcessor;\r
97 import org.simantics.browsing.ui.swt.TypesQueryProcessor;\r
98 import org.simantics.browsing.ui.swt.ViewpointSelector;\r
99 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
100 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
101 import org.simantics.db.AsyncReadGraph;\r
102 import org.simantics.db.ReadGraph;\r
103 import org.simantics.db.Resource;\r
104 import org.simantics.db.Session;\r
105 import org.simantics.db.common.request.ResourceRead;\r
106 import org.simantics.db.common.utils.Logger;\r
107 import org.simantics.db.exception.DatabaseException;\r
108 import org.simantics.db.layer0.SelectionHints;\r
109 import org.simantics.db.layer0.variable.Variable;\r
110 import org.simantics.db.layer0.variable.Variables;\r
111 import org.simantics.db.management.ISessionContext;\r
112 import org.simantics.db.management.ISessionContextChangedListener;\r
113 import org.simantics.db.management.ISessionContextProvider;\r
114 import org.simantics.db.management.SessionContextChangedEvent;\r
115 import org.simantics.project.ProjectKeys;\r
116 import org.simantics.ui.SimanticsUI;\r
117 import org.simantics.ui.dnd.LocalObjectTransfer;\r
118 import org.simantics.ui.dnd.LocalSelectionDragSourceListener;\r
119 import org.simantics.ui.dnd.NoImageDragSourceEffect;\r
120 import org.simantics.ui.dnd.SessionContainer;\r
121 import org.simantics.ui.selection.AnyResource;\r
122 import org.simantics.ui.selection.AnyVariable;\r
123 import org.simantics.ui.selection.ExplorerColumnContentType;\r
124 import org.simantics.ui.selection.ExplorerInputContentType;\r
125 import org.simantics.ui.selection.WorkbenchSelectionContentType;\r
126 import org.simantics.ui.selection.WorkbenchSelectionElement;\r
127 import org.simantics.ui.selection.WorkbenchSelectionUtils;\r
128 import org.simantics.utils.ObjectUtils;\r
129 import org.simantics.utils.datastructures.BinaryFunction;\r
130 import org.simantics.utils.datastructures.Function;\r
131 import org.simantics.utils.datastructures.disposable.DisposeState;\r
132 import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
133 import org.simantics.utils.datastructures.hints.HintTracker;\r
134 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
135 import org.simantics.utils.datastructures.hints.IHintListener;\r
136 import org.simantics.utils.datastructures.hints.IHintObservable;\r
137 import org.simantics.utils.datastructures.hints.IHintTracker;\r
138 \r
139 \r
140 public class GraphExplorerComposite extends Composite implements Widget, IAdaptable {\r
141 \r
142     protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor;\r
143     protected UserSelectedViewpointFactoryQueryProcessor  userSelectedViewpointFactoryQueryProcessor;\r
144     protected FilterSelectionRequestQueryProcessor        filterSelectionRequestQueryProcessor;\r
145     protected IFilterArea                                 filterArea;\r
146     protected EvaluatorData                               evaluatorData;\r
147 \r
148     protected LocalResourceManager                        resourceManager;\r
149 \r
150     protected ISelectionListener                          workbenchSelectionListener;\r
151 \r
152     private final int                                     style;\r
153 \r
154     final private IWorkbenchSite                          site;\r
155 \r
156     protected GraphExplorer                               explorer;\r
157 \r
158     protected IMenuManager                                menuManager;\r
159 \r
160     private final Map<String, Object>                     args;\r
161 \r
162     protected ISessionContextProvider                       contextProvider;\r
163 \r
164     private ISessionContext                               sessionContext;\r
165 \r
166     private Object                                        dragSource;\r
167 \r
168     private IHintTracker                                  sessionContextTracker = new SessionContextProjectTracker();\r
169 \r
170     private InputSource                                   inputSource           = new DirectInputSource();\r
171     private FilterAreaSource                              filterAreaSource    = new SelectionFilterAreaSource();\r
172 \r
173     private final TreeColumnLayout                                                        ad;\r
174     private String[]                                        editingColumn = ColumnKeys.KEYS_SINGLE;\r
175     \r
176     private StatePersistor                                                                      persistor = null;\r
177 \r
178     private final Composite                                                                       toolComposite;\r
179     private final Composite                                                                       toolComposite2;\r
180     private final Composite                                                                       explorerComposite;\r
181     final private WidgetSupport                                 support;\r
182     private final boolean                                                                       useNodeBrowseContexts;\r
183     private final boolean                                                                       useNodeActionContexts;\r
184 \r
185     static class SelectionElement extends AdaptableHintContext {\r
186 \r
187         final public WorkbenchSelectionElement wse;\r
188         final public Object content;\r
189         final public Resource resource;\r
190         final public Variable variable;\r
191         final public Object input;\r
192         final public TransientExplorerState explorerState;\r
193         \r
194         private WorkbenchSelectionElement extractWse(Object content) {\r
195             if(content instanceof NodeContext) {\r
196                 NodeContext context = (NodeContext)content;\r
197                 Object input = context.getConstant(NodeType.TYPE);\r
198                 if(input instanceof NodeType) \r
199                     return ((NodeType)input).getWorkbenchSelectionElement(context);\r
200             }\r
201             return null;\r
202         }\r
203         \r
204         private Resource extractResource(Object content) {\r
205                 if(content instanceof NodeContext) {\r
206                         NodeContext context = (NodeContext)content;\r
207                         Object input = context.getConstant(BuiltinKeys.INPUT);\r
208                         if(input instanceof Resource) return (Resource)input;\r
209                         if(input instanceof IAdaptable) {\r
210                                 Resource var = (Resource)((IAdaptable)input).getAdapter(Resource.class);\r
211                                 if(var != null) return var;\r
212                         }\r
213                 }\r
214                 return null;\r
215         }\r
216         \r
217         private Variable extractVariable(Object content) {\r
218                 if(content instanceof NodeContext) {\r
219                         NodeContext context = (NodeContext)content;\r
220                         Object input = context.getConstant(BuiltinKeys.INPUT);\r
221                         if(input instanceof Variable) return (Variable)input;\r
222                         if(input instanceof IAdaptable) {\r
223                                 Variable var = (Variable)((IAdaptable)input).getAdapter(Variable.class);\r
224                                 if(var != null) return var;\r
225                         }\r
226                 }\r
227                 return null;\r
228         }\r
229 \r
230         private Object extractInput(Object content) {\r
231                 if(content instanceof NodeContext) {\r
232                         NodeContext context = (NodeContext)content;\r
233                         return context.getConstant(BuiltinKeys.INPUT);\r
234                 }\r
235                 return null;\r
236         }\r
237 \r
238         public SelectionElement(GraphExplorer explorer, Key[] keys, Object content) {\r
239             super(keys);\r
240             this.content = content;\r
241             this.wse = extractWse(content);\r
242             this.resource = extractResource(content);\r
243             this.variable = extractVariable(content);\r
244             this.input = extractInput(content);\r
245             this.explorerState = explorer.getTransientState();\r
246         }\r
247 \r
248         @SuppressWarnings("unchecked")\r
249         @Override\r
250         public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {\r
251 \r
252             if(wse != null) {\r
253                 T result = wse.getContent(contentType);\r
254                 if(result != null) return result;\r
255             }\r
256             \r
257             if(contentType instanceof AnyResource) return (T)resource;\r
258             else if(contentType instanceof AnyVariable) {\r
259                 AnyVariable type = (AnyVariable)contentType;\r
260                 try {\r
261                         \r
262                         if(variable != null) return (T)variable;\r
263                         \r
264                         if(resource == null) return null;\r
265                         \r
266                     return (T) type.processor.sync(new ResourceRead<Variable>(resource) {\r
267                         @Override\r
268                         public Variable perform(ReadGraph graph) throws DatabaseException {\r
269                             return Variables.getPossibleVariable(graph, resource);\r
270                         }\r
271                         \r
272                     });\r
273                 } catch (DatabaseException e) {\r
274                     Logger.defaultLogError(e);\r
275                 }\r
276             } else if (contentType instanceof ExplorerInputContentType) {\r
277                 return (T)input;\r
278             } else if (contentType instanceof ExplorerColumnContentType) {\r
279                 return (T)explorerState.getActiveColumn();\r
280             }\r
281             return null;\r
282         }\r
283         \r
284         @SuppressWarnings("rawtypes")\r
285         @Override\r
286         public Object getAdapter(Class adapter) {\r
287                 if(WorkbenchSelectionElement.class == adapter) {\r
288                         return wse;\r
289                 }\r
290                 if(NodeContext.class == adapter) {\r
291                     if(content instanceof NodeContext)\r
292                         return (NodeContext)content;\r
293                     else\r
294                         return null;\r
295                 }\r
296                 return super.getAdapter(adapter);\r
297         }\r
298 \r
299     }\r
300     private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {\r
301 \r
302         private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN };\r
303         \r
304         @Override\r
305         public Object[] call(GraphExplorer explorer, Object[] objects) {\r
306             Object[] result = new Object[objects.length];\r
307             for (int i = 0; i < objects.length; i++) {\r
308                 SelectionElement context = new SelectionElement(explorer, KEYS, objects[i]);\r
309                 context.setHint(SelectionHints.KEY_MAIN, objects[i]);\r
310                 result[i] = context;\r
311             }\r
312             return result;\r
313         }\r
314 \r
315     };\r
316 \r
317     private Set<String>                                   browseContexts        = null;\r
318 \r
319     private DisposeState                                  disposeState          = DisposeState.Alive;\r
320 \r
321     private boolean                                       created               = false;\r
322 \r
323     protected String                                      contextMenuId         = null;\r
324 \r
325     protected Set<String>                                 uiContext             = null;\r
326 \r
327     protected ISessionContextChangedListener              contextChangeListener = new ISessionContextChangedListener() {\r
328         @Override\r
329         public void sessionContextChanged(SessionContextChangedEvent event) {\r
330             sessionContext = event.getNewValue();\r
331             sessionContextTracker.track(sessionContext);\r
332         }\r
333     };\r
334 \r
335     public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, WidgetSupport support, int style) {\r
336 \r
337         super(parent, SWT.NONE);\r
338 \r
339         if (args == null)\r
340             args = Collections.emptyMap();\r
341 \r
342         this.args = args;\r
343         this.site = site;\r
344         this.style = style;\r
345         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), this);\r
346 \r
347         contextProvider = getSessionContextProvider(site);\r
348 \r
349         Integer maxChildren = (Integer)args.get("maxChildren");\r
350 \r
351         GridLayoutFactory.fillDefaults().equalWidth(false).numColumns(1).margins(0,0).spacing(0,0).applyTo(this);\r
352 \r
353         toolComposite = new Composite(this, SWT.NONE);\r
354 //        toolComposite.setBackground(toolComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
355 //        GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
356         GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite);\r
357         GridLayoutFactory.fillDefaults().applyTo(toolComposite);\r
358 \r
359         ad = new TreeColumnLayout();\r
360         explorerComposite = new Composite(this, SWT.NONE);\r
361         explorerComposite.setLayout(ad);\r
362         GridDataFactory.fillDefaults().grab(true, true).minSize(1, 50).applyTo(explorerComposite);\r
363 \r
364         if (args.containsKey("treeView") && Boolean.TRUE.equals(args.get("treeView"))) {\r
365                 explorer = createExplorerControl2(explorerComposite, maxChildren);\r
366         } else if (args.containsKey("natTable") && Boolean.TRUE.equals(args.get("natTable"))) {\r
367                 explorer = createExplorerControl3(explorerComposite, maxChildren);\r
368         } else {\r
369                 explorer = createExplorerControl(explorerComposite, maxChildren);\r
370         }\r
371         \r
372         if (args.containsKey("useNodeBrowseContexts") && Boolean.TRUE.equals(args.get("useNodeBrowseContexts"))) {\r
373                 useNodeBrowseContexts = true;\r
374         } else {\r
375                 useNodeBrowseContexts = false;\r
376         }\r
377         \r
378         if (args.containsKey("useNodeActionContexts") && Boolean.TRUE.equals(args.get("useNodeActionContexts"))) {\r
379                 useNodeActionContexts = true;\r
380         } else {\r
381                 useNodeActionContexts = false;\r
382         }\r
383         \r
384         toolComposite2 = new Composite(this, SWT.NONE);\r
385 //        toolComposite2.setBackground(toolComposite2.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
386 //        GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
387         GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite2);\r
388         GridLayoutFactory.fillDefaults().applyTo(toolComposite2);\r
389 \r
390         this.support = support;\r
391 \r
392         if (support != null)\r
393             support.register(this);\r
394 \r
395     }\r
396 \r
397     public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, int style) {\r
398 \r
399         this(args, site, parent, null, style);\r
400 \r
401     }\r
402 \r
403     public ISessionContextProvider getSessionContextProvider(IWorkbenchSite site) {\r
404         if(site != null)\r
405             return SimanticsUI.getSessionContextProvider(site.getWorkbenchWindow());\r
406         else\r
407             return SimanticsUI.getSessionContextProvider();\r
408     }\r
409 \r
410     public GraphExplorer getExplorer() {\r
411         return explorer;\r
412     }\r
413 \r
414     public Composite getExplorerComposite() {\r
415         return explorerComposite;\r
416     }\r
417 \r
418     public <T> T getExplorerControl() {\r
419         return explorer.getControl();\r
420     }\r
421 \r
422     public void addListenerToControl(int eventType, Listener listener) {\r
423         ((Control)explorer.getControl()).addListener(eventType, listener);\r
424     }\r
425 \r
426     public void finish() {\r
427         created = true;\r
428         createControls(site);\r
429         attachToSession();\r
430     }\r
431 \r
432     IWorkbenchSite getSite() {\r
433         return site;\r
434     }\r
435 \r
436     protected void activateUiContexts() {\r
437         Collection<String> contexts = getUiContexts();\r
438         if (contexts == null || contexts.isEmpty())\r
439             return;\r
440         IWorkbenchSite site = getSite();\r
441         if (site != null) {\r
442             IContextService cs = (IContextService) getSite().getService(IContextService.class);\r
443             for (String context : contexts)\r
444                 cs.activateContext(context);\r
445         }\r
446     }\r
447 \r
448     protected void createControls(IWorkbenchSite site) {\r
449 \r
450         // Initialize explorer control.\r
451 //        GridDataFactory.fillDefaults().grab(true, true).applyTo(explorer.getControl());\r
452 \r
453         Control control = explorer.getControl();\r
454 \r
455         // Initialize context menu if an initializer is provided.\r
456         IContextMenuInitializer cmi = getContextMenuInitializer();\r
457         if (cmi != null) {\r
458             ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
459             menuManager = cmi.createContextMenu(control, selectionProvider, site);\r
460         }\r
461 \r
462         // Initialize UI contexts\r
463         activateUiContexts();\r
464 \r
465         // Initialize DND.\r
466         dragSource = setupDND(explorer);\r
467 \r
468         // Listeners are only added once per listener, not every time the\r
469         // session context changes.\r
470         addListeners(explorer, menuManager);\r
471 \r
472         userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor();\r
473         userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor();\r
474         filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor();\r
475         \r
476         explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
477 \r
478         boolean hasExtraControls = false;\r
479         boolean hasExtraControls2 = false;\r
480 \r
481         Boolean displaySelectors = (Boolean)args.get("displaySelectors");\r
482         if(displaySelectors == null || displaySelectors == true) {\r
483 \r
484             @SuppressWarnings("unused")\r
485             ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
486 //            comparatorSelector.moveAbove(control);\r
487 \r
488             @SuppressWarnings("unused")\r
489             ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
490 //            viewpointSelector.moveAbove(control);\r
491 \r
492             hasExtraControls = true;\r
493 \r
494         }\r
495 \r
496         Boolean displayFilter = (Boolean)args.get("displayFilter");\r
497         if(displayFilter == null || displayFilter == true) {\r
498 \r
499                 \r
500                 filterArea = filterAreaSource.getFilterArea(toolComposite, explorer);\r
501 //            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite, SWT.READ_ONLY);\r
502             //filterArea.moveAbove(control);\r
503 \r
504             hasExtraControls = true;\r
505 \r
506         }\r
507 \r
508         Boolean displayFilter2 = (Boolean)args.get("displayFilter2");\r
509         if(displayFilter2 != null && displayFilter2 == true) {\r
510 \r
511                 filterArea = filterAreaSource.getFilterArea(toolComposite2, explorer);\r
512 //            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite2, SWT.READ_ONLY);\r
513 //            //filterArea.moveAbove(control);\r
514 \r
515             hasExtraControls2 = true;\r
516 \r
517         }\r
518 \r
519 //        filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, this, SWT.READ_ONLY);\r
520 //        filterArea.moveAbove(control);\r
521 \r
522         if(!hasExtraControls)\r
523             GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite);\r
524         if(!hasExtraControls2)\r
525             GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite2);\r
526 \r
527         GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control);\r
528 \r
529         //tree.getTree().setLayout(new FillLayout()\r
530         //this.setLayout(LayoutUtils.createNoBorderGridLayout(2, false));\r
531 \r
532         DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
533         target.setTransfer(getAcceptedDataTypes());\r
534         if (control instanceof Tree)  {\r
535         target.addDropListener(new DropTargetListener() {\r
536 \r
537             Tree tree = (Tree)explorer.getControl();\r
538 \r
539             @Override\r
540             public void dragEnter(DropTargetEvent event) {\r
541                 event.detail = DND.DROP_COPY;\r
542             }\r
543 \r
544             @Override\r
545             public void dragLeave(DropTargetEvent event) {\r
546             }\r
547 \r
548             @Override\r
549             public void dragOperationChanged(DropTargetEvent event) {\r
550             }\r
551 \r
552             @Override\r
553             public void dragOver(DropTargetEvent event) {\r
554             }\r
555 \r
556             @Override\r
557             public void drop(DropTargetEvent event) {\r
558                 TreeItem item = tree.getItem(tree.toControl(event.x, event.y));\r
559                 if(item != null) {\r
560                         Object data = item.getData();\r
561                         if (data instanceof NodeContext)\r
562                                 handleDrop(event.data, (NodeContext) data);\r
563                         else if (data instanceof IAdaptable) {\r
564                                 IAdaptable a = (IAdaptable) data;\r
565                                 handleDrop(event.data, (NodeContext) a.getAdapter(NodeContext.class));\r
566                         }\r
567                 } else\r
568                     handleDrop(event.data, null);\r
569             }\r
570 \r
571             @Override\r
572             public void dropAccept(DropTargetEvent event) {\r
573             }\r
574 \r
575         });\r
576         }\r
577 \r
578         // Add workbench listeners and make sure they are cleaned up\r
579         setWorkbenchListeners();\r
580         control.addListener(SWT.Dispose, new Listener() {\r
581             @Override\r
582             public void handleEvent(Event event) {\r
583                 doDispose();\r
584             }\r
585         });\r
586     }\r
587 \r
588     @SuppressWarnings({ "rawtypes", "unchecked" })\r
589     @Override\r
590     public Object getAdapter(Class adapter) {\r
591         if (GraphExplorer.class == adapter)\r
592             return explorer;\r
593         if (EvaluatorData.class == adapter)\r
594             return evaluatorData;\r
595         if (BrowseContext.class == adapter) {\r
596             EvaluatorData ed = evaluatorData;\r
597             return ed != null ? ed.getBrowseContext() : null;\r
598         }\r
599         if (adapter == IFilterAreaProvider.class)\r
600             return filterArea;\r
601         return explorer.getAdapter(adapter);\r
602     }\r
603 \r
604     protected void doDispose() {\r
605         //System.out.println(this + ".GraphExplorerComposite.doDispose()");\r
606         removeWorkbenchListeners();\r
607         userSelectedComparableFactoryQueryProcessor = null;\r
608         userSelectedViewpointFactoryQueryProcessor = null;\r
609         filterSelectionRequestQueryProcessor = null;\r
610 \r
611         disposeState = DisposeState.Disposing;\r
612         try {\r
613             //System.out.println(this + ".GraphExplorerViewBase.dispose()");\r
614             if (contextProvider != null) {\r
615                 contextProvider.removeContextChangedListener(contextChangeListener);\r
616                 contextProvider = null;\r
617             }\r
618             sessionContextTracker.untrack();\r
619             resourceManager = null;\r
620             explorer = null;\r
621             sessionContext = null;\r
622             dragSource = null;\r
623 //            parent = null;\r
624         } finally {\r
625             disposeState = DisposeState.Disposed;\r
626         }\r
627     }\r
628 \r
629     @Override\r
630     public void dispose() {\r
631         doDispose();\r
632         super.dispose();\r
633     }\r
634 \r
635     protected StatePersistor getStatePersistor() {\r
636         return persistor;\r
637     }\r
638     \r
639     public void setStatePersistor(StatePersistor persistor) {\r
640         this.persistor = persistor;\r
641     }\r
642     \r
643     protected void initializeExplorer(GraphExplorer explorer, ISessionContext context) {\r
644 \r
645         if(explorer == null || explorer.isDisposed()) return;\r
646         if(context == null) return;\r
647         if(browseContexts == null) return;\r
648 \r
649         Session session = context != null ? context.getSession() : null;\r
650         setupDragSource(session);\r
651 \r
652         if (session != null) {\r
653             evaluatorData = createEvaluatorData(session);\r
654             explorer.setDataSource(new AsyncReadGraphDataSource(session));\r
655             explorer.setDataSource(new ReadGraphDataSource(session));\r
656         }\r
657         else {\r
658             evaluatorData = new EvaluatorDataImpl();\r
659             explorer.removeDataSource(AsyncReadGraph.class);\r
660             explorer.removeDataSource(ReadGraph.class);\r
661         }\r
662 \r
663         explorer.setPersistor(getStatePersistor());\r
664         \r
665         explorer.setProcessor(new ComparableFactoryResolver(evaluatorData));\r
666         explorer.setProcessor(new ViewpointFactoryResolver(evaluatorData));\r
667         explorer.setProcessor(new LabelerFactoryResolver(evaluatorData));\r
668         explorer.setProcessor(new ImagerFactoryResolver(evaluatorData));\r
669         explorer.setProcessor(new LabelDecoratorFactoryResolver(evaluatorData));\r
670         explorer.setProcessor(new ImageDecoratorFactoryResolver(evaluatorData));\r
671         explorer.setProcessor(new DefaultIsCheckedProcessor2(evaluatorData));\r
672         explorer.setPrimitiveProcessor(new TypesQueryProcessor());\r
673         explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor());\r
674         explorer.setPrimitiveProcessor(new InheritsQueryProcessor());\r
675         explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor());\r
676 \r
677         explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor);\r
678         explorer.setProcessor(new ComparableSelectorQueryProcessor());\r
679         explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor);\r
680         explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
681 \r
682         initializeExplorerWithEvaluator(explorer, context, evaluatorData);\r
683     }\r
684 \r
685     protected void initializeExplorerWithEvaluator(GraphExplorer explorer, ISessionContext context, EvaluatorData data) {\r
686     }\r
687 \r
688     protected EvaluatorData createEvaluatorData(Session context) {\r
689 \r
690 //        Set<String> browseContexts = getArgument("browseContexts");\r
691 \r
692         return Evaluators.load(context.getSession(), browseContexts, resourceManager, useNodeBrowseContexts, useNodeActionContexts);\r
693 \r
694     }\r
695 \r
696     protected Transfer[] getAcceptedDataTypes() {\r
697         return new Transfer[] {  LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() };\r
698     }\r
699 \r
700     protected void handleDrop(Object data, NodeContext target) {\r
701     }\r
702 \r
703     DragSourceListenerFactory dragSourceListenerFactory = new DragSourceListenerFactory() {\r
704 \r
705         final Transfer[] transfers = new Transfer[] {LocalObjectTransfer.getTransfer(), TextTransfer.getInstance() };\r
706 \r
707         @Override\r
708         public DragSourceListener get(ISelectionProvider selectionProvider) {\r
709 \r
710                 LocalSelectionDragSourceListener ls = new LocalSelectionDragSourceListener(selectionProvider);\r
711 \r
712                 return new DragSourceListener() {\r
713                                 \r
714                                 @Override\r
715                                 public void dragStart(DragSourceEvent event) {\r
716                                         ls.dragStart(event);\r
717                                 }\r
718                                 \r
719                                 @Override\r
720                                 public void dragSetData(DragSourceEvent event) {\r
721                                         if(TextTransfer.getInstance().isSupportedType(event.dataType)) {\r
722                                         try {\r
723                                                         event.data = WorkbenchSelectionUtils.getPossibleJSON(selectionProvider.getSelection());\r
724                                                 } catch (DatabaseException e) {\r
725                                                         event.data = "{ type:\"Exception\" }";\r
726                                                         Logger.defaultLogError(e);\r
727                                                 }\r
728                                         } else if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {\r
729                                                 ls.dragSetData(event);\r
730                                         }\r
731                                 }\r
732                                 \r
733                                 @Override\r
734                                 public void dragFinished(DragSourceEvent event) {\r
735                                         ls.dragFinished(event);\r
736                                 }\r
737                         };\r
738         }\r
739 \r
740         @Override\r
741         public Transfer[] getTransfers() {\r
742             return transfers;\r
743         }\r
744 \r
745     };\r
746 \r
747     public void setDragSourceListenerFactory(DragSourceListenerFactory dragSourceListenerFactory) {\r
748         this.dragSourceListenerFactory = dragSourceListenerFactory;\r
749     }\r
750 \r
751     protected DragSourceListener setupDND(GraphExplorer explorer) {\r
752 \r
753         ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
754 \r
755         DragSourceListener listener = createDragSourceListener(selectionProvider);\r
756 \r
757         Control control = explorer.getControl();\r
758         DragSource source = createDragSource(control);\r
759         source.setTransfer(getTransfers());\r
760         source.addDragListener(listener);\r
761         source.setDragSourceEffect(new NoImageDragSourceEffect(control));\r
762 \r
763         return listener;\r
764 \r
765     }\r
766 \r
767     protected DragSourceListener createDragSourceListener(ISelectionProvider selectionProvider) {\r
768         return dragSourceListenerFactory.get(selectionProvider);\r
769     }\r
770 \r
771     private int dragStyle = DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;\r
772 \r
773     protected void setDragStyle(int style) {\r
774         this.dragStyle = style;\r
775     }\r
776 \r
777     protected int getDragStyle() {\r
778         return dragStyle;\r
779     }\r
780 \r
781     protected DragSource createDragSource(Control control) {\r
782         return new DragSource(control, getDragStyle());\r
783     }\r
784 \r
785     protected Transfer[] getTransfers() {\r
786         return dragSourceListenerFactory.getTransfers();\r
787     }\r
788 \r
789     public EvaluatorData getEvaluatorData() {\r
790         return evaluatorData;\r
791     }\r
792 \r
793     public interface InputSource {\r
794         /**\r
795          * @param ctx the session context to read the input from. May be\r
796          *        <code>null</code> if there is no session.\r
797          * @return the input object of a graph explorer. To indicate no input,\r
798          *         use {@link GraphExplorerConstants#EMPTY_INPUT}. Never return\r
799          *         <code>null</code>.\r
800          */\r
801         Object get(ISessionContext ctx, Object selection);\r
802     }\r
803     \r
804     public interface FilterSource {\r
805         \r
806         \r
807         \r
808     }\r
809 \r
810     /**\r
811      * The default hint tracker that will be active if\r
812      * {@link GraphExplorerComposite#setSessionContextTracker(IHintTracker) is\r
813      * not called.\r
814      */\r
815     public class SessionContextProjectTracker extends HintTracker {\r
816         public SessionContextProjectTracker() {\r
817             IHintListener activeProjectListener = new HintListenerAdapter() {\r
818                 @Override\r
819                 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
820                     applySessionContext(getSessionContext());\r
821                 }\r
822             };\r
823             addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);\r
824         }\r
825     }\r
826 \r
827     public class DirectInputSource implements InputSource {\r
828         @Override\r
829         public Object get(ISessionContext ctx, Object selection) {\r
830             return selection;\r
831         }\r
832     }\r
833     \r
834     public static class SelectionFilterAreaSource implements FilterAreaSource {\r
835 \r
836                 @Override\r
837                 public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
838                         FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
839                         return new FilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
840                 }\r
841         \r
842     }\r
843 \r
844     public static class RootFilterAreaSource implements FilterAreaSource {\r
845 \r
846                 @Override\r
847                 public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
848                         FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
849                         return new RootFilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
850                 }\r
851         \r
852     }\r
853 \r
854     protected void setSessionContextTracker(IHintTracker tracker) {\r
855         this.sessionContextTracker = tracker;\r
856     }\r
857 \r
858     public void setInputSource(InputSource source) {\r
859         this.inputSource = source;\r
860     }\r
861     \r
862     public void setFilterAreaSource(FilterAreaSource provider) {\r
863         this.filterAreaSource = provider;\r
864     }\r
865 \r
866     public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {\r
867         this.selectionTransformation = transformation;\r
868         if(explorer != null) explorer.setSelectionTransformation(transformation);\r
869     }\r
870 \r
871     protected Set<String> getBrowseContexts() {\r
872         return browseContexts;\r
873     }\r
874     \r
875     public void setBrowseContexts(Set<String> contexts) {\r
876         this.browseContexts = contexts;\r
877         //initializeExplorer(explorer, getSessionContext());\r
878     }\r
879 \r
880     public void setBrowseContexts(String ... contexts) {\r
881         this.browseContexts = new HashSet<String>();\r
882         for(String s : contexts) this.browseContexts.add(s);\r
883         initializeExplorer(explorer, getSessionContext());\r
884     }\r
885 \r
886     public void setContextMenuId(String contextMenuId) {\r
887         this.contextMenuId = contextMenuId;\r
888     }\r
889 \r
890 //    protected IContextMenuInitializer getContextMenuInitializer() {\r
891 //        String contextMenuId = getContextMenuId();\r
892 //        if(contextMenuId != null) {\r
893 //            return new ContextMenuInitializer(contextMenuId);\r
894 //        } else {\r
895 //            return null;\r
896 //        }\r
897 //    }\r
898 \r
899     protected String getContextMenuId() {\r
900         return this.contextMenuId;\r
901     }\r
902 \r
903     public void setUiContexts(Set<String> uiContext) {\r
904         this.uiContext = uiContext;\r
905     }\r
906 \r
907     public Set<String> getUiContexts() {\r
908         return uiContext;\r
909     }\r
910 \r
911     protected InputSource getInputSource() {\r
912         return inputSource;\r
913     }\r
914 \r
915     protected Map<String, Object> getArguments() {\r
916         return args;\r
917     }\r
918 \r
919     @SuppressWarnings("unchecked")\r
920     protected <T> T getArgument(String key) {\r
921         return (T) args.get(key);\r
922     }\r
923 \r
924     protected DisposeState getDisposeState() {\r
925         return disposeState;\r
926     }\r
927 \r
928     public ISessionContext getSessionContext() {\r
929         return sessionContext;\r
930     }\r
931 \r
932     public ISessionContextProvider getSessionContextProvider() {\r
933         return contextProvider;\r
934     }\r
935 \r
936     @Override\r
937     public boolean setFocus() {\r
938         if (explorer != null && !explorer.isDisposed())\r
939             explorer.setFocus();\r
940         return true;\r
941     }\r
942 \r
943     public void setWorkbenchListeners() {\r
944         if (workbenchSelectionListener == null && getSite() != null) {\r
945             ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
946             getSite().setSelectionProvider(selectionProvider);\r
947 \r
948             // Listen to the workbench selection also to propagate it to\r
949             // the explorer also.\r
950             workbenchSelectionListener = new DefaultExplorerSelectionListener(site.getPage().getActivePart(), explorer);\r
951             //System.out.println("ADD WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
952             getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener);\r
953         }\r
954     }\r
955 \r
956     protected void removeWorkbenchListeners() {\r
957         //System.out.println("REMOVE WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
958         // Remember to remove the installed workbench selection listener\r
959         if (workbenchSelectionListener != null) {\r
960             getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);\r
961             workbenchSelectionListener = null;\r
962 \r
963             ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
964             if(getSite().getSelectionProvider() == selectionProvider) getSite().setSelectionProvider(null);\r
965             \r
966         }\r
967     }\r
968 \r
969     protected final void attachToSession() {\r
970 \r
971         // Track active ISessionContext changes\r
972         //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());\r
973         contextProvider.addContextChangedListener(contextChangeListener);\r
974 \r
975         // Start tracking the current session context for input changes.\r
976         // This will/must cause applySessionContext to get called.\r
977         // Doing the applySessionContext initialization this way\r
978         // instead of directly calling it will also make sure that\r
979         // applySessionContext is only called once when first initialized,\r
980         // and not twice like with the direct invocation.\r
981         this.sessionContext = contextProvider.getSessionContext();\r
982         sessionContextTracker.track(sessionContext);\r
983     }\r
984 \r
985     // /////////////////////////////////////////////////////////////////////////\r
986     // Override / implement these:\r
987 \r
988 //    /**\r
989 //     * Returns an ID that is used for persisting a GraphExplorer instance.\r
990 //     *\r
991 //     * Used for </code>restoreState(IMemento)</code> and\r
992 //     * <code>restoreState(IMemento)</code> in OntologyExplorer. Must be unique\r
993 //     * within a workbench part.\r
994 //     *\r
995 //     * @return a unique name for this particular graph explorer view used for\r
996 //     *         saving and restoring the state of this view part\r
997 //     */\r
998 //    public String getExplorerName() {\r
999 //        return "GraphExplorerViewBase";\r
1000 //    }\r
1001 \r
1002     /**\r
1003      * Override this method to add controls to the view part. This is invoked\r
1004      * before attaching the view part to a database session.\r
1005      * \r
1006      * @param parent\r
1007      */\r
1008     protected void createControls(Composite parent) {\r
1009 \r
1010     }\r
1011 \r
1012     /**\r
1013      * Override this method and provide a proper context menu initializer if you\r
1014      * want to have this base class initialize one for you.\r
1015      * \r
1016      * @return the initializer to be used by {@link #createControls(Composite)}\r
1017      */\r
1018     protected IContextMenuInitializer getContextMenuInitializer() {\r
1019         String contextMenuId = getContextMenuId();\r
1020         if(contextMenuId != null) {\r
1021             return new ContextMenuInitializer(contextMenuId);\r
1022         } else {\r
1023             return null;\r
1024         }\r
1025     }\r
1026 \r
1027     /**\r
1028      * @param parent\r
1029      * @return\r
1030      */\r
1031     protected GraphExplorer createExplorerControl(Composite parent, Integer maxChildren) {\r
1032         GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
1033         if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
1034 \r
1035         GraphExplorer ge = factory\r
1036         .selectionDataResolver(new DefaultSelectionDataResolver())\r
1037         .selectionTransformation(selectionTransformation)\r
1038         .setServiceLocator(site)\r
1039         .create(parent, style);\r
1040 \r
1041         return ge;\r
1042     }\r
1043     \r
1044     protected GraphExplorer createExplorerControl2(Composite parent, Integer maxChildren) {\r
1045         GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
1046         if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
1047 \r
1048         GraphExplorer ge = factory\r
1049         .selectionDataResolver(new DefaultSelectionDataResolver())\r
1050         .selectionTransformation(selectionTransformation)\r
1051         .setServiceLocator(site)\r
1052         .create2(parent, style);\r
1053 \r
1054         return ge;\r
1055     }\r
1056     \r
1057     protected GraphExplorer createExplorerControl3(Composite parent, Integer maxChildren) {\r
1058         GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
1059         if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
1060 \r
1061         GraphExplorer ge = factory\r
1062         .selectionDataResolver(new DefaultSelectionDataResolver())\r
1063         .selectionTransformation(selectionTransformation)\r
1064         .setServiceLocator(site)\r
1065         .create3(parent, style);\r
1066 \r
1067         return ge;\r
1068     }\r
1069 \r
1070     protected void setupDragSource(Session session) {\r
1071         if (dragSource instanceof SessionContainer) {\r
1072             ((SessionContainer) dragSource).setSession(session);\r
1073         }\r
1074     }\r
1075 \r
1076     /**\r
1077      * Override to customize the addition of listeners a newly created\r
1078      * GraphExplorer.\r
1079      * \r
1080      * @param explorer\r
1081      */\r
1082     protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
1083         addSelectionInputListeners(explorer, menuManager);\r
1084     }\r
1085 \r
1086     protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
1087         // Consider ENTER presses to simulate mouse left button double clicks\r
1088         explorer.addListener(new DefaultKeyListener(contextProvider, explorer, new Function<String[]>() {\r
1089             @Override\r
1090             public String[] execute(Object... obj) {\r
1091                 return getEditingColumn((NodeContext) obj[0]);\r
1092             }\r
1093         }));\r
1094         // Default double click handling\r
1095         explorer.addListener(new DefaultMouseListener(explorer));\r
1096     }\r
1097 \r
1098     protected String[] getEditingColumn(NodeContext context) {\r
1099         return editingColumn;\r
1100     }\r
1101     \r
1102     public void setEditingColumn(String... columnKeysInOrderOfTrial) {\r
1103         this.editingColumn = columnKeysInOrderOfTrial;\r
1104     }\r
1105 \r
1106     // Needed for preventing unnecessary re-initialization of the explorer with the same input.\r
1107     private Object currentInput;\r
1108     private Object currentRoot;\r
1109 \r
1110     /**\r
1111      * Invoke this to reinitialize the explorer and reset its input. The input\r
1112      * will be resolved from the specified ISessionContext based on the\r
1113      * {@link SessionContextInputSource} that is currently in use. If the input\r
1114      * is identical to the previous input, nothing will be done.\r
1115      * \r
1116      * @param context\r
1117      */\r
1118     public final boolean applySessionContext(ISessionContext context) {\r
1119 \r
1120         // If control is not alive anymore, do nothing.\r
1121         //System.out.println(this + ": applySessionContext(" + context + "), explorer="  + explorer);\r
1122         if (disposeState != DisposeState.Alive)\r
1123             return false;\r
1124 \r
1125         //System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");\r
1126         initializeExplorer(explorer, context);\r
1127 \r
1128 \r
1129         // Start tracking the session context.\r
1130         //\r
1131         // If this is not the same session that is currently tracked, it will\r
1132         // cause IHintListeners of the sessionContextTracker to fire.\r
1133         // For this we need the above input equality (identity) checking.\r
1134         // This is here just to make sure that we are tracking the correct\r
1135         // session context.\r
1136         sessionContextTracker.track(sessionContext);\r
1137 \r
1138         this.sessionContext = context;\r
1139         Object root = inputSource.get(context, currentInput);\r
1140         if (ObjectUtils.objectEquals(root, currentRoot))\r
1141             return false;\r
1142 \r
1143         currentRoot = root;\r
1144 \r
1145         //System.out.println(this + ": setRoot(" + input + ")");\r
1146         explorer.setUIContexts(uiContext);\r
1147         explorer.setRoot(root);\r
1148 \r
1149         return true;\r
1150 \r
1151     }\r
1152 \r
1153     protected boolean isImportantInput(Object previousSelection, Object selection) {\r
1154         return !ObjectUtils.objectEquals(previousSelection, selection);\r
1155     }\r
1156 \r
1157     public void setInput(Object selection, boolean force) {\r
1158 \r
1159         assert(created);\r
1160 \r
1161         if (isDisposed())\r
1162             return;\r
1163         if (sessionContext == null)\r
1164             return;\r
1165 \r
1166         // Check if this is a duplicate of the previous selection to reduce unnecessary flicker.\r
1167         if (!force && !isImportantInput(currentInput, selection))\r
1168             return;\r
1169 \r
1170         currentInput = selection;\r
1171 \r
1172         Object root = inputSource.get(sessionContext, selection);\r
1173 \r
1174         currentRoot = root;\r
1175 \r
1176         explorer.setUIContexts(uiContext);\r
1177 \r
1178         if (root == null) {\r
1179             explorer.setRoot(GraphExplorer.EMPTY_INPUT);\r
1180         } else {\r
1181             explorer.setRoot(root);\r
1182         }\r
1183 \r
1184     }\r
1185 \r
1186     public void setColumnsVisible(boolean visible) {\r
1187         explorer.setColumnsVisible(visible);\r
1188     }\r
1189 \r
1190     private int getColumnWidth(Column column, ExplorerState state) {\r
1191         // Get saved width from the persistor if there is one.\r
1192         if (state != null && state.columnWidths != null) {\r
1193                 Integer width = state.columnWidths.get(column.getLabel());\r
1194                 if (width != null)\r
1195                         return width;\r
1196         }\r
1197         return column.getWidth();\r
1198     }\r
1199     \r
1200     public void setColumns(Column[] columns) {\r
1201 \r
1202         explorer.setColumns(columns, new Consumer<Map<Column, Object>>() {\r
1203 \r
1204             @Override\r
1205             public void accept(Map<Column, Object> objects) {\r
1206                 ExplorerState state = null;\r
1207                 if (persistor != null) {\r
1208                         state = persistor.deserialize(\r
1209                                 Platform.getStateLocation(Activator.getDefault().getBundle()).toFile(),\r
1210                                 explorer.getRoot());\r
1211                 }\r
1212 \r
1213                 for(Map.Entry<Column, Object> entry : objects.entrySet()) {\r
1214                     Column column = entry.getKey();\r
1215                     TreeColumn treeColumn = (TreeColumn)entry.getValue();\r
1216 \r
1217                     if (column.getWidth() < 0) {\r
1218                         throw new IllegalArgumentException("Column minimum width cannot be < 0, got " + column.getWidth());\r
1219                     }\r
1220 \r
1221                     int width = getColumnWidth(column, state);\r
1222                     if(column.hasGrab()) {\r
1223                         \r
1224                         ad.setColumnData(treeColumn, new ColumnWeightData(column.getWeight(), width));\r
1225 \r
1226                     } else {\r
1227 \r
1228                         ad.setColumnData(treeColumn, new ColumnWeightData(0, width));\r
1229 \r
1230                     }\r
1231 \r
1232                 }\r
1233             }\r
1234 \r
1235         });\r
1236 \r
1237     }\r
1238 \r
1239     @Override\r
1240     public void setInput(ISessionContext context, Object input) {\r
1241         setInput(input, false);\r
1242     }\r
1243 \r
1244     public void setMaxChildren(int maxChildren) {\r
1245         explorer.setMaxChildren(maxChildren);\r
1246     }\r
1247     \r
1248     public <T> void addListener(ExplorerMouseListenerImpl<T> listener) {\r
1249         \r
1250         support.register(listener);\r
1251         listener.register(explorer);\r
1252         explorer.addListener(listener);\r
1253         \r
1254     }\r
1255 \r
1256 //    @Override\r
1257 //    public Point computeSize(int wHint, int hHint) {\r
1258 //      Point p = super.computeSize(wHint, hHint);\r
1259 //      System.err.println("graphExplorerComposite.computeSize " + p);\r
1260 //      return p;\r
1261 //    }\r
1262 //    \r
1263 //    @Override\r
1264 //    public Point computeSize(int wHint, int hHint, boolean changed) {\r
1265 //      Point p = super.computeSize(wHint, hHint, changed);\r
1266 //      System.err.println("graphExplorerComposite.computeSize " + p);\r
1267 //      return p;\r
1268 //    }\r
1269     \r
1270 }\r