1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.properties.widgets;
\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
19 import javax.swing.Timer;
\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
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
59 * @author Teemu Lempinen
\r
60 * @author Tuomas Miettinen
\r
63 public class ExpressionWidget implements Widget {
\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
80 * Create a new expression widget
\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
92 this.data = new HashMap<String, Object>();
\r
94 // Create a ResourceManager to dispose images when the widget is disposed.
\r
95 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this.parent);
\r
98 * Create a validation timer for expression fields. Validation timer
\r
99 * validates the field as the modeler is typing an expression
\r
101 validationTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {
\r
104 public void actionPerformed(ActionEvent e) {
\r
105 if(variableTable == null || variableTable.isDisposed())
\r
107 variableTable.getDisplay().asyncExec(new Runnable() {
\r
110 public void run() {
\r
116 validationTimer.setRepeats(false);
\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
124 expr = i.expression;
\r
125 variable = i.variable;
\r
126 ExpressionType et = ExpressionTypes.getExpressionType(expr);
\r
127 displayExpression(et.toString(), true);
\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
136 public void displayExpression(String expressionType, boolean original) {
\r
137 if(expressionType == null || parent.isDisposed()) {
\r
141 // Get up-to-date data to data-map
\r
142 if(this.expression != null) expression.updateData(data);
\r
144 // Create the new expression
\r
145 ExpressionType et = ExpressionType.valueOf(expressionType);
\r
146 IExpression exp = null;
\r
149 exp = new AuxiliaryExpression(input); break;
\r
151 exp = new ParameterExpression(input); break;
\r
153 exp = new ConstantExpression(input); break;
\r
155 exp = new LookupExpression(); break;
\r
157 exp = new WithLookupExpression(input); break;
\r
159 exp = new StockExpression(input); break;
\r
161 exp = new DelayExpression(input); break;
\r
163 exp = new EmptyExpression();
\r
167 // If expression was created, remove the old one
\r
168 for(Control c : parent.getChildren()) {
\r
172 // If a completely new expression was selected, read data
\r
174 exp.readData(expr, data);
\r
176 // Create the visual representation of the expression type
\r
177 exp.createExpressionFields(parent, data, variableTable);
\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
195 * Get current IExpression
\r
196 * @return current IExpression
\r
198 public IExpression getExpression() {
\r
203 * Set the variable table that contains information about variables that are connected
\r
204 * to this expression
\r
207 public void setVariableTable(Table table) {
\r
208 this.variableTable = table;
\r
212 * Set timed field validation with default delay time
\r
214 public void validateFieldsTimed() {
\r
215 validateFieldsTimed(VALIDATION_DELAY_TIME);
\r
219 * Set timed field validation
\r
220 * @param delay Delay time for validation
\r
222 public void validateFieldsTimed(int delay) {
\r
223 validationTimer.setDelay(delay);
\r
224 if(!validationTimer.isRunning())
\r
225 validationTimer.start();
\r
227 validationTimer.restart();
\r
231 * Validates expression fields in current IExpression
\r
233 public void validateFields() {
\r
234 if(this.variableTable == null) return;
\r
237 // Find the variable for this experession
\r
238 Resource variable = SimanticsUI.getSession().syncRequest(new Read<Resource>() {
\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
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
255 public void addModifyListener(ModifyListener listener) {
\r
256 this.modifyListener = listener;
\r
259 public void addVerifyKeyListener(VerifyKeyListener listener) {
\r
260 this.verifyKeyListener = listener;
\r
263 public void addFocusListener(FocusListener listener) {
\r
264 this.focusListener = listener;
\r
267 public void save() {
\r
268 if(this.expression != null)
\r
269 this.expression.save(expr, data);
\r