--- /dev/null
+package org.simantics.selectionview.function;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Map;\r
+import java.util.function.Consumer;\r
+\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.ColorDialog;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.FontDialog;\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.content.Labeler.DialogModifier;\r
+import org.simantics.common.format.Formatter;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.NumberBinding;\r
+import org.simantics.databoard.binding.StringBinding;\r
+import org.simantics.databoard.binding.error.BindingConstructionException;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.mutable.MutableStringBinding;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.parser.DataValuePrinter;\r
+import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
+import org.simantics.databoard.parser.repository.DataValueRepository;\r
+import org.simantics.databoard.primitives.MutableString;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.util.ObjectUtils;\r
+import org.simantics.datatypes.literal.Font;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.EnumerationMap;\r
+import org.simantics.db.common.request.InstanceEnumerationMap;\r
+import org.simantics.db.common.request.IsEnumeratedValue;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.variable.ValueAccessor;\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.modeling.ModelingResources;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.selectionview.SelectionInput;\r
+import org.simantics.selectionview.StandardSelectionInput;\r
+import org.simantics.ui.colors.Colors;\r
+import org.simantics.ui.fonts.Fonts;\r
+import org.simantics.ui.selection.WorkbenchSelectionElement;\r
+import org.simantics.ui.selection.WorkbenchSelectionUtils;\r
+import org.simantics.utils.datastructures.collections.CollectionUtils;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class All {\r
+\r
+ final private static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class);\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
+ public static Object colorModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
+ return new DialogModifier() {\r
+\r
+ @Override\r
+ public String getValue() {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public String isValid(String label) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void modify(final String label) {\r
+ Simantics.getSession().async(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ Variable displayValue = context.getParent(graph);\r
+ displayValue.setValue(graph, label, org.simantics.datatypes.literal.RGB.Integer.BINDING);\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ public String query(Object parentControl, Object controlItem, int columnIndex, NodeContext context, Consumer<String> applyCallback) {\r
+ Control ctrl = (Control) parentControl;\r
+\r
+ RGB initialValue = null;\r
+ final Variable v = AdaptionUtils.adaptToSingle(context, Variable.class);\r
+ if (v != null) {\r
+ try {\r
+ org.simantics.datatypes.literal.RGB.Integer rgb = Simantics.getSession().syncRequest(new UniqueRead<org.simantics.datatypes.literal.RGB.Integer>() {\r
+ @Override\r
+ public org.simantics.datatypes.literal.RGB.Integer perform(ReadGraph graph) throws DatabaseException {\r
+ return v.getPossibleValue(graph, org.simantics.datatypes.literal.RGB.Integer.BINDING);\r
+ }\r
+ });\r
+ if (rgb != null) {\r
+ initialValue = Colors.rgb(rgb);\r
+ }\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+\r
+ ColorDialog dialog = new ColorDialog(ctrl.getShell());\r
+ if (initialValue != null)\r
+ dialog.setRGB(initialValue);\r
+ RGB rgb = dialog.open();\r
+ if (rgb != null)\r
+ applyCallback.accept("(" + rgb.red + "," + rgb.green + "," + rgb.blue + ")");\r
+ return null;\r
+ }\r
+\r
+ };\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
+ public static Object fontModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
+ return new DialogModifier() {\r
+\r
+ @Override\r
+ public String getValue() {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public String isValid(String label) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void modify(final String label) {\r
+ Simantics.getSession().async(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ Variable displayValue = context.getParent(graph);\r
+ displayValue.setValue(graph, label, Font.BINDING);\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ public String query(Object parentControl, Object controlItem, int columnIndex, NodeContext context, Consumer<String> applyCallback) {\r
+ Control ctrl = (Control) parentControl;\r
+\r
+ FontData[] initialValue = null;\r
+ final Variable v = AdaptionUtils.adaptToSingle(context, Variable.class);\r
+ if (v != null) {\r
+ try {\r
+ Font font = Simantics.getSession().syncRequest(new UniqueRead<Font>() {\r
+ @Override\r
+ public Font perform(ReadGraph graph) throws DatabaseException {\r
+ return v.getPossibleValue(graph, Font.BINDING);\r
+ }\r
+ });\r
+ if (font != null) {\r
+ initialValue = new FontData[] { Fonts.swtFontData(font) };\r
+ }\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+\r
+ FontDialog dialog = new FontDialog(ctrl.getShell());\r
+ if (initialValue != null)\r
+ dialog.setFontList(initialValue);\r
+ FontData font = dialog.open();\r
+ if (font != null)\r
+ applyCallback.accept("(\"" + font.getName() + "\"," + font.getHeight() + ",\"" + Fonts.fromSwtStyle(font.getStyle()) + "\")");\r
+ return null;\r
+ }\r
+\r
+ };\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+ public static Object getEnumerationValues(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+ if(context instanceof Variable) {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Variable parameter = ((Variable)context).browse(graph, "..");\r
+ Resource parameterResource = parameter.getRepresents(graph);\r
+ if(graph.sync(new IsEnumeratedValue(parameterResource))) {\r
+ Map<String, Resource> map = graph.sync(new InstanceEnumerationMap(parameterResource));\r
+ return new ArrayList<String>(map.keySet());\r
+ } else if(graph.isInstanceOf(parameterResource, L0.Boolean)) {\r
+ return CollectionUtils.toList("true", "false");\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+ public static Object getPropertyChildName(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+ if(context instanceof Variable) {\r
+ Variable variable = (Variable)context;\r
+ return variable.getParent(graph).getName(graph);\r
+ }\r
+ throw new DatabaseException("Unknown context " + context);\r
+ }\r
+ \r
+ @SCLValue(type = "WriteGraph -> Variable -> a -> b -> String")\r
+ public static String inputModifier(WriteGraph graph, Variable variable, Object value, Object _binding) throws DatabaseException {\r
+\r
+ // System.err.println("inputModifier " + variable.getURI(graph));\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+ Variable parent = variable.getParent(graph);\r
+ Resource property = variable.getPredicateResource(graph);\r
+\r
+ Resource container = parent.getRepresents(graph);\r
+ if(container == null) return null;\r
+ if(property == null) return null;\r
+\r
+ Statement object = graph.getPossibleStatement(container, property);\r
+ if(object == null) return null;\r
+\r
+ Resource objectResource = object.getObject();\r
+ if(graph.sync(new IsEnumeratedValue(objectResource))) {\r
+\r
+ Resource type = graph.getSingleObject(objectResource, L0.PartOf);\r
+\r
+ Map<String, Resource> enumMap = graph.syncRequest(new EnumerationMap(type));\r
+ Resource newLiteral = enumMap.get(value);\r
+ graph.deny(container, property, objectResource);\r
+ graph.claim(container, property, newLiteral);\r
+\r
+ return null;\r
+\r
+ }\r
+\r
+ Resource newType = Layer0Utils.getPossibleLiteralType(graph, variable);\r
+ if(newType == null) {\r
+ Type type = Layer0Utils.getSCLType(graph, variable);\r
+ // This means that type is a wildcard e.g. "a"\r
+ if(Types.canonical(type) instanceof TVar) {\r
+ newType = Layer0Utils.inferLiteralTypeFromString(graph, value.toString());\r
+ } else {\r
+ throw new DatabaseException("Failed to find type for property " + NameUtils.getSafeName(graph, property));\r
+ }\r
+ }\r
+\r
+ boolean correctType = graph.getPossibleType(objectResource, newType) != null;\r
+ boolean asserted = object.isAsserted(container);\r
+ if(asserted || !correctType) {\r
+\r
+ if(correctType) {\r
+\r
+ Statement dt = graph.getPossibleStatement(objectResource, L0.HasDataType);\r
+ Datatype custom = dt.isAsserted(objectResource) ? null : (Datatype)graph.getValue(dt.getObject(), datatype_binging);\r
+\r
+ objectResource = graph.newResource();\r
+ graph.claim(objectResource, L0.InstanceOf, null, newType);\r
+ graph.claim(container, property, objectResource);\r
+ if(custom != null) {\r
+ // Only set HasValueType if the calculated new SCL type differs from the asserted value type\r
+ String newValueType = Layer0Utils.getSCLType(custom);\r
+ String currentValueType = graph.getPossibleRelatedValue(objectResource, L0.HasValueType, Bindings.STRING);\r
+ if (!newValueType.equals(currentValueType)) {\r
+ graph.addLiteral(objectResource, L0.HasValueType, L0.HasValueType_Inverse, L0.String, newValueType, Bindings.STRING);\r
+ }\r
+ graph.addLiteral(objectResource, L0.HasDataType, L0.HasDataType_Inverse, L0.DataType, custom, datatype_binging);\r
+ }\r
+\r
+ } else {\r
+\r
+ if(newType != null) {\r
+\r
+ if(!correctType && !asserted) // if not correct type and not asserted, remove the old value\r
+ graph.deny(container, property, objectResource);\r
+\r
+ objectResource = graph.newResource();\r
+ graph.claim(objectResource, L0.InstanceOf, newType);\r
+ graph.claim(container, property, objectResource);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ }\r
+\r
+ Datatype datatype = variable.getDatatype(graph);\r
+ Binding binding = (Binding)_binding;\r
+ Layer0Utils.claimAdaptedValue(graph, objectResource, value, binding, datatype);\r
+\r
+ return null;\r
+\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> a -> Resource")\r
+ public static Resource singleResourceTransformation(ReadGraph graph, Object input) throws DatabaseException {\r
+ return WorkbenchSelectionUtils.getPossibleResource(graph, input);\r
+ }\r
+\r
+\r
+ @SCLValue(type = "ReadGraph -> a -> Variable")\r
+ public static Variable singleVariableTransformation(ReadGraph graph, Object input) throws DatabaseException {\r
+ Variable single = WorkbenchSelectionUtils.getPossibleVariable(graph, input);\r
+ if(single != null) return single;\r
+ return ISelectionUtils.filterSingleSelection(input, Variable.class);\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> a -> Variable")\r
+ public static Variable singleResourceToVariableTransformation(ReadGraph graph, Object input) throws DatabaseException {\r
+ Resource r = WorkbenchSelectionUtils.getPossibleResource(graph, input);\r
+ if (r == null)\r
+ return null;\r
+ return Variables.getPossibleVariable(graph, r);\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> a -> SelectionInput")\r
+ public static SelectionInput standardSelectionInputTransformation(ReadGraph graph, Object input) throws DatabaseException {\r
+ WorkbenchSelectionElement wse = WorkbenchSelectionUtils.getPossibleSelectionElement(input);\r
+ if (wse == null)\r
+ return null;\r
+ return new StandardSelectionInput(wse);\r
+ }\r
+\r
+ @SCLValue(type = "ValueAccessor")\r
+ public static ValueAccessor displayUnitValueAccessor = new ValueAccessor() {\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return Variables.getPossibleUnit(graph, context.getParent(graph));\r
+ }\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+ try {\r
+ Object value = Variables.getPossibleUnit(graph, context.getParent(graph));\r
+ if(value == null) return null;\r
+ Binding srcBinding = Bindings.OBJECT.getContentBinding(value);\r
+ return Bindings.adapt(value, srcBinding, binding);\r
+ } catch (AdaptException e) {\r
+ throw new DatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return org.simantics.db.layer0.function.All.getDatatypeFromValue(graph, context);\r
+ }\r
+\r
+ };\r
+\r
+ @SCLValue(type = "ValueAccessor")\r
+ public static ValueAccessor displayPropertyValueAccessor = new ValueAccessor() {\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return getValue(graph, context, Bindings.STRING);\r
+ }\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Variable property = context.getParent(graph);\r
+ Resource predicate = property.getPossiblePredicateResource(graph);\r
+ if(predicate == null) return property.getName(graph);\r
+ String value = graph.getPossibleRelatedValue2(predicate, L0.HasLabel, Bindings.STRING);\r
+ if(value == null)\r
+ value = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);\r
+ try {\r
+ return Bindings.adapt(value, binding, Bindings.STRING);\r
+ } catch (AdaptException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph, Variable context)\r
+ throws DatabaseException {\r
+ return Datatypes.STRING;\r
+ }\r
+\r
+ }; \r
+\r
+ @SCLValue(type = "ValueAccessor")\r
+ public static ValueAccessor displayValueValueAccessor = new ValueAccessor() {\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return getValue(graph, context, Bindings.STRING);\r
+ }\r
+\r
+ public boolean isPrimitive(Datatype dt) {\r
+ if(Datatypes.STRING.equals(dt)) return true;\r
+ else return false;\r
+ }\r
+\r
+ private String possibleExpression(ReadGraph graph, Variable variable) throws DatabaseException {\r
+\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Resource object = variable.getPossibleRepresents(graph);\r
+ if(object != null && graph.isInstanceOf(object, L0.SCLValue)) {\r
+ String expression = graph.getPossibleRelatedValue(object, L0.SCLValue_expression);\r
+ if (expression != null)\r
+ return "=" + expression;\r
+ }\r
+ return null;\r
+\r
+ }\r
+\r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context, Binding _binding) throws DatabaseException {\r
+\r
+ Variable property = context.getParent(graph);\r
+\r
+ String expression = possibleExpression(graph, property);\r
+ if(expression != null) return expression;\r
+\r
+ Object value = null;\r
+ Resource formatter = property.getPossiblePropertyValue(graph, Variables.FORMATTER);\r
+ if(formatter != null) {\r
+ \r
+ Formatter fmt = graph.adaptContextual(formatter, property, Variable.class, Formatter.class);\r
+ value = fmt.format(property.getValue(graph));\r
+ \r
+ } else {\r
+\r
+ Variant variant = property.getVariantValue(graph);\r
+ value = variant.getValue();\r
+ \r
+ Binding binding = variant.getBinding();\r
+ if(binding != null) {\r
+ Datatype dt = binding.type(); \r
+ if(dt != null) {\r
+ if(!isPrimitive(dt)) {\r
+ try {\r
+ value = DataValuePrinter.writeValueSingleLine(binding, value);\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ } catch (BindingException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ try {\r
+ return Bindings.adapt(value != null ? value.toString() : "null", _binding, Bindings.STRING);\r
+ } catch (AdaptException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+ try {\r
+ Binding binding = Bindings.getBinding(value.getClass());\r
+ setValue(graph, context, value, binding);\r
+ } catch (BindingConstructionException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object _value, Binding _binding) throws DatabaseException {\r
+ try {\r
+\r
+ if(!(_value instanceof String)) throw new DatabaseException("setValue for HasDisplayValue only accepts String (got " + _value.getClass().getSimpleName() + ")");\r
+\r
+ String text = (String)_value;\r
+ if(text.startsWith("=")) {\r
+ Variable property = context.getParent(graph);\r
+ Layer0Utils.setExpression(graph, property, text, ModelingResources.getInstance(graph).SCLValue);\r
+ return;\r
+ }\r
+\r
+ String parsedLabel = (String)_value;\r
+ Object value = parsedLabel;\r
+\r
+ Datatype type = context.getParent(graph).getPossibleDatatype(graph);\r
+ if (type != null) {\r
+\r
+ Binding binding = Bindings.getBinding(type);\r
+\r
+ if (binding instanceof StringBinding) {\r
+\r
+ if (binding instanceof MutableStringBinding)\r
+ value = new MutableString(parsedLabel);\r
+ else\r
+ value = parsedLabel;\r
+\r
+ } else {\r
+\r
+ if (binding instanceof NumberBinding) {\r
+ parsedLabel = parsedLabel.replace(",", ".");\r
+ }\r
+\r
+ value = binding.parseValue(parsedLabel, new DataValueRepository());\r
+ }\r
+\r
+ //System.out.println("VariableWrite " + ObjectUtils.toString(value));\r
+ context.getParent(graph).setValue(graph, value, binding);\r
+\r
+ } else {\r
+\r
+ context.getParent(graph).setValue(graph, value);\r
+\r
+ }\r
+\r
+\r
+ // Add a comment to metadata.\r
+ CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+ graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));\r
+\r
+ } catch (DataTypeSyntaxError e) {\r
+ throw new DatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph, Variable context)\r
+ throws DatabaseException {\r
+ return Datatypes.STRING;\r
+ }\r
+\r
+ }; \r
+}
\ No newline at end of file