1 package org.simantics.document.linking.wizard;
3 import java.util.HashMap;
6 import org.eclipse.jface.layout.GridDataFactory;
7 import org.eclipse.jface.resource.ImageDescriptor;
8 import org.eclipse.jface.resource.LocalResourceManager;
9 import org.eclipse.jface.viewers.CellEditor;
10 import org.eclipse.jface.viewers.ColumnViewer;
11 import org.eclipse.jface.viewers.ColumnViewerEditor;
12 import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
13 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
14 import org.eclipse.jface.viewers.ICellModifier;
15 import org.eclipse.jface.viewers.ISelection;
16 import org.eclipse.jface.viewers.IStructuredSelection;
17 import org.eclipse.jface.viewers.ITreeContentProvider;
18 import org.eclipse.jface.viewers.LabelProvider;
19 import org.eclipse.jface.viewers.StructuredSelection;
20 import org.eclipse.jface.viewers.TextCellEditor;
21 import org.eclipse.jface.viewers.TreeSelection;
22 import org.eclipse.jface.viewers.TreeViewer;
23 import org.eclipse.jface.viewers.TreeViewerEditor;
24 import org.eclipse.jface.viewers.Viewer;
25 import org.eclipse.jface.viewers.ViewerDropAdapter;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.dnd.DND;
28 import org.eclipse.swt.dnd.DragSourceEvent;
29 import org.eclipse.swt.dnd.DragSourceListener;
30 import org.eclipse.swt.dnd.Transfer;
31 import org.eclipse.swt.dnd.TransferData;
32 import org.eclipse.swt.events.MenuDetectEvent;
33 import org.eclipse.swt.events.MenuDetectListener;
34 import org.eclipse.swt.events.MouseEvent;
35 import org.eclipse.swt.events.SelectionAdapter;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.graphics.Image;
38 import org.eclipse.swt.layout.GridLayout;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Menu;
42 import org.eclipse.swt.widgets.MenuItem;
43 import org.eclipse.swt.widgets.TreeItem;
44 import org.eclipse.ui.plugin.AbstractUIPlugin;
45 import org.simantics.browsing.ui.swt.ComboBoxCellEditor2;
46 import org.simantics.document.linking.report.evaluator.EnumEditableNode;
47 import org.simantics.document.linking.report.evaluator.EvaluatorItem;
48 import org.simantics.document.linking.report.evaluator.EvaluatorNode;
49 import org.simantics.document.linking.report.evaluator.EvaluatorRoot;
50 import org.simantics.document.linking.report.evaluator.StringEditableNode;
51 import org.simantics.document.linking.report.templates.custom.EvaluatorCustomizableContent;
52 import org.simantics.ui.dnd.LocalObjectTransfer;
56 * UI component for configuring evaluator trees.
58 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
61 public class EvaluatorConfigurationWidget extends Composite {
64 EvaluatorCustomizableContent input;
65 LocalResourceManager manager;
72 public EvaluatorConfigurationWidget(Composite parent, LocalResourceManager manager, int style) {
74 this.manager = manager;
75 root = new EvaluatorRoot();
77 setLayout(new GridLayout(1,false));
78 viewer = new TreeViewer(this);
80 TreeViewerEditor.create(viewer, null, new DoubleClickEditorActivationStrategy(viewer), ColumnViewerEditor.DEFAULT);
81 viewer.setContentProvider(new EvaluatorNodeContentProvider());
83 viewer.setLabelProvider(new EvaluatorLabelProvider());
84 viewer.setCellEditors(new CellEditor[]{new EvaluatorNodeCellEditor(viewer.getTree())});
85 viewer.setCellModifier(new EvaluatorNodeCellModifier());
86 viewer.setColumnProperties(new String[]{"value"});
87 viewer.setInput(root);
88 viewer.getTree().addMenuDetectListener(new MenuDetectListener() {
91 public void menuDetected(MenuDetectEvent e) {
92 StructuredSelection sel = (StructuredSelection)viewer.getSelection();
93 createPopupMenu(e, sel);
97 int operations = DND.DROP_COPY| DND.DROP_MOVE;
98 viewer.addDragSupport(operations, new Transfer[]{LocalObjectTransfer.getTransfer()}, new DragSourceListener() {
101 public void dragStart(DragSourceEvent event) {
102 ISelection sel = viewer.getSelection();
104 event.doit = !sel.isEmpty();
110 public void dragSetData(DragSourceEvent event) {
111 if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {
112 event.data = viewer.getSelection();
118 public void dragFinished(DragSourceEvent event) {
119 // TODO Auto-generated method stub
124 viewer.addDropSupport(operations, new Transfer[]{LocalObjectTransfer.getTransfer()}, new ViewerDropAdapter(viewer) {
127 public boolean validateDrop(Object target, int operation,
128 TransferData transferType) {
129 if ((operation & DND.DROP_COPY) > 0) {
131 } else if ((operation & DND.DROP_MOVE) > 0) {
142 public boolean performDrop(Object data) {
143 EvaluatorItem item = (EvaluatorItem)determineTarget(getCurrentEvent());
144 EvaluatorNode parent = item.getParent();
145 EvaluatorItem toProcess = (EvaluatorItem)((TreeSelection)data).getFirstElement();
146 if (toProcess == null)
148 EvaluatorNode toProcessParent = toProcess.getParent();
149 int index = parent.indexOf(item);
150 boolean copy = false;
151 if ((getCurrentOperation() & DND.DROP_COPY) > 0) {
153 toProcess = toProcess.copy();
155 switch (getCurrentLocation()) {
156 case LOCATION_BEFORE: {
157 if (!dropValid(parent, toProcessParent, toProcess, index, copy))
160 if (!copy && toProcessParent != null) {
161 toProcessParent.removeChild(toProcess);
162 viewer.refresh(toProcessParent);
164 parent.addChild(index, toProcess);
165 viewer.refresh(parent);
168 case LOCATION_AFTER: {
169 if (!dropValid(parent, toProcessParent, toProcess, index, copy))
172 if (!copy && toProcessParent != null) {
173 toProcessParent.removeChild(toProcess);
174 viewer.refresh(toProcessParent);
176 parent.addChild(index+1, toProcess);
177 viewer.refresh(parent);
182 if (item instanceof EvaluatorNode) {
183 EvaluatorNode node = ((EvaluatorNode)item);
184 if (!dropValid(node, toProcessParent, toProcess, index, copy))
187 if (!copy && toProcessParent != null) {
188 toProcessParent.removeChild(toProcess);
189 viewer.refresh(toProcessParent);
191 node.addChild(toProcess);
192 viewer.refresh(item);
204 GridDataFactory.fillDefaults().span(1, 1).grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(viewer.getTree());
208 private boolean dropValid(EvaluatorNode parent, EvaluatorNode toProcessParent, EvaluatorItem toProcess, int index, boolean copy) {
209 if (parent.equals(toProcessParent)) {
210 if (copy && !parent.acceptChild(index,toProcess))
213 if (!parent.acceptChild(index,toProcess))
219 public void setInput(EvaluatorCustomizableContent content) {
223 public void updateContent() {
228 viewer.getTree().setEnabled(true);
229 root.getChildren().clear();
230 root.addChild(input.getItem());
231 root.setSupportStyles(input.isSupportStyles());
232 root.setSupportMultiline(input.isSupportMultiline());
233 viewer.setInput(root);
235 root.getChildren().clear();
236 viewer.setInput(root);
237 viewer.getTree().setEnabled(false);
241 private Map<Class<? extends EvaluatorItem>, Image> imageMap = new HashMap<Class<? extends EvaluatorItem>, Image>();
243 private Image getImage(Class<? extends EvaluatorItem> cls) {
244 Image image = imageMap.get(cls);
247 EvaluatorItem tempItem = (EvaluatorItem)cls.newInstance();
248 ImageDescriptor imageDescriptor = tempItem.getImage();
249 if (imageDescriptor != null) {
250 image = manager.createImage(imageDescriptor);
251 imageMap.put(cls, image);
253 } catch (Exception e1) {
254 imageMap.put(cls, null);
260 private void createPopupMenu(MenuDetectEvent event, StructuredSelection sel) {
261 EvaluatorItem i = null;
265 i = (EvaluatorItem) sel.getFirstElement();
267 final EvaluatorItem item = i;
268 Menu menu = new Menu(viewer.getControl());
269 MenuItem add = new MenuItem(menu, SWT.CASCADE);
271 Menu addMenu = new Menu(menu);
272 add.setMenu(addMenu);
273 add.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_right.png")));
275 MenuItem insert = new MenuItem(menu, SWT.CASCADE);
276 insert.setText("Insert");
277 Menu insertMenu = new Menu(menu);
278 insert.setMenu(insertMenu);
279 insert.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_left.png")));
282 if (item instanceof EvaluatorNode) {
283 final EvaluatorNode node = (EvaluatorNode)item;
284 for (final Class<? extends EvaluatorItem> cls : node.getPossibleChildren(true)) {
285 MenuItem menuItem = new MenuItem(addMenu, SWT.PUSH);
286 menuItem.setText(cls.getSimpleName());
287 menuItem.addSelectionListener(new SelectionAdapter() {
288 public void widgetSelected(SelectionEvent e) {
289 node.createChild(cls);
295 menuItem.setImage(getImage(cls));
298 if (addMenu.getItemCount() == 0)
299 add.setEnabled(false);
300 if (item.getParent() != null) {
301 final EvaluatorNode node = item.getParent();
302 for (final Class<? extends EvaluatorItem> cls : node.getPossibleChildren(false)) {
303 if (EvaluatorNode.class.isAssignableFrom(cls)) {
304 MenuItem menuItem = new MenuItem(insertMenu, SWT.PUSH);
305 menuItem.setText(cls.getSimpleName());
306 menuItem.addSelectionListener(new SelectionAdapter() {
307 public void widgetSelected(SelectionEvent e) {
308 int index = node.indexOf(item);
309 node.removeChild(item);
310 EvaluatorNode inserted = (EvaluatorNode)node.createChild(index,cls);
311 inserted.addChild(item);
316 menuItem.setImage(getImage(cls));
320 if (insertMenu.getItemCount() == 0)
321 insert.setEnabled(false);
323 MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
324 menuItem.setText("Remove");
325 menuItem.addSelectionListener(new SelectionAdapter() {
326 public void widgetSelected(SelectionEvent e) {
327 EvaluatorNode parent = item.getParent();
328 if (parent != null) {
329 parent.removeChild(item);
334 menuItem.setEnabled(item != root);
335 menuItem.setImage(manager.createImage(AbstractUIPlugin.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/delete.png")));
336 menu.setLocation(event.x,event.y);
337 menu.setVisible(true);
342 private void update(EvaluatorItem item) {
343 viewer.refresh(item);
345 if (root.getChildren().size() > 0) {
346 input.setItem(root.getChildren().get(0));
348 //input.setItem(null);
353 private class EvaluatorLabelProvider extends LabelProvider {
356 public Image getImage(Object element) {
357 EvaluatorItem item = (EvaluatorItem)element;
358 ImageDescriptor descriptor = item.getImage();
359 if (descriptor == null)
362 return manager.createImage(descriptor);
367 private class EvaluatorNodeContentProvider implements ITreeContentProvider {
370 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
375 public void dispose() {
380 public boolean hasChildren(Object element) {
381 if (element instanceof EvaluatorNode) {
388 public Object getParent(Object element) {
389 if (element instanceof EvaluatorItem) {
390 return ((EvaluatorItem)element).getParent();
396 public Object[] getElements(Object inputElement) {
397 if (inputElement instanceof EvaluatorNode) {
398 EvaluatorNode node = (EvaluatorNode)inputElement;
399 return node.getChildren().toArray();
401 return new Object[0];
405 public Object[] getChildren(Object parentElement) {
406 if (parentElement instanceof EvaluatorNode) {
407 EvaluatorNode node = (EvaluatorNode)parentElement;
408 return node.getChildren().toArray();
410 return new Object[0];
414 private class EvaluatorNodeCellEditor extends CellEditor {
416 TextCellEditor textEditor;
417 ComboBoxCellEditor2 enumEditor;
421 public EvaluatorNodeCellEditor(Composite parent) {
426 Object getSelected() {
427 StructuredSelection sel = (StructuredSelection)viewer.getSelection();
428 return sel.getFirstElement();
432 protected Control createControl(Composite parent) {
433 textEditor = new TextCellEditor(parent);
434 enumEditor = new ComboBoxCellEditor2(parent, new String[0]);
435 current = textEditor;
440 protected Object doGetValue() {
441 return current.getValue();
445 protected void doSetValue(Object value) {
446 Object selected = getSelected();
447 if (selected instanceof StringEditableNode) {
448 if (current != textEditor)
449 current = textEditor;
451 } else if (selected instanceof EnumEditableNode) {
452 if (current != enumEditor)
453 current = enumEditor;
454 enumEditor.setItems(((EnumEditableNode)selected).getEnumearation());
456 current.setValue(value);
460 protected void doSetFocus() {
466 public void activate(ColumnViewerEditorActivationEvent activationEvent) {
467 // TODO Auto-generated method stub
468 current.activate(activationEvent);
472 public void activate() {
477 public void deactivate() {
478 current.deactivate();
482 public Control getControl() {
483 return current.getControl();
488 private class EvaluatorNodeCellModifier implements ICellModifier {
492 public boolean canModify(Object element, String property) {
493 return (element instanceof StringEditableNode || element instanceof EnumEditableNode);
497 public Object getValue(Object element, String property) {
498 if (element instanceof StringEditableNode)
499 return ((StringEditableNode)element).getValue();
500 else if (element instanceof EnumEditableNode) {
501 String values[] = ((EnumEditableNode)element).getEnumearation();
502 String value = ((EnumEditableNode)element).getValue();
503 for (int i = 0; i < values.length; i++) {
504 if (value.equals(values[i]))
512 public void modify(Object element, String property, Object value) {
513 StringEditableNode node = null;
514 EnumEditableNode node2 = null;
515 if (element instanceof TreeItem) {
516 Object data = ((TreeItem)element).getData();
517 if (data instanceof StringEditableNode)
518 node = (StringEditableNode)data;
519 else if (data instanceof EnumEditableNode) {
520 node2 = (EnumEditableNode)data;
522 } else if (element instanceof StringEditableNode){
523 node = (StringEditableNode)element;
524 } else if (element instanceof EnumEditableNode) {
525 node2 = (EnumEditableNode)element;
528 node.setValue((String)value);
530 } else if (node2 != null) {
531 node2.setValue(node2.getEnumearation()[(Integer)value]);
539 private class DoubleClickEditorActivationStrategy extends ColumnViewerEditorActivationStrategy {
541 public DoubleClickEditorActivationStrategy(ColumnViewer viewer) {
546 protected boolean isEditorActivationEvent(
547 ColumnViewerEditorActivationEvent event) {
548 boolean singleSelect = ((IStructuredSelection)viewer.getSelection()).size() == 1;
549 boolean isLeftMouseSelect = event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION && ((MouseEvent)event.sourceEvent).button == 1;
551 return singleSelect && (isLeftMouseSelect
552 || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC
553 || event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL);