import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.management.ISessionContext;\r
import org.simantics.layer0.Layer0;\r
-import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.manager.FunctionUtils;\r
import org.simantics.sysdyn.ui.properties.widgets.FunctionLabelFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.properties.widgets.functions.FunctionCodeWidget;\r
\r
public class FunctionTab extends LabelPropertyTabContributor {\r
+ \r
+ ExpressionField modelicaCode;\r
\r
@Override\r
public void createControls(Composite body, IWorkbenchSite site,\r
\r
Label startLabel = new Label(modelicaGroup, support, SWT.NONE);\r
startLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, false));\r
+ \r
+ new FunctionCodeWidget(modelicaGroup, support, SWT.BORDER);\r
+ /*\r
TrackedText modelicaCode = new TrackedText(modelicaGroup, support, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.WRAP);\r
modelicaCode.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HasModelicaFunctionCode));\r
modelicaCode.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HasModelicaFunctionCode));\r
});\r
\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode.getWidget());\r
+ */\r
Label endLabel = new Label(modelicaGroup, support, SWT.NONE);\r
endLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, true));\r
\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.functions;\r
+\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.io.StringReader;\r
+\r
+import javax.swing.Timer;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.VerifyEvent;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelParser.ModelParser;\r
+import org.simantics.sysdyn.modelParser.ParseException;\r
+import org.simantics.sysdyn.modelParser.Token;\r
+import org.simantics.sysdyn.modelParser.TokenMgrError;\r
+import org.simantics.sysdyn.manager.FunctionUtils;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+\r
+public class FunctionCodeWidget implements Widget {\r
+ \r
+ private ExpressionField modelicaCode;\r
+ private Resource function;\r
+ \r
+ private Timer updateChartTimer;\r
+ private static int VALIDATION_DELAY_TIME = 500;\r
+ \r
+ public FunctionCodeWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+ \r
+ modelicaCode = new ExpressionField(parent, SWT.BORDER);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode);\r
+ \r
+\r
+ // Support shift+enter for line change\r
+ modelicaCode.getSourceViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {\r
+\r
+ @Override\r
+ public void verifyKey(VerifyEvent event) {\r
+ if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) {\r
+ if((event.stateMask & SWT.SHIFT) == 0) {\r
+ event.doit = false;\r
+ Listener[] listeners = modelicaCode.getSourceViewer().getTextWidget().getListeners(SWT.FocusOut);\r
+ for(Listener l : listeners) {\r
+ modelicaCode.getSourceViewer().getTextWidget().removeListener(SWT.FocusOut, l);\r
+ }\r
+ ((StyledText)event.widget).getParent().forceFocus();\r
+ save();\r
+ for(Listener l : listeners) {\r
+ modelicaCode.getSourceViewer().getTextWidget().addListener(SWT.FocusOut, l);\r
+ }\r
+ \r
+ }\r
+ }\r
+ }\r
+ });\r
+ \r
+ \r
+ modelicaCode.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ validateFieldsTimed();\r
+ }\r
+ });\r
+ \r
+ modelicaCode.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ save();\r
+ }\r
+ });\r
+ \r
+ \r
+ updateChartTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {\r
+\r
+ @Override\r
+ public void actionPerformed(ActionEvent e) {\r
+ if(modelicaCode == null || modelicaCode.isDisposed())\r
+ return;\r
+ modelicaCode.getDisplay().asyncExec(new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ validate();\r
+ }\r
+ });\r
+ }\r
+ });\r
+ updateChartTimer.setRepeats(false);\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ function = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+ \r
+ try {\r
+ String code = context.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ String code = graph.getPossibleRelatedValue(\r
+ function, SysdynResource.getInstance(graph).HasModelicaFunctionCode);\r
+ return code;\r
+ }\r
+ \r
+ });\r
+ if(code != null) {\r
+ modelicaCode.setExpression(code);\r
+ validate();\r
+ }\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ \r
+ public void validateFieldsTimed() { \r
+ validateFieldsTimed(VALIDATION_DELAY_TIME);\r
+ }\r
+ \r
+ public void validateFieldsTimed(int delay) {\r
+ updateChartTimer.setDelay(delay);\r
+ if(!updateChartTimer.isRunning())\r
+ updateChartTimer.start();\r
+ else\r
+ updateChartTimer.restart();\r
+ }\r
+ \r
+ public void validate() {\r
+ modelicaCode.resetAnnotations();\r
+ String code = modelicaCode.getExpression();\r
+ StringReader sr = new StringReader(code);\r
+ ModelParser modelParser = new ModelParser(sr);\r
+ try {\r
+ modelParser.parse_composition();\r
+ } catch (ParseException e1) {\r
+ Token token = e1.currentToken;\r
+ modelicaCode.setSyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+ } catch (TokenMgrError err) {\r
+ String message = err.getMessage();\r
+ String line = message.substring(0, message.indexOf(","));\r
+ line = line.substring(line.lastIndexOf(" ") + 1);\r
+ String column = message.substring(message.indexOf(",") + 1, message.indexOf("."));\r
+ column = column.substring(column.lastIndexOf(" ") + 1);\r
+ try {\r
+ Integer endLine = Integer.parseInt(line);\r
+ Integer endColumn = Integer.parseInt(column);\r
+ Token token = modelParser.token;\r
+ modelicaCode.setSyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn);\r
+ } catch (NumberFormatException e) {\r
+ \r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ private void save() {\r
+ final String code = modelicaCode.getExpression();\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ graph.claimLiteral(\r
+ function, \r
+ SysdynResource.getInstance(graph).HasModelicaFunctionCode, \r
+ code);\r
+ Resource library = graph.getSingleObject(function, Layer0.getInstance(graph).PartOf);\r
+ FunctionUtils.updateFunctionFileForLibrary(graph, library);\r
+ }\r
+ });\r
+ }\r
+\r
+}\r