]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.team.ui/src/org/simantics/team/ui/TreeView.java
ff11b7198e84255408ab50962f79d33f17ca41b3
[simantics/platform.git] / bundles / org.simantics.team.ui / src / org / simantics / team / ui / TreeView.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 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.team.ui;\r
13 \r
14 import java.util.Map;\r
15 \r
16 import org.eclipse.jface.layout.GridDataFactory;\r
17 import org.eclipse.jface.resource.LocalResourceManager;\r
18 import org.eclipse.jface.viewers.TreeViewer;\r
19 import org.eclipse.jface.viewers.ViewerCell;\r
20 import org.eclipse.jface.viewers.ViewerFilter;\r
21 import org.eclipse.jface.window.ToolTip;\r
22 import org.eclipse.swt.SWT;\r
23 import org.eclipse.swt.graphics.Image;\r
24 import org.eclipse.swt.graphics.Point;\r
25 import org.eclipse.swt.layout.GridData;\r
26 import org.eclipse.swt.layout.GridLayout;\r
27 import org.eclipse.swt.widgets.Composite;\r
28 import org.eclipse.swt.widgets.Control;\r
29 import org.eclipse.swt.widgets.Event;\r
30 import org.eclipse.swt.widgets.Label;\r
31 import org.eclipse.swt.widgets.Text;\r
32 import org.eclipse.swt.widgets.Tree;\r
33 import org.eclipse.ui.IMemento;\r
34 import org.eclipse.ui.IViewSite;\r
35 import org.eclipse.ui.PartInitException;\r
36 import org.eclipse.ui.part.ViewPart;\r
37 import org.simantics.browsing.ui.swt.ViewArgumentUtils;\r
38 import org.simantics.db.management.ISessionContext;\r
39 import org.simantics.db.management.ISessionContextChangedListener;\r
40 import org.simantics.db.management.ISessionContextProvider;\r
41 import org.simantics.db.management.SessionContextChangedEvent;\r
42 import org.simantics.utils.datastructures.disposable.DisposeState;\r
43 \r
44 /**\r
45  * @author Kalle Kondelin\r
46  */\r
47 abstract class TreeView extends ViewPart {\r
48     protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() {\r
49         @Override\r
50         public void sessionContextChanged(SessionContextChangedEvent event) {\r
51             sessionContext = event.getNewValue();\r
52         }\r
53     };\r
54     protected LocalResourceManager resourceManager;\r
55     protected Composite parent;\r
56     protected TreeViewer treeViewer;\r
57     protected IMemento memento;\r
58     private Map<String, String> args;\r
59     private ISessionContextProvider contextProvider;\r
60     private ISessionContext sessionContext;\r
61     private DisposeState disposeState = DisposeState.Alive;\r
62 \r
63     public TreeView() {\r
64     }\r
65 \r
66     \r
67 \r
68     protected Map<String, String> getViewArguments() {\r
69         return args;\r
70     }\r
71 \r
72     protected DisposeState getDisposeState() {\r
73         return disposeState;\r
74     }\r
75 \r
76     public ISessionContext getSessionContext() {\r
77         return sessionContext;\r
78     }\r
79 \r
80     public ISessionContextProvider getSessionContextProvider() {\r
81         return contextProvider;\r
82     }\r
83 \r
84 \r
85     /**\r
86      * Invoked when this viewpart is disposed. Unhooks the view from its\r
87      * ISessionContextProvider. Overriding is allowed but super.dispose() must\r
88      * be called.\r
89      * \r
90      * @see org.eclipse.ui.part.WorkbenchPart#dispose()\r
91      */\r
92     @Override\r
93     public void dispose() {\r
94         disposeState = DisposeState.Disposing;\r
95         try {\r
96             if (contextProvider != null) {\r
97                 contextProvider.removeContextChangedListener(contextChangeListener);\r
98                 contextProvider = null;\r
99             }\r
100             resourceManager.dispose();\r
101             resourceManager = null;\r
102             args = null;\r
103             sessionContext = null;\r
104             parent = null;\r
105             super.dispose();\r
106         } finally {\r
107            disposeState = DisposeState.Disposed;\r
108         }\r
109     }\r
110 \r
111     @Override\r
112     public void setFocus() {\r
113         treeViewer.getTree().setFocus();\r
114     }\r
115 \r
116     @Override\r
117     public void init(IViewSite site) throws PartInitException {\r
118         super.init(site);\r
119         this.args = ViewArgumentUtils.parseViewArguments(this);\r
120     }\r
121 \r
122     @Override\r
123     public void init(IViewSite site, IMemento memento) throws PartInitException {\r
124         super.init(site, memento);\r
125         this.args = ViewArgumentUtils.parseViewArguments(this);\r
126         this.memento = memento;\r
127     }\r
128 \r
129     @Override\r
130     public void saveState(IMemento memento) {\r
131         if (this.memento != null) {\r
132             memento.putMemento(this.memento);\r
133         }\r
134 //        if (explorer != null)\r
135 //            explorer.saveState(memento);\r
136     }\r
137     \r
138     protected static abstract class NameAndDescriptionToolTip extends ToolTip {\r
139         public NameAndDescriptionToolTip(Control control, int style) {\r
140             super(control, style, false);\r
141         }\r
142 \r
143         protected abstract Object getModelElement(Event event);\r
144 \r
145         /**\r
146          * Adds logic to only show a tooltip if a meaningful item is under the\r
147          * cursor.\r
148          */\r
149         protected boolean shouldCreateToolTip(Event event) {\r
150             if (!super.shouldCreateToolTip(event))\r
151                 return false;\r
152             Object tableElement = getModelElement(event); \r
153             return tableElement != null && tableElement instanceof DisplayElement;\r
154         }\r
155 \r
156         protected Composite createToolTipContentArea(Event event,\r
157                 Composite parent) {\r
158             Object modelElement = getModelElement(event);\r
159 \r
160             Image iconImage = null;\r
161             String nameString = "no name";\r
162 \r
163             if (modelElement instanceof DisplayElement) {\r
164                 iconImage = null;\r
165                 nameString = ((DisplayElement)modelElement).getIdText();\r
166             }\r
167 \r
168             // Create the content area\r
169             Composite composite = new Composite(parent, SWT.NONE);\r
170             composite.setBackground(parent.getDisplay().getSystemColor(\r
171                     SWT.COLOR_INFO_BACKGROUND));\r
172             composite.setLayout(new GridLayout(2, false));\r
173 \r
174             // The title area with the icon (if there is one) and label.\r
175             Label title = createEntry(composite, iconImage, nameString);\r
176 //            title.setFont(tooltipHeading);\r
177             GridDataFactory.createFrom((GridData)title.getLayoutData())\r
178                 .hint(SWT.DEFAULT, SWT.DEFAULT)\r
179 //                .minSize(MIN_TOOLTIP_WIDTH, 1)\r
180                 .applyTo(title);\r
181 \r
182             // The description (if there is one)\r
183 //            String descriptionString = "description";\r
184 //            if (descriptionString != null)\r
185 //                createEntry(composite, null, descriptionString);\r
186 \r
187             // Other Content to add\r
188             addContent(composite, modelElement);\r
189 \r
190             return composite;\r
191         }\r
192 \r
193         /**\r
194          * Adds a line of information to <code>parent</code>. If\r
195          * <code>icon</code> is not <code>null</code>, an icon is placed on the\r
196          * left, and then a label with <code>text</code>.\r
197          * \r
198          * @param parent\r
199          *            the composite to add the entry to\r
200          * @param icon\r
201          *            the icon to place next to the text. <code>null</code> for\r
202          *            none.\r
203          * @param text\r
204          *            the text to display\r
205          * @return the created label\r
206          */\r
207         protected Label createEntry(Composite parent, Image icon, String text) {\r
208             if (icon != null) {\r
209                 Label iconLabel = new Label(parent, SWT.NONE);\r
210                 iconLabel.setImage(icon);\r
211                 iconLabel.setBackground(parent.getDisplay().getSystemColor(\r
212                         SWT.COLOR_INFO_BACKGROUND));\r
213                 iconLabel.setData(new GridData());\r
214             }\r
215 \r
216             Label textLabel = new Label(parent, SWT.WRAP);\r
217             \r
218             if(icon == null) {\r
219                 GridDataFactory.generate(textLabel, 2, 1);\r
220             } else {\r
221                 GridDataFactory.generate(textLabel, 1, 1);\r
222             }\r
223             \r
224             textLabel.setText(text);\r
225             textLabel.setBackground(parent.getDisplay().getSystemColor(\r
226                     SWT.COLOR_INFO_BACKGROUND));\r
227             return textLabel;\r
228         }\r
229 \r
230         /**\r
231          * Adds a line of information to <code>parent</code>. If\r
232          * <code>icon</code> is not <code>null</code>, an icon is placed on the\r
233          * left, and then a label with <code>text</code>, which supports using\r
234          * anchor tags to creates links\r
235          * \r
236          * @param parent\r
237          *            the composite to add the entry to\r
238          * @param icon\r
239          *            the icon to place next to the text. <code>null</code> for\r
240          *            none.\r
241          * @param text\r
242          *            the text to display\r
243          * @return the created link\r
244          */\r
245         protected Text createEntryWithText(Composite parent, Image icon, String text) {\r
246             if (icon != null) {\r
247                 Label iconLabel = new Label(parent, SWT.NONE);\r
248                 iconLabel.setImage(icon);\r
249                 iconLabel.setBackground(parent.getDisplay().getSystemColor(\r
250                         SWT.COLOR_INFO_BACKGROUND));\r
251                 iconLabel.setData(new GridData());\r
252             }\r
253             Text texts = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL);\r
254             if(icon == null) {\r
255                 GridDataFactory.generate(texts, 2, 1);\r
256             }\r
257             texts.setText(text);\r
258             texts.setBackground(parent.getDisplay().getSystemColor(\r
259                     SWT.COLOR_INFO_BACKGROUND));\r
260             return texts;\r
261         }\r
262 \r
263         protected void addContent(Composite destination, Object modelElement) {\r
264         }\r
265     }\r
266 \r
267     protected static class ItemDetailToolTip extends NameAndDescriptionToolTip {\r
268 //        private final boolean DEBUG = false;\r
269         private TreeViewer viewer;\r
270         private Tree tree;\r
271         ItemDetailToolTip(TreeViewer viewer, Tree tree, ViewerFilter filter) {\r
272             super(tree,NO_RECREATE);\r
273             this.tree = tree;\r
274             this.viewer = viewer;\r
275             this.setHideOnMouseDown(false);\r
276         }\r
277         public Point getLocation(Point tipSize, Event event) {\r
278             // try to position the tooltip at the bottom of the cell\r
279             ViewerCell cell = viewer.getCell(new Point(event.x, event.y));\r
280             if( cell != null )\r
281                 return tree.toDisplay(event.x,cell.getBounds().y+cell.getBounds().height);\r
282             return super.getLocation(tipSize, event);\r
283         }\r
284         protected Object getToolTipArea(Event event) {\r
285             // Ensure that the tooltip is hidden when the cell is left\r
286             return viewer.getCell(new Point(event.x, event.y));\r
287         }\r
288         protected void addContent(Composite destination, Object modelElement) {\r
289             final DisplayElement item = (DisplayElement)modelElement;\r
290             String text = null;\r
291             if (null != item) {\r
292                 text = item.getValue();\r
293                 createEntryWithText(destination, null, text.toString());\r
294             }\r
295         }\r
296         protected Object getModelElement(Event event) {\r
297             org.eclipse.swt.widgets.TreeItem treeItem = tree.getItem(new Point(event.x, event.y));\r
298             if (treeItem == null)\r
299                 return null;\r
300             return treeItem.getData();\r
301         }\r
302     }\r
303 }\r