]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
5994a0c5e8578a11175ecbf4c643f9c376b232f7
[simantics/sysdyn.git] /
1 package org.simantics.sysdyn.ui.properties.widgets;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Iterator;\r
5 import java.util.Map;\r
6 import java.util.StringTokenizer;\r
7 import java.util.LinkedHashMap;\r
8 \r
9 import org.eclipse.swt.widgets.Combo;\r
10 import org.eclipse.swt.widgets.Composite;\r
11 import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
12 import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl;\r
13 import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
14 import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
15 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
16 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
17 import org.simantics.db.ReadGraph;\r
18 import org.simantics.db.Resource;\r
19 import org.simantics.db.Session;\r
20 import org.simantics.db.VirtualGraph;\r
21 import org.simantics.db.WriteGraph;\r
22 import org.simantics.db.common.request.WriteRequest;\r
23 import org.simantics.db.common.utils.NameUtils;\r
24 import org.simantics.db.common.utils.OrderedSetUtils;\r
25 import org.simantics.db.exception.DatabaseException;\r
26 import org.simantics.db.management.ISessionContext;\r
27 import org.simantics.db.procedure.Listener;\r
28 import org.simantics.db.service.VirtualGraphSupport;\r
29 import org.simantics.layer0.Layer0;\r
30 import org.simantics.sysdyn.SysdynResource;\r
31 import org.simantics.sysdyn.ui.utils.VariableNameUtils;\r
32 \r
33 public class ArrayExpressionCombo extends TrackedCombo {\r
34 \r
35         int lastSelectedIndex = -2;\r
36 \r
37         public ArrayExpressionCombo(Composite parent, WidgetSupport support,\r
38                         int style) {\r
39                 super(parent, support, style);\r
40 \r
41                 /*\r
42                 this.setInputValidator(new VariableNameValidator(support));\r
43                  */\r
44 \r
45                 this.setItemFactory(new ReadFactoryImpl<Resource, Map<String, Object>>()  {\r
46 \r
47                         @Override\r
48                         public Map<String, Object> perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
49                                 Map<String, Object> map = new LinkedHashMap<String, Object>();\r
50                                 if(input == null) {\r
51                                         return map;\r
52                                 }\r
53 \r
54                                 Layer0 l0 = Layer0.getInstance(graph);\r
55                                 String name = graph.getPossibleRelatedValue(input, l0.HasName);\r
56                                 if(name == null)\r
57                                         return map;\r
58 \r
59                                 SysdynResource sr = SysdynResource.getInstance(graph);\r
60 \r
61                                 String defaultRange = getDefaultRange(graph, input);\r
62                                 for(Resource expression : getExpressions(graph, input)) {\r
63                                         String arrayRange = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); \r
64                                         if(arrayRange != null) {\r
65                                                 map.put(name + arrayRange, expression);\r
66                                         } else if(defaultRange != null) {\r
67                                                 map.put(name + defaultRange, expression);\r
68                                         } else {\r
69                                                 map.put(name, expression);\r
70                                         }\r
71                                 }\r
72                                 if(map.isEmpty()) {\r
73                                         map.put(name, input);\r
74                                 }\r
75                                 return map;\r
76                         }\r
77 \r
78                 });\r
79 \r
80 \r
81                 this.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
82 \r
83                         @Override\r
84                         public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
85                                 String name = graph.getPossibleRelatedValue(input,  Layer0.getInstance(graph).HasName);\r
86                                 if(name == null)\r
87                                         return "";\r
88                                 \r
89                                 String defaultRange = getDefaultRange(graph, input);\r
90                                 if(defaultRange == null)\r
91                                         return name;\r
92 \r
93                                 SysdynResource sr = SysdynResource.getInstance(graph);\r
94 \r
95                                 Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression);\r
96                                 Resource expression;\r
97                                 if(activeExpression == null) {\r
98                                         ArrayList<Resource> expressions = getExpressions(graph, input);\r
99                                         if(expressions == null || expressions.isEmpty())\r
100                                                 return name;\r
101                                         expression = expressions.get(0);\r
102                                 } else {\r
103                                         expression = activeExpression;\r
104                                 }\r
105                                 String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);\r
106                                 if(range != null)\r
107                                         return name + range;\r
108                                 else\r
109                                         return name + defaultRange;\r
110                         }\r
111                 });\r
112 \r
113                 this.addModifyListener(new NameAndArrayRangeModifyListener(support));\r
114         }\r
115 \r
116 \r
117         @Override\r
118         public void setInput(ISessionContext context, Object input) {\r
119                 super.setInput(context, input);\r
120 \r
121                 if(selectionFactory != null) {\r
122                         selectionFactory.listen(context, input, new Listener<String>() {\r
123 \r
124                                 @Override\r
125                                 public void execute(final String result) {\r
126                                         if(getWidget().isDisposed()) return;\r
127                                         getWidget().getDisplay().asyncExec(new Runnable() {\r
128                                                 \r
129                                                 @Override\r
130                                                 public void run() {\r
131                                                         Combo combo = getWidget();\r
132                                                         if(combo != null && !combo.isDisposed() && result != null) {\r
133                                                                 Object o = getWidget().getData(result);\r
134                                                                 if(o != null)\r
135                                                                         lastSelectedIndex = (Integer)o;\r
136                                                         }\r
137                                                                 \r
138                                                 }\r
139                                         });\r
140                                 }\r
141 \r
142                                 @Override\r
143                                 public void exception(Throwable t) {\r
144                                         t.printStackTrace();\r
145                                 }\r
146 \r
147                                 @Override\r
148                                 public boolean isDisposed() {\r
149                                         return getWidget().isDisposed();\r
150                                 }\r
151 \r
152                         });\r
153                 }\r
154         }\r
155 \r
156         private ArrayList<Resource> getExpressions(ReadGraph graph, Resource variable) throws DatabaseException {\r
157                 SysdynResource sr = SysdynResource.getInstance(graph);\r
158                 Resource hasExpressions = graph.getPossibleObject(variable, sr.Variable_expressions);\r
159                 if(hasExpressions == null)\r
160                         return new ArrayList<Resource>();\r
161                 else\r
162                         return new ArrayList<Resource>(OrderedSetUtils.toList(graph, hasExpressions));\r
163         }\r
164 \r
165         public static String getDefaultRange(ReadGraph graph, Resource variable) throws DatabaseException {\r
166                 SysdynResource sr = SysdynResource.getInstance(graph);\r
167                 Resource hasArrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexes);\r
168 \r
169                 if(hasArrayIndexes == null)\r
170                         return null;\r
171 \r
172                 Iterator<Resource> iterator = OrderedSetUtils.iterator(graph, hasArrayIndexes);\r
173                 if(!iterator.hasNext())\r
174                         return null;\r
175 \r
176                 StringBuilder sb = new StringBuilder();\r
177                 sb.append("[");\r
178 \r
179                 while(iterator.hasNext()) {\r
180                         sb.append(NameUtils.getSafeName(graph, iterator.next()));\r
181                         if(iterator.hasNext()) {\r
182                                 sb.append(", ");\r
183                         }\r
184                 }\r
185                 sb.append("]");\r
186                 return sb.toString();\r
187         }\r
188 \r
189         private class NameAndArrayRangeModifyListener extends ComboModifyListenerImpl<Resource> implements Widget {\r
190 \r
191                 Resource lastExpression; \r
192 \r
193                 public NameAndArrayRangeModifyListener(WidgetSupport support) {\r
194                         support.register(this);\r
195                 }\r
196 \r
197                 @Override\r
198                 public void setInput(ISessionContext context, Object input) {\r
199                         super.setInput(context, input);\r
200                 }\r
201 \r
202                 @Override\r
203                 public void modifyText(TrackedModifyEvent e) {\r
204 \r
205                         Combo combo = (Combo)e.getWidget();\r
206                         LinkedHashMap<?, ?> data = (LinkedHashMap<?, ?>) combo.getData();\r
207 \r
208                         Resource expression = (Resource) data.get(combo.getText());\r
209                         if(expression != null) {\r
210                                 lastExpression = expression;\r
211                                 lastSelectedIndex = combo.getSelectionIndex();\r
212                         } else {\r
213                                 for(Object key : data.keySet()) {\r
214                                         int index = lastSelectedIndex < 0 ? 0 : lastSelectedIndex;\r
215                                         if((Integer)combo.getData((String)key) == index) {\r
216                                                 lastExpression =  (Resource) data.get((String)key);\r
217                                                 break;\r
218                                         }\r
219                                 }\r
220                         }\r
221 \r
222                         super.modifyText(e);\r
223                 }\r
224 \r
225                 @Override\r
226                 public void applyText(WriteGraph graph, final Resource variable, String text)\r
227                 throws DatabaseException {\r
228                         StringTokenizer st = new StringTokenizer(text, "[]");\r
229                         final String newName = st.nextToken();\r
230                         String range = null;\r
231                         if(st.hasMoreTokens()) {\r
232                                 range = st.nextToken();\r
233                         }\r
234                         String originalName = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName);\r
235                         if(!originalName.equals(newName)) {\r
236                                 VariableNameUtils.renameInEquations(graph, variable, originalName, newName);\r
237                                 graph.claimLiteral(variable, Layer0.getInstance(graph).HasName, newName);\r
238                         }\r
239 \r
240                         SysdynResource sr = SysdynResource.getInstance(graph);\r
241 \r
242                         if(range != null && lastExpression != null) {\r
243                                 String oldRange = graph.getPossibleRelatedValue(lastExpression, sr.Expression_arrayRange);\r
244                                 if(oldRange == null || !range.equals(oldRange)) {\r
245                                         graph.claimLiteral(lastExpression, sr.Expression_arrayRange, "[" + range + "]");\r
246                                 }\r
247                         } else if (range == null && lastExpression != null && graph.hasStatement(lastExpression, sr.Expression_arrayRange)) {\r
248                             graph.deny(lastExpression, sr.Expression_arrayRange);\r
249                         }\r
250 \r
251                         Resource activeExpression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression);\r
252 \r
253                         if(lastExpression != null && !lastExpression.equals(activeExpression)) {\r
254                                 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
255                                 final Session session = graph.getSession();\r
256                                 session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {\r
257                                         @Override\r
258                                         public void perform(WriteGraph graph) throws DatabaseException {\r
259                                                 VirtualGraph runtime = graph.getService(VirtualGraph.class);\r
260                                                 session.asyncRequest(new WriteRequest(runtime) {\r
261                                                         @Override\r
262                                                         public void perform(WriteGraph graph) throws DatabaseException {\r
263                                                                 SysdynResource sr = SysdynResource.getInstance(graph);\r
264                                                                 if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
265                                                                         graph.deny(variable, sr.IndependentVariable_activeExpression);\r
266                                                                 graph.claim(variable, sr.IndependentVariable_activeExpression, lastExpression);\r
267                                                         }\r
268                                                 }\r
269                                                 );\r
270                                         }\r
271                                 });\r
272                         }\r
273                 }\r
274         }\r
275 }\r
276 \r