]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
2d0cb58d077c624ade9f338a04f65dfe5434aff4
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 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.functions;\r
13 \r
14 import java.awt.event.ActionEvent;\r
15 import java.awt.event.ActionListener;\r
16 import java.io.StringReader;\r
17 \r
18 import javax.swing.Timer;\r
19 \r
20 import org.eclipse.jface.layout.GridDataFactory;\r
21 import org.eclipse.swt.SWT;\r
22 import org.eclipse.swt.custom.StyledText;\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.ModifyEvent;\r
27 import org.eclipse.swt.events.ModifyListener;\r
28 import org.eclipse.swt.events.VerifyEvent;\r
29 import org.eclipse.swt.widgets.Composite;\r
30 import org.eclipse.swt.widgets.Listener;\r
31 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
32 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
33 import org.simantics.db.ReadGraph;\r
34 import org.simantics.db.Resource;\r
35 import org.simantics.db.WriteGraph;\r
36 import org.simantics.db.common.request.WriteRequest;\r
37 import org.simantics.db.exception.DatabaseException;\r
38 import org.simantics.db.management.ISessionContext;\r
39 import org.simantics.db.request.Read;\r
40 import org.simantics.sysdyn.SysdynResource;\r
41 import org.simantics.sysdyn.modelParser.ModelParser;\r
42 import org.simantics.sysdyn.modelParser.ParseException;\r
43 import org.simantics.sysdyn.modelParser.Token;\r
44 import org.simantics.sysdyn.modelParser.TokenMgrError;\r
45 import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
46 import org.simantics.sysdyn.ui.utils.SyntaxError;\r
47 import org.simantics.ui.SimanticsUI;\r
48 import org.simantics.ui.utils.AdaptionUtils;\r
49 \r
50 public class FunctionCodeWidget implements Widget {\r
51         \r
52         private ExpressionField modelicaCode;\r
53         private Resource function;\r
54         \r
55     private Timer updateChartTimer;\r
56     private static int VALIDATION_DELAY_TIME = 500;\r
57         \r
58         public FunctionCodeWidget(Composite parent, WidgetSupport support, int style) {\r
59                 support.register(this);\r
60         modelicaCode = new ExpressionField(parent, SWT.BORDER, null, false);\r
61         GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode);\r
62         \r
63 \r
64         // Support shift+enter for line change\r
65         modelicaCode.getSourceViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {\r
66 \r
67                 @Override\r
68                 public void verifyKey(VerifyEvent event) {\r
69                         if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) {\r
70                                 if((event.stateMask & SWT.SHIFT) == 0) {\r
71                                         event.doit = false;\r
72                                         Listener[] listeners = modelicaCode.getSourceViewer().getTextWidget().getListeners(SWT.FocusOut);\r
73                                         for(Listener l : listeners) {\r
74                                                 modelicaCode.getSourceViewer().getTextWidget().removeListener(SWT.FocusOut, l);\r
75                                         }\r
76                                         ((StyledText)event.widget).getParent().forceFocus();\r
77                                         save();\r
78                                         for(Listener l : listeners) {\r
79                                                 modelicaCode.getSourceViewer().getTextWidget().addListener(SWT.FocusOut, l);\r
80                                         }\r
81                                 \r
82                                 }\r
83                         }\r
84                 }\r
85         });\r
86         \r
87         \r
88         modelicaCode.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
89 \r
90                         @Override\r
91                         public void modifyText(ModifyEvent e) {\r
92                                 validateFieldsTimed();\r
93                         }\r
94                 });\r
95         \r
96         modelicaCode.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
97                         @Override\r
98                         public void focusLost(FocusEvent e) {\r
99                                 save();\r
100                         }\r
101                 });\r
102                 \r
103         \r
104         updateChartTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {\r
105 \r
106             @Override\r
107             public void actionPerformed(ActionEvent e) {\r
108                 if(modelicaCode == null || modelicaCode.isDisposed())\r
109                         return;\r
110                 modelicaCode.getDisplay().asyncExec(new Runnable() {\r
111                                 \r
112                                 @Override\r
113                                 public void run() {\r
114                                         validate();\r
115                                 }\r
116                         });\r
117             }\r
118         });\r
119         updateChartTimer.setRepeats(false);\r
120         }\r
121 \r
122         @Override\r
123         public void setInput(ISessionContext context, Object input) {\r
124                 function = AdaptionUtils.adaptToSingle(input, Resource.class);\r
125                 \r
126                 try {\r
127                         String code = context.getSession().syncRequest(new Read<String>() {\r
128 \r
129                                 @Override\r
130                                 public String perform(ReadGraph graph) throws DatabaseException {\r
131                                         String code = graph.getPossibleRelatedValue(\r
132                                                         function, SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionCode);\r
133                                         return code;\r
134                                 }\r
135                                 \r
136                         });\r
137                         if(code != null) {\r
138                                 modelicaCode.setExpression(code);\r
139                                 validate();\r
140                         }\r
141                 } catch (DatabaseException e) {\r
142                         e.printStackTrace();\r
143                 }\r
144         }\r
145         \r
146         \r
147     public void validateFieldsTimed() {         \r
148         validateFieldsTimed(VALIDATION_DELAY_TIME);\r
149     }\r
150     \r
151     public void validateFieldsTimed(int delay) {\r
152         updateChartTimer.setDelay(delay);\r
153         if(!updateChartTimer.isRunning())\r
154             updateChartTimer.start();\r
155         else\r
156             updateChartTimer.restart();\r
157     }\r
158     \r
159     public void validate() {\r
160         modelicaCode.resetAnnotations();\r
161         String code = modelicaCode.getExpression();\r
162         StringReader sr = new StringReader(code);\r
163         ModelParser modelParser = new ModelParser(sr);\r
164         try {\r
165                         modelParser.parse_composition();\r
166                 } catch (ParseException e1) {\r
167                         Token token = e1.currentToken;\r
168                         modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn));\r
169                 } catch (TokenMgrError err) {\r
170                         String message = err.getMessage();\r
171                         String line = message.substring(0, message.indexOf(","));\r
172                         line = line.substring(line.lastIndexOf(" ") + 1);\r
173                         String column = message.substring(message.indexOf(",") + 1, message.indexOf("."));\r
174                         column = column.substring(column.lastIndexOf(" ") + 1);\r
175                         try {\r
176                                 Integer endLine = Integer.parseInt(line);\r
177                                 Integer endColumn = Integer.parseInt(column);\r
178                                 Token token = modelParser.token;\r
179                                 modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn));\r
180                         } catch (NumberFormatException e) {\r
181                                 \r
182                         }\r
183                         \r
184                 }\r
185         }\r
186     \r
187     private void save() {\r
188         final String code = modelicaCode.getExpression();\r
189         SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
190                         \r
191                         @Override\r
192                         public void perform(WriteGraph graph) throws DatabaseException {\r
193                                 graph.claimLiteral(\r
194                                                 function, \r
195                                                 SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionCode, \r
196                                                 code);\r
197                         }\r
198                 });\r
199     }\r
200 \r
201 }\r