0001: /*
0002: * Copyright 2006 Pentaho Corporation. All rights reserved.
0003: * This software was developed by Pentaho Corporation and is provided under the terms
0004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
0005: * this file except in compliance with the license. If you need a copy of the license,
0006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
0007: * BI Platform. The Initial Developer is Pentaho Corporation.
0008: *
0009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
0010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
0011: * the license for the specific language governing your rights and limitations.
0012: */
0013: package org.pentaho.designstudio.widgets.flowtable;
0014:
0015: import java.util.ArrayList;
0016: import java.util.Arrays;
0017: import java.util.Iterator;
0018: import java.util.List;
0019:
0020: import org.dom4j.Element;
0021: import org.eclipse.jface.dialogs.Dialog;
0022: import org.eclipse.jface.dialogs.IDialogConstants;
0023: import org.eclipse.jface.util.ListenerList;
0024: import org.eclipse.jface.viewers.ISelectionChangedListener;
0025: import org.eclipse.jface.viewers.IStructuredSelection;
0026: import org.eclipse.jface.viewers.ITreeContentProvider;
0027: import org.eclipse.jface.viewers.SelectionChangedEvent;
0028: import org.eclipse.jface.viewers.StructuredSelection;
0029: import org.eclipse.jface.viewers.StructuredViewer;
0030: import org.eclipse.jface.viewers.Viewer;
0031: import org.eclipse.jface.viewers.ViewerDropAdapter;
0032: import org.eclipse.swt.SWT;
0033: import org.eclipse.swt.dnd.DragSourceAdapter;
0034: import org.eclipse.swt.dnd.DragSourceEvent;
0035: import org.eclipse.swt.dnd.DragSourceListener;
0036: import org.eclipse.swt.dnd.DropTargetEvent;
0037: import org.eclipse.swt.dnd.TransferData;
0038: import org.eclipse.swt.events.SelectionEvent;
0039: import org.eclipse.swt.events.SelectionListener;
0040: import org.eclipse.swt.graphics.Point;
0041: import org.eclipse.swt.graphics.Rectangle;
0042: import org.eclipse.swt.widgets.Button;
0043: import org.eclipse.swt.widgets.Composite;
0044: import org.eclipse.swt.widgets.Control;
0045: import org.eclipse.swt.widgets.Event;
0046: import org.eclipse.swt.widgets.Listener;
0047: import org.eclipse.swt.widgets.Shell;
0048: import org.eclipse.swt.widgets.Widget;
0049: import org.pentaho.actionsequence.dom.ActionControlStatement;
0050: import org.pentaho.actionsequence.dom.ActionIfStatement;
0051: import org.pentaho.actionsequence.dom.ActionLoop;
0052: import org.pentaho.actionsequence.dom.ActionOutput;
0053: import org.pentaho.actionsequence.dom.ActionSequenceDocument;
0054: import org.pentaho.actionsequence.dom.ActionSequenceInput;
0055: import org.pentaho.actionsequence.dom.IActionSequenceElement;
0056: import org.pentaho.actionsequence.dom.IActionSequenceExecutableStatement;
0057: import org.pentaho.actionsequence.dom.actions.ActionDefinition;
0058: import org.pentaho.designstudio.controls.WidgetFactory;
0059: import org.pentaho.designstudio.editors.actionsequence.pages.ActionSequenceLabelProvider;
0060: import org.pentaho.designstudio.editors.actionsequence.pages.actions.IActionsViewer;
0061: import org.pentaho.designstudio.messages.Messages;
0062:
0063: import de.kupzog.ktable.KTableCellSelectionListener;
0064:
0065: /**
0066: * A concrete viewer based on an SWT <code>Tree</code> control.
0067: * <p>
0068: * This class is not intended to be subclassed outside the viewer framework. It
0069: * is designed to be instantiated with a pre-existing SWT tree control and
0070: * configured with a domain-specific content provider, label provider, element
0071: * filter (optional), and element sorter (optional).
0072: * </p>
0073: * <p>
0074: * Content providers for tree viewers must implement the
0075: * <code>ITreeContentProvider</code> interface.
0076: * </p>
0077: */
0078: public class FlowViewer extends StructuredViewer implements
0079: IActionsViewer {
0080:
0081: public class ActionLocationDialog extends Dialog {
0082:
0083: boolean addWithin = true;
0084:
0085: public ActionLocationDialog(Shell parentShell) {
0086: super (parentShell);
0087: }
0088:
0089: protected void configureShell(Shell shell) {
0090: super .configureShell(shell);
0091: shell
0092: .setText(Messages
0093: .getString("ActionsViewer.UI_ADD_ACTION_POPUP_LABEL")); //$NON-NLS-1$
0094: }
0095:
0096: protected void createButtonsForButtonBar(Composite parent) {
0097: createButton(parent, IDialogConstants.OK_ID,
0098: IDialogConstants.OK_LABEL, true);
0099: }
0100:
0101: protected Control createDialogArea(Composite parent) {
0102: Composite composite = (Composite) super
0103: .createDialogArea(parent);
0104: Button button = WidgetFactory
0105: .createButton(
0106: composite,
0107: Messages
0108: .getString("ActionsViewer.UI_ADD_ACTION_WITHIN_LABEL"), SWT.RADIO); //$NON-NLS-1$
0109: button.addSelectionListener(new SelectionListener() {
0110: public void widgetDefaultSelected(SelectionEvent e) {
0111: }
0112:
0113: public void widgetSelected(SelectionEvent e) {
0114: Button button = (Button) e.getSource();
0115: if (button.getSelection()) {
0116: addWithin = true;
0117: }
0118: }
0119: });
0120: button = WidgetFactory
0121: .createButton(
0122: composite,
0123: Messages
0124: .getString("ActionsViewer.UI_ADD_ACTION_AFTER_LABEL"), SWT.RADIO); //$NON-NLS-1$
0125: button.addSelectionListener(new SelectionListener() {
0126: public void widgetDefaultSelected(SelectionEvent e) {
0127: }
0128:
0129: public void widgetSelected(SelectionEvent e) {
0130: Button button = (Button) e.getSource();
0131: if (button.getSelection()) {
0132: addWithin = false;
0133: }
0134: }
0135: });
0136: return composite;
0137: }
0138: }
0139:
0140: class ActionTreeDragListener extends DragSourceAdapter {
0141: IActionSequenceElement draggedElement;
0142:
0143: /* (non-Javadoc)
0144: * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
0145: */
0146: public void dragFinished(DragSourceEvent event) {
0147: if (!(draggedElement instanceof ActionDefinition)) {
0148: if (lastSelection != null) {
0149: setSelection(
0150: new StructuredSelection(lastSelection),
0151: true);
0152: } else {
0153: setSelection(new StructuredSelection());
0154: }
0155: } else {
0156: getControl().forceFocus();
0157: }
0158: draggedElement = null;
0159: fireDragFinished(event);
0160: }
0161:
0162: /* (non-Javadoc)
0163: * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
0164: */
0165: public void dragSetData(DragSourceEvent event) {
0166:
0167: event.data = draggedElement;
0168: }
0169:
0170: /* (non-Javadoc)
0171: * @see org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
0172: */
0173: public void dragStart(DragSourceEvent event) {
0174: // if (ActionSequenceFormToolkit.isMacOS) {
0175: // if (lastPointMousePressed != null) {
0176: // TreeItem treeItem = getTree().getItem(lastPointMousePressed);
0177: // if (treeItem != null) {
0178: // draggedElement = (IActionSequenceElement)treeItem.getData();
0179: // if (draggedElement instanceof ActionOutput) {
0180: // event.doit = true;
0181: // fireDragStart(event);
0182: // } else {
0183: // draggedElement = null;
0184: // event.doit = false;
0185: // }
0186: //// dropAdapter.setFeedbackEnabled((draggedElement instanceof ActionDefinition) || (draggedElement instanceof ActionControlStatement));
0187: // } else {
0188: // draggedElement = null;
0189: // event.doit = false;
0190: // }
0191: // }
0192: // } else {
0193: IStructuredSelection selection = (IStructuredSelection) getSelection();
0194: if (selection.size() == 1) {
0195: draggedElement = (IActionSequenceElement) selection
0196: .getFirstElement();
0197: if ((draggedElement instanceof ActionOutput)
0198: || (draggedElement instanceof ActionSequenceInput)) {
0199: event.doit = true;
0200: fireDragStart(event);
0201: } else {
0202: draggedElement = null;
0203: event.doit = false;
0204: }
0205: // dropAdapter.setFeedbackEnabled((draggedElement instanceof ActionDefinition) || (draggedElement instanceof ActionControlStatement));
0206: } else {
0207: draggedElement = null;
0208: event.doit = false;
0209: }
0210: // }
0211: }
0212: }
0213:
0214: // class ActionTreeDragListener extends DragSourceAdapter {
0215: // IActionSequenceElement draggedElement;
0216: //
0217: // /* (non-Javadoc)
0218: // * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
0219: // */
0220: // public void dragFinished(DragSourceEvent event) {
0221: // if (!(draggedElement instanceof ActionDefinition)) {
0222: // if (lastSelection != null) {
0223: // setSelection(new StructuredSelection(lastSelection), true);
0224: // } else {
0225: // setSelection(new StructuredSelection());
0226: // }
0227: // } else {
0228: // getControl().forceFocus();
0229: // }
0230: // draggedElement = null;
0231: // fireDragFinished(event);
0232: // }
0233: //
0234: // /* (non-Javadoc)
0235: // * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
0236: // */
0237: // public void dragSetData(DragSourceEvent event) {
0238: // event.data = draggedElement.getElement().getUniquePath();
0239: // }
0240: //
0241: // /* (non-Javadoc)
0242: // * @see org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
0243: // */
0244: // public void dragStart(DragSourceEvent event) {
0245: // //System.out.println("Action Tree drag start");
0246: // IStructuredSelection selection = (IStructuredSelection)getSelection();
0247: // if (selection.size() == 1) {
0248: // int items[] = flowTable.getRowSelection();
0249: // FlowContent flowContent = (FlowContent)flowTable.actionsFlowModel.getContentAt( 0, items[0]);
0250: // if (!(flowContent instanceof TerminatorContent)) {
0251: // draggedElement = (IActionSequenceElement)selection.getFirstElement();
0252: // dropAdapter.setFeedbackEnabled((draggedElement instanceof ActionDefinition) || (draggedElement instanceof ActionControlStatement));
0253: // event.doit = true;
0254: // fireDragStart(event);
0255: // } else {
0256: // draggedElement = null;
0257: // event.doit = false;
0258: // }
0259: // } else {
0260: // draggedElement = null;
0261: // event.doit = false;
0262: // }
0263: // }
0264: // }
0265:
0266: class ActionTreeDropAdapter extends ViewerDropAdapter {
0267: ActionTreeDropAdapter() {
0268: super (FlowViewer.this );
0269: }
0270:
0271: private boolean movingOnTopOfSelf(
0272: IActionSequenceElement targetElement) {
0273: IActionSequenceElement siblingBeforeTarget = null;
0274: IActionSequenceElement siblingAfterTarget = null;
0275: ActionControlStatement parentControlStatement = null;
0276: if (targetElement instanceof ActionDefinition) {
0277: parentControlStatement = ((ActionDefinition) targetElement)
0278: .getParent();
0279: } else if (targetElement instanceof ActionControlStatement) {
0280: parentControlStatement = ((ActionControlStatement) targetElement)
0281: .getParent();
0282: }
0283: IActionSequenceElement[] siblings = null;
0284: if (parentControlStatement != null) {
0285: siblings = parentControlStatement.getChildren();
0286: } else {
0287: siblings = targetElement.getDocument()
0288: .getExecutableChildren();
0289: }
0290: int index = Arrays.asList(siblings).indexOf(targetElement);
0291: siblingBeforeTarget = (index != 0 ? siblings[index - 1]
0292: : null);
0293: siblingAfterTarget = (index < siblings.length - 1 ? siblings[index + 1]
0294: : null);
0295:
0296: return (((getCurrentLocation() == LOCATION_BEFORE) && dragListener.draggedElement
0297: .equals(siblingBeforeTarget))
0298: || dragListener.draggedElement
0299: .equals(targetElement) || ((getCurrentLocation() == LOCATION_AFTER) && dragListener.draggedElement
0300: .equals(siblingAfterTarget)));
0301: }
0302:
0303: /* (non-Javadoc)
0304: * @see org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
0305: */
0306: public boolean performDrop(Object data) {
0307: boolean result = false;
0308: ActionSequenceDocument actionSequenceDocument = (ActionSequenceDocument) getInput();
0309: IActionSequenceElement droppedElement = actionSequenceDocument
0310: .getElement((String) data);
0311: if (droppedElement instanceof ActionOutput) {
0312: ActionOutput actionOutput = (ActionOutput) droppedElement;
0313: droppedElement = actionOutput.getActionDefinition();
0314: }
0315: if (getCurrentTarget() instanceof IActionSequenceElement) {
0316: IActionSequenceElement targetElement = (IActionSequenceElement) getCurrentTarget();
0317: int index = 0;
0318: if (targetElement != null) {
0319: if (!movingOnTopOfSelf(targetElement)) {
0320: int loc = getCurrentLocation();
0321: ActionControlStatement parentControlStatement = null;
0322: if (targetElement instanceof ActionDefinition) {
0323: ActionDefinition actionDef = (ActionDefinition) targetElement;
0324: parentControlStatement = actionDef
0325: .getParent();
0326: if (parentControlStatement != null) {
0327: index = Arrays.asList(
0328: parentControlStatement
0329: .getChildren())
0330: .indexOf(targetElement);
0331: } else {
0332: index = Arrays
0333: .asList(
0334: actionSequenceDocument
0335: .getExecutableChildren())
0336: .indexOf(targetElement);
0337: }
0338: index++;
0339: } else if (targetElement instanceof ActionControlStatement) {
0340: if (loc == LOCATION_ON) {
0341: parentControlStatement = (ActionControlStatement) targetElement;
0342: index = 0;
0343: } else {
0344: ActionControlStatement controlStatement = (ActionControlStatement) targetElement;
0345: parentControlStatement = controlStatement
0346: .getParent();
0347: if (parentControlStatement != null) {
0348: index = Arrays.asList(
0349: parentControlStatement
0350: .getChildren())
0351: .indexOf(targetElement);
0352: } else {
0353: index = Arrays
0354: .asList(
0355: actionSequenceDocument
0356: .getExecutableChildren())
0357: .indexOf(targetElement);
0358: }
0359: if (parentControlStatement != null) {
0360: index = Arrays.asList(
0361: parentControlStatement
0362: .getChildren())
0363: .indexOf(targetElement);
0364: } else {
0365: index = Arrays
0366: .asList(
0367: actionSequenceDocument
0368: .getExecutableChildren())
0369: .indexOf(targetElement);
0370: }
0371: index++;
0372: }
0373: }
0374:
0375: if (parentControlStatement == null) {
0376: Object[] children = actionSequenceDocument
0377: .getExecutableChildren();
0378: if (index >= children.length) {
0379: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0380: ((IActionSequenceExecutableStatement) droppedElement)
0381: .moveTo(null);
0382: }
0383: } else {
0384: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0385: ((IActionSequenceExecutableStatement) droppedElement)
0386: .moveTo(null, index);
0387: }
0388: }
0389: } else {
0390: Object[] children = parentControlStatement
0391: .getChildren();
0392: if (index >= children.length) {
0393: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0394: ((IActionSequenceExecutableStatement) droppedElement)
0395: .moveTo(parentControlStatement);
0396: }
0397: } else {
0398: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0399: ((IActionSequenceExecutableStatement) droppedElement)
0400: .moveTo(
0401: parentControlStatement,
0402: index);
0403: }
0404: }
0405: }
0406: result = true;
0407: setSelection(new StructuredSelection(
0408: droppedElement));
0409: }
0410: } else {
0411: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0412: ((IActionSequenceExecutableStatement) droppedElement)
0413: .moveTo(null);
0414: }
0415: result = true;
0416: setSelection(new StructuredSelection(droppedElement));
0417: }
0418:
0419: } else if (getCurrentTarget() instanceof ActionSequenceDocument) {
0420: if (droppedElement instanceof IActionSequenceExecutableStatement) {
0421: ((IActionSequenceExecutableStatement) droppedElement)
0422: .moveTo(null, 0);
0423: setSelection(new StructuredSelection(droppedElement));
0424: }
0425: }
0426:
0427: ActionsRenderer actionsRenderer = (ActionsRenderer) flowTable
0428: .getModel().getCellRenderer(0, 0);
0429: int prevDragOverRow = actionsRenderer.getDropRow();
0430: if (prevDragOverRow != -1) {
0431: actionsRenderer.setDropRow(-1);
0432: Rectangle rectangle = new Rectangle(0, prevDragOverRow,
0433: 1, 1);
0434: flowTable.redraw(rectangle);
0435: }
0436: return result;
0437: }
0438:
0439: /*
0440: * (non-Javadoc)
0441: *
0442: * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object,
0443: * int, org.eclipse.swt.dnd.TransferData)
0444: */
0445: public boolean validateDrop(Object target, int op,
0446: TransferData type) {
0447: return true;
0448: // boolean isValid = false;
0449: // if (dragListener.draggedElement != null) {
0450: // int location = getCurrentLocation();
0451: // if ((dragListener.draggedElement instanceof ActionLoop) || (dragListener.draggedElement instanceof ActionDefinition)) {
0452: // if ((target == null) || (target instanceof ActionLoop)) {
0453: // isValid = true;
0454: // } else if (target instanceof ActionDefinition) {
0455: // if (location == LOCATION_BEFORE) {
0456: // isValid = true;
0457: // } else if (location == LOCATION_AFTER) {
0458: // isValid = true;
0459: // }
0460: // }
0461: // }
0462: // }
0463: // return isValid;
0464: }
0465:
0466: protected Object determineTarget(DropTargetEvent event) {
0467: Object target = null;
0468: int rowCount = flowTable.getModel().getRowCount();
0469: for (int i = 0; i < rowCount; i++) {
0470: Rectangle rectangle = flowTable.getCellRect(0, i);
0471: Point point = flowTable.toDisplay(rectangle.x,
0472: rectangle.y);
0473: rectangle = new Rectangle(point.x, point.y,
0474: rectangle.width, rectangle.height);
0475: int borderOffset = 0;
0476: if (event.y == point.y + rectangle.height) {
0477: borderOffset = 1;
0478: }
0479: if (rectangle.contains(event.x, event.y - borderOffset)) {
0480: FlowContent content = (FlowContent) flowTable
0481: .getModel().getContentAt(0, i);
0482: if (content != null) {
0483: target = content.getData();
0484: }
0485: }
0486: }
0487: return target;
0488: }
0489:
0490: protected int determineLocation(DropTargetEvent event) {
0491: int location = LOCATION_NONE;
0492: int rowCount = flowTable.getModel().getRowCount();
0493: for (int i = 0; i < rowCount; i++) {
0494: Rectangle rectangle = flowTable.getCellRect(0, i);
0495: Point point = flowTable.toDisplay(rectangle.x,
0496: rectangle.y);
0497: rectangle = new Rectangle(point.x, point.y,
0498: rectangle.width, rectangle.height);
0499: int borderOffset = 0;
0500: if (event.y == point.y + rectangle.height) {
0501: borderOffset = 1;
0502: }
0503: if (rectangle.contains(event.x, event.y - borderOffset)) {
0504: FlowContent content = (FlowContent) flowTable
0505: .getModel().getContentAt(0, i);
0506: if (content != null) {
0507: Object data = content.getData();
0508: if ((data instanceof ActionDefinition)
0509: || (content instanceof TerminatorContent)) {
0510: location = LOCATION_AFTER;
0511: break;
0512: } else if (data instanceof ActionControlStatement) {
0513: location = LOCATION_ON;
0514: break;
0515: }
0516: }
0517: }
0518: }
0519:
0520: return location;
0521: }
0522:
0523: public void dragOver(DropTargetEvent event) {
0524: super .dragOver(event);
0525: ActionsRenderer actionsRenderer = (ActionsRenderer) flowTable
0526: .getModel().getCellRenderer(0, 0);
0527: int rowCount = flowTable.getModel().getRowCount();
0528: int newDropRow = -1;
0529: for (int i = 0; (i < rowCount) && (newDropRow == -1); i++) {
0530: Rectangle rectangle = flowTable.getCellRect(0, i);
0531: Point point = flowTable.toDisplay(rectangle.x,
0532: rectangle.y);
0533: rectangle = new Rectangle(point.x, point.y,
0534: rectangle.width, rectangle.height);
0535: int borderOffset = 0;
0536: if (event.y == point.y + rectangle.height) {
0537: borderOffset = 1;
0538: }
0539: if (rectangle.contains(event.x, event.y - borderOffset)) {
0540: newDropRow = i;
0541: }
0542: }
0543:
0544: if (newDropRow != -1) {
0545: if (getCurrentTarget() instanceof IActionSequenceElement) {
0546: if (movingOnTopOfSelf((IActionSequenceElement) getCurrentTarget())) {
0547: newDropRow = -1;
0548: }
0549: } else if (getCurrentTarget() instanceof ActionSequenceDocument) {
0550: if (flowTable.getModel().getRowCount() <= 1) {
0551: newDropRow = -1;
0552: } else {
0553: newDropRow = 1;
0554: }
0555: }
0556: }
0557:
0558: if (actionsRenderer.getDropRow() != newDropRow) {
0559: if (actionsRenderer.getDropRow() != -1) {
0560: int prevDragOverRow = actionsRenderer.getDropRow();
0561: actionsRenderer.setDropRow(-1);
0562: Rectangle rectangle = new Rectangle(0,
0563: prevDragOverRow, 1, 1);
0564: flowTable.redraw(rectangle);
0565: }
0566: actionsRenderer.setDropRow(newDropRow);
0567: if (newDropRow != -1) {
0568: Rectangle rectangle = new Rectangle(0, newDropRow,
0569: 1, 1);
0570: flowTable.redraw(rectangle);
0571: }
0572: }
0573:
0574: }
0575:
0576: public void dragLeave(DropTargetEvent event) {
0577: // TODO Auto-generated method stub
0578: super .dragLeave(event);
0579: ActionsRenderer actionsRenderer = (ActionsRenderer) flowTable
0580: .getModel().getCellRenderer(0, 0);
0581: if (actionsRenderer.getDropRow() != -1) {
0582: int prevDragOverRow = actionsRenderer.getDropRow();
0583: actionsRenderer.setDropRow(-1);
0584: Rectangle rectangle = new Rectangle(0, prevDragOverRow,
0585: 1, 1);
0586: flowTable.redraw(rectangle);
0587: }
0588: }
0589:
0590: }
0591:
0592: public class ContentProvider implements ITreeContentProvider {
0593:
0594: public ContentProvider() {
0595: }
0596:
0597: /* (non-Javadoc)
0598: * Method declared on ITreeContentProvider.
0599: */
0600: public Object[] getChildren(Object parent) {
0601: Object[] children = new Object[0];
0602: if (parent instanceof ActionControlStatement) {
0603: children = ((ActionControlStatement) parent)
0604: .getChildren();
0605: } else if (parent instanceof ActionDefinition) {
0606: children = ((ActionDefinition) parent)
0607: .getAllOutputParams();
0608: }
0609: return children;
0610: }
0611:
0612: /* (non-Javadoc)
0613: * Method declared on ITreeContentProvider.
0614: */
0615: public Object getParent(Object child) {
0616: Object parent = null;
0617: if (child instanceof ActionControlStatement) {
0618: parent = ((ActionControlStatement) child).getParent();
0619: } else if (child instanceof ActionDefinition) {
0620: parent = ((ActionDefinition) child).getParent();
0621: } else if (child instanceof ActionOutput) {
0622: parent = ((ActionOutput) child).getActionDefinition();
0623: }
0624: return parent;
0625: }
0626:
0627: /* (non-Javadoc)
0628: * Method declared on ITreeContentProvider.
0629: */
0630: public boolean hasChildren(Object node) {
0631: boolean result = false;
0632: if (node instanceof ActionControlStatement) {
0633: result = ((ActionControlStatement) node).getChildren().length > 0;
0634: } else if (node instanceof ActionDefinition) {
0635: result = ((ActionDefinition) node).getAllOutputParams().length > 0;
0636: }
0637: return result;
0638: }
0639:
0640: /* (non-Javadoc)
0641: * Method declared on ITreeContentProvider.
0642: */
0643: public Object[] getElements(Object inputElement) {
0644: if (flowTable.actionsFlowModel.actionSequence != null) {
0645: return flowTable.actionsFlowModel.actionSequence
0646: .getExecutableChildren();
0647: } else {
0648: return new Object[0];
0649: }
0650: }
0651:
0652: /* (non-Javadoc)
0653: * Method declared on ITreeContentProvider.
0654: */
0655: public void dispose() {
0656: }
0657:
0658: /* (non-Javadoc)
0659: * Method declared on ITreeContentProvider.
0660: */
0661: public void inputChanged(Viewer viewer, Object oldInput,
0662: Object newInput) {
0663: flowTable
0664: .setActionSequence((ActionSequenceDocument) newInput);
0665: }
0666:
0667: }
0668:
0669: /**
0670: * This viewer's control.
0671: */
0672: private final ActionsFlowTable flowTable;
0673: IActionSequenceElement lastSelection;
0674: private ActionTreeDropAdapter dropAdapter;
0675: private ActionTreeDragListener dragListener;
0676: private ListenerList dragSourceListeners = new ListenerList(1);
0677:
0678: /**
0679: * Creates a flow viewer on the given flowtable control. The viewer has no input,
0680: * no content provider, a default label provider, no sorter, and no filters.
0681: *
0682: * @param tree
0683: * the tree control
0684: */
0685: public FlowViewer(final ActionsFlowTable flowTable) {
0686: super ();
0687: this .flowTable = flowTable;
0688: hookControl(flowTable);
0689: this .flowTable
0690: .addCellSelectionListener(new KTableCellSelectionListener() {
0691:
0692: public void cellSelected(int col, int row,
0693: int statemask) {
0694: Event e = new Event();
0695: e.time = (int) System.currentTimeMillis();
0696: e.type = SWT.Selection;
0697: e.widget = flowTable;
0698: // SelectionEvent event = new SelectionEvent( e );
0699: flowTable.notifyListeners(SWT.Selection, e);
0700:
0701: //fireSelectionEvent(event);
0702: }
0703:
0704: public void fixedCellSelected(int col, int row,
0705: int statemask) {
0706: // System.out.println( Messages.getString("FlowViewer.DEBUG_FIXED_CELL_SELECTED_PRINTLN") + row + ":" + col + ":" + statemask ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
0707: }
0708:
0709: });
0710:
0711: flowTable.addListener(SWT.MenuDetect, new Listener() {
0712:
0713: public void handleEvent(Event event) {
0714: List selectionList = getSelectionFromWidget();
0715: if ((selectionList == null)
0716: || (selectionList.size() == 0)) {
0717: event.doit = false;
0718: } else {
0719: Object selection = selectionList.get(0);
0720: if (!(selection instanceof Element)
0721: || (!((Element) selection)
0722: .getName()
0723: .equals(
0724: ActionSequenceDocument.ACTION_DEFINITION_NAME) && !((Element) selection)
0725: .getName()
0726: .equals(
0727: ActionSequenceDocument.ACTIONS_NAME))) {
0728: event.doit = false;
0729: }
0730: }
0731: }
0732: });
0733:
0734: setLabelProvider(new ActionSequenceLabelProvider(flowTable
0735: .getDisplay()));
0736: setContentProvider(new ContentProvider());
0737:
0738: addPostSelectionChangedListener(new ISelectionChangedListener() {
0739: public void selectionChanged(SelectionChangedEvent event) {
0740: Object selectedObject = ((IStructuredSelection) getSelection())
0741: .getFirstElement();
0742: if (selectedObject instanceof IActionSequenceElement) {
0743: lastSelection = (IActionSequenceElement) selectedObject;
0744: } else {
0745: lastSelection = null;
0746: }
0747: }
0748: });
0749: // int ops = DND.DROP_MOVE | DND.DROP_COPY;
0750: // Transfer[] transfers = new Transfer[] { TextTransfer.getInstance() };
0751: // dragListener = new ActionTreeDragListener();
0752: // addDragSupport(ops, transfers, dragListener);
0753: // transfers = new Transfer[] { TextTransfer.getInstance() };
0754: // dropAdapter = new ActionTreeDropAdapter();
0755: // addDropSupport(ops, transfers, dropAdapter);
0756: }
0757:
0758: protected Widget doFindInputItem(Object element) {
0759: // System.out.println( Messages.getString("FlowViewer.DEBUG_DO_FIND_INPUT_ITEM") + element ); //$NON-NLS-1$
0760: return null;
0761: }
0762:
0763: protected Widget doFindItem(Object element) {
0764: // System.out.println( Messages.getString("FlowViewer.DEBUG_DO_FIND_ITEM") + element ); //$NON-NLS-1$
0765: return null;
0766: }
0767:
0768: protected void doUpdateItem(Widget item, Object element,
0769: boolean fullMap) {
0770: }
0771:
0772: protected List getSelectionFromWidget() {
0773: ArrayList selections = new ArrayList();
0774: Point[] points = flowTable.getCellSelection();
0775: for (int i = 0; i < points.length; i++) {
0776: selections.add(flowTable.getModel().getContentAt(
0777: points[i].x, points[i].y));
0778: }
0779: return selections;
0780: }
0781:
0782: protected void internalRefresh(Object element) {
0783: flowTable.refresh();
0784: }
0785:
0786: protected void internalUpdate(Widget widget, Object element,
0787: String[] properties) {
0788: // Point point = flowTable.actionsFlowModel.getCellWithContent(element);
0789: // if (point != null) {
0790: // Rectangle rectangle = new Rectangle(point.x, point.y, 1, 1);
0791: // flowTable.redraw(rectangle);
0792: // }
0793: }
0794:
0795: public void reveal(Object element) {
0796: // System.out.println( Messages.getString("FlowViewer.DEBUG_REVEAL") + element ); //$NON-NLS-1$
0797: }
0798:
0799: protected void setSelectionToWidget(List l, boolean reveal) {
0800: int selectedRow = -1;
0801: int selectedColumn = -1;
0802: if (l.size() > 0) {
0803: ActionsFlowModel actionsFlowModel = (ActionsFlowModel) flowTable
0804: .getModel();
0805: for (int row = 0; (row < actionsFlowModel.getRowCount())
0806: && (selectedRow == -1); row++) {
0807: for (int column = 0; (column < actionsFlowModel
0808: .getColumnCount())
0809: && (selectedColumn == -1); column++) {
0810: Point point = flowTable.getValidCell(column, row);
0811: if ((point.x == column)
0812: && (point.y == row)
0813: && (l.get(0).equals(actionsFlowModel
0814: .getContentAt(column, row)))) {
0815: selectedRow = row;
0816: selectedColumn = column;
0817: }
0818: }
0819: }
0820: }
0821: if ((selectedRow != -1) && (selectedColumn != -1)) {
0822: flowTable.setSelection(selectedColumn, selectedRow, reveal);
0823: }
0824: }
0825:
0826: public Control getControl() {
0827: return (flowTable);
0828: }
0829:
0830: public Widget findItemX(Object element) {
0831: return (super .findItem(element));
0832: }
0833:
0834: public void remove(Object element) {
0835: flowTable.refresh(); // This will rebuild the component based on the current document
0836: // System.out.println( Messages.getString("FlowViewer.DEBUG_REMOVE") + element ); //$NON-NLS-1$
0837: }
0838:
0839: protected void inputChanged(Object input, Object oldInput) {
0840: super .inputChanged(input, oldInput);
0841: internalRefresh(input);
0842: }
0843:
0844: public void deleteSelectedActions() {
0845: IStructuredSelection selection = (IStructuredSelection) getSelection();
0846: for (Iterator iter = selection.iterator(); iter.hasNext();) {
0847: Object selectedItem = iter.next();
0848: if (selectedItem instanceof IActionSequenceElement) {
0849: ((IActionSequenceElement) selectedItem).delete();
0850: }
0851: }
0852: }
0853:
0854: public ActionDefinition createNewAction(Class actionDefinitionClass)
0855: throws InstantiationException, IllegalAccessException {
0856: return createNewAction(actionDefinitionClass, null);
0857: }
0858:
0859: public ActionDefinition createNewAction(
0860: Class actionDefinitionClass, String description)
0861: throws InstantiationException, IllegalAccessException {
0862: ActionControlStatement parent = null;
0863: int index = 0;
0864: IStructuredSelection selectedActions = (IStructuredSelection) getSelection();
0865: if (selectedActions.size() == 1) {
0866: if (selectedActions.getFirstElement() instanceof ActionControlStatement) {
0867: ActionControlStatement selectedControlStatement = (ActionControlStatement) selectedActions
0868: .getFirstElement();
0869: ActionLocationDialog dialog = new ActionLocationDialog(
0870: getControl().getShell());
0871: dialog.open();
0872: if (!dialog.addWithin) {
0873: parent = selectedControlStatement.getParent();
0874: if (parent != null) {
0875: index = Arrays.asList(parent.getChildren())
0876: .indexOf(selectedControlStatement) + 1;
0877: } else {
0878: index = Arrays.asList(
0879: selectedControlStatement.getDocument()
0880: .getExecutableChildren())
0881: .indexOf(selectedControlStatement) + 1;
0882: }
0883: } else {
0884: parent = selectedControlStatement;
0885: }
0886: } else if (selectedActions.getFirstElement() instanceof ActionDefinition) {
0887: ActionDefinition selectedActionDef = (ActionDefinition) selectedActions
0888: .getFirstElement();
0889: parent = selectedActionDef.getParent();
0890: if (parent != null) {
0891: index = Arrays.asList(parent.getChildren())
0892: .indexOf(selectedActionDef) + 1;
0893: } else {
0894: index = Arrays.asList(
0895: selectedActionDef.getDocument()
0896: .getExecutableChildren()).indexOf(
0897: selectedActionDef) + 1;
0898: }
0899: }
0900: }
0901:
0902: ActionDefinition newActionDef = null;
0903: if (parent != null) {
0904: newActionDef = parent.addAction(actionDefinitionClass,
0905: index);
0906: } else {
0907: newActionDef = ((ActionSequenceDocument) getInput())
0908: .addAction(actionDefinitionClass, index);
0909: }
0910:
0911: if (newActionDef != null) {
0912: if (description != null) {
0913: newActionDef.setDescription(description);
0914: }
0915: setSelection(new StructuredSelection(newActionDef), true);
0916: lastSelection = newActionDef;
0917: }
0918:
0919: return newActionDef;
0920: }
0921:
0922: public ActionIfStatement createNewIfStatement() {
0923: ActionControlStatement parent = null;
0924: int index = 0;
0925: IStructuredSelection selectedActions = (IStructuredSelection) getSelection();
0926: if (selectedActions.size() == 1) {
0927: if (selectedActions.getFirstElement() instanceof ActionControlStatement) {
0928: ActionControlStatement selectedControlStatement = (ActionControlStatement) selectedActions
0929: .getFirstElement();
0930: ActionLocationDialog dialog = new ActionLocationDialog(
0931: getControl().getShell());
0932: dialog.open();
0933: if (!dialog.addWithin) {
0934: parent = selectedControlStatement.getParent();
0935: if (parent != null) {
0936: index = Arrays.asList(parent.getChildren())
0937: .indexOf(selectedControlStatement) + 1;
0938: } else {
0939: index = Arrays.asList(
0940: selectedControlStatement.getDocument()
0941: .getExecutableChildren())
0942: .indexOf(selectedControlStatement) + 1;
0943: }
0944: } else {
0945: parent = selectedControlStatement;
0946: }
0947: } else if (selectedActions.getFirstElement() instanceof ActionDefinition) {
0948: ActionDefinition selectedActionDef = (ActionDefinition) selectedActions
0949: .getFirstElement();
0950: parent = selectedActionDef.getParent();
0951: if (parent != null) {
0952: index = Arrays.asList(parent.getChildren())
0953: .indexOf(selectedActionDef) + 1;
0954: } else {
0955: index = Arrays.asList(
0956: selectedActionDef.getDocument()
0957: .getExecutableChildren()).indexOf(
0958: selectedActionDef) + 1;
0959: }
0960: }
0961: }
0962:
0963: ActionIfStatement newActionIf = null;
0964:
0965: if (parent == null) {
0966: newActionIf = ((ActionSequenceDocument) getInput()).addIf(
0967: "", index); //$NON-NLS-1$
0968: } else {
0969: newActionIf = parent.addIf("", index); //$NON-NLS-1$
0970: }
0971:
0972: if (newActionIf != null) {
0973: setSelection(new StructuredSelection(newActionIf));
0974: lastSelection = newActionIf;
0975: }
0976:
0977: return newActionIf;
0978: }
0979:
0980: public ActionLoop createNewLoop() {
0981: ActionControlStatement parent = null;
0982: int index = 0;
0983: IStructuredSelection selectedActions = (IStructuredSelection) getSelection();
0984: if (selectedActions.size() == 1) {
0985: if (selectedActions.getFirstElement() instanceof ActionControlStatement) {
0986: ActionControlStatement selectedControlStatement = (ActionControlStatement) selectedActions
0987: .getFirstElement();
0988: ActionLocationDialog dialog = new ActionLocationDialog(
0989: getControl().getShell());
0990: dialog.open();
0991: if (!dialog.addWithin) {
0992: parent = selectedControlStatement.getParent();
0993: if (parent != null) {
0994: index = Arrays.asList(parent.getChildren())
0995: .indexOf(selectedControlStatement) + 1;
0996: } else {
0997: index = Arrays.asList(
0998: selectedControlStatement.getDocument()
0999: .getExecutableChildren())
1000: .indexOf(selectedControlStatement) + 1;
1001: }
1002: } else {
1003: parent = selectedControlStatement;
1004: }
1005: } else if (selectedActions.getFirstElement() instanceof ActionDefinition) {
1006: ActionDefinition selectedActionDef = (ActionDefinition) selectedActions
1007: .getFirstElement();
1008: parent = selectedActionDef.getParent();
1009: if (parent != null) {
1010: index = Arrays.asList(parent.getChildren())
1011: .indexOf(selectedActionDef) + 1;
1012: } else {
1013: index = Arrays.asList(
1014: selectedActionDef.getDocument()
1015: .getExecutableChildren()).indexOf(
1016: selectedActionDef) + 1;
1017: }
1018: }
1019: }
1020:
1021: ActionLoop newActionLoop = null;
1022: if (parent == null) {
1023: newActionLoop = ((ActionSequenceDocument) getInput())
1024: .addLoop("", index); //$NON-NLS-1$
1025: } else {
1026: newActionLoop = parent.addLoop("", index); //$NON-NLS-1$
1027: }
1028:
1029: if (newActionLoop != null) {
1030: setSelection(new StructuredSelection(newActionLoop));
1031: lastSelection = newActionLoop;
1032: }
1033:
1034: return newActionLoop;
1035: }
1036:
1037: public void addDragSourceListener(DragSourceListener listener) {
1038: dragSourceListeners.add(listener);
1039: }
1040:
1041: public void removeDragSourceListener(DragSourceListener listener) {
1042: dragSourceListeners.remove(listener);
1043: }
1044:
1045: protected void fireDragStart(DragSourceEvent event) {
1046: Object[] listeners = dragSourceListeners.getListeners();
1047: for (int i = 0; i < listeners.length; ++i) {
1048: DragSourceListener l = (DragSourceListener) listeners[i];
1049: l.dragStart(event);
1050: }
1051: }
1052:
1053: protected void fireDragFinished(DragSourceEvent event) {
1054: Object[] listeners = dragSourceListeners.getListeners();
1055: for (int i = 0; i < listeners.length; ++i) {
1056: DragSourceListener l = (DragSourceListener) listeners[i];
1057: l.dragFinished(event);
1058: }
1059: }
1060: }
|