]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
Migrated source code from Simantics SVN
[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 {\r
367                 explorer = createExplorerControl(explorerComposite, maxChildren);\r
368         }\r
369         \r
370         if (args.containsKey("useNodeBrowseContexts") && Boolean.TRUE.equals(args.get("useNodeBrowseContexts"))) {\r
371                 useNodeBrowseContexts = true;\r
372         } else {\r
373                 useNodeBrowseContexts = false;\r
374         }\r
375         \r
376         if (args.containsKey("useNodeActionContexts") && Boolean.TRUE.equals(args.get("useNodeActionContexts"))) {\r
377                 useNodeActionContexts = true;\r
378         } else {\r
379                 useNodeActionContexts = false;\r
380         }\r
381         \r
382         toolComposite2 = new Composite(this, SWT.NONE);\r
383 //        toolComposite2.setBackground(toolComposite2.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
384 //        GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
385         GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite2);\r
386         GridLayoutFactory.fillDefaults().applyTo(toolComposite2);\r
387 \r
388         this.support = support;\r
389 \r
390         if (support != null)\r
391             support.register(this);\r
392 \r
393     }\r
394 \r
395     public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, int style) {\r
396 \r
397         this(args, site, parent, null, style);\r
398 \r
399     }\r
400 \r
401     public ISessionContextProvider getSessionContextProvider(IWorkbenchSite site) {\r
402         if(site != null)\r
403             return SimanticsUI.getSessionContextProvider(site.getWorkbenchWindow());\r
404         else\r
405             return SimanticsUI.getSessionContextProvider();\r
406     }\r
407 \r
408     public GraphExplorer getExplorer() {\r
409         return explorer;\r
410     }\r
411 \r
412     public Composite getExplorerComposite() {\r
413         return explorerComposite;\r
414     }\r
415 \r
416     public <T> T getExplorerControl() {\r
417         return explorer.getControl();\r
418     }\r
419 \r
420     public void addListenerToControl(int eventType, Listener listener) {\r
421         ((Tree)explorer.getControl()).addListener(eventType, listener);\r
422     }\r
423 \r
424     public void finish() {\r
425         created = true;\r
426         createControls(site);\r
427         attachToSession();\r
428     }\r
429 \r
430     IWorkbenchSite getSite() {\r
431         return site;\r
432     }\r
433 \r
434     protected void activateUiContexts() {\r
435         Collection<String> contexts = getUiContexts();\r
436         if (contexts == null || contexts.isEmpty())\r
437             return;\r
438         IWorkbenchSite site = getSite();\r
439         if (site != null) {\r
440             IContextService cs = (IContextService) getSite().getService(IContextService.class);\r
441             for (String context : contexts)\r
442                 cs.activateContext(context);\r
443         }\r
444     }\r
445 \r
446     protected void createControls(IWorkbenchSite site) {\r
447 \r
448         // Initialize explorer control.\r
449 //        GridDataFactory.fillDefaults().grab(true, true).applyTo(explorer.getControl());\r
450 \r
451         Control control = explorer.getControl();\r
452 \r
453         // Initialize context menu if an initializer is provided.\r
454         IContextMenuInitializer cmi = getContextMenuInitializer();\r
455         if (cmi != null) {\r
456             ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
457             menuManager = cmi.createContextMenu(control, selectionProvider, site);\r
458         }\r
459 \r
460         // Initialize UI contexts\r
461         activateUiContexts();\r
462 \r
463         // Initialize DND.\r
464         dragSource = setupDND(explorer);\r
465 \r
466         // Listeners are only added once per listener, not every time the\r
467         // session context changes.\r
468         addListeners(explorer, menuManager);\r
469 \r
470         userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor();\r
471         userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor();\r
472         filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor();\r
473         \r
474         explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
475 \r
476         boolean hasExtraControls = false;\r
477         boolean hasExtraControls2 = false;\r
478 \r
479         Boolean displaySelectors = (Boolean)args.get("displaySelectors");\r
480         if(displaySelectors == null || displaySelectors == true) {\r
481 \r
482             @SuppressWarnings("unused")\r
483             ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
484 //            comparatorSelector.moveAbove(control);\r
485 \r
486             @SuppressWarnings("unused")\r
487             ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
488 //            viewpointSelector.moveAbove(control);\r
489 \r
490             hasExtraControls = true;\r
491 \r
492         }\r
493 \r
494         Boolean displayFilter = (Boolean)args.get("displayFilter");\r
495         if(displayFilter == null || displayFilter == true) {\r
496 \r
497                 \r
498                 filterArea = filterAreaSource.getFilterArea(toolComposite, explorer);\r
499 //            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite, SWT.READ_ONLY);\r
500             //filterArea.moveAbove(control);\r
501 \r
502             hasExtraControls = true;\r
503 \r
504         }\r
505 \r
506         Boolean displayFilter2 = (Boolean)args.get("displayFilter2");\r
507         if(displayFilter2 != null && displayFilter2 == true) {\r
508 \r
509                 filterArea = filterAreaSource.getFilterArea(toolComposite2, explorer);\r
510 //            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite2, SWT.READ_ONLY);\r
511 //            //filterArea.moveAbove(control);\r
512 \r
513             hasExtraControls2 = true;\r
514 \r
515         }\r
516 \r
517 //        filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, this, SWT.READ_ONLY);\r
518 //        filterArea.moveAbove(control);\r
519 \r
520         if(!hasExtraControls)\r
521             GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite);\r
522         if(!hasExtraControls2)\r
523             GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite2);\r
524 \r
525         GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control);\r
526 \r
527         //tree.getTree().setLayout(new FillLayout()\r
528         //this.setLayout(LayoutUtils.createNoBorderGridLayout(2, false));\r
529 \r
530         DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
531         target.setTransfer(getAcceptedDataTypes());\r
532         target.addDropListener(new DropTargetListener() {\r
533 \r
534             Tree tree = (Tree)explorer.getControl();\r
535 \r
536             @Override\r
537             public void dragEnter(DropTargetEvent event) {\r
538                 event.detail = DND.DROP_COPY;\r
539             }\r
540 \r
541             @Override\r
542             public void dragLeave(DropTargetEvent event) {\r
543             }\r
544 \r
545             @Override\r
546             public void dragOperationChanged(DropTargetEvent event) {\r
547             }\r
548 \r
549             @Override\r
550             public void dragOver(DropTargetEvent event) {\r
551             }\r
552 \r
553             @Override\r
554             public void drop(DropTargetEvent event) {\r
555                 TreeItem item = tree.getItem(tree.toControl(event.x, event.y));\r
556                 if(item != null) {\r
557                         Object data = item.getData();\r
558                         if (data instanceof NodeContext)\r
559                                 handleDrop(event.data, (NodeContext) data);\r
560                         else if (data instanceof IAdaptable) {\r
561                                 IAdaptable a = (IAdaptable) data;\r
562                                 handleDrop(event.data, (NodeContext) a.getAdapter(NodeContext.class));\r
563                         }\r
564                 } else\r
565                     handleDrop(event.data, null);\r
566             }\r
567 \r
568             @Override\r
569             public void dropAccept(DropTargetEvent event) {\r
570             }\r
571 \r
572         });\r
573 \r
574         // Add workbench listeners and make sure they are cleaned up\r
575         setWorkbenchListeners();\r
576         control.addListener(SWT.Dispose, new Listener() {\r
577             @Override\r
578             public void handleEvent(Event event) {\r
579                 doDispose();\r
580             }\r
581         });\r
582     }\r
583 \r
584     @SuppressWarnings({ "rawtypes", "unchecked" })\r
585     @Override\r
586     public Object getAdapter(Class adapter) {\r
587         if (GraphExplorer.class == adapter)\r
588             return explorer;\r
589         if (EvaluatorData.class == adapter)\r
590             return evaluatorData;\r
591         if (BrowseContext.class == adapter) {\r
592             EvaluatorData ed = evaluatorData;\r
593             return ed != null ? ed.getBrowseContext() : null;\r
594         }\r
595         if (adapter == IFilterAreaProvider.class)\r
596             return filterArea;\r
597         return explorer.getAdapter(adapter);\r
598     }\r
599 \r
600     protected void doDispose() {\r
601         //System.out.println(this + ".GraphExplorerComposite.doDispose()");\r
602         removeWorkbenchListeners();\r
603         userSelectedComparableFactoryQueryProcessor = null;\r
604         userSelectedViewpointFactoryQueryProcessor = null;\r
605         filterSelectionRequestQueryProcessor = null;\r
606 \r
607         disposeState = DisposeState.Disposing;\r
608         try {\r
609             //System.out.println(this + ".GraphExplorerViewBase.dispose()");\r
610             if (contextProvider != null) {\r
611                 contextProvider.removeContextChangedListener(contextChangeListener);\r
612                 contextProvider = null;\r
613             }\r
614             sessionContextTracker.untrack();\r
615             resourceManager = null;\r
616             explorer = null;\r
617             sessionContext = null;\r
618             dragSource = null;\r
619 //            parent = null;\r
620         } finally {\r
621             disposeState = DisposeState.Disposed;\r
622         }\r
623     }\r
624 \r
625     @Override\r
626     public void dispose() {\r
627         doDispose();\r
628         super.dispose();\r
629     }\r
630 \r
631     protected StatePersistor getStatePersistor() {\r
632         return persistor;\r
633     }\r
634     \r
635     public void setStatePersistor(StatePersistor persistor) {\r
636         this.persistor = persistor;\r
637     }\r
638     \r
639     protected void initializeExplorer(GraphExplorer explorer, ISessionContext context) {\r
640 \r
641         if(explorer == null || explorer.isDisposed()) return;\r
642         if(context == null) return;\r
643         if(browseContexts == null) return;\r
644 \r
645         Session session = context != null ? context.getSession() : null;\r
646         setupDragSource(session);\r
647 \r
648         if (session != null) {\r
649             evaluatorData = createEvaluatorData(session);\r
650             explorer.setDataSource(new AsyncReadGraphDataSource(session));\r
651             explorer.setDataSource(new ReadGraphDataSource(session));\r
652         }\r
653         else {\r
654             evaluatorData = new EvaluatorDataImpl();\r
655             explorer.removeDataSource(AsyncReadGraph.class);\r
656             explorer.removeDataSource(ReadGraph.class);\r
657         }\r
658 \r
659         explorer.setPersistor(getStatePersistor());\r
660         \r
661         explorer.setProcessor(new ComparableFactoryResolver(evaluatorData));\r
662         explorer.setProcessor(new ViewpointFactoryResolver(evaluatorData));\r
663         explorer.setProcessor(new LabelerFactoryResolver(evaluatorData));\r
664         explorer.setProcessor(new ImagerFactoryResolver(evaluatorData));\r
665         explorer.setProcessor(new LabelDecoratorFactoryResolver(evaluatorData));\r
666         explorer.setProcessor(new ImageDecoratorFactoryResolver(evaluatorData));\r
667         explorer.setProcessor(new DefaultIsCheckedProcessor2(evaluatorData));\r
668         explorer.setPrimitiveProcessor(new TypesQueryProcessor());\r
669         explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor());\r
670         explorer.setPrimitiveProcessor(new InheritsQueryProcessor());\r
671         explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor());\r
672 \r
673         explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor);\r
674         explorer.setProcessor(new ComparableSelectorQueryProcessor());\r
675         explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor);\r
676         explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
677 \r
678         initializeExplorerWithEvaluator(explorer, context, evaluatorData);\r
679     }\r
680 \r
681     protected void initializeExplorerWithEvaluator(GraphExplorer explorer, ISessionContext context, EvaluatorData data) {\r
682     }\r
683 \r
684     protected EvaluatorData createEvaluatorData(Session context) {\r
685 \r
686 //        Set<String> browseContexts = getArgument("browseContexts");\r
687 \r
688         return Evaluators.load(context.getSession(), browseContexts, resourceManager, useNodeBrowseContexts, useNodeActionContexts);\r
689 \r
690     }\r
691 \r
692     protected Transfer[] getAcceptedDataTypes() {\r
693         return new Transfer[] {  LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() };\r
694     }\r
695 \r
696     protected void handleDrop(Object data, NodeContext target) {\r
697     }\r
698 \r
699     DragSourceListenerFactory dragSourceListenerFactory = new DragSourceListenerFactory() {\r
700 \r
701         final Transfer[] transfers = new Transfer[] {LocalObjectTransfer.getTransfer(), TextTransfer.getInstance() };\r
702 \r
703         @Override\r
704         public DragSourceListener get(ISelectionProvider selectionProvider) {\r
705 \r
706                 LocalSelectionDragSourceListener ls = new LocalSelectionDragSourceListener(selectionProvider);\r
707 \r
708                 return new DragSourceListener() {\r
709                                 \r
710                                 @Override\r
711                                 public void dragStart(DragSourceEvent event) {\r
712                                         ls.dragStart(event);\r
713                                 }\r
714                                 \r
715                                 @Override\r
716                                 public void dragSetData(DragSourceEvent event) {\r
717                                         if(TextTransfer.getInstance().isSupportedType(event.dataType)) {\r
718                                         try {\r
719                                                         event.data = WorkbenchSelectionUtils.getPossibleJSON(selectionProvider.getSelection());\r
720                                                 } catch (DatabaseException e) {\r
721                                                         event.data = "{ type:\"Exception\" }";\r
722                                                         Logger.defaultLogError(e);\r
723                                                 }\r
724                                         } else if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {\r
725                                                 ls.dragSetData(event);\r
726                                         }\r
727                                 }\r
728                                 \r
729                                 @Override\r
730                                 public void dragFinished(DragSourceEvent event) {\r
731                                         ls.dragFinished(event);\r
732                                 }\r
733                         };\r
734         }\r
735 \r
736         @Override\r
737         public Transfer[] getTransfers() {\r
738             return transfers;\r
739         }\r
740 \r
741     };\r
742 \r
743     public void setDragSourceListenerFactory(DragSourceListenerFactory dragSourceListenerFactory) {\r
744         this.dragSourceListenerFactory = dragSourceListenerFactory;\r
745     }\r
746 \r
747     protected DragSourceListener setupDND(GraphExplorer explorer) {\r
748 \r
749         ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
750 \r
751         DragSourceListener listener = createDragSourceListener(selectionProvider);\r
752 \r
753         Control control = explorer.getControl();\r
754         DragSource source = createDragSource(control);\r
755         source.setTransfer(getTransfers());\r
756         source.addDragListener(listener);\r
757         source.setDragSourceEffect(new NoImageDragSourceEffect(control));\r
758 \r
759         return listener;\r
760 \r
761     }\r
762 \r
763     protected DragSourceListener createDragSourceListener(ISelectionProvider selectionProvider) {\r
764         return dragSourceListenerFactory.get(selectionProvider);\r
765     }\r
766 \r
767     private int dragStyle = DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;\r
768 \r
769     protected void setDragStyle(int style) {\r
770         this.dragStyle = style;\r
771     }\r
772 \r
773     protected int getDragStyle() {\r
774         return dragStyle;\r
775     }\r
776 \r
777     protected DragSource createDragSource(Control control) {\r
778         return new DragSource(control, getDragStyle());\r
779     }\r
780 \r
781     protected Transfer[] getTransfers() {\r
782         return dragSourceListenerFactory.getTransfers();\r
783     }\r
784 \r
785     public EvaluatorData getEvaluatorData() {\r
786         return evaluatorData;\r
787     }\r
788 \r
789     public interface InputSource {\r
790         /**\r
791          * @param ctx the session context to read the input from. May be\r
792          *        <code>null</code> if there is no session.\r
793          * @return the input object of a graph explorer. To indicate no input,\r
794          *         use {@link GraphExplorerConstants#EMPTY_INPUT}. Never return\r
795          *         <code>null</code>.\r
796          */\r
797         Object get(ISessionContext ctx, Object selection);\r
798     }\r
799     \r
800     public interface FilterSource {\r
801         \r
802         \r
803         \r
804     }\r
805 \r
806     /**\r
807      * The default hint tracker that will be active if\r
808      * {@link GraphExplorerComposite#setSessionContextTracker(IHintTracker) is\r
809      * not called.\r
810      */\r
811     public class SessionContextProjectTracker extends HintTracker {\r
812         public SessionContextProjectTracker() {\r
813             IHintListener activeProjectListener = new HintListenerAdapter() {\r
814                 @Override\r
815                 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
816                     applySessionContext(getSessionContext());\r
817                 }\r
818             };\r
819             addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);\r
820         }\r
821     }\r
822 \r
823     public class DirectInputSource implements InputSource {\r
824         @Override\r
825         public Object get(ISessionContext ctx, Object selection) {\r
826             return selection;\r
827         }\r
828     }\r
829     \r
830     public static class SelectionFilterAreaSource implements FilterAreaSource {\r
831 \r
832                 @Override\r
833                 public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
834                         FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
835                         return new FilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
836                 }\r
837         \r
838     }\r
839 \r
840     public static class RootFilterAreaSource implements FilterAreaSource {\r
841 \r
842                 @Override\r
843                 public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
844                         FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
845                         return new RootFilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
846                 }\r
847         \r
848     }\r
849 \r
850     protected void setSessionContextTracker(IHintTracker tracker) {\r
851         this.sessionContextTracker = tracker;\r
852     }\r
853 \r
854     public void setInputSource(InputSource source) {\r
855         this.inputSource = source;\r
856     }\r
857     \r
858     public void setFilterAreaSource(FilterAreaSource provider) {\r
859         this.filterAreaSource = provider;\r
860     }\r
861 \r
862     public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {\r
863         this.selectionTransformation = transformation;\r
864         if(explorer != null) explorer.setSelectionTransformation(transformation);\r
865     }\r
866 \r
867     protected Set<String> getBrowseContexts() {\r
868         return browseContexts;\r
869     }\r
870     \r
871     public void setBrowseContexts(Set<String> contexts) {\r
872         this.browseContexts = contexts;\r
873         //initializeExplorer(explorer, getSessionContext());\r
874     }\r
875 \r
876     public void setBrowseContexts(String ... contexts) {\r
877         this.browseContexts = new HashSet<String>();\r
878         for(String s : contexts) this.browseContexts.add(s);\r
879         initializeExplorer(explorer, getSessionContext());\r
880     }\r
881 \r
882     public void setContextMenuId(String contextMenuId) {\r
883         this.contextMenuId = contextMenuId;\r
884     }\r
885 \r
886 //    protected IContextMenuInitializer getContextMenuInitializer() {\r
887 //        String contextMenuId = getContextMenuId();\r
888 //        if(contextMenuId != null) {\r
889 //            return new ContextMenuInitializer(contextMenuId);\r
890 //        } else {\r
891 //            return null;\r
892 //        }\r
893 //    }\r
894 \r
895     protected String getContextMenuId() {\r
896         return this.contextMenuId;\r
897     }\r
898 \r
899     public void setUiContexts(Set<String> uiContext) {\r
900         this.uiContext = uiContext;\r
901     }\r
902 \r
903     public Set<String> getUiContexts() {\r
904         return uiContext;\r
905     }\r
906 \r
907     protected InputSource getInputSource() {\r
908         return inputSource;\r
909     }\r
910 \r
911     protected Map<String, Object> getArguments() {\r
912         return args;\r
913     }\r
914 \r
915     @SuppressWarnings("unchecked")\r
916     protected <T> T getArgument(String key) {\r
917         return (T) args.get(key);\r
918     }\r
919 \r
920     protected DisposeState getDisposeState() {\r
921         return disposeState;\r
922     }\r
923 \r
924     public ISessionContext getSessionContext() {\r
925         return sessionContext;\r
926     }\r
927 \r
928     public ISessionContextProvider getSessionContextProvider() {\r
929         return contextProvider;\r
930     }\r
931 \r
932     @Override\r
933     public boolean setFocus() {\r
934         if (explorer != null && !explorer.isDisposed())\r
935             explorer.setFocus();\r
936         return true;\r
937     }\r
938 \r
939     public void setWorkbenchListeners() {\r
940         if (workbenchSelectionListener == null && getSite() != null) {\r
941             ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
942             getSite().setSelectionProvider(selectionProvider);\r
943 \r
944             // Listen to the workbench selection also to propagate it to\r
945             // the explorer also.\r
946             workbenchSelectionListener = new DefaultExplorerSelectionListener(site.getPage().getActivePart(), explorer);\r
947             //System.out.println("ADD WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
948             getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener);\r
949         }\r
950     }\r
951 \r
952     protected void removeWorkbenchListeners() {\r
953         //System.out.println("REMOVE WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
954         // Remember to remove the installed workbench selection listener\r
955         if (workbenchSelectionListener != null) {\r
956             getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);\r
957             workbenchSelectionListener = null;\r
958 \r
959             ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
960             if(getSite().getSelectionProvider() == selectionProvider) getSite().setSelectionProvider(null);\r
961             \r
962         }\r
963     }\r
964 \r
965     protected final void attachToSession() {\r
966 \r
967         // Track active ISessionContext changes\r
968         //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());\r
969         contextProvider.addContextChangedListener(contextChangeListener);\r
970 \r
971         // Start tracking the current session context for input changes.\r
972         // This will/must cause applySessionContext to get called.\r
973         // Doing the applySessionContext initialization this way\r
974         // instead of directly calling it will also make sure that\r
975         // applySessionContext is only called once when first initialized,\r
976         // and not twice like with the direct invocation.\r
977         this.sessionContext = contextProvider.getSessionContext();\r
978         sessionContextTracker.track(sessionContext);\r
979     }\r
980 \r
981     // /////////////////////////////////////////////////////////////////////////\r
982     // Override / implement these:\r
983 \r
984 //    /**\r
985 //     * Returns an ID that is used for persisting a GraphExplorer instance.\r
986 //     *\r
987 //     * Used for </code>restoreState(IMemento)</code> and\r
988 //     * <code>restoreState(IMemento)</code> in OntologyExplorer. Must be unique\r
989 //     * within a workbench part.\r
990 //     *\r
991 //     * @return a unique name for this particular graph explorer view used for\r
992 //     *         saving and restoring the state of this view part\r
993 //     */\r
994 //    public String getExplorerName() {\r
995 //        return "GraphExplorerViewBase";\r
996 //    }\r
997 \r
998     /**\r
999      * Override this method to add controls to the view part. This is invoked\r
1000      * before attaching the view part to a database session.\r
1001      * \r
1002      * @param parent\r
1003      */\r
1004     protected void createControls(Composite parent) {\r
1005 \r
1006     }\r
1007 \r
1008     /**\r
1009      * Override this method and provide a proper context menu initializer if you\r
1010      * want to have this base class initialize one for you.\r
1011      * \r
1012      * @return the initializer to be used by {@link #createControls(Composite)}\r
1013      */\r
1014     protected IContextMenuInitializer getContextMenuInitializer() {\r
1015         String contextMenuId = getContextMenuId();\r
1016         if(contextMenuId != null) {\r
1017             return new ContextMenuInitializer(contextMenuId);\r
1018         } else {\r
1019             return null;\r
1020         }\r
1021     }\r
1022 \r
1023     /**\r
1024      * @param parent\r
1025      * @return\r
1026      */\r
1027     protected GraphExplorer createExplorerControl(Composite parent, Integer maxChildren) {\r
1028         GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
1029         if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
1030 \r
1031         GraphExplorer ge = factory\r
1032         .selectionDataResolver(new DefaultSelectionDataResolver())\r
1033         .selectionTransformation(selectionTransformation)\r
1034         .setServiceLocator(site)\r
1035         .create(parent, style);\r
1036 \r
1037         return ge;\r
1038     }\r
1039     \r
1040     protected GraphExplorer createExplorerControl2(Composite parent, Integer maxChildren) {\r
1041         GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
1042         if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
1043 \r
1044         GraphExplorer ge = factory\r
1045         .selectionDataResolver(new DefaultSelectionDataResolver())\r
1046         .selectionTransformation(selectionTransformation)\r
1047         .setServiceLocator(site)\r
1048         .create2(parent, style);\r
1049 \r
1050         return ge;\r
1051     }\r
1052 \r
1053     protected void setupDragSource(Session session) {\r
1054         if (dragSource instanceof SessionContainer) {\r
1055             ((SessionContainer) dragSource).setSession(session);\r
1056         }\r
1057     }\r
1058 \r
1059     /**\r
1060      * Override to customize the addition of listeners a newly created\r
1061      * GraphExplorer.\r
1062      * \r
1063      * @param explorer\r
1064      */\r
1065     protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
1066         addSelectionInputListeners(explorer, menuManager);\r
1067     }\r
1068 \r
1069     protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
1070         // Consider ENTER presses to simulate mouse left button double clicks\r
1071         explorer.addListener(new DefaultKeyListener(contextProvider, explorer, new Function<String[]>() {\r
1072             @Override\r
1073             public String[] execute(Object... obj) {\r
1074                 return getEditingColumn((NodeContext) obj[0]);\r
1075             }\r
1076         }));\r
1077         // Default double click handling\r
1078         explorer.addListener(new DefaultMouseListener(explorer));\r
1079     }\r
1080 \r
1081     protected String[] getEditingColumn(NodeContext context) {\r
1082         return editingColumn;\r
1083     }\r
1084     \r
1085     public void setEditingColumn(String... columnKeysInOrderOfTrial) {\r
1086         this.editingColumn = columnKeysInOrderOfTrial;\r
1087     }\r
1088 \r
1089     // Needed for preventing unnecessary re-initialization of the explorer with the same input.\r
1090     private Object currentInput;\r
1091     private Object currentRoot;\r
1092 \r
1093     /**\r
1094      * Invoke this to reinitialize the explorer and reset its input. The input\r
1095      * will be resolved from the specified ISessionContext based on the\r
1096      * {@link SessionContextInputSource} that is currently in use. If the input\r
1097      * is identical to the previous input, nothing will be done.\r
1098      * \r
1099      * @param context\r
1100      */\r
1101     public final boolean applySessionContext(ISessionContext context) {\r
1102 \r
1103         // If control is not alive anymore, do nothing.\r
1104         //System.out.println(this + ": applySessionContext(" + context + "), explorer="  + explorer);\r
1105         if (disposeState != DisposeState.Alive)\r
1106             return false;\r
1107 \r
1108         //System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");\r
1109         initializeExplorer(explorer, context);\r
1110 \r
1111 \r
1112         // Start tracking the session context.\r
1113         //\r
1114         // If this is not the same session that is currently tracked, it will\r
1115         // cause IHintListeners of the sessionContextTracker to fire.\r
1116         // For this we need the above input equality (identity) checking.\r
1117         // This is here just to make sure that we are tracking the correct\r
1118         // session context.\r
1119         sessionContextTracker.track(sessionContext);\r
1120 \r
1121         this.sessionContext = context;\r
1122         Object root = inputSource.get(context, currentInput);\r
1123         if (ObjectUtils.objectEquals(root, currentRoot))\r
1124             return false;\r
1125 \r
1126         currentRoot = root;\r
1127 \r
1128         //System.out.println(this + ": setRoot(" + input + ")");\r
1129         explorer.setUIContexts(uiContext);\r
1130         explorer.setRoot(root);\r
1131 \r
1132         return true;\r
1133 \r
1134     }\r
1135 \r
1136     protected boolean isImportantInput(Object previousSelection, Object selection) {\r
1137         return !ObjectUtils.objectEquals(previousSelection, selection);\r
1138     }\r
1139 \r
1140     public void setInput(Object selection, boolean force) {\r
1141 \r
1142         assert(created);\r
1143 \r
1144         if (isDisposed())\r
1145             return;\r
1146         if (sessionContext == null)\r
1147             return;\r
1148 \r
1149         // Check if this is a duplicate of the previous selection to reduce unnecessary flicker.\r
1150         if (!force && !isImportantInput(currentInput, selection))\r
1151             return;\r
1152 \r
1153         currentInput = selection;\r
1154 \r
1155         Object root = inputSource.get(sessionContext, selection);\r
1156 \r
1157         currentRoot = root;\r
1158 \r
1159         explorer.setUIContexts(uiContext);\r
1160 \r
1161         if (root == null) {\r
1162             explorer.setRoot(GraphExplorer.EMPTY_INPUT);\r
1163         } else {\r
1164             explorer.setRoot(root);\r
1165         }\r
1166 \r
1167     }\r
1168 \r
1169     public void setColumnsVisible(boolean visible) {\r
1170         explorer.setColumnsVisible(visible);\r
1171     }\r
1172 \r
1173     private int getColumnWidth(Column column, ExplorerState state) {\r
1174         // Get saved width from the persistor if there is one.\r
1175         if (state != null && state.columnWidths != null) {\r
1176                 Integer width = state.columnWidths.get(column.getLabel());\r
1177                 if (width != null)\r
1178                         return width;\r
1179         }\r
1180         return column.getWidth();\r
1181     }\r
1182     \r
1183     public void setColumns(Column[] columns) {\r
1184 \r
1185         explorer.setColumns(columns, new Consumer<Map<Column, Object>>() {\r
1186 \r
1187             @Override\r
1188             public void accept(Map<Column, Object> objects) {\r
1189                 ExplorerState state = null;\r
1190                 if (persistor != null) {\r
1191                         state = persistor.deserialize(\r
1192                                 Platform.getStateLocation(Activator.getDefault().getBundle()).toFile(),\r
1193                                 explorer.getRoot());\r
1194                 }\r
1195 \r
1196                 for(Map.Entry<Column, Object> entry : objects.entrySet()) {\r
1197                     Column column = entry.getKey();\r
1198                     TreeColumn treeColumn = (TreeColumn)entry.getValue();\r
1199 \r
1200                     if (column.getWidth() < 0) {\r
1201                         throw new IllegalArgumentException("Column minimum width cannot be < 0, got " + column.getWidth());\r
1202                     }\r
1203 \r
1204                     int width = getColumnWidth(column, state);\r
1205                     if(column.hasGrab()) {\r
1206                         \r
1207                         ad.setColumnData(treeColumn, new ColumnWeightData(column.getWeight(), width));\r
1208 \r
1209                     } else {\r
1210 \r
1211                         ad.setColumnData(treeColumn, new ColumnWeightData(0, width));\r
1212 \r
1213                     }\r
1214 \r
1215                 }\r
1216             }\r
1217 \r
1218         });\r
1219 \r
1220     }\r
1221 \r
1222     @Override\r
1223     public void setInput(ISessionContext context, Object input) {\r
1224         setInput(input, false);\r
1225     }\r
1226 \r
1227     public void setMaxChildren(int maxChildren) {\r
1228         explorer.setMaxChildren(maxChildren);\r
1229     }\r
1230     \r
1231     public <T> void addListener(ExplorerMouseListenerImpl<T> listener) {\r
1232         \r
1233         support.register(listener);\r
1234         listener.register(explorer);\r
1235         explorer.addListener(listener);\r
1236         \r
1237     }\r
1238 \r
1239 //    @Override\r
1240 //    public Point computeSize(int wHint, int hHint) {\r
1241 //      Point p = super.computeSize(wHint, hHint);\r
1242 //      System.err.println("graphExplorerComposite.computeSize " + p);\r
1243 //      return p;\r
1244 //    }\r
1245 //    \r
1246 //    @Override\r
1247 //    public Point computeSize(int wHint, int hHint, boolean changed) {\r
1248 //      Point p = super.computeSize(wHint, hHint, changed);\r
1249 //      System.err.println("graphExplorerComposite.computeSize " + p);\r
1250 //      return p;\r
1251 //    }\r
1252     \r
1253 }\r