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