]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / DerivedPropertiesSection.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java
new file mode 100644 (file)
index 0000000..41356de
--- /dev/null
@@ -0,0 +1,379 @@
+package org.simantics.modeling.ui.componentTypeEditor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.layout.TableColumnLayout;\r
+import org.eclipse.jface.viewers.ColumnWeightData;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.TableEditor;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.ui.forms.widgets.Form;\r
+import org.eclipse.ui.forms.widgets.FormToolkit;\r
+import org.eclipse.ui.forms.widgets.Section;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleIndexRoot;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.userComponent.ComponentTypeCommands;\r
+import org.simantics.scl.runtime.function.Function4;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+public class DerivedPropertiesSection implements ComponentTypeViewerSection {\r
+    private static final String[] COLUMN_NAMES = \r
+            new String[] {"Name", "Type", "Expression", "Label", "Description"};\r
+    private static final int[] COLUMN_LENGTHS =\r
+            new int[] { 120, 100, 100, 100, 100 };\r
+    private static final int[] COLUMN_WEIGHTS =\r
+            new int[] { 0, 0, 100, 0, 0 };\r
+    private static Function4<RequestProcessor, Resource, Resource, String, String> VALIDATE_MONITOR_EXPRESSION =\r
+            new Function4<RequestProcessor, Resource, Resource, String, String>() {\r
+        @Override\r
+        public String apply(RequestProcessor p0, Resource p1, Resource p2, String p3) {\r
+            return validateMonitorExpression(p0, p1, p2, p3);\r
+        }\r
+    };\r
+    \r
+    ComponentTypeViewerData data;\r
+    Table table;\r
+    TableColumn[] columns;\r
+    TableEditor editor;\r
+    Button newProperty;\r
+    Button removeProperty;\r
+    \r
+    Section section;\r
+    \r
+    public DerivedPropertiesSection(ComponentTypeViewerData data) {\r
+        this.data = data;\r
+        FormToolkit tk = data.tk;\r
+        Form form = data.form;\r
+        section = tk.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED);\r
+        section.setLayout(new FillLayout());\r
+        section.setText("Derived properties");\r
+\r
+        Composite sectionBody = tk.createComposite(section);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(sectionBody);\r
+        section.setClient(sectionBody);\r
+\r
+        Composite tableComposite = tk.createComposite(sectionBody);\r
+        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(tableComposite);\r
+        TableColumnLayout tcl = new TableColumnLayout();\r
+        tableComposite.setLayout(tcl);\r
+\r
+        table = tk.createTable(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);\r
+        table.setLinesVisible(true);\r
+        table.setHeaderVisible(true);\r
+\r
+        columns = new TableColumn[COLUMN_NAMES.length];\r
+        for(int i=0;i<COLUMN_NAMES.length;++i) {\r
+            TableColumn column = new TableColumn(table, SWT.NONE);\r
+            columns[i] = column;\r
+            tcl.setColumnData(column, new ColumnWeightData(COLUMN_WEIGHTS[i], COLUMN_LENGTHS[i], true));\r
+            column.setText(COLUMN_NAMES[i]);\r
+        }\r
+\r
+        // Table editor\r
+        editor = new TableEditor(table);\r
+        editor.grabHorizontal = true;\r
+        editor.grabVertical = true;\r
+        editor.horizontalAlignment = SWT.LEFT;\r
+        table.addMouseListener(new MouseAdapter() {\r
+            @Override\r
+            public void mouseDown(MouseEvent e) {\r
+                // Clean up any previous editor control\r
+                Control oldEditor = editor.getEditor();\r
+                if (oldEditor != null) oldEditor.dispose();\r
+\r
+                if (data.readOnly)\r
+                    return;\r
+\r
+                // Relative position\r
+                Rectangle tableBounds = table.getClientArea();\r
+                int rx = e.x - tableBounds.x;\r
+                int ry = e.y - tableBounds.y;\r
+\r
+                // Find cell\r
+                TableItem selectedItem = null;\r
+                int selectedColumn = -1;\r
+                Rectangle selectedItemBounds = null;\r
+                for(TableItem item : table.getItems()) {\r
+                    for(int column = 0;column < COLUMN_NAMES.length;++column) {\r
+                        Rectangle bounds = item.getBounds(column);\r
+                        if(bounds.contains(rx, ry)) {\r
+                            selectedItemBounds = bounds;\r
+                            selectedItem = item;\r
+                            selectedColumn = column;\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+                if(selectedItem == null) {\r
+                    return;\r
+                }\r
+\r
+                // Table editor\r
+                final int column = selectedColumn; \r
+                final ComponentTypeViewerPropertyInfo propertyInfo = (ComponentTypeViewerPropertyInfo)selectedItem.getData();\r
+                final Resource resource = propertyInfo.resource;\r
+                switch (column) {\r
+                case 0:\r
+                    data.editName(table, editor, propertyInfo, selectedItem, column, ComponentTypeViewerData.PROPERTY_NAME_PATTERN);\r
+                    break;\r
+\r
+                case 1:\r
+                    data.editType(table, editor, propertyInfo, selectedItem, column, false);\r
+                    break;\r
+\r
+                case 2:\r
+                    data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
+                            ComponentTypeCommands.setMonitorExpression(graph, data.componentType, resource, newValue);\r
+                        }\r
+                    }, VALIDATE_MONITOR_EXPRESSION);\r
+                    break;\r
+\r
+//                case 3:\r
+//                    editUnit(table2, editor2, propertyInfo, selectedItem, column);\r
+//                    break;\r
+\r
+                case 3:\r
+                    data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
+                            graph.markUndoPoint();\r
+                            String value = newValue.isEmpty() ? null : newValue;\r
+                            ComponentTypeCommands.setLabel(graph, resource, value);\r
+                        }\r
+                    }, null);\r
+                    break;\r
+\r
+                case 4:\r
+                    data.editMultilineText(table, editor, propertyInfo, selectedItem, selectedItemBounds, column, new StringWriter() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
+                            graph.markUndoPoint();\r
+                            String value = newValue.isEmpty() ? null : newValue;\r
+                            ComponentTypeCommands.setDescription(graph, resource, value);\r
+                        }\r
+                    });\r
+                    break;\r
+                }\r
+            }\r
+\r
+        });\r
+\r
+        // Buttons\r
+\r
+        Composite buttons = tk.createComposite(sectionBody);\r
+        GridDataFactory.fillDefaults().applyTo(buttons);\r
+        GridLayoutFactory.fillDefaults().applyTo(buttons);\r
+\r
+        newProperty = tk.createButton(buttons, "New property", SWT.PUSH);\r
+        GridDataFactory.fillDefaults().applyTo(newProperty);\r
+        removeProperty = tk.createButton(buttons, "Remove property", SWT.PUSH);\r
+        GridDataFactory.fillDefaults().applyTo(removeProperty);\r
+\r
+        // Actions\r
+\r
+        newProperty.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                if(editor.getEditor() != null)\r
+                    editor.getEditor().dispose();\r
+                Simantics.getSession().async(new WriteRequest() {\r
+                    @Override\r
+                    public void perform(WriteGraph graph)\r
+                            throws DatabaseException {\r
+                        ComponentTypeCommands.createMonitorPropertyWithDefaults(graph, data.componentType);\r
+                    }\r
+                });\r
+            }\r
+        });\r
+\r
+        removeProperty.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                if(editor.getEditor() != null)\r
+                    editor.getEditor().dispose();\r
+                final List<Resource> propertiesToBeRemoved = \r
+                        new ArrayList<>();\r
+                for(TableItem item : table.getSelection())\r
+                    propertiesToBeRemoved.add(((ComponentTypeViewerPropertyInfo)item.getData()).resource);\r
+                //System.out.println("remove " + propertiesToBeRemoved.size() + " resources");\r
+                if(!propertiesToBeRemoved.isEmpty())\r
+                    Simantics.getSession().async(new WriteRequest() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph)\r
+                                throws DatabaseException {\r
+                            graph.markUndoPoint();\r
+                            for(Resource property : propertiesToBeRemoved)\r
+                                ComponentTypeCommands.removeProperty(graph, data.componentType, property);\r
+                        }\r
+                    });\r
+            }\r
+        });\r
+    }\r
+\r
+    @Override\r
+    public void setReadOnly(boolean readOnly) {\r
+        boolean e = !readOnly;\r
+        newProperty.setEnabled(e);\r
+        removeProperty.setEnabled(e);\r
+    }\r
+\r
+    public static String validateMonitorExpression(final RequestProcessor processor, final Resource componentType, final Resource relation, final String expression) {\r
+\r
+        if (expression.trim().isEmpty()) {\r
+            return "Expression is empty.";\r
+        }\r
+\r
+        if (expression.trim().isEmpty()) {\r
+            return "Expression is empty.";\r
+        }\r
+        try {\r
+            return processor.sync(new UniqueRead<String>() {\r
+\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+\r
+                    StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+\r
+                    Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(componentType));\r
+\r
+                    for(Resource literal : graph.getAssertedObjects(componentType, relation)) {\r
+\r
+                        try {\r
+                            // TODO validation\r
+                            if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) {\r
+                                //Layer0 L0 = Layer0.getInstance(graph);\r
+                                //Resource environment = graph.getPossibleObject(literal, L0.SCLValue_environment); \r
+                                //ContextModule context = graph.sync(new TypeMonitorContextRequest(componentType));\r
+                                //String SCLMain = graph.syncRequest(new SCLMainModuleRequest(indexRoot));\r
+                                //CompilationContext cc = new CompilationContext(environment, context, SCLMain);\r
+                                //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());\r
+                            } else {\r
+                                //CompilationContext cc = new CompileSCLMonitorRequest(literal, componentType, indexRoot).getContext(graph);\r
+                                //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());\r
+                                //graph.syncRequest(new CompileSCLMonitorRequest(graph, context));\r
+                            }\r
+                            \r
+                        } catch (Exception e) {\r
+                            String msg = e.getMessage();\r
+                            int index = msg.indexOf(":");\r
+                            if(index > 0) msg = msg.substring(index);\r
+                            return msg;\r
+                        }\r
+                        \r
+                    }\r
+                    \r
+                    return null;\r
+                    \r
+                }\r
+                \r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        return null;\r
+\r
+    }\r
+\r
+    @Override\r
+    public void update(ComponentTypePropertiesResult result) {\r
+        if (table.isDisposed())\r
+            return;\r
+\r
+        Set<ComponentTypeViewerPropertyInfo> selected = new HashSet<>();\r
+        List<TableItem> selectedItems = new ArrayList<TableItem>(selected.size());\r
+        for (int i : table.getSelectionIndices()) {\r
+            TableItem item = table.getItem(i);\r
+            selected.add((ComponentTypeViewerPropertyInfo) item.getData());\r
+        }\r
+        \r
+        int topIndex = table.getTopIndex();\r
+        table.removeAll();\r
+        if(editor.getEditor() != null)\r
+            editor.getEditor().dispose();\r
+        \r
+        for(ComponentTypeViewerPropertyInfo info : result.getProperties()) {\r
+            boolean immutable = result.isImmutable() || info.immutable;\r
+            Color fg = immutable ? table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY) : null;\r
+            if(info.sectionSpecificData != MONITOR)\r
+                continue;\r
+\r
+            TableItem item = new TableItem(table, SWT.NONE);\r
+\r
+            item.setText(0, info.valid != null ? info.name + " (!)" : info.name);\r
+            item.setText(1, info.type);\r
+            item.setText(2, info.expression);\r
+            //item.setText(3, unitStr(info));\r
+            item.setText(3, info.label);\r
+            item.setText(4, info.description);\r
+\r
+            item.setForeground(fg);\r
+\r
+            item.setData(info);\r
+\r
+            if (selected.contains(info))\r
+                selectedItems.add(item);\r
+        }\r
+        \r
+        table.setTopIndex(topIndex);\r
+        table.setSelection(selectedItems.toArray(new TableItem[selectedItems.size()]));\r
+        table.redraw();\r
+    }\r
+\r
+    @Override\r
+    public Section getSection() {\r
+        return section;\r
+    }\r
+\r
+    @Override\r
+    public double getPriority() {\r
+        return 100.0;\r
+    }\r
+\r
+    private static final Object MONITOR = new Object();\r
+    \r
+    @Override\r
+    public Object getSectionSpecificData(ReadGraph graph,\r
+            ComponentTypeViewerPropertyInfo info) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+        Resource range = graph.getPossibleObject(info.resource, L0.HasRange);\r
+        if(range != null && graph.isInstanceOf(range, STR.MonitorValueType))\r
+            return MONITOR;\r
+        else\r
+            return null;\r
+    }\r
+    \r
+    @Override\r
+    public double getDataPriority() {\r
+        return 100.0;\r
+    }\r
+\r
+}\r