]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
41f0871fc5b0f7026f42801c1abc404599ef4e33
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010 Association for Decentralized Information Management in\r
3  * 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.sysdyn.ui.properties.widgets;\r
13 \r
14 import java.text.Collator;\r
15 import java.util.ArrayList;\r
16 import java.util.Collections;\r
17 import java.util.HashSet;\r
18 import java.util.Locale;\r
19 import java.util.concurrent.CopyOnWriteArrayList;\r
20 \r
21 import org.eclipse.jface.layout.GridDataFactory;\r
22 import org.eclipse.jface.layout.GridLayoutFactory;\r
23 import org.eclipse.jface.resource.JFaceResources;\r
24 import org.eclipse.jface.resource.LocalResourceManager;\r
25 import org.eclipse.jface.viewers.IStructuredSelection;\r
26 import org.eclipse.swt.SWT;\r
27 import org.eclipse.swt.events.FocusListener;\r
28 import org.eclipse.swt.events.MouseListener;\r
29 import org.eclipse.swt.widgets.Composite;\r
30 import org.eclipse.swt.widgets.TabFolder;\r
31 import org.eclipse.swt.widgets.TabItem;\r
32 import org.eclipse.swt.widgets.Table;\r
33 import org.eclipse.swt.widgets.TableItem;\r
34 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
35 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
36 import org.simantics.db.AsyncReadGraph;\r
37 import org.simantics.db.ReadGraph;\r
38 import org.simantics.db.Resource;\r
39 import org.simantics.db.exception.DatabaseException;\r
40 import org.simantics.db.layer0.request.PossibleModel;\r
41 import org.simantics.db.management.ISessionContext;\r
42 import org.simantics.db.procedure.AsyncListener;\r
43 import org.simantics.db.request.Read;\r
44 import org.simantics.layer0.Layer0;\r
45 import org.simantics.sysdyn.SysdynResource;\r
46 import org.simantics.sysdyn.ui.properties.widgets.expressions.Function;\r
47 import org.simantics.sysdyn.ui.validation.ValidationUtils;\r
48 import org.simantics.ui.SimanticsUI;\r
49 import org.simantics.utils.ui.ISelectionUtils;\r
50 \r
51 public class ShortcutTabWidget implements Widget {\r
52 \r
53     TabFolder tabFolder;\r
54     TabItem variables;\r
55     TabItem functions;\r
56     Table variableTable;\r
57     Table functionTable;\r
58     Composite composite;\r
59     TableItem item2;\r
60     \r
61         CopyOnWriteArrayList<Runnable> dependencyListeners =\r
62                 new CopyOnWriteArrayList<Runnable>();\r
63         \r
64     private final LocalResourceManager resourceManager;\r
65 \r
66     public ShortcutTabWidget(Composite parent, WidgetSupport support, int style) {\r
67         if(support!=null)\r
68                 support.register(this);\r
69 \r
70         composite = new Composite(parent, style);\r
71         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
72         \r
73         tabFolder = new TabFolder (composite, SWT.NONE);\r
74         GridDataFactory.fillDefaults().grab(false, true).applyTo(tabFolder);\r
75         GridLayoutFactory.fillDefaults().applyTo(tabFolder);\r
76         variables = new TabItem(tabFolder, SWT.NULL);\r
77         variables.setText("Variables");\r
78         variableTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);\r
79         \r
80         variables.setControl(variableTable);\r
81 \r
82         functions = new TabItem(tabFolder, SWT.NULL);\r
83         functions.setText("Functions"); \r
84 \r
85         functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);\r
86         \r
87         // Create a ResourceManager to dispose images when the widget is disposed.\r
88         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable);\r
89         \r
90         functions.setControl(functionTable);\r
91         \r
92         // Add the functions only after we know which variable is connected to this widget.\r
93     }\r
94 \r
95     public Composite getWidget() {\r
96         return composite;\r
97     }\r
98     \r
99     private void addFunctions(Resource model) {\r
100         TableItem item;\r
101         \r
102         ArrayList<Function> functionList = Function.getUserDefinedFunctions(model);\r
103         functionList.addAll(Function.getSharedFunctions(model));        \r
104         functionList.addAll(Function.getAllBuiltInFunctions());        \r
105         \r
106         Collections.sort(functionList);\r
107         \r
108         for(Function function : functionList){\r
109             item = new TableItem(functionTable, SWT.NONE);\r
110             item.setText(function.getName() + "()");\r
111             item.setData(function.getName() + "(" + function.getParameterList() + ")");\r
112             item.setImage(Function.getImage(this.resourceManager, function));\r
113         }\r
114         \r
115     }\r
116     \r
117     @Override\r
118     public void setInput(ISessionContext context, Object input) {\r
119         if(input instanceof IStructuredSelection) {\r
120             final Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
121             if(variable != null) {\r
122                 \r
123                 // Fill the function table\r
124                 try { \r
125                     Resource model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
126 \r
127                         @Override\r
128                         public Resource perform(ReadGraph graph) throws DatabaseException {\r
129                             return graph.syncRequest(new PossibleModel(variable));\r
130                         }\r
131                     });\r
132                     addFunctions(model);\r
133                 } catch (DatabaseException e) {\r
134                     e.printStackTrace();\r
135                 }\r
136 \r
137                 // Fill the variable table\r
138                 SimanticsUI.getSession().asyncRequest(new Read<HashSet<String>>() {\r
139 \r
140                                         @Override\r
141                                         public HashSet<String> perform(ReadGraph graph)\r
142                                                         throws DatabaseException {\r
143                                                 return ValidationUtils.getDependencies(graph, variable);\r
144                                         }\r
145                                 }, new AsyncListener<HashSet<String>>() {\r
146 \r
147                                         @Override\r
148                                         public void execute(AsyncReadGraph graph,\r
149                                                         HashSet<String> result) {\r
150                                                 \r
151                                                 final HashSet<String> dependencies = result;\r
152                                                 variableTable.getDisplay().asyncExec(new Runnable() {\r
153                                                         \r
154                                                         @Override\r
155                                                         public void run() {\r
156                                                                 if(variableTable.isDisposed()) return;\r
157                                                                 \r
158                                                                 TableItem[] items = variableTable.getItems();\r
159                                                                 \r
160                                                                 // Remove deleted dependencies and create the list of current dependencies (itemStrings)\r
161                                                                 ArrayList<String> itemStrings = new ArrayList<String>();\r
162                                                 for(TableItem i : items) {\r
163                                                         String text = i.getText();\r
164                                                         if(dependencies.contains(text))\r
165                                                                 itemStrings.add(text);\r
166                                                         else\r
167                                                                 variableTable.remove(variableTable.indexOf(i));\r
168                                                 }\r
169                                                 \r
170                                                 // Add all new dependencies\r
171                                                 TableItem item;\r
172                                                 for(String d : dependencies) {\r
173                                                         if(!itemStrings.contains(d)) {\r
174                                                                 item = new TableItem(variableTable, SWT.NONE);\r
175                                                                 item.setText(d);\r
176                                                                 item.setData(d);\r
177                                                         }\r
178                                                 }\r
179                                                 \r
180                                                 sort();\r
181                                                 \r
182                                                 String selfName = getName();\r
183 \r
184                                                 // Time and self are not added if selfName (we have an error or a stock).\r
185                                                 if (selfName != null)\r
186                                                 {\r
187                                     item = new TableItem(variableTable, SWT.NONE);\r
188                                     item.setText(selfName);\r
189                                     item.setData(selfName);\r
190                                     \r
191                                     item = new TableItem(variableTable, SWT.NONE);\r
192                                     item.setText("time");\r
193                                     item.setData("time");\r
194                                                 }\r
195                                                 \r
196                                                                 synchronized(dependencyListeners) {\r
197                                                                         for(Runnable listener : dependencyListeners)\r
198                                                                                 listener.run();\r
199                                                                 }                                                               \r
200                                                         }\r
201                                                 });\r
202                                         }\r
203                                         \r
204                                         /**\r
205                                          * Sort items to alphabetical order.\r
206                                          */\r
207                                         private void sort() {\r
208                                             TableItem[] connectedVariables = variableTable.getItems();\r
209                                             Collator collator = Collator.getInstance(Locale.getDefault());\r
210                                             for (int i = 1; i < connectedVariables.length; i++) {\r
211                                                 String value1 = connectedVariables[i].getText(0);\r
212                                                 for (int j = 0; j < i; j++) {\r
213                                                     String value2 = connectedVariables[j].getText(0);\r
214                                                     if (collator.compare(value1, value2) < 0) {\r
215                                                         String value = connectedVariables[i].getText(0);\r
216                                                         connectedVariables[i].dispose();\r
217                                                         TableItem item2 = new TableItem(variableTable, SWT.NONE, j);\r
218                                                         item2.setText(value);\r
219                                                         item2.setData(value);\r
220                                                         connectedVariables = variableTable.getItems();\r
221                                                         break;\r
222                                                     }\r
223                                                 }\r
224                                             }\r
225                                         }\r
226                                         \r
227                                         /**\r
228                                          * Get the name of the respective variable.\r
229                                          */\r
230                                         private String getName() {\r
231                                             String selfName = null;\r
232                         try {\r
233                                                 selfName = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
234                                 @Override\r
235                                 public String perform(ReadGraph graph)\r
236                                         throws DatabaseException {\r
237                                     Layer0 l0 = Layer0.getInstance(graph);\r
238                                     SysdynResource sr = SysdynResource.getInstance(graph);\r
239                                     \r
240                                     // Check if we have a stock or some other mystic error.\r
241                                     if (!graph.isInstanceOf(variable, sr.Stock)) {\r
242                                         Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName);\r
243                                         if (selfName instanceof String) {\r
244                                             return (String)selfName;\r
245                                         }\r
246                                     }\r
247                                     return null;\r
248                                 }\r
249                             });\r
250                         }\r
251                         catch (DatabaseException e) {\r
252                             e.printStackTrace();\r
253                         }\r
254                                             return selfName;\r
255                                         }\r
256 \r
257                                         @Override\r
258                                         public void exception(AsyncReadGraph graph,\r
259                                                         Throwable throwable) {\r
260                                                 throwable.printStackTrace();\r
261                                         }\r
262 \r
263                                         @Override\r
264                                         public boolean isDisposed() {\r
265                                                 return variableTable.isDisposed();\r
266                                         }\r
267                                 });\r
268             }\r
269         }\r
270     }\r
271 \r
272 \r
273     \r
274     public void addFocusListener(FocusListener listener) {\r
275         this.functionTable.addFocusListener(listener);\r
276         this.variableTable.addFocusListener(listener);\r
277     }\r
278     \r
279     public void addMouseListener(MouseListener listener) {\r
280         this.functionTable.addMouseListener(listener);\r
281         this.variableTable.addMouseListener(listener);\r
282     }\r
283     \r
284         public void addDependencyListener(Runnable listener) {\r
285                 synchronized(dependencyListeners) {\r
286                         dependencyListeners.add(listener);\r
287                 }\r
288         }\r
289 \r
290         public void removeDependencyListener(Runnable listener) {\r
291                 synchronized(dependencyListeners) {\r
292                         dependencyListeners.remove(listener);\r
293                 }\r
294         }\r
295     \r
296     public Table getVariableTable() {\r
297         return variableTable;\r
298     }\r
299 \r
300 \r
301 }\r