0001: /*******************************************************************************
0002: * Copyright (c) 2006, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.cheatsheet.simple;
0011:
0012: import org.eclipse.jface.action.IMenuManager;
0013: import org.eclipse.jface.action.MenuManager;
0014: import org.eclipse.jface.action.Separator;
0015: import org.eclipse.jface.action.ToolBarManager;
0016: import org.eclipse.jface.fieldassist.ControlDecoration;
0017: import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
0018: import org.eclipse.jface.viewers.ISelection;
0019: import org.eclipse.jface.viewers.IStructuredSelection;
0020: import org.eclipse.jface.viewers.StructuredSelection;
0021: import org.eclipse.jface.viewers.TreeViewer;
0022: import org.eclipse.jface.viewers.ViewerDropAdapter;
0023: import org.eclipse.pde.core.IModelChangedEvent;
0024: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCS;
0025: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSConstants;
0026: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSIntro;
0027: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSItem;
0028: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSModel;
0029: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSObject;
0030: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSRunContainerObject;
0031: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSSubItem;
0032: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSSubItemObject;
0033: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
0034: import org.eclipse.pde.internal.ui.PDEPlugin;
0035: import org.eclipse.pde.internal.ui.PDEUIMessages;
0036: import org.eclipse.pde.internal.ui.editor.PDEFormEditor;
0037: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
0038: import org.eclipse.pde.internal.ui.editor.TreeSection;
0039: import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
0040: import org.eclipse.pde.internal.ui.editor.cheatsheet.ICSMaster;
0041: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSAddStepAction;
0042: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSAddSubStepAction;
0043: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSPreviewAction;
0044: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSRemoveRunObjectAction;
0045: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSRemoveStepAction;
0046: import org.eclipse.pde.internal.ui.editor.cheatsheet.simple.actions.SimpleCSRemoveSubStepAction;
0047: import org.eclipse.pde.internal.ui.parts.TreePart;
0048: import org.eclipse.swt.SWT;
0049: import org.eclipse.swt.events.DisposeEvent;
0050: import org.eclipse.swt.events.DisposeListener;
0051: import org.eclipse.swt.graphics.Cursor;
0052: import org.eclipse.swt.widgets.Button;
0053: import org.eclipse.swt.widgets.Composite;
0054: import org.eclipse.swt.widgets.Display;
0055: import org.eclipse.swt.widgets.ToolBar;
0056: import org.eclipse.ui.actions.ActionFactory;
0057: import org.eclipse.ui.forms.widgets.FormToolkit;
0058: import org.eclipse.ui.forms.widgets.Section;
0059:
0060: /**
0061: * SimpleCSElementSection
0062: *
0063: */
0064: public class SimpleCSMasterTreeSection extends TreeSection implements
0065: ICSMaster {
0066:
0067: private static final int F_BUTTON_ADD_STEP = 0;
0068:
0069: private static final int F_BUTTON_ADD_SUBSTEP = 1;
0070:
0071: private static final int F_BUTTON_REMOVE = 4;
0072:
0073: private static final int F_BUTTON_UP = 5;
0074:
0075: private static final int F_BUTTON_DOWN = 6;
0076:
0077: private static final int F_BUTTON_PREVIEW = 9;
0078:
0079: private static final int F_UP_FLAG = -1;
0080:
0081: private static final int F_DOWN_FLAG = 1;
0082:
0083: private TreeViewer fTreeViewer;
0084:
0085: private ISimpleCSModel fModel;
0086:
0087: private SimpleCSAddStepAction fAddStepAction;
0088:
0089: private SimpleCSRemoveStepAction fRemoveStepAction;
0090:
0091: private SimpleCSRemoveSubStepAction fRemoveSubStepAction;
0092:
0093: private SimpleCSAddSubStepAction fAddSubStepAction;
0094:
0095: private SimpleCSRemoveRunObjectAction fRemoveRunObjectAction;
0096:
0097: private CollapseAction fCollapseAction;
0098:
0099: private ControlDecoration fSubStepInfoDecoration;
0100:
0101: /**
0102: * @param formPage
0103: * @param parent
0104: * @param style
0105: * @param buttonLabels
0106: */
0107: public SimpleCSMasterTreeSection(PDEFormPage formPage,
0108: Composite parent) {
0109: super (formPage, parent, Section.DESCRIPTION, new String[] {
0110: PDEUIMessages.SimpleCSElementSection_0,
0111: PDEUIMessages.SimpleCSElementSection_6, null, null,
0112: PDEUIMessages.SimpleCSElementSection_7,
0113: PDEUIMessages.SimpleCSElementSection_1,
0114: PDEUIMessages.SimpleCSElementSection_2, null, null,
0115: PDEUIMessages.SimpleCSElementSection_3 });
0116:
0117: // Create actions
0118: fAddStepAction = new SimpleCSAddStepAction();
0119: fRemoveStepAction = new SimpleCSRemoveStepAction();
0120: fRemoveSubStepAction = new SimpleCSRemoveSubStepAction();
0121: fAddSubStepAction = new SimpleCSAddSubStepAction();
0122: fRemoveRunObjectAction = new SimpleCSRemoveRunObjectAction();
0123: fCollapseAction = null;
0124: }
0125:
0126: /* (non-Javadoc)
0127: * @see org.eclipse.pde.internal.ui.editor.PDESection#createClient(org.eclipse.ui.forms.widgets.Section, org.eclipse.ui.forms.widgets.FormToolkit)
0128: */
0129: protected void createClient(Section section, FormToolkit toolkit) {
0130: // Get the model
0131: fModel = (ISimpleCSModel) getPage().getModel();
0132: // Set section title
0133: section.setText(PDEUIMessages.SimpleCSElementSection_4);
0134: // Set section description
0135: section.setDescription(PDEUIMessages.SimpleCSElementSection_5);
0136: // Create section client
0137: Composite container = createClientContainer(section, 2, toolkit);
0138: createTree(container, toolkit);
0139: toolkit.paintBordersFor(container);
0140: section.setClient(container);
0141: // Create section toolbar
0142: createSectionToolbar(section, toolkit);
0143: }
0144:
0145: /**
0146: * @param section
0147: * @param toolkit
0148: */
0149: private void createSectionToolbar(Section section,
0150: FormToolkit toolkit) {
0151:
0152: ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
0153: ToolBar toolbar = toolBarManager.createControl(section);
0154: final Cursor handCursor = new Cursor(Display.getCurrent(),
0155: SWT.CURSOR_HAND);
0156: toolbar.setCursor(handCursor);
0157: // Cursor needs to be explicitly disposed
0158: toolbar.addDisposeListener(new DisposeListener() {
0159: public void widgetDisposed(DisposeEvent e) {
0160: if ((handCursor != null)
0161: && (handCursor.isDisposed() == false)) {
0162: handCursor.dispose();
0163: }
0164: }
0165: });
0166: // Add collapse action to the tool bar
0167: fCollapseAction = new CollapseAction(fTreeViewer,
0168: PDEUIMessages.ExtensionsPage_collapseAll, 1, fModel
0169: .getSimpleCS());
0170: toolBarManager.add(fCollapseAction);
0171:
0172: toolBarManager.update(true);
0173:
0174: section.setTextClient(toolbar);
0175: }
0176:
0177: /**
0178: *
0179: */
0180: private void initializeTreeViewer() {
0181:
0182: if (fModel == null) {
0183: return;
0184: }
0185: fTreeViewer.setInput(fModel);
0186:
0187: getTreePart().setButtonEnabled(F_BUTTON_ADD_STEP,
0188: fModel.isEditable());
0189: // Set to false because initial node selected is the root cheatsheet node
0190: getTreePart().setButtonEnabled(F_BUTTON_ADD_SUBSTEP, false);
0191: // Set to false because initial node selected is the root cheatsheet node
0192: getTreePart().setButtonEnabled(F_BUTTON_REMOVE, false);
0193: // Set to false because initial node selected is the root cheatsheet node
0194: getTreePart().setButtonEnabled(F_BUTTON_UP, false);
0195: // Set to false because initial node selected is the root cheatsheet node
0196: getTreePart().setButtonEnabled(F_BUTTON_DOWN, false);
0197: getTreePart().setButtonEnabled(F_BUTTON_PREVIEW, true);
0198:
0199: ISimpleCS cheatsheet = fModel.getSimpleCS();
0200: // Select the cheatsheet node in the tree
0201: fTreeViewer.setSelection(new StructuredSelection(cheatsheet),
0202: true);
0203: fTreeViewer.expandToLevel(2);
0204: }
0205:
0206: /**
0207: * @param container
0208: * @param toolkit
0209: */
0210: private void createTree(Composite container, FormToolkit toolkit) {
0211: TreePart treePart = getTreePart();
0212: createViewerPartControl(container, SWT.SINGLE, 2, toolkit);
0213: fTreeViewer = treePart.getTreeViewer();
0214: fTreeViewer.setContentProvider(new SimpleCSContentProvider());
0215: fTreeViewer.setLabelProvider(PDEPlugin.getDefault()
0216: .getLabelProvider());
0217: PDEPlugin.getDefault().getLabelProvider().connect(this );
0218: createTreeListeners();
0219: createSubStepInfoDecoration();
0220: }
0221:
0222: /* (non-Javadoc)
0223: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#isDragAndDropEnabled()
0224: */
0225: protected boolean isDragAndDropEnabled() {
0226: return true;
0227: }
0228:
0229: /* (non-Javadoc)
0230: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canDragMove(java.lang.Object[])
0231: */
0232: public boolean canDragMove(Object[] sourceObjects) {
0233: // Validate source objects
0234: if (validatePaste(sourceObjects) == false) {
0235: return false;
0236: }
0237: ISelection selection = new StructuredSelection(sourceObjects);
0238: return canCut(selection);
0239: }
0240:
0241: /* (non-Javadoc)
0242: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canDropMove(java.lang.Object, java.lang.Object[], int)
0243: */
0244: public boolean canDropMove(Object targetObject,
0245: Object[] sourceObjects, int targetLocation) {
0246: // Validate arguments
0247: if (validatePaste(targetObject, sourceObjects) == false) {
0248: return false;
0249: }
0250: // Multi-select not supported
0251: ISimpleCSObject sourceCSObject = (ISimpleCSObject) sourceObjects[0];
0252: ISimpleCSObject targetCSObject = (ISimpleCSObject) targetObject;
0253: // Objects have to be from the same model
0254: ISimpleCSModel sourceModel = sourceCSObject.getModel();
0255: ISimpleCSModel targetModel = targetCSObject.getModel();
0256: if (sourceModel.equals(targetModel) == false) {
0257: return false;
0258: }
0259: // Validate move
0260: if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0261: ISimpleCSItem sourceItem = (ISimpleCSItem) sourceCSObject;
0262: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET) {
0263: // Source: Item
0264: // Target: Cheat Sheet
0265: ISimpleCS targetCheatSheet = (ISimpleCS) targetCSObject;
0266: return canDropMove(targetCheatSheet, sourceItem,
0267: targetLocation);
0268: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0269: // Source: Item
0270: // Target: Item
0271: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
0272: return canDropMove(targetItem, sourceItem,
0273: targetLocation);
0274: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_INTRO) {
0275: // Source: Item
0276: // Target: Intro
0277: ISimpleCSIntro targetIntro = (ISimpleCSIntro) targetCSObject;
0278: return canDropMove(targetIntro, sourceItem,
0279: targetLocation);
0280: }
0281: } else if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
0282: ISimpleCSSubItem sourceSubItem = (ISimpleCSSubItem) sourceCSObject;
0283: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0284: // Source: SubItem
0285: // Target: Item
0286: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
0287: return canDropMove(targetItem, sourceSubItem,
0288: targetLocation);
0289: } else if ((targetCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM)
0290: && (targetCSObject.getParent().getType() == ISimpleCSConstants.TYPE_ITEM)) {
0291: // Source: SubItem
0292: // Target: SubItem
0293: ISimpleCSSubItem targetSubItem = (ISimpleCSSubItem) targetCSObject;
0294: return canDropMove(targetSubItem, sourceSubItem,
0295: targetLocation);
0296: }
0297: }
0298: return false;
0299: }
0300:
0301: /**
0302: * @param targetCheatSheet
0303: * @param sourceItem
0304: * @param targetLocation
0305: * @return
0306: */
0307: private boolean canDropMove(ISimpleCS targetCheatSheet,
0308: ISimpleCSItem sourceItem, int targetLocation) {
0309: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0310: return false;
0311: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0312: return false;
0313: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0314: if (targetCheatSheet.isLastItem(sourceItem)) {
0315: return false;
0316: }
0317: // Paste item as last child of cheat sheet root
0318: return true;
0319: }
0320: return false;
0321: }
0322:
0323: /**
0324: * @param targetItem
0325: * @param sourceItem
0326: * @param targetLocation
0327: * @return
0328: */
0329: private boolean canDropMove(ISimpleCSItem targetItem,
0330: ISimpleCSItem sourceItem, int targetLocation) {
0331: ISimpleCS parent = targetItem.getSimpleCS();
0332: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0333: IDocumentElementNode previousNode = parent
0334: .getPreviousSibling(targetItem, ISimpleCSItem.class);
0335: if (sourceItem.equals(previousNode)) {
0336: return false;
0337: }
0338: // Paste item as sibling of item (before)
0339: return true;
0340: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0341: IDocumentElementNode nextNode = parent.getNextSibling(
0342: targetItem, ISimpleCSItem.class);
0343: if (sourceItem.equals(nextNode)) {
0344: return false;
0345: }
0346: // Paste item as sibling of item (after)
0347: return true;
0348: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0349: IDocumentElementNode nextNode = parent.getNextSibling(
0350: targetItem, ISimpleCSItem.class);
0351: if (sourceItem.equals(nextNode)) {
0352: return false;
0353: }
0354: // Paste item as sibling of item (after)
0355: return true;
0356: }
0357: return false;
0358: }
0359:
0360: /**
0361: * @param targetIntro
0362: * @param sourceItem
0363: * @param targetLocation
0364: * @return
0365: */
0366: private boolean canDropMove(ISimpleCSIntro targetIntro,
0367: ISimpleCSItem sourceItem, int targetLocation) {
0368: ISimpleCS parent = targetIntro.getSimpleCS();
0369: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0370: return false;
0371: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0372: IDocumentElementNode nextNode = parent.getNextSibling(
0373: targetIntro, ISimpleCSItem.class);
0374: if (sourceItem.equals(nextNode)) {
0375: return false;
0376: }
0377: // Paste item as sibling of intro (first item child of cheat sheet after intro)
0378: return true;
0379: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0380: IDocumentElementNode nextNode = parent.getNextSibling(
0381: targetIntro, ISimpleCSItem.class);
0382: if (sourceItem.equals(nextNode)) {
0383: return false;
0384: }
0385: // Paste item as sibling of intro (first item child of cheat sheet after intro)
0386: return true;
0387: }
0388: return false;
0389: }
0390:
0391: /**
0392: * @param targetItem
0393: * @param sourceSubItem
0394: * @param targetLocation
0395: * @return
0396: */
0397: private boolean canDropMove(ISimpleCSItem targetItem,
0398: ISimpleCSSubItem sourceSubItem, int targetLocation) {
0399: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0400: return false;
0401: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0402: if (targetItem.getExecutable() != null) {
0403: return false;
0404: } else if (targetItem.isFirstSubItem(sourceSubItem)) {
0405: return false;
0406: }
0407: // Paste subitem as the first child of item
0408: return true;
0409: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0410: if (targetItem.getExecutable() != null) {
0411: return false;
0412: } else if (targetItem.isLastSubItem(sourceSubItem)) {
0413: return false;
0414: }
0415: // Paste subitem as the last child of item
0416: return true;
0417: }
0418: return false;
0419: }
0420:
0421: /**
0422: * @param targetSubItem
0423: * @param sourceSubItem
0424: * @param targetLocation
0425: * @return
0426: */
0427: private boolean canDropMove(ISimpleCSSubItem targetSubItem,
0428: ISimpleCSSubItem sourceSubItem, int targetLocation) {
0429: ISimpleCSItem parent = (ISimpleCSItem) targetSubItem
0430: .getParent();
0431: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0432: IDocumentElementNode previousNode = parent
0433: .getPreviousSibling(targetSubItem,
0434: ISimpleCSSubItem.class);
0435: if (sourceSubItem.equals(previousNode)) {
0436: return false;
0437: }
0438: // Paste subitem as sibling of subitem (before)
0439: return true;
0440: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0441: IDocumentElementNode nextNode = parent.getNextSibling(
0442: targetSubItem, ISimpleCSSubItem.class);
0443: if (sourceSubItem.equals(nextNode)) {
0444: return false;
0445: }
0446: // Paste subitem as sibling of subitem (after)
0447: return true;
0448: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0449: IDocumentElementNode nextNode = parent.getNextSibling(
0450: targetSubItem, ISimpleCSSubItem.class);
0451: if (sourceSubItem.equals(nextNode)) {
0452: return false;
0453: }
0454: // Paste subitem as sibling of subitem (after)
0455: return true;
0456: }
0457: return false;
0458: }
0459:
0460: /* (non-Javadoc)
0461: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doDropMove(java.lang.Object, java.lang.Object[], int)
0462: */
0463: public void doDropMove(Object targetObject, Object[] sourceObjects,
0464: int targetLocation) {
0465: // Validate arguments
0466: if (validatePaste(targetObject, sourceObjects) == false) {
0467: Display.getDefault().beep();
0468: return;
0469: }
0470: // Multi-select not supported
0471: ISimpleCSObject sourceCSObject = (ISimpleCSObject) sourceObjects[0];
0472: ISimpleCSObject targetCSObject = (ISimpleCSObject) targetObject;
0473: // Validate move
0474: if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0475: ISimpleCSItem sourceItem = (ISimpleCSItem) sourceCSObject;
0476: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET) {
0477: // Source: Item
0478: // Target: Cheat Sheet
0479: ISimpleCS targetCheatSheet = (ISimpleCS) targetCSObject;
0480: doDropMove(targetCheatSheet, sourceItem, targetLocation);
0481: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0482: // Source: Item
0483: // Target: Item
0484: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
0485: doDropMove(targetItem, sourceItem, targetLocation);
0486: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_INTRO) {
0487: // Source: Item
0488: // Target: Intro
0489: ISimpleCSIntro targetIntro = (ISimpleCSIntro) targetCSObject;
0490: doDropMove(targetIntro, sourceItem, targetLocation);
0491: }
0492: } else if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
0493: ISimpleCSSubItem sourceSubItem = (ISimpleCSSubItem) sourceCSObject;
0494: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0495: // Source: SubItem
0496: // Target: Item
0497: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
0498: doDropMove(targetItem, sourceSubItem, targetLocation);
0499: } else if ((targetCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM)
0500: && (targetCSObject.getParent().getType() == ISimpleCSConstants.TYPE_ITEM)) {
0501: // Source: SubItem
0502: // Target: SubItem
0503: ISimpleCSSubItem targetSubItem = (ISimpleCSSubItem) targetCSObject;
0504: doDropMove(targetSubItem, sourceSubItem, targetLocation);
0505: }
0506: }
0507: }
0508:
0509: /**
0510: * @param targetCheatSheet
0511: * @param sourceItem
0512: * @param targetLocation
0513: */
0514: private void doDropMove(ISimpleCS targetCheatSheet,
0515: ISimpleCSItem sourceItem, int targetLocation) {
0516: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0517: // NO-OP, not legal
0518: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0519: // NO-OP, not legal
0520: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0521: if (targetCheatSheet.isLastItem(sourceItem)) {
0522: return;
0523: }
0524: // Adjust all the source object transient field values to
0525: // acceptable values
0526: sourceItem.reconnect(targetCheatSheet, fModel);
0527: // Paste item as the last child of cheat sheet root
0528: targetCheatSheet.addItem(sourceItem);
0529: }
0530: }
0531:
0532: /**
0533: * @param targetItem
0534: * @param sourceItem
0535: * @param targetLocation
0536: */
0537: private void doDropMove(ISimpleCSItem targetItem,
0538: ISimpleCSItem sourceItem, int targetLocation) {
0539: ISimpleCS parent = targetItem.getSimpleCS();
0540: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0541: IDocumentElementNode previousNode = parent
0542: .getPreviousSibling(targetItem, ISimpleCSItem.class);
0543: if (sourceItem.equals(previousNode)) {
0544: // NO-OP, not legal
0545: return;
0546: }
0547: // Adjust all the source object transient field values to
0548: // acceptable values
0549: sourceItem.reconnect(parent, fModel);
0550: // Get index of target item
0551: int index = parent.indexOfItem(targetItem);
0552: // Paste item as sibling of item (before)
0553: if (index != -1) {
0554: parent.addItem(index, sourceItem);
0555: }
0556: } else if ((targetLocation == ViewerDropAdapter.LOCATION_AFTER)
0557: || (targetLocation == ViewerDropAdapter.LOCATION_ON)) {
0558: IDocumentElementNode nextNode = parent.getNextSibling(
0559: targetItem, ISimpleCSItem.class);
0560: if (sourceItem.equals(nextNode)) {
0561: // NO-OP, not legal
0562: return;
0563: }
0564: // Adjust all the source object transient field values to
0565: // acceptable values
0566: sourceItem.reconnect(parent, fModel);
0567:
0568: if (nextNode == null) {
0569: parent.addItem(sourceItem);
0570: } else {
0571: // Get index of target item
0572: int index = parent
0573: .indexOfItem((ISimpleCSItem) nextNode);
0574: // Paste item as sibling of item (after)
0575: if (index != -1) {
0576: parent.addItem(index, sourceItem);
0577: }
0578: }
0579: }
0580: }
0581:
0582: /**
0583: * @param targetIntro
0584: * @param sourceItem
0585: * @param targetLocation
0586: */
0587: private void doDropMove(ISimpleCSIntro targetIntro,
0588: ISimpleCSItem sourceItem, int targetLocation) {
0589: ISimpleCS parent = targetIntro.getSimpleCS();
0590: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0591: // NO-OP, not legal
0592: } else if ((targetLocation == ViewerDropAdapter.LOCATION_AFTER)
0593: || (targetLocation == ViewerDropAdapter.LOCATION_ON)) {
0594: IDocumentElementNode nextNode = parent.getNextSibling(
0595: targetIntro, ISimpleCSItem.class);
0596: if (sourceItem.equals(nextNode)) {
0597: // NO-OP, not legal
0598: return;
0599: }
0600: // Adjust all the source object transient field values to
0601: // acceptable values
0602: sourceItem.reconnect(parent, fModel);
0603: if (nextNode == null) {
0604: parent.addItem(sourceItem);
0605: } else {
0606: // Get index of target item
0607: int index = parent
0608: .indexOfItem((ISimpleCSItem) nextNode);
0609: // Paste item as sibling of intro (first item child of cheat sheet after intro)
0610: if (index != -1) {
0611: parent.addItem(index, sourceItem);
0612: }
0613: }
0614: }
0615: }
0616:
0617: /**
0618: * @param targetItem
0619: * @param sourceSubItem
0620: * @param targetLocation
0621: */
0622: private void doDropMove(ISimpleCSItem targetItem,
0623: ISimpleCSSubItem sourceSubItem, int targetLocation) {
0624: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0625: // NO-OP, not legal
0626: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0627: if (targetItem.getExecutable() != null) {
0628: return;
0629: } else if (targetItem.isFirstSubItem(sourceSubItem)) {
0630: return;
0631: }
0632: // Adjust all the source object transient field values to
0633: // acceptable values
0634: sourceSubItem.reconnect(targetItem, fModel);
0635: // Get the item's first subitem child
0636: ISimpleCSSubItem firstSubItem = (ISimpleCSSubItem) targetItem
0637: .getChildNode(ISimpleCSSubItem.class);
0638: // Paste subitem as the first child of item
0639: if (firstSubItem == null) {
0640: targetItem.addSubItem(sourceSubItem);
0641: } else {
0642: int index = targetItem.indexOfSubItem(firstSubItem);
0643: // Paste subitem as the first child of item
0644: if (index != -1) {
0645: targetItem.addSubItem(index, sourceSubItem);
0646: }
0647: }
0648: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0649: if (targetItem.getExecutable() != null) {
0650: return;
0651: } else if (targetItem.isLastSubItem(sourceSubItem)) {
0652: return;
0653: }
0654: // Adjust all the source object transient field values to
0655: // acceptable values
0656: sourceSubItem.reconnect(targetItem, fModel);
0657: // Paste subitem as the last child of item
0658: targetItem.addSubItem(sourceSubItem);
0659: }
0660: }
0661:
0662: /**
0663: * @param targetSubItem
0664: * @param sourceSubItem
0665: * @param targetLocation
0666: */
0667: private void doDropMove(ISimpleCSSubItem targetSubItem,
0668: ISimpleCSSubItem sourceSubItem, int targetLocation) {
0669: ISimpleCSItem parent = (ISimpleCSItem) targetSubItem
0670: .getParent();
0671: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0672: IDocumentElementNode previousNode = parent
0673: .getPreviousSibling(targetSubItem,
0674: ISimpleCSSubItem.class);
0675: if (sourceSubItem.equals(previousNode)) {
0676: // NO-OP, not legal
0677: return;
0678: }
0679: // Adjust all the source object transient field values to
0680: // acceptable values
0681: sourceSubItem.reconnect(parent, fModel);
0682: // Get index of target item
0683: int index = parent.indexOfSubItem(targetSubItem);
0684: // Paste item as sibling of item (before)
0685: if (index != -1) {
0686: parent.addSubItem(index, sourceSubItem);
0687: }
0688: } else if ((targetLocation == ViewerDropAdapter.LOCATION_AFTER)
0689: || (targetLocation == ViewerDropAdapter.LOCATION_ON)) {
0690: IDocumentElementNode nextNode = parent.getNextSibling(
0691: targetSubItem, ISimpleCSSubItem.class);
0692: if (sourceSubItem.equals(nextNode)) {
0693: // NO-OP, not legal
0694: return;
0695: }
0696: // Adjust all the source object transient field values to
0697: // acceptable values
0698: sourceSubItem.reconnect(parent, fModel);
0699:
0700: if (nextNode == null) {
0701: parent.addSubItem(sourceSubItem);
0702: } else {
0703: // Get index of target item
0704: int index = parent
0705: .indexOfSubItem((ISimpleCSSubItem) nextNode);
0706: // Paste item as sibling of item (after)
0707: if (index != -1) {
0708: parent.addSubItem(index, sourceSubItem);
0709: }
0710: }
0711: }
0712: }
0713:
0714: /* (non-Javadoc)
0715: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doDragRemove(java.lang.Object[])
0716: */
0717: public void doDragRemove(Object[] sourceObjects) {
0718: // Validate source objects
0719: if (validatePaste(sourceObjects) == false) {
0720: return;
0721: }
0722: ISimpleCSObject object = (ISimpleCSObject) sourceObjects[0];
0723: // Remove the object from the model
0724: if (object.getType() == ISimpleCSConstants.TYPE_ITEM) {
0725: ISimpleCSItem item = (ISimpleCSItem) object;
0726: ISimpleCS cheatsheet = object.getSimpleCS();
0727: doSelect(false);
0728: cheatsheet.removeItem(item);
0729: doSelect(true);
0730: } else if (object.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
0731: ISimpleCSObject parent = object.getParent();
0732: if (parent.getType() == ISimpleCSConstants.TYPE_ITEM) {
0733: ISimpleCSSubItem subitem = (ISimpleCSSubItem) object;
0734: ISimpleCSItem item = ((ISimpleCSItem) parent);
0735: doSelect(false);
0736: item.removeSubItem(subitem);
0737: doSelect(true);
0738: }
0739: }
0740: // Applicable for move operations
0741: // Flush the text edit operations associated with the move operation
0742: // to the source page
0743: // Move involves add new cloned object x and remove of original object
0744: // x
0745: // Without flushing, multiple move operations up and down cause the
0746: // text edit operations to get completely screwed up (e.g. mark-up
0747: // in wrong position or getting lost)
0748: // TODO: MP: Undo: What are the implications of this?
0749: ((PDEFormEditor) getPage().getEditor()).getContextManager()
0750: .getPrimaryContext().flushEditorInput();
0751: }
0752:
0753: /**
0754: *
0755: */
0756: private void createSubStepInfoDecoration() {
0757: //
0758: Button button = getStructuredViewerPart().getButton(
0759: F_BUTTON_ADD_SUBSTEP);
0760: int bits = SWT.TOP | SWT.RIGHT;
0761: fSubStepInfoDecoration = new ControlDecoration(button, bits);
0762: fSubStepInfoDecoration.setMarginWidth(0);
0763: updateSubStepInfoDecoration(false, false, false);
0764: fSubStepInfoDecoration.setImage(FieldDecorationRegistry
0765: .getDefault().getFieldDecoration(
0766: FieldDecorationRegistry.DEC_INFORMATION)
0767: .getImage());
0768: }
0769:
0770: /**
0771: * @param show
0772: * @param itemHasNoExecutable
0773: * @param itemIsNotOptional
0774: */
0775: private void updateSubStepInfoDecoration(boolean show,
0776: boolean itemHasNoExecutable, boolean itemIsNotOptional) {
0777: //
0778: if (show) {
0779: fSubStepInfoDecoration.show();
0780: if (itemHasNoExecutable == false) {
0781: fSubStepInfoDecoration
0782: .setDescriptionText(PDEUIMessages.SimpleCSMasterTreeSection_msgButtonDisabledCommand);
0783: } else if (itemIsNotOptional == false) {
0784: fSubStepInfoDecoration
0785: .setDescriptionText(PDEUIMessages.SimpleCSMasterTreeSection_msgButtonDisabledOptional);
0786: }
0787: } else {
0788: fSubStepInfoDecoration.hide();
0789: }
0790: fSubStepInfoDecoration.setShowHover(show);
0791: }
0792:
0793: /**
0794: *
0795: */
0796: private void createTreeListeners() {
0797: // Create listener for the outline view 'link with editor' toggle
0798: // button
0799: fTreeViewer.addPostSelectionChangedListener(getPage()
0800: .getPDEEditor().new PDEFormEditorChangeListener());
0801: }
0802:
0803: /**
0804: * @return
0805: */
0806: public ISelection getSelection() {
0807: return fTreeViewer.getSelection();
0808: }
0809:
0810: /* (non-Javadoc)
0811: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#buttonSelected(int)
0812: */
0813: protected void buttonSelected(int index) {
0814: switch (index) {
0815: case F_BUTTON_ADD_STEP:
0816: handleAddStepAction();
0817: break;
0818: case F_BUTTON_ADD_SUBSTEP:
0819: handleAddSubStepAction();
0820: break;
0821: case F_BUTTON_REMOVE:
0822: handleDeleteAction();
0823: break;
0824: case F_BUTTON_UP:
0825: handleMoveStepAction(F_UP_FLAG);
0826: break;
0827: case F_BUTTON_DOWN:
0828: handleMoveStepAction(F_DOWN_FLAG);
0829: break;
0830: case F_BUTTON_PREVIEW:
0831: handlePreviewAction();
0832: break;
0833: }
0834: }
0835:
0836: /* (non-Javadoc)
0837: * @see org.eclipse.pde.internal.ui.editor.TreeSection#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection)
0838: */
0839: protected void selectionChanged(IStructuredSelection selection) {
0840: // Update global selection used by source page to sychronize selections
0841: // made in the master tree viewer with elements in the source view
0842: getPage().getPDEEditor().setSelection(selection);
0843: updateButtons();
0844: }
0845:
0846: /**
0847: *
0848: */
0849: public void updateButtons() {
0850: if (!fModel.isEditable()) {
0851: return;
0852: }
0853: ISimpleCSObject csObject = getCurrentSelection();
0854:
0855: boolean canAddItem = false;
0856: boolean canAddSubItem = false;
0857: boolean canRemove = false;
0858: boolean canMoveUp = false;
0859: boolean canMoveDown = false;
0860:
0861: boolean itemHasNoExecutable = false;
0862: boolean itemIsNotOptional = false;
0863: boolean showDecoration = false;
0864:
0865: if (csObject != null) {
0866:
0867: if (csObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET) {
0868: // Add item to end of cheat sheet child items
0869: canAddItem = true;
0870: } else if (csObject.getType() == ISimpleCSConstants.TYPE_INTRO) {
0871: // Add item as the first cheat sheet child item
0872: // which is right after the introduction node
0873: canAddItem = true;
0874: } else if (csObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
0875: ISimpleCSItem item = (ISimpleCSItem) csObject;
0876: if (item.getSimpleCS().isFirstItem(item) == false) {
0877: canMoveUp = true;
0878: }
0879: if (item.getSimpleCS().isLastItem(item) == false) {
0880: canMoveDown = true;
0881: }
0882:
0883: // Preserve cheat sheet validity
0884: // Semantic Rule: Cannot have a cheat sheet with no items
0885: if (item.getSimpleCS().getItemCount() > 1) {
0886: canRemove = true;
0887: }
0888:
0889: // Preserve cheat sheet validity
0890: // Semantic Rule: Cannot have a subitem and any of the following
0891: // together: perform-when, command, action
0892: // Preserve cheat sheet validity
0893: // Semantic Rule: Cannot add subitems to an item that is
0894: // optional
0895: itemHasNoExecutable = (item.getExecutable() == null);
0896: itemIsNotOptional = (item.getSkip() == false);
0897: if (itemHasNoExecutable && itemIsNotOptional) {
0898: canAddSubItem = true;
0899: }
0900: showDecoration = (canAddSubItem == false);
0901: // Add item right after this item
0902: canAddItem = true;
0903:
0904: } else if (csObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
0905: ISimpleCSSubItem subitem = (ISimpleCSSubItem) csObject;
0906: ISimpleCSObject parent = subitem.getParent();
0907: if (parent.getType() == ISimpleCSConstants.TYPE_ITEM) {
0908: ISimpleCSItem item = (ISimpleCSItem) parent;
0909: if (item.isFirstSubItem(subitem) == false) {
0910: canMoveUp = true;
0911: }
0912: if (item.isLastSubItem(subitem) == false) {
0913: canMoveDown = true;
0914: }
0915: // Preserve cheat sheet validity
0916: // Semantic Rule: Cannot have a subitem and any of the following
0917: // together: perform-when, command, action
0918: // Preserve cheat sheet validity
0919: // Semantic Rule: Cannot add subitems to an item that is
0920: // optional
0921: itemHasNoExecutable = (item.getExecutable() == null);
0922: itemIsNotOptional = (item.getSkip() == false);
0923: if (itemHasNoExecutable && itemIsNotOptional) {
0924: canAddSubItem = true;
0925: }
0926: showDecoration = (canAddSubItem == false);
0927: }
0928: canRemove = true;
0929:
0930: } else if ((csObject.getType() == ISimpleCSConstants.TYPE_REPEATED_SUBITEM)
0931: || (csObject.getType() == ISimpleCSConstants.TYPE_CONDITIONAL_SUBITEM)
0932: || (csObject.getType() == ISimpleCSConstants.TYPE_PERFORM_WHEN)
0933: || (csObject.getType() == ISimpleCSConstants.TYPE_ACTION)
0934: || (csObject.getType() == ISimpleCSConstants.TYPE_COMMAND)) {
0935: // Specifically for perform-when, repeated-subitem,
0936: // conditional-subitem edge cases
0937: // Action and command supported; but, will never be applicable
0938: canRemove = true;
0939: }
0940:
0941: updateSubStepInfoDecoration(showDecoration,
0942: itemHasNoExecutable, itemIsNotOptional);
0943: }
0944:
0945: getTreePart().setButtonEnabled(F_BUTTON_ADD_STEP, canAddItem);
0946: getTreePart().setButtonEnabled(F_BUTTON_ADD_SUBSTEP,
0947: canAddSubItem);
0948: getTreePart().setButtonEnabled(F_BUTTON_REMOVE, canRemove);
0949: getTreePart().setButtonEnabled(F_BUTTON_UP, canMoveUp);
0950: getTreePart().setButtonEnabled(F_BUTTON_DOWN, canMoveDown);
0951: }
0952:
0953: /**
0954: *
0955: */
0956: private void handleAddStepAction() {
0957: // Get the current selection
0958: ISimpleCSObject csObject = getCurrentSelection();
0959: // If nothing is selected add to the root cheat sheet node
0960: if (csObject == null) {
0961: fAddStepAction.setDataObject(fModel.getSimpleCS());
0962: } else {
0963: fAddStepAction.setDataObject(csObject);
0964: }
0965: // Execute the action
0966: fAddStepAction.run();
0967: }
0968:
0969: /**
0970: * @return
0971: */
0972: private ISimpleCSObject getCurrentSelection() {
0973: ISelection selection = fTreeViewer.getSelection();
0974: Object object = ((IStructuredSelection) selection)
0975: .getFirstElement();
0976: return (ISimpleCSObject) object;
0977: }
0978:
0979: /**
0980: *
0981: */
0982: private void handleAddSubStepAction() {
0983: // Get the current selection
0984: ISimpleCSObject csObject = getCurrentSelection();
0985: // Ensure the selection is defined
0986: if (csObject == null) {
0987: return;
0988: }
0989: // Set the selection object to operate on
0990: fAddSubStepAction.setDataObject(csObject);
0991: // Execute the action
0992: fAddSubStepAction.run();
0993: }
0994:
0995: /**
0996: *
0997: */
0998: private void handleMoveStepAction(int positionFlag) {
0999: ISimpleCSObject object = getCurrentSelection();
1000: if (object != null) {
1001: if (object instanceof ISimpleCSItem) {
1002: ISimpleCSItem item = (ISimpleCSItem) object;
1003: item.getSimpleCS().moveItem(item, positionFlag);
1004: } else if (object instanceof ISimpleCSSubItem) {
1005: ISimpleCSSubItem subitem = (ISimpleCSSubItem) object;
1006: // Get the current index of the subitem
1007: ISimpleCSObject parent = subitem.getParent();
1008: if (parent.getType() == ISimpleCSConstants.TYPE_ITEM) {
1009: ISimpleCSItem item = (ISimpleCSItem) parent;
1010: item.moveSubItem(subitem, positionFlag);
1011: }
1012: }
1013: }
1014: }
1015:
1016: /**
1017: *
1018: */
1019: private void handlePreviewAction() {
1020: // Get the editor
1021: PDEFormEditor editor = (PDEFormEditor) getPage().getEditor();
1022: // Get the form editor contributor
1023: SimpleCSEditorContributor contributor = (SimpleCSEditorContributor) editor
1024: .getContributor();
1025: // Get the preview action
1026: SimpleCSPreviewAction previewAction = contributor
1027: .getPreviewAction();
1028: // Set the cheat sheet object
1029: previewAction.setDataModelObject(fModel.getSimpleCS());
1030: // Set the editor input
1031: previewAction.setEditorInput(getPage().getEditorInput());
1032: // Run the preview action
1033: previewAction.run();
1034: }
1035:
1036: /* (non-Javadoc)
1037: * @see org.eclipse.pde.internal.ui.editor.PDESection#modelChanged(org.eclipse.pde.core.IModelChangedEvent)
1038: */
1039: public void modelChanged(IModelChangedEvent event) {
1040: // No need to call super, world changed event handled here
1041:
1042: if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
1043: handleModelEventWorldChanged(event);
1044: } else if (event.getChangeType() == IModelChangedEvent.INSERT) {
1045: handleModelInsertType(event);
1046: } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
1047: handleModelRemoveType(event);
1048: } else if ((event.getChangeType() == IModelChangedEvent.CHANGE)
1049: && (event.getChangedProperty()
1050: .equals(IDocumentElementNode.F_PROPERTY_CHANGE_TYPE_SWAP))) {
1051: handleModelChangeTypeSwap(event);
1052: } else if (event.getChangeType() == IModelChangedEvent.CHANGE) {
1053: handleModelChangeType(event);
1054: }
1055: }
1056:
1057: /* (non-Javadoc)
1058: * @see org.eclipse.ui.forms.AbstractFormPart#refresh()
1059: */
1060: public void refresh() {
1061: // Get the form page
1062: SimpleCSDefinitionPage page = (SimpleCSDefinitionPage) getPage();
1063: // Replace the current dirty model with the model reloaded from
1064: // file
1065: fModel = (ISimpleCSModel) page.getModel();
1066: // Re-initialize the tree viewer. Makes a details page selection
1067: initializeTreeViewer();
1068:
1069: super .refresh();
1070: }
1071:
1072: /**
1073: * @param event
1074: */
1075: private void handleModelEventWorldChanged(IModelChangedEvent event) {
1076: // Section will be updated on refresh
1077: markStale();
1078: }
1079:
1080: /**
1081: * @param event
1082: */
1083: private void handleModelChangeTypeSwap(IModelChangedEvent event) {
1084: // Swap event
1085: Object[] objects = event.getChangedObjects();
1086: // Ensure right type
1087: if ((objects[0] instanceof ISimpleCSObject) == false) {
1088: return;
1089: }
1090: ISimpleCSObject object = (ISimpleCSObject) objects[0];
1091: if (object == null) {
1092: // Ignore
1093: } else if ((object.getType() == ISimpleCSConstants.TYPE_ITEM)
1094: || (object.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET)) {
1095: // Refresh the element
1096: fTreeViewer.refresh(object);
1097: }
1098: }
1099:
1100: /**
1101: * @param event
1102: */
1103: private void handleModelInsertType(IModelChangedEvent event) {
1104: // Insert event
1105: Object[] objects = event.getChangedObjects();
1106: ISimpleCSObject object = (ISimpleCSObject) objects[0];
1107: if (object == null) {
1108: // Ignore
1109: } else if ((object.getType() == ISimpleCSConstants.TYPE_ITEM)
1110: || (object.getType() == ISimpleCSConstants.TYPE_SUBITEM)) {
1111: // Refresh the parent element in the tree viewer
1112: fTreeViewer.refresh(object.getParent());
1113: // Select the new item in the tree
1114: fTreeViewer.setSelection(new StructuredSelection(object),
1115: true);
1116: }
1117: }
1118:
1119: /**
1120: * @param event
1121: */
1122: private void handleModelRemoveType(IModelChangedEvent event) {
1123: // Remove event
1124: Object[] objects = event.getChangedObjects();
1125: ISimpleCSObject object = (ISimpleCSObject) objects[0];
1126: if (object == null) {
1127: // Ignore
1128: } else if (object.getType() == ISimpleCSConstants.TYPE_ITEM) {
1129: // Remove the item
1130: fTreeViewer.remove(object);
1131: // Determine if we should make a selection
1132: if (canSelect() == false) {
1133: return;
1134: }
1135: // Select the appropriate object
1136: ISimpleCSObject csObject = fRemoveStepAction
1137: .getObjectToSelect();
1138: if (csObject == null) {
1139: csObject = object.getParent();
1140: }
1141: fTreeViewer.setSelection(new StructuredSelection(csObject),
1142: true);
1143: } else if (object.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
1144: // Remove the subitem
1145: fTreeViewer.remove(object);
1146: // Determine if we should make a selection
1147: if (canSelect() == false) {
1148: return;
1149: }
1150: // Select the appropriate object
1151: ISimpleCSObject csObject = fRemoveSubStepAction
1152: .getObjectToSelect();
1153: if (csObject == null) {
1154: csObject = object.getParent();
1155: }
1156: fTreeViewer.setSelection(new StructuredSelection(csObject),
1157: true);
1158: } else if ((object.getType() == ISimpleCSConstants.TYPE_CONDITIONAL_SUBITEM)
1159: || (object.getType() == ISimpleCSConstants.TYPE_REPEATED_SUBITEM)
1160: || (object.getType() == ISimpleCSConstants.TYPE_PERFORM_WHEN)) {
1161: // Remove the object
1162: fTreeViewer.remove(object);
1163: // Select the parent in the tree
1164: fTreeViewer.setSelection(new StructuredSelection(object
1165: .getParent()), true);
1166: }
1167: }
1168:
1169: /**
1170: * @param event
1171: */
1172: private void handleModelChangeType(IModelChangedEvent event) {
1173: // Change event
1174: Object[] objects = event.getChangedObjects();
1175: // Ensure right type
1176: if ((objects[0] instanceof ISimpleCSObject) == false) {
1177: return;
1178: }
1179: ISimpleCSObject object = (ISimpleCSObject) objects[0];
1180: if (object == null) {
1181: // Ignore
1182: } else if ((object.getType() == ISimpleCSConstants.TYPE_ITEM)
1183: || (object.getType() == ISimpleCSConstants.TYPE_SUBITEM)
1184: || (object.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET)) {
1185: // Refresh the element in the tree viewer
1186: fTreeViewer.update(object, null);
1187: }
1188: }
1189:
1190: /* (non-Javadoc)
1191: * @see org.eclipse.pde.internal.ui.editor.cheatsheet.ICSMaster#fireSelection()
1192: */
1193: public void fireSelection() {
1194: fTreeViewer.setSelection(fTreeViewer.getSelection());
1195: }
1196:
1197: /* (non-Javadoc)
1198: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#fillContextMenu(org.eclipse.jface.action.IMenuManager)
1199: */
1200: protected void fillContextMenu(IMenuManager manager) {
1201: // Get the current selection
1202: ISimpleCSObject csObject = getCurrentSelection();
1203: // Create the "New" submenu
1204: MenuManager submenu = new MenuManager(
1205: PDEUIMessages.Menus_new_label);
1206: // Add the "New" submenu to the main context menu
1207: manager.add(submenu);
1208: if ((csObject == null)
1209: || (csObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET)) {
1210: // Add to the "New" submenu
1211: // Add step action
1212: fAddStepAction.setDataObject(fModel.getSimpleCS());
1213: fAddStepAction.setEnabled(fModel.isEditable());
1214: submenu.add(fAddStepAction);
1215: } else if (csObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1216: ISimpleCSItem item = (ISimpleCSItem) csObject;
1217: // Add to the "New" submenu
1218: // Add sub-step action
1219: fAddSubStepAction.setDataObject(csObject);
1220: // Preserve cheat sheet validity
1221: // Semantic Rule: Cannot have a subitem and any of the following
1222: // together: perform-when, command, action
1223: // Preserve cheat sheet validity
1224: // Semantic Rule: Cannot add subitems to an item that is
1225: // optional
1226: if ((item.getExecutable() == null)
1227: && (item.getSkip() == false)) {
1228: fAddSubStepAction.setEnabled(fModel.isEditable());
1229: } else {
1230: fAddSubStepAction.setEnabled(false);
1231: }
1232: submenu.add(fAddSubStepAction);
1233: // Add to the main context menu
1234: // Add a separator to the main context menu
1235: manager.add(new Separator());
1236: // Delete step action
1237: fRemoveStepAction.setItem((ISimpleCSItem) csObject);
1238: // Preserve cheat sheet validity
1239: // Semantic Rule: Cannot have a cheat sheet with no items
1240: if (item.getSimpleCS().getItemCount() > 1) {
1241: fRemoveStepAction.setEnabled(fModel.isEditable());
1242: } else {
1243: fRemoveStepAction.setEnabled(false);
1244: }
1245: manager.add(fRemoveStepAction);
1246: } else if ((csObject.getType() == ISimpleCSConstants.TYPE_SUBITEM)
1247: || (csObject.getType() == ISimpleCSConstants.TYPE_REPEATED_SUBITEM)
1248: || (csObject.getType() == ISimpleCSConstants.TYPE_CONDITIONAL_SUBITEM)) {
1249: // Add to the main context menu
1250: // Add a separator to the main context menu
1251: manager.add(new Separator());
1252: // Delete sub-step action
1253: fRemoveSubStepAction
1254: .setSubItem((ISimpleCSSubItemObject) csObject);
1255: fRemoveSubStepAction.setEnabled(fModel.isEditable());
1256: manager.add(fRemoveSubStepAction);
1257: } else if ((csObject.getType() == ISimpleCSConstants.TYPE_PERFORM_WHEN)
1258: || (csObject.getType() == ISimpleCSConstants.TYPE_ACTION)
1259: || (csObject.getType() == ISimpleCSConstants.TYPE_COMMAND)) {
1260: // Specifically for perform-when edge case
1261: // Action and command supported; but, will never be applicable
1262: // Add to the main context menu
1263: // Add a separator to the main context menu
1264: manager.add(new Separator());
1265: // Delete run object action
1266: fRemoveRunObjectAction
1267: .setRunObject((ISimpleCSRunContainerObject) csObject);
1268: fRemoveRunObjectAction.setEnabled(fModel.isEditable());
1269: manager.add(fRemoveRunObjectAction);
1270: }
1271: // Add clipboard operations
1272: manager.add(new Separator());
1273: getPage().getPDEEditor().getContributor()
1274: .contextMenuAboutToShow(manager);
1275:
1276: }
1277:
1278: /* (non-Javadoc)
1279: * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
1280: */
1281: public boolean doGlobalAction(String actionId) {
1282: // Ensure model is editable
1283: if (isEditable() == false) {
1284: return false;
1285: } else if (actionId.equals(ActionFactory.DELETE.getId())) {
1286: handleDeleteAction();
1287: return true;
1288: } else if (actionId.equals(ActionFactory.CUT.getId())) {
1289: // Handle the delete here and let the editor transfer
1290: // the selection to the clipboard
1291: handleDeleteAction();
1292: return false;
1293: } else if (actionId.equals(ActionFactory.PASTE.getId())) {
1294: doPaste();
1295: return true;
1296: }
1297: return false;
1298: }
1299:
1300: /**
1301: * @param object
1302: */
1303: private void handleDeleteAction() {
1304: ISimpleCSObject object = getCurrentSelection();
1305: if (object != null) {
1306: if (object instanceof ISimpleCSItem) {
1307: ISimpleCSItem item = (ISimpleCSItem) object;
1308: // Preserve cheat sheet validity
1309: // Semantic Rule: Cannot have a cheat sheet with no items
1310: if (item.getSimpleCS().getItemCount() > 1) {
1311: fRemoveStepAction.setItem(item);
1312: fRemoveStepAction.run();
1313: } else {
1314: // Produce audible beep
1315: Display.getCurrent().beep();
1316: }
1317: } else if (object instanceof ISimpleCSSubItemObject) {
1318: fRemoveSubStepAction
1319: .setSubItem((ISimpleCSSubItemObject) object);
1320: fRemoveSubStepAction.run();
1321: } else if (object instanceof ISimpleCSRunContainerObject) {
1322: // Specifically for perform-when edge case
1323: // Action and command supported; but, will never be applicable
1324: fRemoveRunObjectAction
1325: .setRunObject((ISimpleCSRunContainerObject) object);
1326: fRemoveRunObjectAction.run();
1327: } else if (object instanceof ISimpleCS) {
1328: // Preserve cheat sheet validity
1329: // Semantic Rule: Cannot have a cheat sheet with no root
1330: // cheatsheet node
1331: // Produce audible beep
1332: Display.getCurrent().beep();
1333: } else if (object instanceof ISimpleCSIntro) {
1334: // Preserve cheat sheet validity
1335: // Semantic Rule: Cannot have a cheat sheet with no
1336: // introduction
1337: // Produce audible beep
1338: Display.getCurrent().beep();
1339: }
1340: }
1341: }
1342:
1343: /* (non-Javadoc)
1344: * @see org.eclipse.ui.forms.AbstractFormPart#setFormInput(java.lang.Object)
1345: */
1346: public boolean setFormInput(Object object) {
1347: // This method allows the outline view to select items in the tree
1348: // Invoked by
1349: // org.eclipse.ui.forms.editor.IFormPage.selectReveal(Object object)
1350: if (object instanceof ISimpleCSObject) {
1351: // Select the item in the tree
1352: fTreeViewer.setSelection(new StructuredSelection(object),
1353: true);
1354: // Verify that something was actually selected
1355: ISelection selection = fTreeViewer.getSelection();
1356: if ((selection != null) && (selection.isEmpty() == false)) {
1357: return true;
1358: }
1359: }
1360: return false;
1361: }
1362:
1363: /**
1364: * @param targetObject
1365: * @param sourceObjects
1366: * @return
1367: */
1368: private boolean validatePaste(Object targetObject,
1369: Object[] sourceObjects) {
1370: // Validate target object
1371: if ((targetObject instanceof ISimpleCSObject) == false) {
1372: return false;
1373: }
1374: // Validate source objects
1375: if (validatePaste(sourceObjects) == false) {
1376: return false;
1377: }
1378: return true;
1379: }
1380:
1381: /**
1382: * @param sourceObjects
1383: * @return
1384: */
1385: private boolean validatePaste(Object[] sourceObjects) {
1386: // Validate source objects
1387: if (sourceObjects == null) {
1388: return false;
1389: } else if (sourceObjects.length != 1) {
1390: return false;
1391: } else if ((sourceObjects[0] instanceof ISimpleCSObject) == false) {
1392: return false;
1393: }
1394: return true;
1395: }
1396:
1397: /* (non-Javadoc)
1398: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
1399: */
1400: protected boolean canPaste(Object targetObject,
1401: Object[] sourceObjects) {
1402: // Validate arguments
1403: if (validatePaste(targetObject, sourceObjects) == false) {
1404: return false;
1405: }
1406: // Multi-select not supported
1407: ISimpleCSObject sourceCSObject = (ISimpleCSObject) sourceObjects[0];
1408: ISimpleCSObject targetCSObject = (ISimpleCSObject) targetObject;
1409: // Validate paste
1410: if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1411: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET) {
1412: // Paste item as child of cheat sheet root
1413: return true;
1414: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1415: // Paste item as sibling of item
1416: return true;
1417: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_INTRO) {
1418: // Paste item as sibling of intro (first item child of cheat sheet)
1419: return true;
1420: }
1421: } else if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
1422: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1423: // Paste subitem as child of item
1424: return true;
1425: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
1426: // Paste subitem as sibling of subitem
1427: return true;
1428: }
1429: }
1430:
1431: return false;
1432: }
1433:
1434: /* (non-Javadoc)
1435: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
1436: */
1437: protected void doPaste(Object targetObject, Object[] sourceObjects) {
1438: // Validate arguments
1439: if (validatePaste(targetObject, sourceObjects) == false) {
1440: Display.getDefault().beep();
1441: return;
1442: }
1443: // Multi-select not supported
1444: ISimpleCSObject sourceCSObject = (ISimpleCSObject) sourceObjects[0];
1445: ISimpleCSObject targetCSObject = (ISimpleCSObject) targetObject;
1446: // Validate paste
1447: if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1448: ISimpleCSItem sourceItem = (ISimpleCSItem) sourceCSObject;
1449: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_CHEAT_SHEET) {
1450: ISimpleCS targetCheatSheet = (ISimpleCS) targetCSObject;
1451: // Adjust all the source object transient field values to
1452: // acceptable values
1453: sourceItem.reconnect(targetCheatSheet, fModel);
1454: // Paste item as the last child of cheat sheet root
1455: targetCheatSheet.addItem(sourceItem);
1456: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1457: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
1458: ISimpleCS targetCheatSheet = targetItem.getSimpleCS();
1459: // Adjust all the source object transient field values to
1460: // acceptable values
1461: sourceItem.reconnect(targetCheatSheet, fModel);
1462: // Paste source item as sibling of the target item (right after it)
1463: int index = targetCheatSheet.indexOfItem(targetItem) + 1;
1464: targetCheatSheet.addItem(index, sourceItem);
1465: } else if (targetCSObject.getType() == ISimpleCSConstants.TYPE_INTRO) {
1466: ISimpleCSIntro targetIntro = (ISimpleCSIntro) targetCSObject;
1467: ISimpleCS targetCheatSheet = targetCSObject
1468: .getSimpleCS();
1469: // Adjust all the source object transient field values to
1470: // acceptable values
1471: sourceItem.reconnect(targetCheatSheet, fModel);
1472: // Paste source item as the first item (right after intro node)
1473: int index = targetCheatSheet.indexOf(targetIntro) + 1;
1474: targetCheatSheet.addItem(index, sourceItem);
1475: }
1476: } else if (sourceCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM) {
1477: ISimpleCSSubItem sourceSubitem = (ISimpleCSSubItem) sourceCSObject;
1478: if (targetCSObject.getType() == ISimpleCSConstants.TYPE_ITEM) {
1479: ISimpleCSItem targetItem = (ISimpleCSItem) targetCSObject;
1480: // Adjust all the source object transient field values to
1481: // acceptable values
1482: sourceSubitem.reconnect(targetItem, fModel);
1483: // Paste subitem as the last child of the item
1484: targetItem.addSubItem(sourceSubitem);
1485: } else if ((targetCSObject.getType() == ISimpleCSConstants.TYPE_SUBITEM)
1486: && (targetCSObject.getParent().getType() == ISimpleCSConstants.TYPE_ITEM)) {
1487: ISimpleCSSubItem targetSubItem = (ISimpleCSSubItem) targetCSObject;
1488: ISimpleCSItem targetItem = (ISimpleCSItem) targetSubItem
1489: .getParent();
1490: // Adjust all the source object transient field values to
1491: // acceptable values
1492: sourceSubitem.reconnect(targetItem, fModel);
1493: // Paste source item as sibling of the target item (right after it)
1494: int index = targetItem.indexOfSubItem(targetSubItem) + 1;
1495: targetItem.addSubItem(index, sourceSubitem);
1496: }
1497: }
1498: }
1499:
1500: /* (non-Javadoc)
1501: * @see org.eclipse.pde.internal.ui.editor.PDESection#canCut(org.eclipse.jface.viewers.ISelection)
1502: */
1503: public boolean canCut(ISelection selection) {
1504: // Validate selection
1505: if (selection == null) {
1506: return false;
1507: } else if ((selection instanceof IStructuredSelection) == false) {
1508: return false;
1509: } else if (selection.isEmpty()) {
1510: return false;
1511: }
1512: // Get the first element
1513: Object object = ((IStructuredSelection) selection)
1514: .getFirstElement();
1515: // Ensure we have a CS object
1516: if ((object instanceof ISimpleCSObject) == false) {
1517: return false;
1518: }
1519: ISimpleCSObject csObject = (ISimpleCSObject) object;
1520: // Can cut only items and subitems
1521: if ((csObject.getType() == ISimpleCSConstants.TYPE_ITEM)
1522: && (csObject.getSimpleCS().getItemCount() != 1)) {
1523: // Is an item and is not the last item
1524: return true;
1525: } else if (object instanceof ISimpleCSSubItem) {
1526: // Is a subitem
1527: return true;
1528: }
1529: // Cannot cut anything else
1530: return false;
1531: }
1532:
1533: }
|