]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
0fa9e8bc06c02769b6aeb90aee3723768f8c1e45
[simantics/sysdyn.git] /
1 package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
2 \r
3 import java.awt.BasicStroke;\r
4 import java.awt.Frame;\r
5 import java.awt.event.ActionEvent;\r
6 import java.awt.event.ActionListener;\r
7 import java.awt.geom.Point2D;\r
8 import java.io.StringReader;\r
9 import java.util.ArrayList;\r
10 import java.util.Arrays;\r
11 import java.util.List;\r
12 import java.util.Map;\r
13 \r
14 import javax.swing.Timer;\r
15 \r
16 import org.eclipse.jface.layout.GridDataFactory;\r
17 import org.eclipse.jface.layout.GridLayoutFactory;\r
18 import org.eclipse.jface.text.BadLocationException;\r
19 import org.eclipse.jface.text.IDocument;\r
20 import org.eclipse.swt.SWT;\r
21 import org.eclipse.swt.awt.SWT_AWT;\r
22 import org.eclipse.swt.custom.VerifyKeyListener;\r
23 import org.eclipse.swt.events.FocusAdapter;\r
24 import org.eclipse.swt.events.FocusEvent;\r
25 import org.eclipse.swt.events.FocusListener;\r
26 import org.eclipse.swt.events.KeyListener;\r
27 import org.eclipse.swt.events.ModifyEvent;\r
28 import org.eclipse.swt.events.ModifyListener;\r
29 import org.eclipse.swt.graphics.Point;\r
30 import org.eclipse.swt.widgets.Composite;\r
31 import org.eclipse.swt.widgets.Label;\r
32 import org.jfree.chart.ChartFactory;\r
33 import org.jfree.chart.ChartPanel;\r
34 import org.jfree.chart.JFreeChart;\r
35 import org.jfree.chart.plot.PlotOrientation;\r
36 import org.jfree.data.xy.XYDataset;\r
37 import org.jfree.data.xy.XYSeries;\r
38 import org.jfree.data.xy.XYSeriesCollection;\r
39 import org.simantics.db.ReadGraph;\r
40 import org.simantics.db.Resource;\r
41 import org.simantics.db.WriteGraph;\r
42 import org.simantics.db.common.request.WriteRequest;\r
43 import org.simantics.db.exception.DatabaseException;\r
44 import org.simantics.db.procedure.Listener;\r
45 import org.simantics.db.request.Read;\r
46 import org.simantics.layer0.Layer0;\r
47 import org.simantics.sysdyn.SysdynResource;\r
48 import org.simantics.sysdyn.representation.Auxiliary;\r
49 import org.simantics.sysdyn.tableParser.ParseException;\r
50 import org.simantics.sysdyn.tableParser.TableParser;\r
51 import org.simantics.sysdyn.tableParser.Token;\r
52 import org.simantics.ui.SimanticsUI;\r
53 \r
54 public class WithLookupExpression implements IExpression {\r
55 \r
56     private ExpressionField expression;\r
57     private ExpressionField lookup;\r
58     private ExpressionField lastSelectedText = expression;\r
59     private Timer updateChartTimer;\r
60 \r
61     private ChartPanel smallPanel;\r
62     private Frame smallFrame;\r
63 \r
64     private Resource variable;\r
65 \r
66     public WithLookupExpression(Resource variable) {\r
67         this.variable = variable;\r
68     }\r
69 \r
70     @Override\r
71     public void createExpressionFields(Composite parent, final Map<String, Object> data) {\r
72         GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parent);\r
73 \r
74         updateChartTimer = new Timer(1000, new ActionListener() {\r
75 \r
76             @Override\r
77             public void actionPerformed(ActionEvent e) {\r
78                 updateChart();\r
79             }\r
80         });\r
81         updateChartTimer.setRepeats(false);\r
82 \r
83         String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
84         String lookupTable = data.get("lookup") != null ? (String)data.get("lookup") : "";\r
85 \r
86         Label l = new Label(parent, SWT.NONE);\r
87         l.setText("With\nLookup");\r
88 \r
89         expression = new ExpressionField(parent, SWT.BORDER);\r
90         expression.setExpression(equation);\r
91         GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
92 \r
93         expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
94 \r
95             @Override\r
96             public void focusLost(FocusEvent e) {\r
97                 lastSelectedText = expression;\r
98             }\r
99         });\r
100 \r
101         Composite chartContainer = new Composite(parent, SWT.NONE);\r
102         createChart(chartContainer, data);\r
103 \r
104 \r
105         l = new Label(parent, SWT.NONE);\r
106         l.setText("Lookup\ntable");\r
107 \r
108         lookup = new ExpressionField(parent, SWT.BORDER);\r
109         lookup.setExpression(lookupTable);\r
110         GridDataFactory.fillDefaults().grab(true, true).applyTo(lookup);\r
111 \r
112         lookup.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
113 \r
114             @Override\r
115             public void focusLost(FocusEvent e) {\r
116                 lastSelectedText = lookup;\r
117                 save(variable, data);\r
118             }\r
119         });\r
120 \r
121         lookup.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
122 \r
123             @Override\r
124             public void modifyText(ModifyEvent e) {\r
125                 if(!updateChartTimer.isRunning())\r
126                     updateChartTimer.start();\r
127                 else\r
128                     updateChartTimer.restart();\r
129             }\r
130         });\r
131 \r
132 \r
133         SimanticsUI.getSession().asyncRequest(new Read<String>() {\r
134 \r
135             @Override\r
136             public String perform(ReadGraph graph) throws DatabaseException {\r
137                 SysdynResource sr = SysdynResource.getInstance(graph);\r
138                 Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
139                 String result = "";\r
140                 if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
141                     result = graph.getRelatedValue(expression, sr.HasLookup);\r
142                 }\r
143                 return result;\r
144             }\r
145         }, new Listener<String>() {\r
146 \r
147             @Override\r
148             public void exception(Throwable t) {\r
149                 t.printStackTrace();\r
150             }\r
151 \r
152             @Override\r
153             public void execute(final String result) {\r
154                 if(lookup != null)\r
155                     lookup.getDisplay().asyncExec(new Runnable() {\r
156 \r
157                         @Override\r
158                         public void run() {\r
159                             lookup.setExpression(result);                            \r
160                         }\r
161                     });\r
162                 updateChart();\r
163             }\r
164 \r
165             @Override\r
166             public boolean isDisposed() {\r
167                 if(lookup != null && !lookup.isDisposed()) {\r
168                     return false;\r
169                 }\r
170                 return true;\r
171             }\r
172         });\r
173 \r
174         updateChart();\r
175     }\r
176 \r
177     @Override\r
178     public void focus() {\r
179         if(this.lastSelectedText != null) this.lastSelectedText.focus();        \r
180     }\r
181 \r
182     @Override\r
183     public List<ExpressionField> getExpressionFields() {\r
184         return Arrays.asList(this.expression, this.lookup);\r
185     }\r
186 \r
187     @Override\r
188     public void readData(final Resource variable, Map<String, Object> data) {\r
189 \r
190         class Auxiliary {\r
191             String equation, lookup;\r
192         }\r
193 \r
194         Auxiliary results = null;\r
195 \r
196         if (variable != null && data.get("equation") == null) {\r
197             try {\r
198                 results = SimanticsUI.getSession().syncRequest(new Read<Auxiliary>() {\r
199 \r
200                     @Override\r
201                     public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
202                         Auxiliary results = new Auxiliary();\r
203                         SysdynResource sr = SysdynResource.getInstance(graph);\r
204                         Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
205                         if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
206                             results.equation = graph.getRelatedValue(expression, sr.HasEquation);\r
207                             results.lookup = graph.getRelatedValue(expression, sr.HasLookup);\r
208                         } else {\r
209                             results.equation = "";\r
210                             results.lookup = "";\r
211                         }\r
212                         return results;\r
213                     }\r
214                 });\r
215             } catch (DatabaseException e1) {\r
216                 e1.printStackTrace();\r
217             }\r
218             data.put("equation", results.equation);\r
219             data.put("lookup", results.lookup);\r
220         }\r
221 \r
222     }\r
223 \r
224     @Override\r
225     public void replaceSelection(String var) {\r
226         if(lastSelectedText != null) {\r
227             IDocument doc = lastSelectedText.getDocument();\r
228             try {\r
229                 Point selection = lastSelectedText.getSelection();\r
230                 doc.replace(selection.x, selection.y, var);\r
231                 lastSelectedText.setSelection(selection.x + var.length());\r
232             } catch (BadLocationException e) {\r
233                 e.printStackTrace();\r
234             }\r
235         }        \r
236     }\r
237 \r
238     @Override\r
239     public void save(final Resource variable, Map<String, Object> data) {\r
240         final String currentExpression = expression.getExpression();\r
241         final String currentLookupTable = lookup.getExpression();\r
242         String oldExpression = (String)data.get("equation");\r
243         String oldLookupTable = (String)data.get("lookup");\r
244 \r
245         if(oldExpression == null || oldLookupTable == null ||\r
246                 (currentExpression != null && currentLookupTable != null\r
247                         && (!currentExpression.equals(oldExpression) || \r
248                                 !currentLookupTable.equals(oldLookupTable)))) {\r
249             data.putAll(data);\r
250             data.put("equation", currentExpression);\r
251             data.put("lookup", currentLookupTable);\r
252             SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
253                 @Override\r
254                 public void perform(WriteGraph g)\r
255                 throws DatabaseException {\r
256                     SysdynResource sr = SysdynResource.getInstance(g);\r
257                     Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
258                     Layer0 l0 = Layer0.getInstance(g);\r
259                     if(expression != null && !g.isInstanceOf(expression, sr.WithLookupExpression)) {\r
260                         g.deny(variable, sr.HasExpression);\r
261                         expression = null;\r
262                     }\r
263                     if(expression == null) {\r
264                         expression = g.newResource();\r
265                         g.claim(expression, l0.InstanceOf, null, sr.WithLookupExpression);\r
266                         g.claim(variable, sr.HasExpression, expression);\r
267                         g.claimLiteral(expression, sr.HasMinX, 0.0);\r
268                         g.claimLiteral(expression, sr.HasMaxX, 10.0);\r
269                         g.claimLiteral(expression, sr.HasMinY, 0.0);\r
270                         g.claimLiteral(expression, sr.HasMaxY, 10.0);\r
271 \r
272                     } \r
273                     g.claimLiteral(expression, sr.HasEquation, currentExpression);\r
274                     g.claimLiteral(expression, sr.HasLookup, currentLookupTable);\r
275                 }\r
276             });\r
277         }\r
278 \r
279     }\r
280 \r
281     @Override\r
282     public void updateData(Map<String, Object> data) {\r
283         if(this.expression != null && this.expression.getExpression() != null)\r
284             data.put("equation", this.expression.getExpression());\r
285         if(this.lookup != null && this.lookup.getExpression() != null)\r
286             data.put("lookup", this.lookup.getExpression());   \r
287     }\r
288 \r
289     @Override\r
290     public void addKeyListener(KeyListener listener) {\r
291         this.expression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
292         this.lookup.getSourceViewer().getTextWidget().addKeyListener(listener);\r
293     }\r
294     \r
295         @Override\r
296         public void addVerifyKeyListener(VerifyKeyListener listener) {\r
297                 this.expression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
298                 this.lookup.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
299         }\r
300 \r
301     @Override\r
302     public void addModifyListener(ModifyListener listener) {\r
303         this.expression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
304         this.lookup.getSourceViewer().getTextWidget().addModifyListener(listener);\r
305     }\r
306 \r
307     @Override\r
308     public void addFocusListener(FocusListener listener) {\r
309         this.expression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
310         this.lookup.getSourceViewer().getTextWidget().addFocusListener(listener);\r
311     }\r
312 \r
313     private void createChart(Composite composite, final Map<String, Object> data) {\r
314         GridLayoutFactory.fillDefaults().applyTo(composite);\r
315         GridDataFactory.fillDefaults().span(1, 2).hint(150, SWT.DEFAULT).applyTo(composite);\r
316         final Composite chartComposite = new Composite(composite, \r
317                 SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
318         GridDataFactory.fillDefaults().grab(true, true).applyTo(chartComposite);\r
319         smallFrame = SWT_AWT.new_Frame(chartComposite);\r
320 \r
321         XYDataset dataset = new XYSeriesCollection(new XYSeries("Lookup Table"));\r
322         JFreeChart chart = createChart(dataset);\r
323         smallPanel = new ChartPanel(chart);\r
324         smallFrame.add(smallPanel);\r
325 \r
326     }\r
327 \r
328     private static JFreeChart createChart(XYDataset dataset) {\r
329         JFreeChart chart = ChartFactory.createXYLineChart(\r
330                 null,\r
331                 null,\r
332                 null,\r
333                 dataset,\r
334                 PlotOrientation.VERTICAL,\r
335                 true,\r
336                 true,\r
337                 false\r
338         );\r
339         chart.removeLegend();\r
340         chart.getXYPlot().getDomainAxis().setTickLabelsVisible(true);\r
341         chart.getXYPlot().getDomainAxis().setAxisLineVisible(false);\r
342         chart.getXYPlot().getDomainAxis().setTickMarksVisible(true);\r
343         chart.getXYPlot().getRangeAxis().setTickLabelsVisible(true);\r
344         chart.getXYPlot().getRangeAxis().setAxisLineVisible(false);\r
345         chart.getXYPlot().getRangeAxis().setTickMarksVisible(true);\r
346         chart.getXYPlot().getRenderer().setSeriesStroke(0, new BasicStroke(3.0f));\r
347         return chart;\r
348     }\r
349 \r
350     private void updateChart() {\r
351         ArrayList<Point2D> dataPoints = new ArrayList<Point2D>();\r
352         TableParser parser = new TableParser(new StringReader(""));\r
353         parser.ReInit(new StringReader(lookup.getExpression()));\r
354         try {\r
355             parser.table();\r
356             ArrayList<Token> xTokens = parser.getXTokens();\r
357             ArrayList<Token> yTokens = parser.getYTokens();\r
358             for(int i = 0; i < xTokens.size(); i++) {\r
359                 dataPoints.add(new Point2D.Double(\r
360                         Double.parseDouble(xTokens.get(i).image), \r
361                         Double.parseDouble(yTokens.get(i).image)));\r
362             }\r
363         } catch (ParseException e1) {\r
364 //            e1.printStackTrace();\r
365             return;\r
366         }\r
367 \r
368         XYSeries series = new XYSeries("Lookup Table");\r
369         for(Point2D point : dataPoints) {\r
370             series.add(point.getX(), point.getY());\r
371         }\r
372         XYSeriesCollection dataset =  new XYSeriesCollection(series);\r
373         smallPanel.getChart().getXYPlot().setDataset(dataset);\r
374     }\r
375 \r
376 \r
377 }\r