]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/wizard/EvaluatorConfigurationWidget.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.document.linking.ui / src / org / simantics / document / linking / wizard / EvaluatorConfigurationWidget.java
diff --git a/bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/wizard/EvaluatorConfigurationWidget.java b/bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/wizard/EvaluatorConfigurationWidget.java
new file mode 100644 (file)
index 0000000..3fd2aa0
--- /dev/null
@@ -0,0 +1,559 @@
+package org.simantics.document.linking.wizard;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ColumnViewer;\r
+import org.eclipse.jface.viewers.ColumnViewerEditor;\r
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;\r
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;\r
+import org.eclipse.jface.viewers.ICellModifier;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.jface.viewers.TreeSelection;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.viewers.TreeViewerEditor;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerDropAdapter;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DragSourceEvent;\r
+import org.eclipse.swt.dnd.DragSourceListener;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.dnd.TransferData;\r
+import org.eclipse.swt.events.MenuDetectEvent;\r
+import org.eclipse.swt.events.MenuDetectListener;\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.Image;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.swt.widgets.MenuItem;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.simantics.browsing.ui.swt.ComboBoxCellEditor2;\r
+import org.simantics.document.linking.report.evaluator.EnumEditableNode;\r
+import org.simantics.document.linking.report.evaluator.EvaluatorItem;\r
+import org.simantics.document.linking.report.evaluator.EvaluatorNode;\r
+import org.simantics.document.linking.report.evaluator.EvaluatorRoot;\r
+import org.simantics.document.linking.report.evaluator.StringEditableNode;\r
+import org.simantics.document.linking.report.templates.custom.EvaluatorCustomizableContent;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+\r
+\r
+/**\r
+ * UI component for configuring evaluator trees.\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class EvaluatorConfigurationWidget extends Composite {\r
+       \r
+       \r
+       EvaluatorCustomizableContent input;\r
+       LocalResourceManager manager;\r
+       \r
+       EvaluatorRoot root;\r
+\r
+       TreeViewer viewer;\r
+\r
+       \r
+       public EvaluatorConfigurationWidget(Composite parent, LocalResourceManager manager, int style) {\r
+               super(parent, style);\r
+               this.manager = manager;\r
+               root = new EvaluatorRoot();\r
+               \r
+               setLayout(new GridLayout(1,false));\r
+               viewer = new TreeViewer(this);\r
+               \r
+               TreeViewerEditor.create(viewer, null, new DoubleClickEditorActivationStrategy(viewer), ColumnViewerEditor.DEFAULT);\r
+               viewer.setContentProvider(new EvaluatorNodeContentProvider());\r
+               \r
+               viewer.setLabelProvider(new EvaluatorLabelProvider());\r
+               viewer.setCellEditors(new CellEditor[]{new EvaluatorNodeCellEditor(viewer.getTree())});\r
+               viewer.setCellModifier(new EvaluatorNodeCellModifier());\r
+               viewer.setColumnProperties(new String[]{"value"});\r
+               viewer.setInput(root);\r
+               viewer.getTree().addMenuDetectListener(new MenuDetectListener() {\r
+                       \r
+                       @Override\r
+                       public void menuDetected(MenuDetectEvent e) {\r
+                               StructuredSelection sel = (StructuredSelection)viewer.getSelection();\r
+                               createPopupMenu(e, sel);\r
+                               \r
+                       }\r
+               });\r
+               int operations = DND.DROP_COPY| DND.DROP_MOVE;\r
+               viewer.addDragSupport(operations, new Transfer[]{LocalObjectTransfer.getTransfer()}, new DragSourceListener() {\r
+                       \r
+                       @Override\r
+                       public void dragStart(DragSourceEvent event) {\r
+                               ISelection sel = viewer.getSelection();\r
+                               \r
+                               event.doit = !sel.isEmpty();\r
+                                       \r
+                               \r
+                       }\r
+                       \r
+                       @Override\r
+                       public void dragSetData(DragSourceEvent event) {\r
+                               if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {\r
+                                       event.data = viewer.getSelection();\r
+                               }\r
+                               \r
+                       }\r
+                       \r
+                       @Override\r
+                       public void dragFinished(DragSourceEvent event) {\r
+                               // TODO Auto-generated method stub\r
+                               \r
+                       }\r
+               });\r
+               \r
+               viewer.addDropSupport(operations, new Transfer[]{LocalObjectTransfer.getTransfer()}, new ViewerDropAdapter(viewer) {\r
+                       \r
+                       @Override\r
+                       public boolean validateDrop(Object target, int operation,\r
+                                       TransferData transferType) {\r
+                               if ((operation & DND.DROP_COPY) > 0) {\r
+                                       return true;\r
+                               } else if ((operation & DND.DROP_MOVE) > 0) {\r
+                                       return true;\r
+                               }  else {\r
+                                       return false;\r
+                               }\r
+                               \r
+                       }\r
+                       \r
+                       \r
+                       \r
+                       @Override\r
+                       public boolean performDrop(Object data) {\r
+                               EvaluatorItem item = (EvaluatorItem)determineTarget(getCurrentEvent());\r
+                               EvaluatorNode parent = item.getParent();\r
+                               EvaluatorItem toProcess = (EvaluatorItem)((TreeSelection)data).getFirstElement();\r
+                               if (toProcess == null)\r
+                                       return false;\r
+                               EvaluatorNode toProcessParent = toProcess.getParent();\r
+                               int index = parent.indexOf(item);\r
+                               boolean copy = false;\r
+                               if ((getCurrentOperation() & DND.DROP_COPY) > 0) {\r
+                                       copy = true;\r
+                                       toProcess = toProcess.copy();\r
+                               }\r
+                               switch (getCurrentLocation()) {\r
+                                       case LOCATION_BEFORE: {\r
+                                               if (!dropValid(parent, toProcessParent, toProcess, index, copy))\r
+                                                       return false;\r
+                                                       \r
+                                               if (!copy && toProcessParent != null) {\r
+                                                       toProcessParent.removeChild(toProcess);\r
+                                                       viewer.refresh(toProcessParent);\r
+                                               }\r
+                                               parent.addChild(index, toProcess);\r
+                                               viewer.refresh(parent);\r
+                                               return true;\r
+                                       }\r
+                                       case LOCATION_AFTER: {\r
+                                               if (!dropValid(parent, toProcessParent, toProcess, index, copy))\r
+                                                       return false;\r
+                                               \r
+                                               if (!copy && toProcessParent != null) {\r
+                                                       toProcessParent.removeChild(toProcess);\r
+                                                       viewer.refresh(toProcessParent);\r
+                                               }\r
+                                               parent.addChild(index+1, toProcess);\r
+                                               viewer.refresh(parent);\r
+                                               return true;\r
+                                       }\r
+                                       \r
+                                       case LOCATION_ON: {\r
+                                               if (item instanceof EvaluatorNode) {\r
+                                                       EvaluatorNode node = ((EvaluatorNode)item);\r
+                                                       if (!dropValid(node, toProcessParent, toProcess, index, copy))\r
+                                                               return false;\r
+                                                       \r
+                                                       if (!copy && toProcessParent != null) {\r
+                                                               toProcessParent.removeChild(toProcess);\r
+                                                               viewer.refresh(toProcessParent);\r
+                                                       }\r
+                                                       node.addChild(toProcess);\r
+                                                       viewer.refresh(item);\r
+                                                       if (!copy)\r
+                                                               \r
+                                                       return true;\r
+                                               } \r
+                                               return false;\r
+                                       }\r
+                               }\r
+                               return false;\r
+                       }\r
+               });\r
+               \r
+               GridDataFactory.fillDefaults().span(1, 1).grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(viewer.getTree());\r
+\r
+       }\r
+       \r
+       private boolean dropValid(EvaluatorNode parent, EvaluatorNode toProcessParent, EvaluatorItem toProcess, int index, boolean copy) {\r
+               if (parent.equals(toProcessParent)) {\r
+                       if (copy && !parent.acceptChild(index,toProcess))\r
+                               return false;\r
+               } else {\r
+                       if (!parent.acceptChild(index,toProcess))\r
+                               return false;\r
+               }\r
+               return true;\r
+       }\r
+       \r
+       public void setInput(EvaluatorCustomizableContent content) {\r
+               input = content;\r
+       }\r
+       \r
+       public void updateContent() {\r
+\r
+               if (input != null) {\r
+                       \r
+                       \r
+                       viewer.getTree().setEnabled(true);\r
+                       root.getChildren().clear();\r
+                       root.addChild(input.getItem());\r
+                       root.setSupportStyles(input.isSupportStyles());\r
+                       root.setSupportMultiline(input.isSupportMultiline());\r
+                       viewer.setInput(root);\r
+               } else {\r
+                       root.getChildren().clear();\r
+                       viewer.setInput(root);\r
+                       viewer.getTree().setEnabled(false);\r
+               }\r
+       }\r
+       \r
+       private Map<Class<? extends EvaluatorItem>, Image> imageMap = new HashMap<Class<? extends EvaluatorItem>, Image>();\r
+       \r
+       private Image getImage(Class<? extends EvaluatorItem> cls) {\r
+               Image image = imageMap.get(cls);\r
+               if (image == null) {\r
+                       try {\r
+                               EvaluatorItem tempItem = (EvaluatorItem)cls.newInstance();\r
+                               ImageDescriptor imageDescriptor = tempItem.getImage();\r
+                               if (imageDescriptor != null) {\r
+                                       image = manager.createImage(imageDescriptor);\r
+                                       imageMap.put(cls, image);\r
+                               }\r
+                       } catch (Exception e1) {\r
+                               imageMap.put(cls, null);\r
+                       }\r
+               }\r
+               return image;\r
+       }\r
+       \r
+       private void createPopupMenu(MenuDetectEvent event, StructuredSelection sel) {\r
+               EvaluatorItem i = null;\r
+               if (sel.isEmpty()) {\r
+                       i = root;\r
+               } else {\r
+                       i = (EvaluatorItem) sel.getFirstElement();\r
+               }\r
+               final EvaluatorItem item = i;\r
+               Menu menu = new Menu(viewer.getControl());\r
+               MenuItem add = new MenuItem(menu, SWT.CASCADE);\r
+               add.setText("Add");\r
+               Menu addMenu = new Menu(menu);\r
+               add.setMenu(addMenu);\r
+               add.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_right.png")));\r
+               \r
+               MenuItem insert = new MenuItem(menu, SWT.CASCADE);\r
+               insert.setText("Insert");\r
+               Menu insertMenu = new Menu(menu);\r
+               insert.setMenu(insertMenu);\r
+               insert.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_left.png")));\r
+               \r
+               // add menu\r
+               if (item instanceof EvaluatorNode) {\r
+                       final EvaluatorNode node = (EvaluatorNode)item;\r
+                       for (final Class<? extends EvaluatorItem> cls : node.getPossibleChildren(true)) {\r
+                               MenuItem menuItem = new MenuItem(addMenu, SWT.PUSH);\r
+                               menuItem.setText(cls.getSimpleName());\r
+                               menuItem.addSelectionListener(new SelectionAdapter() {\r
+                                       public void widgetSelected(SelectionEvent e) {\r
+                                               node.createChild(cls);\r
+                                               update(node);\r
+                                       };\r
+                               });\r
+                               \r
+                               \r
+                               menuItem.setImage(getImage(cls));\r
+                       }\r
+               }\r
+               if (addMenu.getItemCount() == 0)\r
+                       add.setEnabled(false);\r
+               if (item.getParent() != null) {\r
+                       final EvaluatorNode node = item.getParent();\r
+                       for (final Class<? extends EvaluatorItem> cls : node.getPossibleChildren(false)) {\r
+                               if (EvaluatorNode.class.isAssignableFrom(cls)) {\r
+                                       MenuItem menuItem = new MenuItem(insertMenu, SWT.PUSH);\r
+                                       menuItem.setText(cls.getSimpleName());\r
+                                       menuItem.addSelectionListener(new SelectionAdapter() {\r
+                                               public void widgetSelected(SelectionEvent e) {\r
+                                                       int index = node.indexOf(item);\r
+                                                       node.removeChild(item);\r
+                                                       EvaluatorNode inserted = (EvaluatorNode)node.createChild(index,cls);\r
+                                                       inserted.addChild(item);\r
+                                                       update(node);\r
+                                               };\r
+                                       });\r
+                                       \r
+                                       menuItem.setImage(getImage(cls));\r
+                               }\r
+                       }\r
+               }\r
+               if (insertMenu.getItemCount() == 0)\r
+                       insert.setEnabled(false);\r
+               \r
+               MenuItem menuItem = new MenuItem(menu, SWT.PUSH);\r
+               menuItem.setText("Remove");\r
+               menuItem.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               EvaluatorNode parent = item.getParent();\r
+                               if (parent != null) {\r
+                                       parent.removeChild(item);\r
+                                       update(parent);\r
+                               }\r
+                       };\r
+               });\r
+               menuItem.setEnabled(item != root);\r
+               menuItem.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/delete.png")));\r
+               menu.setLocation(event.x,event.y);\r
+               menu.setVisible(true);\r
+               \r
+               \r
+       }\r
+       \r
+       private void update(EvaluatorItem item) {\r
+               viewer.refresh(item);\r
+               if (item == root) {\r
+                       if (root.getChildren().size() > 0) {\r
+                               input.setItem(root.getChildren().get(0));\r
+                       } else {\r
+                               //input.setItem(null);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private class EvaluatorLabelProvider extends LabelProvider {\r
+               \r
+               @Override\r
+               public Image getImage(Object element) {\r
+                       EvaluatorItem item = (EvaluatorItem)element;\r
+                       ImageDescriptor descriptor = item.getImage();\r
+                       if (descriptor == null)\r
+                               return null;\r
+                       \r
+                       return manager.createImage(descriptor);\r
+               }\r
+               \r
+       }\r
+       \r
+       private class EvaluatorNodeContentProvider implements ITreeContentProvider {\r
+               \r
+               @Override\r
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public void dispose() {\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public boolean hasChildren(Object element) {\r
+                       if (element instanceof EvaluatorNode) {\r
+                               return true;\r
+                       }\r
+                       return false;\r
+               }\r
+               \r
+               @Override\r
+               public Object getParent(Object element) {\r
+                       if (element instanceof EvaluatorItem) {\r
+                               return ((EvaluatorItem)element).getParent();\r
+                       }\r
+                       return null;\r
+               }\r
+               \r
+               @Override\r
+               public Object[] getElements(Object inputElement) {\r
+                       if (inputElement instanceof EvaluatorNode) {\r
+                               EvaluatorNode node = (EvaluatorNode)inputElement;\r
+                               return node.getChildren().toArray();\r
+                       }\r
+                       return new Object[0];\r
+               }\r
+               \r
+               @Override\r
+               public Object[] getChildren(Object parentElement) {\r
+                       if (parentElement instanceof EvaluatorNode) {\r
+                               EvaluatorNode node = (EvaluatorNode)parentElement;\r
+                               return node.getChildren().toArray();\r
+                       }\r
+                       return new Object[0];\r
+               }\r
+       }\r
+       \r
+       private class EvaluatorNodeCellEditor extends CellEditor {\r
+\r
+               TextCellEditor textEditor;\r
+               ComboBoxCellEditor2 enumEditor;\r
+               \r
+               CellEditor current;\r
+               \r
+               public EvaluatorNodeCellEditor(Composite parent) {\r
+                       super(parent);\r
+                       \r
+               }\r
+               \r
+               Object getSelected() {\r
+                       StructuredSelection sel = (StructuredSelection)viewer.getSelection();\r
+                       return sel.getFirstElement();\r
+               }\r
+               \r
+               @Override\r
+               protected Control createControl(Composite parent) {\r
+                       textEditor = new TextCellEditor(parent);\r
+                       enumEditor = new ComboBoxCellEditor2(parent, new String[0]);\r
+                       current = textEditor;\r
+                       return null;\r
+               }\r
+               \r
+               @Override\r
+               protected Object doGetValue() {\r
+                       return current.getValue();\r
+               }\r
+               \r
+               @Override\r
+               protected void doSetValue(Object value) {\r
+                       Object selected = getSelected();\r
+                       if (selected instanceof StringEditableNode) {\r
+                               if (current != textEditor)\r
+                                       current = textEditor;\r
+                               \r
+                       } else if (selected instanceof EnumEditableNode) {\r
+                               if (current != enumEditor)\r
+                                       current = enumEditor;\r
+                               enumEditor.setItems(((EnumEditableNode)selected).getEnumearation());\r
+                       }\r
+                       current.setValue(value);\r
+               }\r
+               \r
+               @Override\r
+               protected void doSetFocus() {\r
+                       current.setFocus();\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public void activate(ColumnViewerEditorActivationEvent activationEvent) {\r
+                       // TODO Auto-generated method stub\r
+                       current.activate(activationEvent);\r
+               }\r
+               \r
+               @Override\r
+               public void activate() {\r
+                       current.activate();\r
+               }\r
+               \r
+               @Override\r
+               public void deactivate() {\r
+                       current.deactivate();\r
+               }\r
+               \r
+               @Override\r
+               public Control getControl() {\r
+                       return current.getControl();\r
+               }\r
+               \r
+       }\r
+       \r
+       private class EvaluatorNodeCellModifier implements ICellModifier {\r
+               \r
+               \r
+               @Override\r
+               public boolean canModify(Object element, String property) {\r
+                       return (element instanceof StringEditableNode || element instanceof EnumEditableNode);\r
+               }\r
+               \r
+               @Override\r
+               public Object getValue(Object element, String property) {\r
+                       if (element instanceof StringEditableNode)\r
+                               return ((StringEditableNode)element).getValue();\r
+                       else if (element instanceof EnumEditableNode) {\r
+                               String values[] = ((EnumEditableNode)element).getEnumearation();\r
+                               String value = ((EnumEditableNode)element).getValue();\r
+                               for (int i = 0; i < values.length; i++) {\r
+                                       if (value.equals(values[i]))\r
+                                               return i;\r
+                               }\r
+                               return 0;\r
+                       }\r
+                       return "";\r
+               }\r
+               @Override\r
+               public void modify(Object element, String property, Object value) {\r
+                       StringEditableNode node = null;\r
+                       EnumEditableNode node2 = null;\r
+                       if (element instanceof TreeItem) {\r
+                               Object data = ((TreeItem)element).getData();\r
+                               if (data instanceof StringEditableNode)\r
+                                       node = (StringEditableNode)data;\r
+                               else if (data instanceof EnumEditableNode) {\r
+                                       node2 = (EnumEditableNode)data;\r
+                               }\r
+                       } else if (element instanceof StringEditableNode){\r
+                               node = (StringEditableNode)element;\r
+                       } else if (element instanceof EnumEditableNode) {\r
+                               node2 = (EnumEditableNode)element;\r
+                       }\r
+                       if (node != null) {\r
+                               node.setValue((String)value);\r
+                               update(node);\r
+                       } else if (node2 != null) {\r
+                               node2.setValue(node2.getEnumearation()[(Integer)value]);\r
+                               update(node2);\r
+                       }\r
+                       \r
+               }\r
+       }\r
+       \r
+       \r
+       private class DoubleClickEditorActivationStrategy extends ColumnViewerEditorActivationStrategy {\r
+\r
+               public DoubleClickEditorActivationStrategy(ColumnViewer viewer) {\r
+                       super(viewer);\r
+               }\r
+               \r
+               @Override\r
+               protected boolean isEditorActivationEvent(\r
+                               ColumnViewerEditorActivationEvent event) {\r
+                       boolean singleSelect = ((IStructuredSelection)viewer.getSelection()).size() == 1;\r
+                       boolean isLeftMouseSelect = event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION && ((MouseEvent)event.sourceEvent).button == 1;\r
+\r
+                       return singleSelect && (isLeftMouseSelect\r
+                                       || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC\r
+                                       || event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL);\r
+               }\r
+               \r
+       }\r
+       \r
+\r
+}\r