import java.io.InputStream;\r
import java.util.ArrayList;\r
import java.util.HashMap;\r
-import java.util.List;\r
\r
\r
public class CSVSimulationResult extends SimulationResult {\r
\r
- HashMap<String, List<Double>> valueMap = new HashMap<String, List<Double>>();\r
+ HashMap<String, DataSet> valueMap = new HashMap<String, DataSet>();\r
\r
@Override\r
public void read(InputStream stream) {\r
// Create lists for receiving values for each variable. Names still with quotes.\r
for(String name : names) {\r
if(!name.isEmpty())\r
- valueMap.put(name, new ArrayList<Double>());\r
+ valueMap.put(name, new DataSet(name, new ArrayList<Double>(), new ArrayList<Double>()));\r
}\r
\r
// Data sets\r
for(int i = 0; i<values.length; i++) {\r
if(values[i] != null && !values[i].isEmpty() && i < names.length) {\r
try {\r
- valueMap.get(names[i]).add(Double.parseDouble(values[i]));\r
+ valueMap.get(names[i]).values.add(Double.parseDouble(values[i]));\r
} catch (NumberFormatException e) {\r
ArrayList<TimeValuePair> list = errors.get(names[i]);\r
if(list == null) {\r
}\r
}\r
\r
- // Create datasets for variables. Substring quotes from variable names.\r
- for(String key : valueMap.keySet()) {\r
- DataSet ds = new DataSet(key, valueMap.get("time"), valueMap.get(key));\r
+ // Add time values for each dataset and add them to variables. \r
+ for(DataSet ds : valueMap.values()) {\r
+ ds.times = valueMap.get("time").values;\r
variables.add(ds);\r
}\r
}\r
</with>\r
</visibleWhen>\r
</command>\r
+ <command\r
+ commandId="org.simantics.sysdyn.ui.newSpreadSheet"\r
+ label="Sheet"\r
+ style="push">\r
+ <visibleWhen\r
+ checkEnabled="true">\r
+ <with\r
+ variable="selection">\r
+ <test\r
+ args="org.simantics.sysdyn.ui.browser.nodes.BookNode"\r
+ property="org.simantics.sysdyn.ui.nodeClass">\r
+ </test>\r
+ </with>\r
+ </visibleWhen>\r
+ </command>\r
</menu>\r
<dynamic\r
class="org.simantics.ui.contribution.OpenWithMenuContribution"\r
id="org.simantics.sysdyn.ui.exportModule"\r
name="Export Module">\r
</command>\r
+ <command\r
+ id="org.simantics.sysdyn.ui.newSpreadSheet"\r
+ name="New SpreadSheet">\r
+ </command>\r
</extension>\r
<extension\r
point="org.eclipse.ui.handlers">\r
args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
property="org.simantics.sysdyn.ui.nodeClass">\r
</test>\r
+ <test\r
+ args="org.simantics.sysdyn.ui.browser.nodes.SheetNode"\r
+ property="org.simantics.sysdyn.ui.nodeClass">\r
+ </test>\r
</or>\r
</with>\r
</activeWhen>\r
</with>\r
</activeWhen>\r
</handler>\r
+ <handler\r
+ class="org.simantics.sysdyn.ui.handlers.NewSpreadSheetHandler"\r
+ commandId="org.simantics.sysdyn.ui.newSpreadSheet">\r
+ </handler>\r
</extension>\r
<extension\r
point="org.simantics.browsing.ui.common.viewpointContributionBinding">\r
value="plugin_customization.ini"/>\r
<property\r
name="windowImages"\r
- value="icons/sysdyn3.png,icons/sysdyn32.png">\r
+ value="icons/sysdyn.png">\r
</property>\r
</product>\r
</extension>\r
public BookNode(Resource data) {\r
super(data);\r
}\r
-\r
- @SuppressWarnings("rawtypes")\r
- @Override\r
- public Object getAdapter(Class adapter) {\r
- if(clazz == adapter) // There is no resource for this node..\r
- return null;\r
- return super.getAdapter(adapter);\r
- }\r
}\r
IHintContext h = ctx.getDefaultHintContext();\r
h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE);\r
h.setHint(RulerPainter.KEY_RULER_ENABLED, Boolean.FALSE);\r
+ h.setHint(Hints.KEY_DISPLAY_MARGINS, Boolean.FALSE);\r
+ h.setHint(Hints.KEY_DISPLAY_PAGE, Boolean.FALSE);\r
return ctx;\r
}\r
\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.ui.Activator;\r
import org.simantics.sysdyn.ui.utils.OldTransferableGraph1;\r
+import org.simantics.sysdyn.ui.utils.SheetUtils;\r
import org.simantics.ui.SimanticsUI;\r
\r
public class ImportModelHandler extends AbstractHandler {\r
graph.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING);\r
graph.claim(conf, l0.ConsistsOf, l0.PartOf, book);\r
\r
- createSheet(graph, book, "Sheet1", new String[] { }, new int[] { 50 });\r
+ SheetUtils.createSheet(graph, book, "Sheet1", new String[] { }, new int[] { 50 });\r
}\r
} catch (DatabaseException e) {\r
e.printStackTrace();\r
}\r
}\r
\r
- /**\r
- * Create a sheet (Copied from SysdynProject)\r
- * \r
- * @param graph\r
- * @param book\r
- * @param name\r
- * @param colNames\r
- * @param colWidths\r
- * @return\r
- * @throws DatabaseException\r
- */\r
- private static Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException {\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
-\r
- Resource result = graph.newResource();\r
- graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet);\r
-\r
- if(name == null) {\r
- name = NameUtils.findFreshEscapedName(graph, "Sheet", book, sr.HasSheet);\r
- }\r
- graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
- graph.claim(book, L0.ConsistsOf, L0.PartOf, result);\r
-\r
- {\r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
- graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.FitColumns, sr.FitColumnsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
- graph.addLiteral(newCell, sr.FitRows, sr.FitRowsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
- graph.addLiteral(newCell, sr.ColumnCount, sr.ColumnCountOf, L0.Integer, 128, Bindings.INTEGER);\r
- graph.addLiteral(newCell, sr.RowCount, sr.RowCountOf, L0.Integer, 256, Bindings.INTEGER);\r
- graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
- }\r
-\r
- {\r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
- graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.ColumnLabels, sr.ColumnLabelsOf, L0.StringArray, colNames, Bindings.STRING_ARRAY);\r
- graph.addLiteral(newCell, sr.ColumnWidths, sr.ColumnWidthsOf, L0.IntegerArray, colWidths, Bindings.INT_ARRAY);\r
- graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
- }\r
-\r
- {\r
- \r
- double[] doubles = new double[10*2];\r
- for(int i=0;i<10*2;i++) doubles[i] = i;\r
- \r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell);\r
- graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER);\r
- graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY);\r
- graph.claim(result, L0.HasChildVariables, L0.HasChildVariables_Inverse, newCell);\r
- \r
- }\r
- \r
- return result;\r
-\r
- }\r
-\r
}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\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.sysdyn.ui.utils.SheetUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class NewSpreadSheetHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ final Resource book = ResourceAdaptionUtils.toSingleResource(sel);\r
+ if(book == null) return null;\r
+\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ SheetUtils.createSheet(graph, book, null, new String[] {}, new int[] {50});\r
+ }\r
+ }); \r
+ return null;\r
+ }\r
+\r
+}\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.ui.Activator;\r
import org.simantics.sysdyn.ui.editor.SysdynEditorNamingService;\r
+import org.simantics.sysdyn.ui.utils.SheetUtils;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.ui.workbench.IEditorNamingService;\r
import org.simantics.ui.workbench.action.ChooseActionRequest;\r
\r
private final WriteRunnable CREATE_MODEL = new WriteRunnable() {\r
\r
- Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException {\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
-\r
- Resource result = graph.newResource();\r
- graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet);\r
-\r
- if(name == null) {\r
- name = NameUtils.findFreshEscapedName(graph, "Sheet", book, sr.HasSheet);\r
- }\r
- graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
- graph.claim(book, L0.ConsistsOf, L0.PartOf, result);\r
-\r
- {\r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
- graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.FitColumns, sr.FitColumnsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
- graph.addLiteral(newCell, sr.FitRows, sr.FitRowsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
- graph.addLiteral(newCell, sr.ColumnCount, sr.ColumnCountOf, L0.Integer, 128, Bindings.INTEGER);\r
- graph.addLiteral(newCell, sr.RowCount, sr.RowCountOf, L0.Integer, 256, Bindings.INTEGER);\r
- graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
- }\r
-\r
- {\r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
- graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.ColumnLabels, sr.ColumnLabelsOf, L0.StringArray, colNames, Bindings.STRING_ARRAY);\r
- graph.addLiteral(newCell, sr.ColumnWidths, sr.ColumnWidthsOf, L0.IntegerArray, colWidths, Bindings.INT_ARRAY);\r
- graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
- }\r
-\r
- {\r
- \r
- double[] doubles = new double[10*2];\r
- for(int i=0;i<10*2;i++) doubles[i] = i;\r
- \r
- Resource newCell = graph.newResource();\r
- graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell);\r
- graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER);\r
- graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING);\r
- graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY);\r
- graph.claim(result, L0.HasChildVariables, L0.HasChildVariables_Inverse, newCell);\r
- \r
- }\r
- \r
- return result;\r
-\r
- }\r
- \r
@Override\r
public void run(WriteGraph g, Resource library, Callback<Resource> callback, Callback<Throwable> errorCallback) {\r
try {\r
g.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING);\r
g.claim(conf, l0.ConsistsOf, l0.PartOf, book);\r
\r
- createSheet(g, book, "Sheet1", new String[] { "ARG" }, new int[] { 50 });\r
+ SheetUtils.createSheet(g, book, "Sheet1", new String[] { }, new int[] { 50 });\r
\r
\r
\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Set;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
\r
import org.eclipse.jface.text.Position;\r
import org.eclipse.swt.custom.StyledText;\r
final HashMap<ExpressionField, HashMap<String, List<List<Token>>>> ranges = new HashMap<ExpressionField, HashMap<String, List<List<Token>>>>();\r
HashMap<ExpressionField, HashMap<Token, List<Token>>> forIndices = new HashMap<ExpressionField, HashMap<Token, List<Token>>>();\r
HashMap<ExpressionField, HashMap<String, List<Token>>> enumerationReferences = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
+ HashMap<ExpressionField, HashMap<String, List<Token>>> functionReferences = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
\r
// Build references and variable array\r
for(ExpressionField ef : expression.getExpressionFields()) {\r
references.put(ef, refs);\r
variables.addAll(refs.keySet());\r
\r
- HashMap<String, List<List<Token>>> rangs = parser.getRanges();\r
- ranges.put(ef, rangs);\r
+ ranges.put(ef, parser.getRanges());\r
\r
- HashMap<Token, List<Token>> fInds = parser.getForIndices();\r
- forIndices.put(ef, fInds);\r
+ forIndices.put(ef, parser.getForIndices());\r
\r
+ enumerationReferences.put(ef, parser.getEnumerationReferences());\r
\r
- HashMap<String, List<Token>> enumRefs = parser.getEnumerationReferences();\r
- enumerationReferences.put(ef, enumRefs);\r
+ functionReferences.put(ef, parser.getFunctionCallReferences());\r
\r
} catch (ParseException e1) {\r
ef.setSyntaxError(e1.currentToken, "Syntax Error");\r
final HashMap<String, Variable> modelVariables = new HashMap<String, Variable>();\r
HashSet<String> ignoreVariables = new HashSet<String>();\r
\r
- if(!variables.isEmpty()) {\r
+ if(!variables.isEmpty() || !functionReferences.isEmpty()) {\r
Set<String> noSuchVariables = new HashSet<String>();\r
SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
SysdynModel model = sdm.getModel(configuration);\r
\r
if(variables.contains("time"))\r
variables.remove("time");\r
+ \r
+ // Examine sheets\r
+ for(ExpressionField ef : functionReferences.keySet()) {\r
+ for(String key : functionReferences.get(ef).keySet()) {\r
+ String[] parts = key.split("\\.");\r
+ Object current = conf;\r
+ for(int i = 0; i < parts.length && current != null; i++) {\r
+ current = getElement(current, parts[i]);\r
+ }\r
+ if(current != null && current instanceof Sheet) {\r
+ Sheet sheet = (Sheet) current;\r
+ String e = ef.getExpression();\r
+ int start = 0, end = 0, call = 0;\r
+ String cellOrRange = null;\r
+ while((call = e.indexOf(key, end)) >= 0) {\r
+ start = e.indexOf("(", call) +1;\r
+ end = e.indexOf(")", start);\r
+ if(start < 0 || end < 0 || end < start) {\r
+ break;\r
+ }\r
+ Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]");\r
+ cellOrRange = e.substring(start, end);\r
+ Matcher m = p.matcher(cellOrRange);\r
+ if (m.find() || cellOrRange.split(":").length > 2) {\r
+ ef.setSyntaxError(start, end - start, ExpressionField.SYNTAX_ERROR, "Not a valid cell or range");\r
+ }\r
+ }\r
+ \r
+ List<Token> tokens = functionReferences.get(ef).get(key);\r
+ for(Token cell : tokens) {\r
+ List<Token> refs = references.get(ef).get(cell.image);\r
+ if(refs != null)\r
+ refs.remove(cell);\r
+ if(!sheet.getCells().containsKey(cell.image))\r
+ ef.setSyntaxError(cell.image, "Invalid cell", cell.beginLine, cell.beginColumn, cell.endLine, cell.endColumn); \r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
\r
for(String v : variables) {\r
\r
--- /dev/null
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+\r
+public class SheetUtils {\r
+ \r
+ public static Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException {\r
+\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
+\r
+ Resource result = graph.newResource();\r
+ graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet);\r
+\r
+ if(name == null) {\r
+ name = NameUtils.findFreshEscapedName(graph, "Sheet", book, L0.ConsistsOf);\r
+ }\r
+ graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
+ graph.claim(book, L0.ConsistsOf, L0.PartOf, result);\r
+\r
+ {\r
+ Resource newCell = graph.newResource();\r
+ graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
+ graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING);\r
+ graph.addLiteral(newCell, sr.FitColumns, sr.FitColumnsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
+ graph.addLiteral(newCell, sr.FitRows, sr.FitRowsOf, L0.Boolean, false, Bindings.BOOLEAN);\r
+ graph.addLiteral(newCell, sr.ColumnCount, sr.ColumnCountOf, L0.Integer, 128, Bindings.INTEGER);\r
+ graph.addLiteral(newCell, sr.RowCount, sr.RowCountOf, L0.Integer, 256, Bindings.INTEGER);\r
+ graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
+ }\r
+\r
+ {\r
+ Resource newCell = graph.newResource();\r
+ graph.claim(newCell, L0.InstanceOf, null, sr.Cell);\r
+ graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING);\r
+ graph.addLiteral(newCell, sr.ColumnLabels, sr.ColumnLabelsOf, L0.StringArray, colNames, Bindings.STRING_ARRAY);\r
+ graph.addLiteral(newCell, sr.ColumnWidths, sr.ColumnWidthsOf, L0.IntegerArray, colWidths, Bindings.INT_ARRAY);\r
+ graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
+ }\r
+\r
+// {\r
+// \r
+// double[] doubles = new double[10*2];\r
+// for(int i=0;i<10*2;i++) doubles[i] = i;\r
+// \r
+// Resource newCell = graph.newResource();\r
+// graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell);\r
+// graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER);\r
+// graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING);\r
+// graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY);\r
+// graph.claim(result, L0.HasChildVariables, L0.HasChildVariables_Inverse, newCell);\r
+// \r
+// }\r
+ \r
+ return result;\r
+\r
+ }\r
+\r
+}\r
public HashMap<String, List<Token>> getEnumerationReferences() {\r
return enumerationReferences;\r
}\r
+\r
+/*\r
+ Collect EACH function call and all references that are inside the call brackets.\r
+ These are later used to exclude spread sheet references out of the normal functions.\r
+*/\r
+ String functionCall = null;\r
+ HashMap<String, List<Token>> functionCallReferences = new HashMap<String, List<Token>>();\r
+ \r
+ public HashMap<String, List<Token>> getFunctionCallReferences() {\r
+ return functionCallReferences;\r
+ } \r
\r
\r
}\r
| <STRING>\r
| "false"\r
| "true"\r
- | LOOKAHEAD( name() "(" ) name() function_call_args()\r
+ | LOOKAHEAD( name() "(" )\r {\r functionCall = null;\r
+ }\r
+ name() function_call_args()\r {\r functionCall = null;\r
+ } \r
| component_reference(null)\r
| "(" output_expression_list() ")"\r
| "[" expression_list() ( ";" expression_list() )* "]"\r
\r
void name() : {\r
} {\r
- <IDENT> ( "." name() )?\r
+ <IDENT>\r {\r if (functionCall == null)\r
+ functionCall = token.image;\r
+ else\r
+ functionCall += "." + token.image;\r
+ }\r
+ ( "." name() )?\r
}\r
\r
void component_reference(String prevToken) : {\r
<IDENT> {\r
String name = token.image; \r
// forIndex == true and prevToken != null => this is the second part of an enumeration in for-index\r
- if(forIndex == true && prevToken != null) {\r
- if(enumerationReferences.get(prevToken) == null) {\r enumerationReferences.put(prevToken, new ArrayList<Token>());\r
- }\r
- List<Token> list = enumerationReferences.get(prevToken);\r
- list.add(token); \r
-\r
- // forIndex == true and prevToken == null => this is the enumeration in for-index\r
- } else if(forIndex == true && prevToken == null) {\r
- if(enumerationReferences.get(name) == null) {\r
- enumerationReferences.put(name, new ArrayList<Token>());\r
- }\r
- List<Token> list = enumerationReferences.get(name);\r
- list.add(token); \r
+ if(forIndex == true) {\r if(prevToken != null) {\r
+ if(enumerationReferences.get(prevToken) == null) {\r enumerationReferences.put(prevToken, new ArrayList<Token>());\r
+ }\r
+ List<Token> list = enumerationReferences.get(prevToken);\r
+ list.add(token); \r
+ \r
+ // forIndex == true and prevToken == null => this is the enumeration in for-index\r
+ } else {\r
+ if(enumerationReferences.get(name) == null) {\r
+ enumerationReferences.put(name, new ArrayList<Token>());\r
+ }\r
+ List<Token> list = enumerationReferences.get(name);\r
+ list.add(token);\r
+ }\r
} else {\r
if(prevToken != null)\r
name = prevToken + "." + name; \r if(references.get(name) == null) {\r
}\r
List<Token> list = references.get(name);\r
list.add(token);\r
+\r
+ if(functionCall != null) {\r
+ if(!functionCallReferences.containsKey(functionCall))\r
+ functionCallReferences.put(functionCall, new ArrayList<Token>());\r
+ List<Token> functionReferencelist = getFunctionCallReferences().get(functionCall);\r
+ functionReferencelist.add(token);\r }\r
}\r
\r
}\r
( array_subscripts() )? ( "." component_reference(name) )?\r
}\r
\r
-\r
void function_call_args() : {\r
} {\r
"(" ( function_arguments() )? ")"\r
} {\r
//expression [ "," function_arguments | for for_indices ]\r
//| named_arguments\r
- LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )?\r
- | named_arguments()\r
+ LOOKAHEAD(2) named_argument() ( "," function_arguments() )?\r
+ | expression() ( "," function_arguments() | "for" for_indices() )?\r
+ \r
}\r
\r
void for_indices() : {\r
}\r
}\r
\r
+/* Removed by Teemu. Refactored in function_arguments)\r
void named_arguments() : {\r
} {\r
named_argument() ( "," named_arguments() )?\r
}\r
+*/\r
\r
void named_argument() : {\r
} { \r
for(Resource config : readModules(g, configurationResource)) {\r
modules.add((Configuration)mapping.map(g, config));\r
}\r
- System.out.println("Loaded model with " + modules.size() + " modules.");\r
+// System.out.println("Loaded model with " + modules.size() + " modules.");\r
}\r
\r
public SysdynModel(ReadGraph g, Resource configurationResource) {\r
progressMonitor.subTask("Build model");\r
previousModelStructure = modelText;\r
System.out.println("== Modelica == ");\r
- System.out.println(writer.toString());\r
+// System.out.println(writer.toString());\r
System.out.println("== Modelica ends == ");\r
\r
try {\r
\r
if(book != null) {\r
b.append("// Spreadsheet definition\n");\r
- b.append(book.getBook());\r
+ b.append(book.markBook());\r
}\r
\r
boolean initialEquations = false;\r
b.append("end ").append(className).append(";\n\n");\r
\r
\r
-// for(Module m : modules) {\r
-// writeConfiguration(m.getConfiguration());\r
-// }\r
-\r
+ // Update sheet definitions to contain the elements that were used.\r
+ if(book != null) {\r
+ int s = b.indexOf(book.markBook());\r
+ b.replace(s, s + book.markBook().length(), book.getBook());\r
+ }\r
}\r
\r
public String escape(String name) {\r
return sheets;\r
}\r
\r
+ public String markBook() {\r
+ return "BOOK " + this.getName();\r
+ }\r
+ \r
public String getBook() {\r
StringBuilder book = new StringBuilder();\r
for(Sheet sheet : sheets)\r
package org.simantics.sysdyn.representation;\r
\r
import java.util.HashMap;\r
+import java.util.HashSet;\r
\r
import org.simantics.databoard.Bindings;\r
import org.simantics.databoard.binding.mutable.Variant;\r
import org.simantics.databoard.primitives.MutableString;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ReadRequest;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.util.Simantics;\r
import org.simantics.db.layer0.variable.Variable;\r
import org.simantics.db.layer0.variable.Variables;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedElement;\r
import org.simantics.objmap.annotations.UpdateMethod;\r
-import org.simantics.spreadsheet.Range;\r
import org.simantics.spreadsheet.SheetVariables;\r
import org.simantics.spreadsheet.common.exception.CellParseException;\r
+import org.simantics.spreadsheet.common.matrix.VariantMatrix;\r
import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid;\r
\r
protected Book book;\r
\r
HashMap<String, Object> cells = new HashMap<String, Object>();\r
+ HashSet<String> usedRanges = new HashSet<String>();\r
+ \r
+ Resource resource;\r
\r
public String getSheet() {\r
return "Sheet";\r
\r
@UpdateMethod\r
public boolean updateCells(ReadGraph g, Resource r) throws DatabaseException {\r
+ this.resource = r;\r
\r
g.getObjects(r, Layer0.getInstance(g).ConsistsOf);\r
\r
Variable v = g.adapt(r, Variable.class);\r
cells.clear();\r
+ usedRanges.clear();\r
for(Variable child : v.browseChildren(g)) {\r
String name = child.getPropertyValue(g, Variables.NAME);\r
try {\r
- Range range = SpreadsheetUtils.decodeCellAbsolute(name);\r
+ SpreadsheetUtils.decodeCellAbsolute(name);\r
Variant value = child.getPropertyValue(g, SheetVariables.CONTENT, Bindings.VARIANT);\r
cells.put(name, value.getValue());\r
} catch (CellParseException e) {\r
}\r
\r
public String getStringRepresentation() {\r
- StringBuilder clazz = new StringBuilder();\r
- \r
+ final StringBuilder clazz = new StringBuilder();\r
+ final HashSet<String> possibleRanges = new HashSet<String>();\r
+\r
clazz.append(" class " + name + "_class\n ");\r
\r
+ // Write all doubles that have been used in expressions\r
int counter = 0;\r
- for(String key : cells.keySet()) {\r
- Object value = cells.get(key);\r
- if(value instanceof String || value instanceof MutableString) {\r
- try {\r
- Double d = Double.parseDouble(value.toString());\r
- value = d;\r
- } catch (NumberFormatException e) {\r
- }\r
- } \r
- \r
- if(value instanceof Double) {\r
- Double d = (Double)value;\r
- clazz.append("constant Real " + key + " = " + d + "; ");\r
- counter++;\r
- if(counter > 10) {\r
- counter = 0;\r
- clazz.append("\n ");\r
+ for(String key : usedRanges) {\r
+ if(cells.containsKey(key)) {\r
+ Object value = cells.get(key);\r
+ if(value instanceof String || value instanceof MutableString) {\r
+ try {\r
+ Double d = Double.parseDouble(value.toString());\r
+ value = d;\r
+ } catch (NumberFormatException e) {\r
+ }\r
+ } \r
+\r
+ if(value instanceof Double) {\r
+ Double d = (Double)value;\r
+ clazz.append("constant Real " + key + " = " + d + "; ");\r
+ counter++;\r
+ if(counter > 10) {\r
+ counter = 0;\r
+ clazz.append("\n ");\r
+ }\r
}\r
+ } else {\r
+ possibleRanges.add(key);\r
}\r
}\r
+ \r
+ try {\r
+ Simantics.getSession().syncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ Variable v = graph.adapt(resource, Variable.class);\r
+ for(String possibleRange : possibleRanges) {\r
+ String[] parts = possibleRange.split(":");\r
+ if(parts.length != 2 || !cells.containsKey(parts[0]) || !cells.containsKey(parts[1]))\r
+ continue;\r
+ Variable range = v.getChild(graph, possibleRange);\r
+ if(range == null)\r
+ continue;\r
+ Variant content = range.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT);\r
+ Object matrixValue = content.getValue();\r
+ if(matrixValue instanceof VariantMatrix) {\r
+ VariantMatrix vm = (VariantMatrix)matrixValue;\r
+ Double[][] array = toDoubleMatrix(vm);\r
+ \r
+ if(array[0].length > 1) {\r
+ // Has two dimensions \r
+ clazz.append("Real[" + array.length + ", " + array[0].length + "] ");\r
+ clazz.append(possibleRange.replace(":", "_") + " = {");\r
+ for(int i = 0; i < array.length; i++) {\r
+ clazz.append("{");\r
+ for(int j = 0; j < array[i].length; j++) {\r
+ clazz.append(array[i][j]);\r
+ if(j < array[i].length - 1)\r
+ clazz.append(", ");\r
+ }\r
+ clazz.append("}");\r
+ if(i < array.length - 1)\r
+ clazz.append(", ");\r
+ }\r
+ clazz.append("};\n");\r
+ } else {\r
+ // Has one dimension\r
+ clazz.append("Real[" + array.length + "] ");\r
+ clazz.append(possibleRange.replace(":", "_") + " = {");\r
+ for(int i = 0; i < array.length; i++) {\r
+ clazz.append(array[i][0]);\r
+ if(i < array.length - 1)\r
+ clazz.append(", ");\r
+ }\r
+ clazz.append("};\n");\r
+ }\r
+ \r
+ }\r
+ }\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ \r
clazz.append("\n end " + name + "_class;\n");\r
clazz.append(" " + name + "_class " + name + ";\n");\r
return clazz.toString();\r
}\r
\r
+ private Double[][] toDoubleMatrix(VariantMatrix matrix) {\r
+ Double[][] array = new Double[matrix.getRowCount()][matrix.getColumnCount()];\r
+ for(int i = 0; i < matrix.getRowCount(); i++) {\r
+ for(int j = 0; j < matrix.getColumnCount(); j++) {\r
+ Variant cell = matrix.get(i, j);\r
+ if(cell.getBinding().equals(Bindings.DOUBLE)) {\r
+ array[i][j] = (Double)cell.getValue();\r
+ } else if (cell.getBinding().equals(Bindings.MUTABLE_STRING)) {\r
+ try {\r
+ array[i][j] = Double.parseDouble(cell.getValue().toString());\r
+ } catch (NumberFormatException e) {\r
+ array[i][j] = 0.0;\r
+ }\r
+ } else {\r
+ array[i][j] = 0.0;\r
+ }\r
+ }\r
+ }\r
+ return array;\r
+ }\r
+ \r
public HashMap<String, Object> getCells() {\r
return cells;\r
}\r
\r
}\r
\r
+ /**\r
+ * Add a range that has been used for this sheet. \r
+ * \r
+ * Used ranges help to reduce code sent to Modelica.\r
+ * \r
+ * @param range range of cell/cells. (e.g. B2 or B4:B6)\r
+ */\r
+ public void use(String range) {\r
+ usedRanges.add(range);\r
+ }\r
+ \r
\r
\r
}\r
import org.simantics.sysdyn.representation.ArrayIndexes;\r
import org.simantics.sysdyn.representation.Enumeration;\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
@GraphType("http://www.simantics.org/Sysdyn-1.0/NormalExpression")\r
\r
@Override\r
public String getEquation(IndependentVariable variable) {\r
- String equation = IndexUtils.equationRangesToIndexes(variable, this.equation);\r
+ String equation = FormatUtils.formatExpressionForModelica(variable, this.equation);\r
String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
}\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.Stock;\r
import org.simantics.sysdyn.representation.Valve;\r
+import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
@GraphType("http://www.simantics.org/Sysdyn-1.0/StockExpression")\r
b.append(" der(")\r
.append(variable.getName() + range)\r
.append(") =");\r
- for(Valve valve : ((Stock)variable).getIncomingValves())\r
- b.append("\n + ").append(valve.getName() + range);\r
- for(Valve valve : ((Stock)variable).getOutgoingValves())\r
- b.append("\n - ").append(valve.getName() + range);\r
+ ArrayList<Valve> incoming = ((Stock)variable).getIncomingValves();\r
+ ArrayList<Valve> outgoing = ((Stock)variable).getOutgoingValves();\r
+ if(incoming.isEmpty() && outgoing.isEmpty()) {\r
+ // No connections, add 0 for each array index if any.\r
+ ArrayIndexes ai = variable.getArrayIndexes();\r
+ ArrayList<Enumeration> enumerations = null;\r
+ if(ai != null) \r
+ enumerations = ai.getEnumerations();\r
+ \r
+ if(ai == null || enumerations == null || enumerations.isEmpty()) {\r
+ b.append(" 0.0");\r
+ } else {\r
+ b.append(" zeros(");\r
+ for(int i = 0; i < enumerations.size(); i++) {\r
+ b.append(enumerations.get(i).getEnumerationIndexes().size());\r
+ if(i != enumerations.size() - 1)\r
+ b.append(", ");\r
+ }\r
+ b.append(")");\r
+ }\r
+\r
+ } else {\r
+ for(Valve valve : incoming)\r
+ b.append("\n + ").append(valve.getName() + range);\r
+ for(Valve valve : outgoing)\r
+ b.append("\n - ").append(valve.getName() + range);\r
+ }\r
b.append(";\n");\r
return b.toString();\r
}\r
} catch (Exception e){\r
// Has an initial equation\r
} \r
+ String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation);\r
String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
if(range == null)\r
range = "";\r
- return " " + variable.getName() + range + " = " + initialEquation + ";\n";\r
+ return " " + variable.getName() + range + " = " + equation + ";\n";\r
\r
}\r
\r
import org.simantics.sysdyn.representation.ArrayIndexes;\r
import org.simantics.sysdyn.representation.Enumeration;\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
\r
\r
@Override\r
public String getEquation(IndependentVariable variable) {\r
- String equation = IndexUtils.equationRangesToIndexes(variable, this.equation);\r
+ String equation = FormatUtils.formatExpressionForModelica(variable, this.equation);\r
String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
\r
return \r
--- /dev/null
+package org.simantics.sysdyn.representation.utils;\r
+\r
+import org.simantics.sysdyn.representation.Variable;\r
+\r
+public class FormatUtils {\r
+ \r
+ public static String formatExpressionForModelica(Variable variable, String expression) {\r
+ String modified = expression;\r
+ modified = IndexUtils.equationRangesToIndexes(variable, modified);\r
+ modified = SheetFormatUtils.reformatSheetReferences(variable, modified);\r
+ return modified;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.representation.utils;\r
+\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.expressionParser.ParseException;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Sheet;\r
+import org.simantics.sysdyn.representation.Variable;\r
+\r
+public class SheetFormatUtils {\r
+ \r
+ public static String reformatSheetReferences(Variable v, String expression) {\r
+ if(!expression.contains("("))\r
+ return expression;\r
+ ExpressionParser parser = new ExpressionParser(new StringReader(expression));\r
+ try {\r
+ parser.expr();\r
+\r
+ HashMap<String, List<Token>> functionCalls = parser.getFunctionCallReferences();\r
+ for(String key : functionCalls.keySet()) {\r
+ String[] parts = key.split("\\.");\r
+ Object current = v.getParentConfiguration();\r
+ Object found = null;\r
+ for(int i = 0; i < parts.length && current != null; i++) {\r
+ found = null;\r
+ if(current instanceof Configuration) {\r
+ for(IElement e : ((Configuration)current).getElements()) {\r
+ if(e instanceof Configuration &&\r
+ ((Variable)e).getName().equals(parts[i])) {\r
+ found = e;\r
+ break;\r
+ } else if(e instanceof Variable &&\r
+ ((Variable)e).getName().equals(parts[i])) {\r
+ found = e;\r
+ break;\r
+ } \r
+ }\r
+ }\r
+ current = found;\r
+ }\r
+ \r
+ if(current != null && current instanceof Sheet) {\r
+ \r
+ String tmp = "";\r
+ int start = 0, end = 0, call = 0;\r
+ String cellOrRange = null;\r
+ while((call = expression.indexOf(key, end)) >= 0) {\r
+ start = expression.indexOf("(", call);\r
+ \r
+ tmp += expression.substring(end, start);\r
+ \r
+ end = expression.indexOf(")", start) + 1;\r
+ if(start < 0 || end < 0 || end < start) {\r
+ break;\r
+ }\r
+ cellOrRange = expression.substring(start, end);\r
+ cellOrRange = cellOrRange.substring(1, cellOrRange.length() - 1);\r
+ cellOrRange = cellOrRange.trim();\r
+ cellOrRange = cellOrRange.replace(" ", "");\r
+ \r
+ Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]");\r
+ Matcher m = p.matcher(cellOrRange);\r
+ if (m.find() || cellOrRange.split(":").length > 2 || cellOrRange.length() == 0) {\r
+ continue;\r
+ }\r
+ \r
+ // Use the cell or range in the sheet.\r
+ ((Sheet)current).use(cellOrRange);\r
+ \r
+ cellOrRange = cellOrRange.replace(":", "_");\r
+ \r
+ tmp += "." + cellOrRange;\r
+ }\r
+ tmp += expression.substring(end, expression.length());\r
+ return tmp;\r
+ }\r
+ }\r
+\r
+ } catch (ParseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return expression;\r
+ }\r
+\r
+}\r