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