]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
07b448bfdeab10d0f27308cc37c8ddba0a2bbe7e
[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.awt.event.ActionEvent;\r
15 import java.awt.event.ActionListener;\r
16 import java.util.HashMap;\r
17 import java.util.Map;\r
18 \r
19 import javax.swing.Timer;\r
20 \r
21 import org.eclipse.jface.resource.JFaceResources;\r
22 import org.eclipse.jface.resource.LocalResourceManager;\r
23 import org.eclipse.swt.custom.VerifyKeyListener;\r
24 import org.eclipse.swt.events.FocusListener;\r
25 import org.eclipse.swt.events.ModifyListener;\r
26 import org.eclipse.swt.widgets.Composite;\r
27 import org.eclipse.swt.widgets.Control;\r
28 import org.eclipse.swt.widgets.Table;\r
29 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
30 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
31 import org.simantics.db.ReadGraph;\r
32 import org.simantics.db.Resource;\r
33 import org.simantics.db.exception.DatabaseException;\r
34 import org.simantics.db.layer0.variable.Variable;\r
35 import org.simantics.db.management.ISessionContext;\r
36 import org.simantics.db.request.Read;\r
37 import org.simantics.layer0.Layer0;\r
38 import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
39 import org.simantics.sysdyn.ui.properties.widgets.expressions.AuxiliaryExpression;\r
40 import org.simantics.sysdyn.ui.properties.widgets.expressions.ConstantExpression;\r
41 import org.simantics.sysdyn.ui.properties.widgets.expressions.DelayExpression;\r
42 import org.simantics.sysdyn.ui.properties.widgets.expressions.EmptyExpression;\r
43 import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite;\r
44 import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionWidgetInput;\r
45 import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;\r
46 import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupExpression;\r
47 import org.simantics.sysdyn.ui.properties.widgets.expressions.ParameterExpression;\r
48 import org.simantics.sysdyn.ui.properties.widgets.expressions.StockExpression;\r
49 import org.simantics.sysdyn.ui.properties.widgets.expressions.WithLookupExpression;\r
50 import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
51 import org.simantics.ui.SimanticsUI;\r
52 import org.simantics.utils.ui.AdaptionUtils;\r
53 \r
54 /**\r
55  * Widget for displaying an expression. Widget creates the IExpression for displaying\r
56  * properties for each expression type and adds validation, saving and other services\r
57  * to the active IExpression.\r
58  * \r
59  * @author Teemu Lempinen\r
60  * @author Tuomas Miettinen\r
61  *\r
62  */\r
63 public class ExpressionWidget implements Widget {\r
64 \r
65     private ExpressionWidgetInput input;\r
66         private Resource expr;\r
67         private Variable variable;\r
68         private Composite parent;\r
69         private Map<String, Object> data;\r
70         private IExpression expression;\r
71         private ModifyListener modifyListener;\r
72         private FocusListener focusListener;\r
73         private Table variableTable;\r
74         private VerifyKeyListener verifyKeyListener;\r
75     private Timer validationTimer;\r
76     private static int VALIDATION_DELAY_TIME = 500;\r
77     private final LocalResourceManager resourceManager;\r
78     \r
79     /**\r
80      * Create a new expression widget\r
81      * @param parent\r
82      * @param support\r
83      * @param style\r
84      */\r
85     public ExpressionWidget(Composite parent, WidgetSupport support, int style) {\r
86                 support.register(this);\r
87                 this.parent = parent;\r
88                 if (parent instanceof ExpressionComposite) {\r
89                     ExpressionComposite expressionComposite = (ExpressionComposite)parent;\r
90                     expressionComposite.setExpressionWidget(this);\r
91                 }\r
92                 this.data = new HashMap<String, Object>();\r
93                 \r
94                 // Create a ResourceManager to dispose images when the widget is disposed.\r
95         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this.parent);\r
96         \r
97                 /*\r
98                  *  Create a validation timer for expression fields. Validation timer\r
99                  *  validates the field as the modeler is typing an expression \r
100                  */\r
101                 validationTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {\r
102 \r
103             @Override\r
104             public void actionPerformed(ActionEvent e) {\r
105                 if(variableTable == null || variableTable.isDisposed())\r
106                         return;\r
107                         variableTable.getDisplay().asyncExec(new Runnable() {\r
108                                 \r
109                                 @Override\r
110                                 public void run() {\r
111                                         validateFields();\r
112                                 }\r
113                         });\r
114             }\r
115         });\r
116                 validationTimer.setRepeats(false);\r
117         }\r
118    \r
119         @Override\r
120         public void setInput(ISessionContext context, Object input) {  \r
121             // Update IExpression based on the newly selected expression\r
122                 ExpressionWidgetInput i =  AdaptionUtils.adaptToSingle(input, ExpressionWidgetInput.class);\r
123                 this.input = i;\r
124                 expr = i.expression;\r
125                 variable = i.variable;\r
126                 ExpressionType et = ExpressionTypes.getExpressionType(expr);\r
127                 displayExpression(et.toString(), true);\r
128         }\r
129 \r
130         /**\r
131          * Displays IExpression corresponding to expressionType.\r
132          * @param expressionType Expression type\r
133          * @param original Is the displayed expression for a newly selected expression (true) or did the\r
134          * expression change its type (false) \r
135          */\r
136         public void displayExpression(String expressionType, boolean original) {\r
137                 if(expressionType == null || parent.isDisposed()) {\r
138                         return;\r
139                 }\r
140 \r
141                 // Get up-to-date data to data-map\r
142                 if(this.expression != null) expression.updateData(data);\r
143                 \r
144                 // Create the new expression\r
145                 ExpressionType et = ExpressionType.valueOf(expressionType);\r
146                 IExpression exp = null;\r
147                 switch (et) {\r
148                 case Auxiliary: \r
149                         exp = new AuxiliaryExpression(input); break;\r
150                 case Parameter: \r
151                         exp = new ParameterExpression(input); break;\r
152                 case Constant: \r
153                         exp = new ConstantExpression(input); break;\r
154                 case Lookup: \r
155                         exp = new LookupExpression(); break;\r
156                 case WithLookup: \r
157                         exp = new WithLookupExpression(input); break;\r
158                 case Stock: \r
159                         exp = new StockExpression(input); break;\r
160                 case Delay: \r
161                         exp = new DelayExpression(input); break;\r
162                 default: \r
163                         exp = new EmptyExpression();\r
164                 }\r
165 \r
166                 if (exp != null) {\r
167                     // If expression was created, remove the old one\r
168                         for(Control c : parent.getChildren()) {\r
169                                 c.dispose();\r
170                         } \r
171 \r
172                         // If a completely new expression was selected, read data\r
173                         if(original) \r
174                                 exp.readData(expr, data);\r
175 \r
176                         // Create the visual representation of the expression type\r
177                         exp.createExpressionFields(parent, data, variableTable);\r
178                         \r
179                         // Add listeners\r
180                         if(modifyListener != null)\r
181                                 exp.addModifyListener(modifyListener);\r
182                         if(focusListener != null)\r
183                                 exp.addFocusListener(focusListener);\r
184                         if(verifyKeyListener != null)\r
185                                 exp.addVerifyKeyListener(verifyKeyListener);\r
186                         this.expression = exp;\r
187                         this.parent.layout();\r
188                         validateFieldsTimed();\r
189 \r
190                         save();\r
191                 }  \r
192         }\r
193 \r
194         /**\r
195          * Get current IExpression\r
196          * @return current IExpression\r
197          */\r
198         public IExpression getExpression() {\r
199                 return expression;\r
200         }\r
201 \r
202         /**\r
203          * Set the variable table that contains information about variables that are connected \r
204          * to this expression\r
205          * @param table\r
206          */\r
207         public void setVariableTable(Table table) {\r
208                 this.variableTable = table;\r
209         }\r
210 \r
211         /**\r
212          * Set timed field validation with default delay time\r
213          */\r
214     public void validateFieldsTimed() {         \r
215         validateFieldsTimed(VALIDATION_DELAY_TIME);\r
216     }\r
217     \r
218     /**\r
219      * Set timed field validation\r
220      * @param delay Delay time for validation\r
221      */\r
222     public void validateFieldsTimed(int delay) {\r
223         validationTimer.setDelay(delay);\r
224         if(!validationTimer.isRunning())\r
225             validationTimer.start();\r
226         else\r
227             validationTimer.restart();\r
228     }\r
229     \r
230     /**\r
231      * Validates expression fields in current IExpression\r
232      */\r
233         public void validateFields() {\r
234                 if(this.variableTable == null) return;\r
235         \r
236                 try {\r
237                     // Find the variable for this experession\r
238                         Resource variable = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
239 \r
240                                 @Override\r
241                                 public Resource perform(ReadGraph graph) throws DatabaseException {\r
242                                         Layer0 l0 = Layer0.getInstance(graph);\r
243                                         return graph.getPossibleObject(expr, l0.PartOf);\r
244                                 }\r
245                         });\r
246                         // Validate the variable\r
247                         if(variable != null)\r
248                                 ExpressionUtils.validateExpressionFields(variable, expression, variableTable, resourceManager);\r
249                 } catch (DatabaseException e) {\r
250                         e.printStackTrace();\r
251                 }\r
252 \r
253         }\r
254 \r
255         public void addModifyListener(ModifyListener listener) {\r
256                 this.modifyListener = listener;\r
257         }\r
258 \r
259         public void addVerifyKeyListener(VerifyKeyListener listener) {\r
260                 this.verifyKeyListener = listener;\r
261         }\r
262         \r
263         public void addFocusListener(FocusListener listener) {\r
264                 this.focusListener = listener;\r
265         }\r
266 \r
267         public void save() {\r
268                 if(this.expression != null)\r
269                         this.expression.save(expr, data);\r
270         }\r
271 \r
272 }\r