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