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