import java.awt.Font;\r
import java.awt.geom.AffineTransform;\r
\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.diagram.elements.ITextListener;\r
import org.simantics.diagram.elements.TextElementNoBounds;\r
import org.simantics.diagram.elements.TextNode;\r
import org.simantics.g2d.element.ElementUtils;\r
import org.simantics.g2d.element.IElement;\r
import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.modeling.ModelingResources;\r
import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.sysdyn.ui.properties.VariableNameValidator;\r
+import org.simantics.sysdyn.ui.properties.VariableNameUtils;\r
+import org.simantics.ui.SimanticsUI;\r
import org.simantics.utils.datastructures.Callback;\r
import org.simantics.utils.datastructures.hints.IHintListener;\r
import org.simantics.utils.datastructures.hints.IHintObservable;\r
node.setTextListener(new ITextListener() {\r
\r
String textBeforeEdit;\r
+ Resource component;\r
\r
@Override\r
public void textChanged() {\r
TextNode node = (TextNode) e.getHint(SG_NODE);\r
- if(!VariableNameValidator.isValid(node.getText())) {\r
+ if(!VariableNameUtils.isValid(component, node.getText())) {\r
node.setColor(Color.RED);\r
} else {\r
node.setColor(Color.BLACK);\r
public void textEditingStarted() {\r
TextNode node = (TextNode) e.getHint(SG_NODE);\r
textBeforeEdit = node.getText();\r
+\r
+ if(component != null) return;\r
+ \r
+ Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+ if(o != null && o instanceof Resource) {\r
+ final Resource element = (Resource)o;\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent);\r
+ }\r
+ });\r
+ }\r
}\r
\r
@Override\r
public void textEditingCancelled() {\r
TextNode node = (TextNode) e.getHint(SG_NODE);\r
- if (node != null)\r
+ if (node != null) {\r
+ if(VariableNameUtils.isValid(component, node.getText()))\r
+ node.setColor(Color.BLACK);\r
endEdit(node);\r
+ }\r
}\r
\r
@Override\r
if (node == null)\r
return;\r
String text = node.getText();\r
- if(!VariableNameValidator.isValid(text)) {\r
+ if(!VariableNameUtils.isValid(component, text)) {\r
text = textBeforeEdit;\r
node.setText(text);\r
- if(VariableNameValidator.isValid(text))\r
+ if(VariableNameUtils.isValid(component, text))\r
node.setColor(Color.BLACK);\r
+ } else {\r
+ Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+ final String textAfterEdit = text;\r
+ if(o != null && o instanceof Resource) {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ VariableNameUtils.renameInEquations(graph, component, textBeforeEdit, textAfterEdit);\r
+ }\r
+ });\r
+ }\r
}\r
ElementUtils.setText(e, text);\r
IDiagram diagram = ElementUtils.getDiagram(e);\r
\r
@Override\r
public String isValid(String newText) {\r
- if (!VariableNameValidator.isValid(newText))\r
+ if (VariableNameUtils.isValid(newText))\r
return "Sorry but spaces and special characters are not allowed for names right now";\r
return null;\r
}\r
import java.util.HashMap;\r
import java.util.Map;\r
\r
-import org.eclipse.jface.dialogs.IInputValidator;\r
import org.eclipse.jface.layout.GridDataFactory;\r
import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.ui.IWorkbenchSite;\r
import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
-import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl;\r
import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget;\r
import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget;\r
import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameValidator;\r
\r
public class EquationTab extends PropertyTabContributorImpl {\r
\r
GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite);\r
TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
- nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
- nameText.setInputValidator(new IInputValidator() {\r
- \r
- @Override\r
- public String isValid(String newText) {\r
- if (!VariableNameValidator.isValid(newText))\r
- return "Sorry but spaces and special characters are not allowed for names right now";\r
- return null;\r
- }\r
- });\r
+ nameText.addModifyListener(new VariableNamePropertyModifier(context, Layer0.URIs.HasName));\r
+ nameText.setInputValidator(new VariableNameValidator(support));\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
\r
\r
import org.eclipse.ui.IWorkbenchSite;\r
import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
-import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
import org.simantics.db.Builtins;\r
import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget;\r
import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameValidator;\r
\r
public class InputVariableTab extends PropertyTabContributorImpl {\r
\r
\r
TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
- nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new VariableNamePropertyModifier(context, Builtins.URIs.HasName));\r
+ nameText.setInputValidator(new VariableNameValidator(support));\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
\r
Composite defaultValueComposite = new Composite(composite, SWT.NONE);\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+import java.util.StringTokenizer;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class VariableNameUtils {\r
+\r
+ /**\r
+ * Replaces variable names in all the expressions in the defined configuration. \r
+ * Replace doesn't have to replace words in other configurations than the configuration where the renamed variable is\r
+ * because input variables handle the transitions between configurations (modules).\r
+ * \r
+ * @param graph WriteGraph\r
+ * @param configuration The configuration where the renamed variable is located\r
+ * @param originalName The original name of the variable\r
+ * @param newName New name of the variable\r
+ */\r
+ public static void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource configuration = graph.getSingleObject(variable, l0.PartOf);\r
+ for(Resource r : graph.getObjects(configuration, l0.ConsistsOf)) {\r
+ if(graph.isInstanceOf(r, sr.IndependentVariable)) {\r
+ Resource s = graph.getSingleObject(r, sr.HasExpression);\r
+ for(Resource p : graph.getPredicates(s)) {\r
+ Resource o = graph.getPossibleObject(s, p);\r
+ if(o != null && graph.isInstanceOf(o, l0.String)) {\r
+ String string = graph.getRelatedValue(s, p);\r
+ String replaced = replaceAllWords(string, originalName, newName);\r
+ graph.claimLiteral(s, p, replaced);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ private static String replaceAllWords(String original, String find, String replacement) {\r
+ if(!original.contains(find)) return original;\r
+ StringBuilder result = new StringBuilder(original.length());\r
+ String delimiters = "+-*/(){}[],. ";\r
+ StringTokenizer st = new StringTokenizer(original, delimiters, true);\r
+ while (st.hasMoreTokens()) {\r
+ String w = st.nextToken();\r
+ if (w.equals(find)) {\r
+ result.append(replacement);\r
+ } else {\r
+ result.append(w);\r
+ }\r
+ }\r
+ return result.toString();\r
+ }\r
+ \r
+ public static boolean nameIsTaken(final Resource variable, final String name) {\r
+ boolean result = false;\r
+ try {\r
+ result = SimanticsUI.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+ @Override\r
+ public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+ return nameIsTaken(graph, variable, name);\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ public static boolean nameIsTaken(ReadGraph graph, Resource variable, String name) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ Resource configuration = graph.getSingleObject(variable, l0.PartOf);\r
+ for(Resource r : graph.getObjects(configuration, l0.ConsistsOf)) {\r
+ String componentName = graph.getPossibleRelatedValue(r, l0.HasName);\r
+ if(componentName != null && !r.equals(variable) && componentName.equals(name)) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ /**\r
+ * Checks that the syntax of the given name is valid and there \r
+ * are no other variables that have the same name in the configuration\r
+ * \r
+ * @param graph ReadGraph\r
+ * @param variable The variable that is being renamed\r
+ * @param name The new name of the variable\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean isValid(ReadGraph graph, Resource variable, String name) throws DatabaseException {\r
+ if(nameIsTaken(graph, variable, name)) return false;\r
+ if(!isValid(name)) return false;\r
+ return true;\r
+ }\r
+ \r
+ /**\r
+ * Checks that the syntax of the given name is valid and there \r
+ * are no other variables that have the same name in the configuration\r
+ * \r
+ * @param variable The variable that is being renamed\r
+ * @param name The new name of the variable\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean isValid(Resource variable, String name) {\r
+ if(nameIsTaken(variable, name)) return false;\r
+ if(!isValid(name)) return false;\r
+ return true;\r
+ }\r
+ \r
+ /**\r
+ * Checks that the syntax of the given name is valid \r
+ * and that it is not a keyword in Modelica.\r
+ * \r
+ * @param name\r
+ * @return\r
+ */\r
+ public static boolean isValid(String name) {\r
+ String lowerCase = name.toLowerCase();\r
+ Pattern p = Pattern.compile("[a-zA-Z0-9]++");\r
+ Matcher m = p.matcher(lowerCase);\r
+ if (!m.matches() || keywords.contains(name))\r
+ return false;\r
+ else\r
+ return true;\r
+ }\r
+ \r
+ public static final Set<String> keywords = new HashSet<String>();\r
+\r
+ static {\r
+ keywords.add("algorithm");\r
+ keywords.add("discrete");\r
+ keywords.add("false");\r
+ keywords.add("model");\r
+ keywords.add("redeclare");\r
+ keywords.add("and");\r
+ keywords.add("each");\r
+ keywords.add("final");\r
+ keywords.add("not");\r
+ keywords.add("replaceable");\r
+ keywords.add("annotation");\r
+ keywords.add("else");\r
+ keywords.add("flow");\r
+ keywords.add("operator");\r
+ keywords.add("return");\r
+ keywords.add("assert");\r
+ keywords.add("elseif");\r
+ keywords.add("for");\r
+ keywords.add("or");\r
+ keywords.add("stream");\r
+ keywords.add("block");\r
+ keywords.add("elsewhen");\r
+ keywords.add("function");\r
+ keywords.add("outer");\r
+ keywords.add("then");\r
+ keywords.add("break");\r
+ keywords.add("encapsulated");\r
+ keywords.add("if");\r
+ keywords.add("output");\r
+ keywords.add("true");\r
+ keywords.add("class");\r
+ keywords.add("end");\r
+ keywords.add("import");\r
+ keywords.add("package");\r
+ keywords.add("type");\r
+ keywords.add("connect");\r
+ keywords.add("enumeration");\r
+ keywords.add("in");\r
+ keywords.add("parameter");\r
+ keywords.add("when");\r
+ keywords.add("connector");\r
+ keywords.add("equation");\r
+ keywords.add("initial");\r
+ keywords.add("partial");\r
+ keywords.add("while");\r
+ keywords.add("constant");\r
+ keywords.add("expandable");\r
+ keywords.add("inner");\r
+ keywords.add("protected");\r
+ keywords.add("within");\r
+ keywords.add("constrainedby");\r
+ keywords.add("extends");\r
+ keywords.add("input");\r
+ keywords.add("public");\r
+ keywords.add("der");\r
+ keywords.add("external");\r
+ keywords.add("loop");\r
+ keywords.add("record");\r
+ keywords.add("time");\r
+ }\r
+}\r
+++ /dev/null
-package org.simantics.sysdyn.ui.properties;\r
-\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-public class VariableNameValidator {\r
-\r
- public static boolean isValid(String name) {\r
- String lowerCase = name.toLowerCase();\r
- Pattern p = Pattern.compile("[a-zA-Z0-9]++");\r
- Matcher m = p.matcher(lowerCase);\r
- if (!m.matches() || keywords.contains(name))\r
- return false;\r
- else\r
- return true;\r
- }\r
- \r
- public static final Set<String> keywords = new HashSet<String>();\r
-\r
- static {\r
- keywords.add("algorithm");\r
- keywords.add("discrete");\r
- keywords.add("false");\r
- keywords.add("model");\r
- keywords.add("redeclare");\r
- keywords.add("and");\r
- keywords.add("each");\r
- keywords.add("final");\r
- keywords.add("not");\r
- keywords.add("replaceable");\r
- keywords.add("annotation");\r
- keywords.add("else");\r
- keywords.add("flow");\r
- keywords.add("operator");\r
- keywords.add("return");\r
- keywords.add("assert");\r
- keywords.add("elseif");\r
- keywords.add("for");\r
- keywords.add("or");\r
- keywords.add("stream");\r
- keywords.add("block");\r
- keywords.add("elsewhen");\r
- keywords.add("function");\r
- keywords.add("outer");\r
- keywords.add("then");\r
- keywords.add("break");\r
- keywords.add("encapsulated");\r
- keywords.add("if");\r
- keywords.add("output");\r
- keywords.add("true");\r
- keywords.add("class");\r
- keywords.add("end");\r
- keywords.add("import");\r
- keywords.add("package");\r
- keywords.add("type");\r
- keywords.add("connect");\r
- keywords.add("enumeration");\r
- keywords.add("in");\r
- keywords.add("parameter");\r
- keywords.add("when");\r
- keywords.add("connector");\r
- keywords.add("equation");\r
- keywords.add("initial");\r
- keywords.add("partial");\r
- keywords.add("while");\r
- keywords.add("constant");\r
- keywords.add("expandable");\r
- keywords.add("inner");\r
- keywords.add("protected");\r
- keywords.add("within");\r
- keywords.add("constrainedby");\r
- keywords.add("extends");\r
- keywords.add("input");\r
- keywords.add("public");\r
- keywords.add("der");\r
- keywords.add("external");\r
- keywords.add("loop");\r
- keywords.add("record");\r
- }\r
-}\r
import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.graphics.RGB;\r
-import org.simantics.sysdyn.ui.properties.VariableNameValidator;\r
+import org.simantics.sysdyn.ui.properties.VariableNameUtils;\r
\r
public class ExpressionFieldConfiguration extends SourceViewerConfiguration {\r
\r
}, defaultToken);\r
\r
\r
- for(String s : VariableNameValidator.keywords) {\r
+ for(String s : VariableNameUtils.keywords) {\r
reservedWord.addWord(s, reserved);\r
}\r
\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.properties.VariableNameUtils;\r
+\r
+public class VariableNamePropertyModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+ final private String propertyURI;\r
+\r
+ public VariableNamePropertyModifier(ISessionContext context, String propertyURI) {\r
+ this.propertyURI = propertyURI;\r
+ }\r
+\r
+ /**\r
+ * Overrides the original applyText. Renames variables also in equations in the same configuration.\r
+ */\r
+ @Override\r
+ public void applyText(WriteGraph graph, Resource variable, String text) throws DatabaseException {\r
+ String originalName = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName);\r
+ VariableNameUtils.renameInEquations(graph, variable, originalName, text);\r
+ graph.claimLiteral(variable, graph.getResource(propertyURI), text, StringBindingDefault.INSTANCE);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\r
+import org.eclipse.jface.viewers.ISelection;\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.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.ui.properties.VariableNameUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class VariableNameValidator implements IInputValidator, Widget {\r
+\r
+ private Resource lastInput = null;\r
+ \r
+ public VariableNameValidator(WidgetSupport support) {\r
+ support.register(this);\r
+ }\r
+ \r
+ /**\r
+ * Checks that the syntax of the given name is valid and there \r
+ * are no other components that have the same name in the configuration.\r
+ */\r
+ @Override\r
+ public String isValid(final String newText) {\r
+ if (!VariableNameUtils.isValid(newText))\r
+ return "Sorry but spaces and special characters are not allowed for names right now";\r
+ if(lastInput == null) return null;\r
+ String result = null;\r
+ try {\r
+ result = SimanticsUI.getSession().syncRequest(new Read<String>(){\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ if(VariableNameUtils.nameIsTaken(graph, lastInput, newText)) {\r
+ return "Name is taken.";\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ }) ;\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return result;\r
+\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ lastInput = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
+ }\r
+\r
+}\r