001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.cheatsheet.comp;
011:
012: import java.io.IOException;
013: import java.io.PrintWriter;
014: import java.io.StringWriter;
015: import java.net.URL;
016:
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.jface.action.IMenuManager;
019: import org.eclipse.jface.action.MenuManager;
020: import org.eclipse.jface.action.Separator;
021: import org.eclipse.jface.action.ToolBarManager;
022: import org.eclipse.jface.viewers.ISelection;
023: import org.eclipse.jface.viewers.IStructuredSelection;
024: import org.eclipse.jface.viewers.StructuredSelection;
025: import org.eclipse.jface.viewers.TreeViewer;
026: import org.eclipse.pde.core.IModelChangedEvent;
027: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCS;
028: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSConstants;
029: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSModel;
030: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSObject;
031: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSTask;
032: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSTaskGroup;
033: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSTaskObject;
034: import org.eclipse.pde.internal.ui.PDEPlugin;
035: import org.eclipse.pde.internal.ui.PDEUIMessages;
036: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
037: import org.eclipse.pde.internal.ui.editor.TreeSection;
038: import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
039: import org.eclipse.pde.internal.ui.editor.cheatsheet.ICSDetails;
040: import org.eclipse.pde.internal.ui.editor.cheatsheet.ICSMaster;
041: import org.eclipse.pde.internal.ui.editor.cheatsheet.comp.actions.CompCSAddGroupAction;
042: import org.eclipse.pde.internal.ui.editor.cheatsheet.comp.actions.CompCSAddTaskAction;
043: import org.eclipse.pde.internal.ui.editor.cheatsheet.comp.actions.CompCSRemoveTaskObjectAction;
044: import org.eclipse.pde.internal.ui.parts.TreePart;
045: import org.eclipse.swt.SWT;
046: import org.eclipse.swt.events.DisposeEvent;
047: import org.eclipse.swt.events.DisposeListener;
048: import org.eclipse.swt.graphics.Cursor;
049: import org.eclipse.swt.widgets.Composite;
050: import org.eclipse.swt.widgets.Display;
051: import org.eclipse.swt.widgets.ToolBar;
052: import org.eclipse.ui.IEditorInput;
053: import org.eclipse.ui.IFileEditorInput;
054: import org.eclipse.ui.IStorageEditorInput;
055: import org.eclipse.ui.actions.ActionFactory;
056: import org.eclipse.ui.cheatsheets.OpenCheatSheetAction;
057: import org.eclipse.ui.forms.IDetailsPage;
058: import org.eclipse.ui.forms.widgets.FormToolkit;
059: import org.eclipse.ui.forms.widgets.Section;
060:
061: /**
062: * CompCSMasterTreeSection
063: *
064: */
065: public class CompCSMasterTreeSection extends TreeSection implements
066: ICSMaster {
067:
068: private static final int F_BUTTON_ADD_TASK = 0;
069:
070: private static final int F_BUTTON_ADD_GROUP = 1;
071:
072: private static final int F_BUTTON_REMOVE = 2;
073:
074: private static final int F_BUTTON_UP = 3;
075:
076: private static final int F_BUTTON_DOWN = 4;
077:
078: private static final int F_BUTTON_PREVIEW = 5;
079:
080: private static final int F_UP_FLAG = -1;
081:
082: private static final int F_DOWN_FLAG = 1;
083:
084: private TreeViewer fTreeViewer;
085:
086: private ICompCSModel fModel;
087:
088: private CollapseAction fCollapseAction;
089:
090: private CompCSRemoveTaskObjectAction fRemoveTaskObjectAction;
091:
092: private CompCSAddGroupAction fAddGroupAction;
093:
094: private CompCSAddTaskAction fAddTaskAction;
095:
096: private CompCSGroupValidator fGroupValidator;
097:
098: /**
099: * @param formPage
100: * @param parent
101: * @param style
102: * @param buttonLabels
103: */
104: public CompCSMasterTreeSection(PDEFormPage formPage,
105: Composite parent) {
106: super (formPage, parent, Section.DESCRIPTION, new String[] {
107: PDEUIMessages.CompCSMasterTreeSection_addTask,
108: PDEUIMessages.CompCSMasterTreeSection_addGroup,
109: PDEUIMessages.SimpleCSElementSection_7,
110: PDEUIMessages.SimpleCSElementSection_1,
111: PDEUIMessages.SimpleCSElementSection_2,
112: PDEUIMessages.SimpleCSElementSection_3 });
113:
114: // Create actions
115: fAddGroupAction = new CompCSAddGroupAction();
116: fAddTaskAction = new CompCSAddTaskAction();
117: fRemoveTaskObjectAction = new CompCSRemoveTaskObjectAction();
118: fCollapseAction = null;
119: }
120:
121: /* (non-Javadoc)
122: * @see org.eclipse.pde.internal.ui.editor.PDESection#createClient(org.eclipse.ui.forms.widgets.Section, org.eclipse.ui.forms.widgets.FormToolkit)
123: */
124: protected void createClient(Section section, FormToolkit toolkit) {
125: // Get the model
126: fModel = (ICompCSModel) getPage().getModel();
127:
128: Composite container = createClientContainer(section, 2, toolkit);
129: createTree(container, toolkit);
130: toolkit.paintBordersFor(container);
131: section.setText(PDEUIMessages.SimpleCSElementSection_4);
132: section.setDescription(PDEUIMessages.SimpleCSElementSection_5);
133: section.setClient(container);
134: initializeTreeViewer();
135: createSectionToolbar(section, toolkit);
136: }
137:
138: /**
139: * @param container
140: * @param toolkit
141: */
142: private void createTree(Composite container, FormToolkit toolkit) {
143: TreePart treePart = getTreePart();
144: createViewerPartControl(container, SWT.SINGLE, 2, toolkit);
145: fTreeViewer = treePart.getTreeViewer();
146: fTreeViewer.setContentProvider(new CompCSContentProvider());
147: fTreeViewer.setLabelProvider(PDEPlugin.getDefault()
148: .getLabelProvider());
149: PDEPlugin.getDefault().getLabelProvider().connect(this );
150: createTreeListeners();
151: // TODO: MP: LOW: CompCS: Implement drag and drop move feature
152: }
153:
154: /**
155: *
156: */
157: private void createTreeListeners() {
158: // Create listener for the outline view 'link with editor' toggle
159: // button
160: fTreeViewer.addPostSelectionChangedListener(getPage()
161: .getPDEEditor().new PDEFormEditorChangeListener());
162: }
163:
164: /**
165: * @return
166: */
167: public ISelection getSelection() {
168: return fTreeViewer.getSelection();
169: }
170:
171: /**
172: *
173: */
174: private void initializeTreeViewer() {
175:
176: if (fModel == null) {
177: return;
178: }
179: fTreeViewer.setInput(fModel);
180: ICompCS cheatsheet = fModel.getCompCS();
181:
182: // Create the group validator and register all existing groups to be
183: // validated within the workspace model
184: fGroupValidator = new CompCSGroupValidator(cheatsheet,
185: getManagedForm().getForm().getForm(),
186: PDEUIMessages.SimpleCSElementSection_4);
187:
188: // If the cheat sheet already has a task object, then the object has
189: // to be deleted first before a new task or group can be added to
190: // the root cheatsheet node
191: boolean addFlag = false;
192: if (cheatsheet.getFieldTaskObject() == null) {
193: addFlag = fModel.isEditable();
194: }
195: getTreePart().setButtonEnabled(F_BUTTON_ADD_TASK, addFlag);
196: getTreePart().setButtonEnabled(F_BUTTON_ADD_GROUP, addFlag);
197:
198: // Set to false because initial node selected is the root cheatsheet node
199: getTreePart().setButtonEnabled(F_BUTTON_REMOVE, false);
200: // Set to false because initial node selected is the root cheatsheet node
201: getTreePart().setButtonEnabled(F_BUTTON_UP, false);
202: // Set to false because initial node selected is the root cheatsheet node
203: getTreePart().setButtonEnabled(F_BUTTON_DOWN, false);
204:
205: // Validate initial file content
206: // TODO: MP: LOW: CompCS: The error message does not show up in the form on load for some reason
207: // TODO: MP: LOW: CompCS: Implement error image overlay on icon ILightWeightLabelDecorator
208: // TODO: MP: LOW: CompCS: The error message dissapears on up / down movement
209: updatePreviewButton(fGroupValidator.validate());
210:
211: // Select the cheatsheet node in the tree
212: fTreeViewer.setSelection(new StructuredSelection(cheatsheet),
213: true);
214: fTreeViewer.expandToLevel(2);
215: }
216:
217: /**
218: * @param section
219: * @param toolkit
220: */
221: private void createSectionToolbar(Section section,
222: FormToolkit toolkit) {
223:
224: ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
225: ToolBar toolbar = toolBarManager.createControl(section);
226: final Cursor handCursor = new Cursor(Display.getCurrent(),
227: SWT.CURSOR_HAND);
228: toolbar.setCursor(handCursor);
229: // Cursor needs to be explicitly disposed
230: toolbar.addDisposeListener(new DisposeListener() {
231: public void widgetDisposed(DisposeEvent e) {
232: if ((handCursor != null)
233: && (handCursor.isDisposed() == false)) {
234: handCursor.dispose();
235: }
236: }
237: });
238: // Add collapse action to the tool bar
239: fCollapseAction = new CollapseAction(fTreeViewer,
240: PDEUIMessages.ExtensionsPage_collapseAll, 1, fModel
241: .getCompCS());
242: toolBarManager.add(fCollapseAction);
243:
244: toolBarManager.update(true);
245:
246: section.setTextClient(toolbar);
247: }
248:
249: /* (non-Javadoc)
250: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#buttonSelected(int)
251: */
252: protected void buttonSelected(int index) {
253: switch (index) {
254: case F_BUTTON_ADD_TASK:
255: handleAddTaskAction();
256: break;
257: case F_BUTTON_ADD_GROUP:
258: handleAddGroupAction();
259: break;
260: case F_BUTTON_REMOVE:
261: handleDeleteAction();
262: break;
263: case F_BUTTON_UP:
264: handleMoveTaskObjectAction(F_UP_FLAG);
265: break;
266: case F_BUTTON_DOWN:
267: handleMoveTaskObjectAction(F_DOWN_FLAG);
268: break;
269: case F_BUTTON_PREVIEW:
270: handlePreviewAction();
271: break;
272: }
273: }
274:
275: /* (non-Javadoc)
276: * @see org.eclipse.pde.internal.ui.editor.TreeSection#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection)
277: */
278: protected void selectionChanged(IStructuredSelection selection) {
279: updateButtons();
280: }
281:
282: /* (non-Javadoc)
283: * @see org.eclipse.pde.internal.ui.editor.cheatsheet.simple.details.ISimpleCSMaster#updateButtons()
284: */
285: public void updateButtons() {
286: if (!fModel.isEditable()) {
287: return;
288: }
289: Object object = ((IStructuredSelection) fTreeViewer
290: .getSelection()).getFirstElement();
291: ICompCSObject csObject = (ICompCSObject) object;
292: boolean canAddTask = false;
293: boolean canAddGroup = false;
294: boolean canRemove = false;
295: boolean canMoveUp = false;
296: boolean canMoveDown = false;
297:
298: if (csObject != null) {
299: ICompCSObject parent = csObject.getParent();
300: if ((csObject.getType() == ICompCSConstants.TYPE_TASK)
301: || (csObject.getType() == ICompCSConstants.TYPE_TASKGROUP)) {
302:
303: if ((parent.getType() == ICompCSConstants.TYPE_COMPOSITE_CHEATSHEET)
304: && (csObject.getType() == ICompCSConstants.TYPE_TASKGROUP)) {
305: canAddTask = true;
306: canAddGroup = true;
307: } else if (parent.getType() == ICompCSConstants.TYPE_TASKGROUP) {
308: ICompCSTaskGroup taskGroup = (ICompCSTaskGroup) parent;
309: ICompCSTaskObject taskObject = (ICompCSTaskObject) csObject;
310: if (taskGroup.isFirstFieldTaskObject(taskObject) == false) {
311: canMoveUp = true;
312: }
313: if (taskGroup.isLastFieldTaskObject(taskObject) == false) {
314: canMoveDown = true;
315: }
316: canRemove = canRemoveTaskObject(taskGroup);
317: canAddTask = true;
318: canAddGroup = true;
319: }
320: }
321: }
322:
323: getTreePart().setButtonEnabled(F_BUTTON_ADD_TASK, canAddTask);
324: getTreePart().setButtonEnabled(F_BUTTON_ADD_GROUP, canAddGroup);
325: getTreePart().setButtonEnabled(F_BUTTON_REMOVE, canRemove);
326: getTreePart().setButtonEnabled(F_BUTTON_UP, canMoveUp);
327: getTreePart().setButtonEnabled(F_BUTTON_DOWN, canMoveDown);
328: }
329:
330: /**
331: *
332: */
333: private void handleAddTaskAction() {
334:
335: ISelection sel = fTreeViewer.getSelection();
336: Object object = ((IStructuredSelection) sel).getFirstElement();
337: if (object == null) {
338: return;
339: }
340: if (object instanceof ICompCSTaskGroup) {
341: fAddTaskAction.setParentObject((ICompCSObject) object);
342: fAddTaskAction.run();
343: } else if (object instanceof ICompCSTask) {
344: fAddTaskAction.setParentObject(((ICompCSObject) object)
345: .getParent());
346: fAddTaskAction.run();
347: }
348: }
349:
350: /**
351: * @param flag
352: */
353: private void updatePreviewButton(boolean flag) {
354: getTreePart().setButtonEnabled(F_BUTTON_PREVIEW, flag);
355: }
356:
357: /**
358: *
359: */
360: private void handleAddGroupAction() {
361:
362: ISelection sel = fTreeViewer.getSelection();
363: Object object = ((IStructuredSelection) sel).getFirstElement();
364: if (object == null) {
365: return;
366: }
367: if (object instanceof ICompCSTaskGroup) {
368: fAddGroupAction.setParentObject((ICompCSObject) object);
369: fAddGroupAction.run();
370: } else if (object instanceof ICompCSTask) {
371: fAddGroupAction.setParentObject(((ICompCSObject) object)
372: .getParent());
373: fAddGroupAction.run();
374: }
375: }
376:
377: /**
378: *
379: */
380: private void handleMoveTaskObjectAction(int positionFlag) {
381:
382: ISelection sel = fTreeViewer.getSelection();
383: Object object = ((IStructuredSelection) sel).getFirstElement();
384: if (object == null) {
385: return;
386: } else if (object instanceof ICompCSTaskObject) {
387: ICompCSTaskObject taskObject = (ICompCSTaskObject) object;
388: ICompCSTaskGroup parent = null;
389: // Determine the parents type
390: if (taskObject.getParent().getType() == ICompCSConstants.TYPE_TASKGROUP) {
391: parent = (ICompCSTaskGroup) taskObject.getParent();
392: } else {
393: return;
394: }
395: // Move the task object up or down one position
396: parent.moveFieldTaskObject(taskObject, positionFlag);
397: }
398: }
399:
400: /**
401: *
402: */
403: private void handlePreviewAction() {
404: // Get the editor input
405: // Could be IFileEditorInput (File in workpspace - e.g. Package Explorer View)
406: // Could be IStorageEditorInput (File not in workpsace - e.g. CVS Repositories View)
407: IEditorInput input = getPage().getEditorInput();
408: URL url = null;
409: try {
410: if (input instanceof IFileEditorInput) {
411: IFileEditorInput fileInput = (IFileEditorInput) input;
412: url = fileInput.getFile().getLocationURI().toURL();
413: } else if (input instanceof IStorageEditorInput) {
414: // Note: This URL does not exist on the local file system
415: // As a result any tasks this composite cheat sheet has that
416: // specify a pathes to simple cheat sheets will not resolve
417: // Cheat sheet view will log an error loading simple cheat
418: // sheets
419: IStorageEditorInput storageInput = (IStorageEditorInput) input;
420: url = storageInput.getStorage().getFullPath().toFile()
421: .toURL();
422: } else {
423: // No base URL. Pathes will definitely not resolve here
424: url = null;
425: }
426:
427: // Write the current model into a String as raw XML
428: StringWriter swriter = new StringWriter();
429: PrintWriter writer = new PrintWriter(swriter);
430: fModel.getCompCS().write("", writer); //$NON-NLS-1$
431: writer.flush();
432: swriter.close();
433: // Launch in the cheat sheet view
434: OpenCheatSheetAction openAction = new OpenCheatSheetAction(
435: input.getName(), input.getName(), swriter
436: .toString(), url);
437: openAction.run();
438: } catch (IOException e) {
439: PDEPlugin.logException(e);
440: } catch (CoreException e) {
441: PDEPlugin.logException(e);
442: }
443: }
444:
445: /* (non-Javadoc)
446: * @see org.eclipse.pde.internal.ui.editor.PDESection#modelChanged(org.eclipse.pde.core.IModelChangedEvent)
447: */
448: public void modelChanged(IModelChangedEvent event) {
449: // No need to call super, world changed event handled here
450: if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
451: handleModelEventWorldChanged(event);
452: } else if (event.getChangeType() == IModelChangedEvent.INSERT) {
453: handleModelInsertType(event);
454: } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
455: handleModelRemoveType(event);
456: } else if (event.getChangeType() == IModelChangedEvent.CHANGE) {
457: handleModelChangeType(event);
458: }
459:
460: // Validate registered groups regardless of change type
461: // Validation is not required for task and composite cheat sheet
462: // change types (performance savings available); but, is required for
463: // everything else
464: updatePreviewButton(fGroupValidator.validate());
465: }
466:
467: /**
468: * @param event
469: */
470: private void handleModelEventWorldChanged(IModelChangedEvent event) {
471:
472: Object[] objects = event.getChangedObjects();
473: ICompCSObject object = (ICompCSObject) objects[0];
474: if (object == null) {
475: // Ignore
476: return;
477: } else if (object.getType() == ICompCSConstants.TYPE_COMPOSITE_CHEATSHEET) {
478: // Get the form page
479: CompCSPage page = (CompCSPage) getPage();
480: // Remember the currently selected page
481: IDetailsPage previousDetailsPage = page.getBlock()
482: .getDetailsPart().getCurrentPage();
483: // Replace the current dirty model with the model reloaded from
484: // file
485: fModel = ((ICompCS) object).getModel();
486: // Reset the treeviewer using the new model as input
487: // TODO: MP: CompCS: This is redundant and should be deleted
488: fTreeViewer.setInput(fModel);
489: // Re-initialize the tree viewer. Makes a details page selection
490: initializeTreeViewer();
491: // Get the current details page selection
492: IDetailsPage currentDetailsPage = page.getBlock()
493: .getDetailsPart().getCurrentPage();
494: // If the selected page before the revert is the same as the
495: // selected page after the revert, then its fields will need to
496: // be updated
497: // TODO: MP: REVERT: LOW: Revisit to see if updating details page is necessary - especially after making static
498: if (currentDetailsPage.equals(previousDetailsPage)
499: && currentDetailsPage instanceof ICSDetails) {
500: ((ICSDetails) currentDetailsPage).updateFields();
501: }
502: }
503:
504: }
505:
506: /**
507: * @param event
508: */
509: private void handleModelInsertType(IModelChangedEvent event) {
510: // Insert event
511: Object[] objects = event.getChangedObjects();
512: ICompCSObject object = (ICompCSObject) objects[0];
513: if (object == null) {
514: // Ignore
515: } else if (object.getType() == ICompCSConstants.TYPE_TASK) {
516: handleTaskObjectInsert(object);
517: } else if (object.getType() == ICompCSConstants.TYPE_TASKGROUP) {
518: handleTaskObjectInsert(object);
519: // Register the group for validation
520: fGroupValidator.addGroup((ICompCSTaskGroup) object);
521: }
522: }
523:
524: /**
525: * @param object
526: */
527: private void handleTaskObjectInsert(ICompCSObject object) {
528: // Refresh the parent element in the tree viewer
529: // TODO: MP: CompCS: LOW: Can we get away with an update instead of a refresh here?
530: fTreeViewer.refresh(object.getParent());
531: // Select the new task / group in the tree
532: fTreeViewer.setSelection(new StructuredSelection(object), true);
533: }
534:
535: /**
536: * @param event
537: */
538: private void handleModelRemoveType(IModelChangedEvent event) {
539: // Remove event
540: Object[] objects = event.getChangedObjects();
541: ICompCSObject object = (ICompCSObject) objects[0];
542: if (object == null) {
543: // Ignore
544: } else if (object.getType() == ICompCSConstants.TYPE_TASK) {
545: handleTaskObjectRemove(object);
546: } else if (object.getType() == ICompCSConstants.TYPE_TASKGROUP) {
547: handleTaskObjectRemove(object);
548: // Unregister the group from validation
549: fGroupValidator.removeGroup((ICompCSTaskGroup) object);
550: }
551: }
552:
553: /**
554: * @param object
555: */
556: private void handleTaskObjectRemove(ICompCSObject object) {
557: // Remove the item
558: fTreeViewer.remove(object);
559: // Select the appropriate object
560: ICompCSObject csObject = fRemoveTaskObjectAction
561: .getObjectToSelect();
562: if (csObject == null) {
563: csObject = object.getParent();
564: }
565: fTreeViewer.setSelection(new StructuredSelection(csObject),
566: true);
567: }
568:
569: /**
570: * @param event
571: */
572: private void handleModelChangeType(IModelChangedEvent event) {
573: // Change event
574: Object[] objects = event.getChangedObjects();
575: ICompCSObject object = (ICompCSObject) objects[0];
576: if (object == null) {
577: // Ignore
578: } else if (object.getType() == ICompCSConstants.TYPE_TASK) {
579: // Update the element in the tree viewer
580: fTreeViewer.update(object, null);
581: } else if (object.getType() == ICompCSConstants.TYPE_TASKGROUP) {
582: // Refresh the element in the tree viewer
583: fTreeViewer.update(object, null);
584: } else if (object.getType() == ICompCSConstants.TYPE_COMPOSITE_CHEATSHEET) {
585: // Refresh the element in the tree viewer
586: fTreeViewer.update(object, null);
587: }
588: }
589:
590: /*
591: * (non-Javadoc)
592: *
593: * @see org.eclipse.pde.internal.ui.editor.cheatsheet.ICSMaster#fireSelection()
594: */
595: public void fireSelection() {
596: fTreeViewer.setSelection(fTreeViewer.getSelection());
597: }
598:
599: /* (non-Javadoc)
600: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#fillContextMenu(org.eclipse.jface.action.IMenuManager)
601: */
602: protected void fillContextMenu(IMenuManager manager) {
603: // Get the current selection
604: ISelection selection = fTreeViewer.getSelection();
605: Object object = ((IStructuredSelection) selection)
606: .getFirstElement();
607: // Do blind cast - has to be a composite CS object
608: // Could be null
609: ICompCSObject csObject = (ICompCSObject) object;
610: // Create the "New" sub-menu
611: MenuManager submenu = new MenuManager(
612: PDEUIMessages.Menus_new_label);
613: // Add the "New" sub-menu to the main context menu
614: manager.add(submenu);
615: if ((csObject == null)
616: || (csObject.getType() == ICompCSConstants.TYPE_COMPOSITE_CHEATSHEET)) {
617: // NO-OP
618: } else if (csObject.getType() == ICompCSConstants.TYPE_TASK) {
619: // Remove task action
620: fillContextMenuRemoveAction(manager,
621: (ICompCSTaskObject) csObject);
622: } else if (csObject.getType() == ICompCSConstants.TYPE_TASKGROUP) {
623: ICompCSTaskGroup group = (ICompCSTaskGroup) csObject;
624: // Add to the "New" sub-menu
625: // Add task action
626: fAddTaskAction.setParentObject(group);
627: fAddTaskAction.setEnabled(fModel.isEditable());
628: submenu.add(fAddTaskAction);
629: // Add to the "New" sub-menu
630: // Add group action
631: fAddGroupAction.setParentObject(group);
632: fAddGroupAction.setEnabled(fModel.isEditable());
633: submenu.add(fAddGroupAction);
634: // Remove task group action
635: fillContextMenuRemoveAction(manager,
636: (ICompCSTaskObject) csObject);
637: }
638: // Add normal edit operations
639: // TODO: MP: LOW: SimpleCS: Enable context menu edit operations
640: //getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager);
641: //manager.add(new Separator());
642: }
643:
644: /**
645: * @param manager
646: * @param csObject
647: */
648: private void fillContextMenuRemoveAction(IMenuManager manager,
649: ICompCSTaskObject taskObject) {
650: // Add to the main context menu
651: // Add a separator to the main context menu
652: manager.add(new Separator());
653: // Delete task object action
654: fRemoveTaskObjectAction.setTaskObject(taskObject);
655: manager.add(fRemoveTaskObjectAction);
656: ICompCSObject parent = taskObject.getParent();
657: if (canRemoveTaskObject(parent) == false) {
658: fRemoveTaskObjectAction.setEnabled(false);
659: } else {
660: fRemoveTaskObjectAction.setEnabled(fModel.isEditable());
661: }
662: }
663:
664: /* (non-Javadoc)
665: * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
666: */
667: public boolean doGlobalAction(String actionId) {
668: if (actionId.equals(ActionFactory.DELETE.getId())) {
669: handleDeleteAction();
670: return true;
671: }
672: return false;
673: }
674:
675: /**
676: * @param object
677: */
678: private void handleDeleteAction() {
679:
680: ISelection sel = fTreeViewer.getSelection();
681: Object object = ((IStructuredSelection) sel).getFirstElement();
682: if (object != null) {
683: if (object instanceof ICompCSTaskObject) {
684: ICompCSTaskObject taskObject = (ICompCSTaskObject) object;
685: ICompCSObject parent = taskObject.getParent();
686: if (canRemoveTaskObject(parent) == false) {
687: // Preserve cheat sheet validity
688: // Semantic Rule: Cannot have a task group with no tasks
689: Display.getCurrent().beep();
690: } else {
691: fRemoveTaskObjectAction.setTaskObject(taskObject);
692: fRemoveTaskObjectAction.run();
693: }
694: } else if (object instanceof ICompCS) {
695: // Preserve cheat sheet validity
696: // Semantic Rule: Cannot have a cheat sheet with no root
697: // cheatsheet node
698: // Produce audible beep
699: Display.getCurrent().beep();
700: }
701: }
702: }
703:
704: /**
705: * @param parent
706: * @return
707: */
708: private boolean canRemoveTaskObject(ICompCSObject parent) {
709: if (parent.getType() == ICompCSConstants.TYPE_COMPOSITE_CHEATSHEET) {
710: // Preserve cheat sheet validity
711: // Semantic Rule: Cannot delete the task object directly under
712: // the root cheat sheet node
713: // Wizard by default creates a task group as the only allowed
714: // child of the root cheat sheet node. No good reason to
715: // substitute with a task instead. Specification supports its,
716: // but cheat sheet editor will not support it
717: return false;
718: }
719: return true;
720: }
721:
722: /* (non-Javadoc)
723: * @see org.eclipse.ui.forms.AbstractFormPart#setFormInput(java.lang.Object)
724: */
725: public boolean setFormInput(Object object) {
726: // This method allows the outline view to select items in the tree
727: // Invoked by
728: // org.eclipse.ui.forms.editor.IFormPage.selectReveal(Object object)
729: if (object instanceof ICompCSObject) {
730: // Select the item in the tree
731: fTreeViewer.setSelection(new StructuredSelection(object),
732: true);
733: // Verify that something was actually selected
734: ISelection selection = fTreeViewer.getSelection();
735: if ((selection != null) && (selection.isEmpty() == false)) {
736: return true;
737: }
738: }
739: return false;
740: }
741:
742: }
|