]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
18b2e8cdf9f953fdd55c8930d4918c05c9c45393
[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.expressions;\r
13 \r
14 import java.util.Arrays;\r
15 import java.util.List;\r
16 import java.util.Map;\r
17 \r
18 import org.eclipse.jface.layout.GridDataFactory;\r
19 import org.eclipse.jface.layout.GridLayoutFactory;\r
20 import org.eclipse.jface.text.BadLocationException;\r
21 import org.eclipse.jface.text.IDocument;\r
22 import org.eclipse.swt.SWT;\r
23 import org.eclipse.swt.custom.VerifyKeyListener;\r
24 import org.eclipse.swt.events.FocusAdapter;\r
25 import org.eclipse.swt.events.FocusEvent;\r
26 import org.eclipse.swt.events.FocusListener;\r
27 import org.eclipse.swt.events.KeyListener;\r
28 import org.eclipse.swt.events.ModifyListener;\r
29 import org.eclipse.swt.events.SelectionAdapter;\r
30 import org.eclipse.swt.events.SelectionEvent;\r
31 import org.eclipse.swt.graphics.Point;\r
32 import org.eclipse.swt.widgets.Composite;\r
33 import org.eclipse.swt.widgets.Label;\r
34 import org.eclipse.swt.widgets.Spinner;\r
35 import org.simantics.databoard.Bindings;\r
36 import org.simantics.db.ReadGraph;\r
37 import org.simantics.db.Resource;\r
38 import org.simantics.db.VirtualGraph;\r
39 import org.simantics.db.WriteGraph;\r
40 import org.simantics.db.common.request.WriteRequest;\r
41 import org.simantics.db.common.utils.OrderedSetUtils;\r
42 import org.simantics.db.exception.DatabaseException;\r
43 import org.simantics.db.request.Read;\r
44 import org.simantics.layer0.Layer0;\r
45 import org.simantics.layer0.utils.direct.GraphUtils;\r
46 import org.simantics.sysdyn.SysdynResource;\r
47 import org.simantics.ui.SimanticsUI;\r
48 \r
49 /**\r
50  * IExpression for displaying fields of DelayExpression\r
51  * @author Teemu Lempinen\r
52  *\r
53  */\r
54 public class DelayExpression implements IExpression {\r
55 \r
56     private ExpressionField equation, delayTime, initialValue;\r
57     private ExpressionField lastSelectedText = equation;\r
58     private Spinner order;\r
59     private Resource expression;\r
60 \r
61     /**\r
62      * Creates a new DelayExpression\r
63      * @param expression\r
64      */\r
65     public DelayExpression(Resource expression) {\r
66         this.expression = expression;\r
67     }\r
68 \r
69     /**\r
70      * Displays the fields for delayExpression\r
71      */\r
72     @Override\r
73     public void createExpressionFields(Composite parent, final Map<String, Object> data) {\r
74         // Get possible existing data\r
75         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
76         String eq = data.get("equation") != null ? (String)data.get("equation") : "";\r
77         String dt = data.get("delayTime") != null ? (String)data.get("delayTime") : "";\r
78         String iv = data.get("initialValue") != null ? (String)data.get("initialValue") : "";\r
79         int o = data.get("order") != null ? (Integer)data.get("order") : 3;\r
80 \r
81         Label l = new Label(parent, SWT.NONE);\r
82         l.setText("expression");\r
83 \r
84         // Equation that is delayed\r
85         equation = new ExpressionField(parent, SWT.BORDER);\r
86         equation.setExpression(eq);\r
87         GridDataFactory.fillDefaults().grab(true, true).applyTo(equation);\r
88         equation.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
89 \r
90             @Override\r
91             public void focusLost(FocusEvent e) {\r
92                 lastSelectedText = equation;\r
93             }\r
94         });\r
95 \r
96         l = new Label(parent, SWT.NONE);\r
97         l.setText("delay time");\r
98 \r
99         // How much the equation is delayed\r
100         delayTime = new ExpressionField(parent, SWT.BORDER);\r
101         delayTime.setExpression(dt);\r
102         GridDataFactory.fillDefaults().grab(true, true).applyTo(delayTime);\r
103 \r
104         delayTime.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
105 \r
106             @Override\r
107             public void focusLost(FocusEvent e) {\r
108                 lastSelectedText = delayTime;\r
109             }\r
110         });\r
111 \r
112         l = new Label(parent, SWT.NONE);\r
113         l.setText("initial value");\r
114 \r
115         // What is the initial value of the delay (empty == same as equation)\r
116         initialValue = new ExpressionField(parent, SWT.BORDER);\r
117         initialValue.setExpression(iv);\r
118         GridDataFactory.fillDefaults().grab(true, true).applyTo(initialValue);\r
119 \r
120         initialValue.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
121 \r
122             @Override\r
123             public void focusLost(FocusEvent e) {\r
124                 lastSelectedText = initialValue;\r
125             }\r
126         });\r
127 \r
128 \r
129         l = new Label(parent, SWT.NONE);\r
130         l.setText("order");\r
131 \r
132         // The order of the delay (default == 3)\r
133         order = new Spinner(parent, SWT.BORDER);\r
134         order.setMinimum(1);\r
135         order.setSelection(o);\r
136         order.addSelectionListener(new SelectionAdapter() {\r
137             @Override\r
138             public void widgetSelected(SelectionEvent e) {\r
139                 save(expression, data);\r
140             }\r
141         });\r
142         GridDataFactory.fillDefaults().applyTo(order);\r
143     }\r
144 \r
145     @Override\r
146     public void focus() {\r
147         equation.setFocus();\r
148     }\r
149 \r
150     @Override\r
151     public List<ExpressionField> getExpressionFields() {\r
152         return Arrays.asList(equation, delayTime);\r
153     }\r
154 \r
155     @Override\r
156     public void readData(final Resource expression, Map<String, Object> data) {\r
157         class Auxiliary {\r
158             String equation, delayTime, initialValue;\r
159             Integer order;\r
160         }\r
161 \r
162         Auxiliary results = null;\r
163 \r
164         try {\r
165             results = SimanticsUI.getSession().syncRequest(new Read<Auxiliary>() {\r
166 \r
167                 @Override\r
168                 public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
169                     Auxiliary results = new Auxiliary();\r
170                     SysdynResource sr = SysdynResource.getInstance(graph);\r
171                     if (expression != null && graph.isInstanceOf(expression, sr.DelayExpression)) {\r
172                         results.equation = graph.getPossibleRelatedValue(expression, sr.DelayExpression_expression);\r
173                         results.delayTime = graph.getPossibleRelatedValue(expression, sr.DelayExpression_delayTime);\r
174                         results.initialValue = graph.getPossibleRelatedValue(expression, sr.DelayExpression_initialValue);\r
175                         results.order = graph.getPossibleRelatedValue(expression, sr.DelayExpression_order);\r
176                     } else {\r
177                         results.equation = "";\r
178                         results.delayTime = "";\r
179                         results.order = 1;\r
180                     }\r
181                     return results;\r
182                 }\r
183             });\r
184         } catch (DatabaseException e1) {\r
185             e1.printStackTrace();\r
186         }\r
187         if(results.equation != null)\r
188             data.put("equation", results.equation);\r
189         if(results.delayTime != null)\r
190             data.put("delayTime", results.delayTime);\r
191         if(results.initialValue != null)\r
192             data.put("initialValue", results.initialValue);\r
193         if(results.order != null)\r
194             data.put("order", results.order);\r
195     }\r
196 \r
197     @Override\r
198     public void replaceSelection(String var) {\r
199         if(lastSelectedText != null) {\r
200             IDocument doc = lastSelectedText.getDocument();\r
201             try {\r
202                 Point selection = lastSelectedText.getSelection();\r
203                 doc.replace(selection.x, selection.y, var);\r
204                 lastSelectedText.setSelection(selection.x + var.length());\r
205             } catch (BadLocationException e) {\r
206                 e.printStackTrace();\r
207             }\r
208         }    \r
209     }\r
210 \r
211     @Override\r
212     public void save(Resource expr, Map<String, Object> data) {\r
213         this.expression = expr;\r
214         final String currentEquation = this.equation.getExpression();\r
215         final String currentDelayTime =  this.delayTime.getExpression();\r
216         final String currentInitialValue = this.initialValue.getExpression();\r
217         final Integer currentOrder = this.order.getSelection();\r
218 \r
219         String oldEquation = (String)data.get("equation");\r
220         String oldDelayTime = (String)data.get("delayTime");\r
221         String oldInitialValue = (String)data.get("initialValue");\r
222         Integer oldOrder = (Integer)data.get("order");\r
223 \r
224         if((oldEquation == null || oldDelayTime == null || oldOrder == null || oldInitialValue == null) ||\r
225                 !oldEquation.equals(currentEquation) || !oldDelayTime.equals(currentDelayTime) ||\r
226                 !oldOrder.equals(currentOrder) || !oldInitialValue.equals(currentInitialValue)) {\r
227             // old value was null or value has changed -> Do save\r
228 \r
229             data.putAll(data);\r
230             data.put("equation", currentEquation);\r
231             data.put("delayTime", currentDelayTime);\r
232             data.put("initialValue", currentInitialValue);\r
233             data.put("order", currentOrder);\r
234 \r
235             SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
236                 @Override\r
237                 public void perform(WriteGraph g)\r
238                         throws DatabaseException {\r
239                     SysdynResource sr = SysdynResource.getInstance(g);\r
240                     Layer0 l0 = Layer0.getInstance(g);\r
241 \r
242                     if(!g.isInstanceOf(expression, sr.DelayExpression)) {\r
243                         // Create a new DelayExpression, if the old expression was something else\r
244                         Resource ownerList = OrderedSetUtils.getSingleOwnerList(g, expression);\r
245                         final Resource newExpression = GraphUtils.create2(g, sr.DelayExpression);\r
246                         String arrayRange = g.getPossibleRelatedValue(expression, sr.HasArrayRange, Bindings.STRING);\r
247                         if(arrayRange != null)\r
248                             g.claimLiteral(newExpression, sr.HasArrayRange, arrayRange);\r
249 \r
250                         final Resource variable = g.getSingleObject(ownerList, sr.HasExpressions_Inverse);\r
251                         OrderedSetUtils.replace(g, ownerList, expression, newExpression);\r
252                         g.deny(expression, l0.PartOf);\r
253                         g.claim(newExpression, l0.PartOf, variable);\r
254 \r
255                         VirtualGraph runtime = g.getService(VirtualGraph.class);\r
256                         g.syncRequest(new WriteRequest(runtime) {\r
257                             @Override\r
258                             public void perform(WriteGraph graph) throws DatabaseException {\r
259                                 SysdynResource sr = SysdynResource.getInstance(graph);\r
260                                 if(graph.hasStatement(variable, sr.HasActiveExpression))\r
261                                     graph.deny(variable, sr.HasActiveExpression);\r
262                                 graph.claim(variable, sr.HasActiveExpression, newExpression);\r
263                             }\r
264                         }\r
265                                 );\r
266                         expression = newExpression;\r
267                     }\r
268                     \r
269                     // Claim values\r
270                     g.claimLiteral(expression, sr.DelayExpression_expression, currentEquation);\r
271                     g.claimLiteral(expression, sr.DelayExpression_delayTime, currentDelayTime);\r
272                     g.claimLiteral(expression, sr.DelayExpression_initialValue, currentInitialValue);\r
273                     g.claimLiteral(expression, sr.DelayExpression_order, currentOrder);\r
274                 }\r
275             });\r
276         }\r
277 \r
278     }\r
279 \r
280     @Override\r
281     public void updateData(Map<String, Object> data) {\r
282         if(this.equation != null && this.equation.getExpression() != null)\r
283             data.put("equation", this.equation.getExpression());\r
284         if(this.delayTime != null && this.delayTime.getExpression() != null)\r
285             data.put("delayTime", this.delayTime.getExpression());   \r
286         if(this.initialValue != null && this.initialValue.getExpression() != null)\r
287             data.put("initialValue", this.initialValue.getExpression());   \r
288         if(this.order != null)\r
289             data.put("order", this.order.getSelection());   \r
290     }\r
291 \r
292     @Override\r
293     public void addKeyListener(KeyListener listener) {\r
294         this.equation.getSourceViewer().getTextWidget().addKeyListener(listener);\r
295         this.delayTime.getSourceViewer().getTextWidget().addKeyListener(listener);\r
296         this.initialValue.getSourceViewer().getTextWidget().addKeyListener(listener);\r
297     }\r
298 \r
299     @Override\r
300     public void addModifyListener(ModifyListener listener) {\r
301         this.equation.getSourceViewer().getTextWidget().addModifyListener(listener);\r
302         this.delayTime.getSourceViewer().getTextWidget().addModifyListener(listener);\r
303         this.initialValue.getSourceViewer().getTextWidget().addModifyListener(listener);\r
304     }\r
305 \r
306     @Override\r
307     public void addFocusListener(FocusListener listener) {\r
308         this.equation.getSourceViewer().getTextWidget().addFocusListener(listener);\r
309         this.delayTime.getSourceViewer().getTextWidget().addFocusListener(listener);\r
310         this.initialValue.getSourceViewer().getTextWidget().addFocusListener(listener);\r
311     }\r
312 \r
313     @Override\r
314     public void addVerifyKeyListener(VerifyKeyListener listener) {\r
315         this.equation.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
316         this.delayTime.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
317         this.initialValue.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
318     }\r
319 \r
320 }\r