Source Code Cross Referenced for TocTreeSection.java in  » IDE-Eclipse » Eclipse-plug-in-development » org » eclipse » pde » internal » ui » editor » toc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » Eclipse plug in development » org.eclipse.pde.internal.ui.editor.toc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 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.toc;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Iterator;
0014:        import java.util.List;
0015:
0016:        import org.eclipse.core.resources.IFile;
0017:        import org.eclipse.core.resources.IProject;
0018:        import org.eclipse.core.resources.IResource;
0019:        import org.eclipse.core.resources.IWorkspaceRoot;
0020:        import org.eclipse.core.resources.ResourcesPlugin;
0021:        import org.eclipse.core.runtime.IPath;
0022:        import org.eclipse.core.runtime.Path;
0023:        import org.eclipse.jface.action.Action;
0024:        import org.eclipse.jface.action.IMenuManager;
0025:        import org.eclipse.jface.action.MenuManager;
0026:        import org.eclipse.jface.action.Separator;
0027:        import org.eclipse.jface.action.ToolBarManager;
0028:        import org.eclipse.jface.dialogs.MessageDialog;
0029:        import org.eclipse.jface.viewers.ISelection;
0030:        import org.eclipse.jface.viewers.IStructuredSelection;
0031:        import org.eclipse.jface.viewers.StructuredSelection;
0032:        import org.eclipse.jface.viewers.TreeViewer;
0033:        import org.eclipse.jface.viewers.ViewerDropAdapter;
0034:        import org.eclipse.jface.window.Window;
0035:        import org.eclipse.jface.wizard.IWizardPage;
0036:        import org.eclipse.jface.wizard.WizardDialog;
0037:        import org.eclipse.pde.core.IModelChangedEvent;
0038:        import org.eclipse.pde.internal.core.itoc.ITocConstants;
0039:        import org.eclipse.pde.internal.core.text.IDocumentElementNode;
0040:        import org.eclipse.pde.internal.core.text.toc.Toc;
0041:        import org.eclipse.pde.internal.core.text.toc.TocLink;
0042:        import org.eclipse.pde.internal.core.text.toc.TocModel;
0043:        import org.eclipse.pde.internal.core.text.toc.TocObject;
0044:        import org.eclipse.pde.internal.core.text.toc.TocTopic;
0045:        import org.eclipse.pde.internal.ui.PDEPlugin;
0046:        import org.eclipse.pde.internal.ui.PDEUIMessages;
0047:        import org.eclipse.pde.internal.ui.editor.ModelDataTransfer;
0048:        import org.eclipse.pde.internal.ui.editor.PDEFormPage;
0049:        import org.eclipse.pde.internal.ui.editor.TreeSection;
0050:        import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
0051:        import org.eclipse.pde.internal.ui.editor.plugin.FormFilteredTree;
0052:        import org.eclipse.pde.internal.ui.editor.toc.actions.TocAddAnchorAction;
0053:        import org.eclipse.pde.internal.ui.editor.toc.actions.TocAddLinkAction;
0054:        import org.eclipse.pde.internal.ui.editor.toc.actions.TocAddObjectAction;
0055:        import org.eclipse.pde.internal.ui.editor.toc.actions.TocAddTopicAction;
0056:        import org.eclipse.pde.internal.ui.editor.toc.actions.TocRemoveObjectAction;
0057:        import org.eclipse.pde.internal.ui.parts.TreePart;
0058:        import org.eclipse.pde.internal.ui.util.PDELabelUtility;
0059:        import org.eclipse.pde.internal.ui.wizards.toc.NewTocFileWizard;
0060:        import org.eclipse.pde.internal.ui.wizards.toc.TocHTMLWizard;
0061:        import org.eclipse.swt.SWT;
0062:        import org.eclipse.swt.dnd.DND;
0063:        import org.eclipse.swt.dnd.FileTransfer;
0064:        import org.eclipse.swt.dnd.TextTransfer;
0065:        import org.eclipse.swt.dnd.Transfer;
0066:        import org.eclipse.swt.events.DisposeEvent;
0067:        import org.eclipse.swt.events.DisposeListener;
0068:        import org.eclipse.swt.graphics.Cursor;
0069:        import org.eclipse.swt.widgets.Composite;
0070:        import org.eclipse.swt.widgets.Display;
0071:        import org.eclipse.swt.widgets.ToolBar;
0072:        import org.eclipse.ui.PartInitException;
0073:        import org.eclipse.ui.PlatformUI;
0074:        import org.eclipse.ui.actions.ActionFactory;
0075:        import org.eclipse.ui.actions.ContributionItemFactory;
0076:        import org.eclipse.ui.dialogs.PatternFilter;
0077:        import org.eclipse.ui.dialogs.WizardNewFileCreationPage;
0078:        import org.eclipse.ui.forms.widgets.FormToolkit;
0079:        import org.eclipse.ui.forms.widgets.Section;
0080:        import org.eclipse.ui.ide.IDE;
0081:        import org.eclipse.ui.keys.IBindingService;
0082:
0083:        /**
0084:         * TocTreeSection - The section that displays the TOC
0085:         * tree structure and any buttons used to manipulate it.
0086:         * This is the main section that the user will interact
0087:         * with the TOC through.
0088:         */
0089:        public class TocTreeSection extends TreeSection {
0090:            private TocModel fModel;
0091:            private TreeViewer fTocTree;
0092:            private FormFilteredTree fFilteredTree;
0093:
0094:            /* The indices for each button attached to the Tree Viewer.
0095:             * This type of UI form does not permit direct access to each particular
0096:             * button. However, using these indices, one can perform any typical SWT
0097:             * operation on any button.
0098:             */
0099:            private static final int F_BUTTON_ADD_TOPIC = 0;
0100:            private static final int F_BUTTON_ADD_LINK = 3;
0101:            private static final int F_BUTTON_ADD_ANCHOR = 4;
0102:            private static final int F_BUTTON_REMOVE = 5;
0103:            private static final int F_BUTTON_UP = 6;
0104:            private static final int F_BUTTON_DOWN = 7;
0105:            private static final int F_UP_FLAG = -1;
0106:            private static final int F_DOWN_FLAG = 1;
0107:
0108:            private class TocOpenLinkAction extends Action {
0109:                private TocObject fOpenTarget;
0110:
0111:                public TocOpenLinkAction() {
0112:                    setText(PDEUIMessages.Actions_open_label);
0113:                }
0114:
0115:                public void setTarget(TocObject target) {
0116:                    fOpenTarget = target;
0117:                }
0118:
0119:                public void run() {
0120:                    if (fOpenTarget != null) {
0121:                        open(fOpenTarget);
0122:                    }
0123:                }
0124:            }
0125:
0126:            // The action that collapses down the TOC tree
0127:            private CollapseAction fCollapseAction;
0128:
0129:            // The actions that will add each type of TOC object
0130:            private TocAddTopicAction fAddTopicAction;
0131:            private TocAddLinkAction fAddLinkAction;
0132:            private TocAddAnchorAction fAddAnchorAction;
0133:
0134:            // The object removal action
0135:            private TocRemoveObjectAction fRemoveObjectAction;
0136:
0137:            // The action for opening a link from the context menu
0138:            private TocOpenLinkAction fOpenLinkAction;
0139:
0140:            // The adapter that will listen for drag events in the tree
0141:            private TocDragAdapter fDragAdapter;
0142:
0143:            /* If items are dragged and dropped within this tree, then
0144:             * this flag inhibits reselection on the removal (drag) action,
0145:             * thus ensuring that the selected objects are the ones that were
0146:             * dropped.
0147:             */
0148:            private boolean fDragFromHere;
0149:
0150:            /**
0151:             * Constructs a new TOC tree section.
0152:             * 
0153:             * @param formPage The page that will hold this new tree section
0154:             * @param parent The parent composite in the page that will contain the section widgets
0155:             */
0156:            public TocTreeSection(PDEFormPage formPage, Composite parent) {
0157:
0158:                /* Create a new section with a description area, and some buttons.
0159:                 * The null entries in the String array will become blank space 
0160:                 * separators between the buttons.
0161:                 */
0162:                super (formPage, parent, Section.DESCRIPTION, new String[] {
0163:                        PDEUIMessages.TocPage_addTopic, null, null,
0164:                        PDEUIMessages.TocPage_addLink,
0165:                        PDEUIMessages.TocPage_addAnchor,
0166:                        PDEUIMessages.TocPage_remove, PDEUIMessages.TocPage_up,
0167:                        PDEUIMessages.TocPage_down });
0168:
0169:                // Initialize all the actions
0170:                fAddTopicAction = new TocAddTopicAction();
0171:                fAddLinkAction = new TocAddLinkAction();
0172:                fAddAnchorAction = new TocAddAnchorAction();
0173:                fRemoveObjectAction = new TocRemoveObjectAction();
0174:                fOpenLinkAction = new TocOpenLinkAction();
0175:            }
0176:
0177:            /* (non-Javadoc)
0178:             * @see org.eclipse.pde.internal.ui.editor.PDESection#createClient(org.eclipse.ui.forms.widgets.Section, org.eclipse.ui.forms.widgets.FormToolkit)
0179:             */
0180:            protected void createClient(Section section, FormToolkit toolkit) {
0181:                // Get the model
0182:                fModel = (TocModel) getPage().getModel();
0183:
0184:                // Create a container in the section
0185:                Composite container = createClientContainer(section, 2, toolkit);
0186:                // Create a TOC tree in the new container
0187:                createTree(container, toolkit);
0188:                toolkit.paintBordersFor(container);
0189:                section.setText(PDEUIMessages.TocTreeSection_title);
0190:                section
0191:                        .setDescription(PDEUIMessages.TocTreeSection_sectionDescription);
0192:                section.setClient(container);
0193:
0194:                initializeTreeViewer();
0195:                createSectionToolbar(section, toolkit);
0196:
0197:                // Create the adapted listener for the filter entry field
0198:                fFilteredTree.createUIListenerEntryFilter(this );
0199:            }
0200:
0201:            /**
0202:             * Adds a link (with hand cursor) for tree 'Collapse All' action,
0203:             * which collapses the TOC tree down to the second level
0204:             * 
0205:             * @param section The section that the toolbar will belong to
0206:             * @param toolkit The toolkit that will be used to make the toolbar
0207:             */
0208:            private void createSectionToolbar(Section section,
0209:                    FormToolkit toolkit) {
0210:                ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
0211:                ToolBar toolbar = toolBarManager.createControl(section);
0212:
0213:                final Cursor handCursor = new Cursor(Display.getCurrent(),
0214:                        SWT.CURSOR_HAND);
0215:                toolbar.setCursor(handCursor);
0216:                // Cursor needs to be explicitly disposed
0217:                toolbar.addDisposeListener(new DisposeListener() {
0218:                    public void widgetDisposed(DisposeEvent e) {
0219:                        if ((handCursor != null)
0220:                                && (handCursor.isDisposed() == false)) {
0221:                            handCursor.dispose();
0222:                        }
0223:                    }
0224:                });
0225:
0226:                // Add collapse action to the tool bar
0227:                fCollapseAction = new CollapseAction(fTocTree,
0228:                        PDEUIMessages.ExtensionsPage_collapseAll, 1, fModel
0229:                                .getToc());
0230:                toolBarManager.add(fCollapseAction);
0231:
0232:                toolBarManager.update(true);
0233:                section.setTextClient(toolbar);
0234:            }
0235:
0236:            /**
0237:             * Create the tree widget that will contain the TOC
0238:             * 
0239:             * @param container The container of the tree widget
0240:             * @param toolkit The toolkit used to create the tree
0241:             */
0242:            private void createTree(Composite container, FormToolkit toolkit) {
0243:                TreePart treePart = getTreePart();
0244:                createViewerPartControl(container, SWT.MULTI, 2, toolkit);
0245:
0246:                fTocTree = treePart.getTreeViewer();
0247:                fTocTree.setContentProvider(new TocContentProvider());
0248:                fTocTree.setLabelProvider(PDEPlugin.getDefault()
0249:                        .getLabelProvider());
0250:
0251:                PDEPlugin.getDefault().getLabelProvider().connect(this );
0252:
0253:                createTreeListeners();
0254:                initDragAndDrop();
0255:            }
0256:
0257:            /**
0258:             * Initialize the section's drag and drop capabilities
0259:             */
0260:            private void initDragAndDrop() {
0261:                int ops = DND.DROP_COPY;
0262:                if (isEditable()) {
0263:                    ops |= DND.DROP_MOVE;
0264:                }
0265:
0266:                //Content dragged from the tree viewer can be treated as model objects (TocObjects)
0267:                //or as text (XML representation of the TocObjects)
0268:                Transfer[] dragTransfers = new Transfer[] {
0269:                        ModelDataTransfer.getInstance(),
0270:                        TextTransfer.getInstance() };
0271:                fDragAdapter = new TocDragAdapter(this );
0272:                fTocTree.addDragSupport(ops, dragTransfers, fDragAdapter);
0273:
0274:                if (isEditable()) { //Model objects and files can be dropped onto the viewer
0275:                    //TODO: Consider allowing drops/pastes of pure XML text
0276:                    Transfer[] dropTransfers = new Transfer[] {
0277:                            ModelDataTransfer.getInstance(),
0278:                            FileTransfer.getInstance() };
0279:                    fTocTree.addDropSupport(ops | DND.DROP_DEFAULT,
0280:                            dropTransfers, new TocDropAdapter(fTocTree, this ));
0281:                }
0282:            }
0283:
0284:            /**
0285:             * Create the action listeners for the tree.
0286:             */
0287:            private void createTreeListeners() {
0288:                // Create listener for the outline view 'link with editor' toggle button
0289:                fTocTree.addPostSelectionChangedListener(getPage()
0290:                        .getPDEEditor().new PDEFormEditorChangeListener());
0291:            }
0292:
0293:            /**
0294:             * Initialize the tree viewer widget and its buttons.
0295:             */
0296:            private void initializeTreeViewer() {
0297:                if (fModel == null) {
0298:                    return;
0299:                }
0300:
0301:                // Connect the tree viewer to the TOC model
0302:                fTocTree.setInput(fModel);
0303:                Toc toc = fModel.getToc();
0304:
0305:                // Nodes can always be added to the root TOC node
0306:                getTreePart()
0307:                        .setButtonEnabled(F_BUTTON_ADD_TOPIC, isEditable());
0308:                getTreePart().setButtonEnabled(F_BUTTON_ADD_ANCHOR,
0309:                        isEditable());
0310:                getTreePart().setButtonEnabled(F_BUTTON_ADD_LINK, isEditable());
0311:
0312:                // Set to false because initial node selected is the root TOC node
0313:                getTreePart().setButtonEnabled(F_BUTTON_REMOVE, false);
0314:                // Set to false because initial node selected is the root TOC node
0315:                getTreePart().setButtonEnabled(F_BUTTON_UP, false);
0316:                // Set to false because initial node selected is the root TOC node
0317:                getTreePart().setButtonEnabled(F_BUTTON_DOWN, false);
0318:
0319:                //Initially, the root TOC element is selected
0320:                fTocTree.setSelection(new StructuredSelection(toc), true);
0321:                fTocTree.expandToLevel(2);
0322:            }
0323:
0324:            /* (non-Javadoc)
0325:             * @see org.eclipse.ui.forms.AbstractFormPart#setFormInput(java.lang.Object)
0326:             */
0327:            public boolean setFormInput(Object object) {
0328:                // This method allows the outline view to select items in the tree
0329:                // (Invoked by org.eclipse.ui.forms.editor.IFormPage.selectReveal(Object object))
0330:
0331:                if (object instanceof  TocObject) { // Select the item in the tree
0332:                    fTocTree
0333:                            .setSelection(new StructuredSelection(object), true);
0334:
0335:                    // Verify that something was actually selected
0336:                    ISelection selection = fTocTree.getSelection();
0337:                    if (selection != null && !selection.isEmpty()) {
0338:                        return true;
0339:                    }
0340:                }
0341:
0342:                return false;
0343:            }
0344:
0345:            /**
0346:             * @return the selection of the tree section
0347:             */
0348:            public ISelection getSelection() {
0349:                return fTocTree.getSelection();
0350:            }
0351:
0352:            /**
0353:             * @param selection the new selection for the tree section
0354:             */
0355:            public void setSelection(ISelection selection) {
0356:                fTocTree.setSelection(selection);
0357:            }
0358:
0359:            /**
0360:             * Fire a selection change event and refresh the viewer's selection
0361:             */
0362:            public void fireSelection() {
0363:                fTocTree.setSelection(fTocTree.getSelection());
0364:            }
0365:
0366:            /* (non-Javadoc)
0367:             * @see org.eclipse.pde.internal.ui.editor.TreeSection#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection)
0368:             */
0369:            protected void selectionChanged(IStructuredSelection selection) {
0370:                getPage().getPDEEditor().setSelection(selection);
0371:                updateButtons();
0372:            }
0373:
0374:            /**
0375:             * Update the buttons in the section based on the current selection
0376:             */
0377:            public void updateButtons() {
0378:                if (!fModel.isEditable()) {
0379:                    return;
0380:                }
0381:
0382:                // 'Add' actions are enabled if any object in the selection can
0383:                // be added to
0384:                boolean canAddObject = false;
0385:                // 'Remove' is enabled if any object in the selection is removable
0386:                boolean canRemove = false;
0387:
0388:                IStructuredSelection sel = (IStructuredSelection) fTocTree
0389:                        .getSelection();
0390:                //TODO: Implement multi-select move actions from the root TOC element
0391:
0392:                // 'Up' is disabled if any object in the selection can't be moved up.
0393:                boolean canMoveUp = sel.size() == 1;
0394:
0395:                // 'Down' is disabled if any object in the selection can't be moved down.
0396:                boolean canMoveDown = sel.size() == 1;
0397:
0398:                for (Iterator iter = sel.iterator(); iter.hasNext();) {
0399:                    TocObject tocObject = (TocObject) iter.next();
0400:
0401:                    if (tocObject != null) {
0402:                        if (tocObject.canBeRemoved()) {
0403:                            canRemove = true;
0404:                        }
0405:
0406:                        TocObject parent = tocObject.getParent();
0407:                        if (sel.size() == 1
0408:                                && (tocObject.getType() == ITocConstants.TYPE_TOC
0409:                                        || parent.getType() == ITocConstants.TYPE_TOPIC || parent
0410:                                        .getType() == ITocConstants.TYPE_TOC)) { /* Semantic rule: 
0411:                         * As long as the selection is a child of a 
0412:                         * TOC root or a topic, or the selection itself
0413:                         * is a TOC root, then a new object can be added
0414:                         * either to the selection or to the parent
0415:                         */
0416:                            canAddObject = true;
0417:                        }
0418:
0419:                        //Semantic rule:
0420:                        //You cannot rearrange the TOC root itself
0421:                        if (tocObject.getType() == ITocConstants.TYPE_TOC) {
0422:                            canMoveUp = false;
0423:                            canMoveDown = false;
0424:                        } else {
0425:                            if (parent != null) {
0426:                                TocTopic topic = (TocTopic) parent;
0427:                                if (topic.isFirstChildObject(tocObject)) {
0428:                                    canMoveUp = false;
0429:                                }
0430:
0431:                                if (topic.isLastChildObject(tocObject)) {
0432:                                    canMoveDown = false;
0433:                                }
0434:                            }
0435:                        }
0436:                    } else { // How anyone can select a null object, I don't know.
0437:                        // However, if it happens, disable all buttons.
0438:                        canAddObject = false;
0439:                        canRemove = false;
0440:                        canMoveUp = false;
0441:                        canMoveDown = false;
0442:
0443:                        break;
0444:                    }
0445:                }
0446:
0447:                getTreePart()
0448:                        .setButtonEnabled(F_BUTTON_ADD_TOPIC, canAddObject);
0449:                getTreePart().setButtonEnabled(F_BUTTON_ADD_LINK, canAddObject);
0450:                getTreePart().setButtonEnabled(F_BUTTON_ADD_ANCHOR,
0451:                        canAddObject);
0452:                getTreePart().setButtonEnabled(F_BUTTON_REMOVE, canRemove);
0453:                getTreePart().setButtonEnabled(F_BUTTON_UP, canMoveUp);
0454:                getTreePart().setButtonEnabled(F_BUTTON_DOWN, canMoveDown);
0455:            }
0456:
0457:            /* (non-Javadoc)
0458:             * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#fillContextMenu(org.eclipse.jface.action.IMenuManager)
0459:             */
0460:            protected void fillContextMenu(IMenuManager manager) {
0461:                // Get the current selection
0462:                ISelection selection = fTocTree.getSelection();
0463:                Object object = ((IStructuredSelection) selection)
0464:                        .getFirstElement();
0465:                // Has to be null or a TOC object
0466:                TocObject tocObject = (TocObject) object;
0467:
0468:                if (tocObject != null) {
0469:                    boolean emptyMenu = true;
0470:
0471:                    if (tocObject.canBeParent()) { // Create the "New" sub-menu
0472:                        MenuManager submenu = new MenuManager(
0473:                                PDEUIMessages.Menus_new_label);
0474:                        // Populate the "New" sub-menu
0475:                        fillContextMenuAddActions(submenu, tocObject);
0476:                        // Add the "New" sub-menu to the main context menu
0477:                        manager.add(submenu);
0478:                        emptyMenu = false;
0479:                    }
0480:
0481:                    if (tocObject.getPath() != null) {
0482:                        fOpenLinkAction.setTarget(tocObject);
0483:                        manager.add(fOpenLinkAction);
0484:                        emptyMenu = false;
0485:                    }
0486:
0487:                    if (!emptyMenu) { // Add a separator to the main context menu
0488:                        manager.add(new Separator());
0489:                    }
0490:                }
0491:
0492:                // Add clipboard actions
0493:                getPage().getPDEEditor().getContributor()
0494:                        .contextMenuAboutToShow(manager);
0495:                manager.add(new Separator());
0496:
0497:                if (tocObject != null) { // Add the Remove action and Show In action if an object is selected
0498:                    fillContextMenuRemoveAction(manager, tocObject);
0499:                    manager.add(new Separator());
0500:
0501:                    fillContextMenuShowInAction(manager);
0502:                    manager.add(new Separator());
0503:                }
0504:            }
0505:
0506:            private void fillContextMenuShowInAction(IMenuManager manager) {
0507:                String showInLabel = PDEUIMessages.PluginsView_showIn;
0508:
0509:                // Add a label for the keybinding for Show In action, if one exists
0510:                IBindingService bindingService = (IBindingService) PlatformUI
0511:                        .getWorkbench().getAdapter(IBindingService.class);
0512:                if (bindingService != null) {
0513:                    String keyBinding = bindingService
0514:                            .getBestActiveBindingFormattedFor("org.eclipse.ui.navigate.showInQuickMenu"); //$NON-NLS-1$
0515:                    if (keyBinding != null) {
0516:                        showInLabel += '\t' + keyBinding;
0517:                    }
0518:                }
0519:
0520:                // Add the "Show In" action and its contributions
0521:                IMenuManager showInMenu = new MenuManager(showInLabel);
0522:                showInMenu.add(ContributionItemFactory.VIEWS_SHOW_IN
0523:                        .create(getPage().getSite().getWorkbenchWindow()));
0524:
0525:                manager.add(showInMenu);
0526:            }
0527:
0528:            /**
0529:             * Add the addition actions (Topic, Link, Anchor) to the specified submenu
0530:             * 
0531:             * @param submenu The submenu to add the addition actions to
0532:             * @param tocObject The object that the additions would occur relative to
0533:             */
0534:            private void fillContextMenuAddActions(MenuManager submenu,
0535:                    TocObject tocObject) {
0536:
0537:                if (tocObject != null && tocObject.canBeParent()) { // Add the 'Add Topic' action to the sub-menu
0538:                    fAddTopicAction.setParentObject(tocObject);
0539:                    fAddTopicAction.setEnabled(fModel.isEditable());
0540:                    submenu.add(fAddTopicAction);
0541:
0542:                    // Add the 'Add Link' action to the sub-menu
0543:                    fAddLinkAction.setParentObject(tocObject);
0544:                    fAddLinkAction.setEnabled(fModel.isEditable());
0545:                    submenu.add(fAddLinkAction);
0546:
0547:                    // Add the 'Add Anchor' action to the sub-menu
0548:                    fAddAnchorAction.setParentObject(tocObject);
0549:                    fAddAnchorAction.setEnabled(fModel.isEditable());
0550:                    submenu.add(fAddAnchorAction);
0551:                }
0552:            }
0553:
0554:            /**
0555:             * Add the remove action to the context menu.
0556:             * 
0557:             * @param manager The context menu to add the remove action to
0558:             * @param tocObject The object that would be targetted for removal
0559:             */
0560:            private void fillContextMenuRemoveAction(IMenuManager manager,
0561:                    TocObject tocObject) {
0562:                // Add to the main context menu
0563:
0564:                // Delete task object action
0565:                fRemoveObjectAction.setToRemove(tocObject);
0566:                manager.add(fRemoveObjectAction);
0567:
0568:                fRemoveObjectAction.setEnabled(tocObject.canBeRemoved()
0569:                        && fModel.isEditable());
0570:            }
0571:
0572:            /* (non-Javadoc)
0573:             * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
0574:             */
0575:            protected boolean canPaste(Object targetObject,
0576:                    Object[] sourceObjects) {
0577:                return true;
0578:            }
0579:
0580:            /* (non-Javadoc)
0581:             * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
0582:             */
0583:            public boolean doGlobalAction(String actionId) {
0584:                boolean cutAction = actionId.equals(ActionFactory.CUT.getId());
0585:
0586:                if (cutAction || actionId.equals(ActionFactory.DELETE.getId())) {
0587:                    handleDeleteAction();
0588:                    return !cutAction;
0589:                }
0590:
0591:                if (actionId.equals(ActionFactory.PASTE.getId())) {
0592:                    doPaste();
0593:                    return true;
0594:                }
0595:
0596:                return false;
0597:            }
0598:
0599:            /* (non-Javadoc)
0600:             * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
0601:             */
0602:            protected void doPaste(Object targetObject, Object[] sourceObjects) {
0603:                performDrop(targetObject, sourceObjects,
0604:                        ViewerDropAdapter.LOCATION_ON);
0605:            }
0606:
0607:            /* (non-Javadoc)
0608:             * @see org.eclipse.pde.internal.ui.editor.TreeSection#handleDoubleClick(org.eclipse.jface.viewers.IStructuredSelection)
0609:             */
0610:            protected void handleDoubleClick(IStructuredSelection selection) {
0611:                Object selected = selection.getFirstElement();
0612:                if (selected instanceof  TocObject) {
0613:                    open((TocObject) selected);
0614:                }
0615:            }
0616:
0617:            /**
0618:             * Opens a document with the specified path
0619:             * 
0620:             * @param path a path to a resource, relative to this TOC's root project
0621:             */
0622:            private void open(TocObject obj) {
0623:                Path resourcePath = new Path(obj.getPath());
0624:                if (!isEditable() || resourcePath == null
0625:                        || resourcePath.isEmpty()) {
0626:                    MessageDialog.openWarning(PDEPlugin
0627:                            .getActiveWorkbenchShell(),
0628:                            PDEUIMessages.WindowImagesSection_open,
0629:                            PDEUIMessages.WindowImagesSection_emptyPath);
0630:                    return;
0631:                }
0632:
0633:                IResource resource = findResource(resourcePath);
0634:                if (resource != null && resource instanceof  IFile) {
0635:                    openResource(resource,
0636:                            obj.getType() == ITocConstants.TYPE_LINK);
0637:                } else {
0638:                    MessageDialog.openWarning(PDEPlugin
0639:                            .getActiveWorkbenchShell(),
0640:                            PDEUIMessages.WindowImagesSection_open,
0641:                            PDEUIMessages.WindowImagesSection_warning);
0642:                }
0643:            }
0644:
0645:            public IFile openFile(String path, boolean isTOCFile) {
0646:                Path resourcePath = new Path(path);
0647:                if (isEditable()) {
0648:                    if (!resourcePath.isEmpty()) {
0649:                        IResource page = findResource(resourcePath);
0650:
0651:                        if (page != null && page instanceof  IFile) {
0652:                            openResource(page, isTOCFile);
0653:                            return null;
0654:                        }
0655:                    }
0656:
0657:                    return showNewWizard(path, isTOCFile);
0658:                }
0659:
0660:                return null;
0661:            }
0662:
0663:            private IFile showNewWizard(String path, boolean tocWizard) {
0664:                TocHTMLWizard wizard;
0665:                if (tocWizard) {
0666:                    wizard = new NewTocFileWizard();
0667:                } else {
0668:                    wizard = new TocHTMLWizard();
0669:                }
0670:
0671:                // By default, the file will be created in the same project as the TOC
0672:                IResource selectedFolder = fModel.getUnderlyingResource()
0673:                        .getProject();
0674:                String filename = null;
0675:
0676:                // Find the folder associated with the specified path
0677:                IPath initialFolder = new Path(path.trim());
0678:                if (!initialFolder.isEmpty()) {
0679:                    IPath newPath = selectedFolder.getFullPath().append(
0680:                            initialFolder);
0681:
0682:                    IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
0683:                            .getRoot();
0684:                    IResource newFolder = root.findMember(newPath);
0685:
0686:                    if (newFolder == null) {
0687:                        if (!newPath.hasTrailingSeparator()) {
0688:                            filename = newPath.lastSegment();
0689:                        }
0690:                    }
0691:
0692:                    while (newFolder == null && !newPath.isEmpty()) {
0693:                        newPath = newPath.removeLastSegments(1);
0694:                        newFolder = root.findMember(newPath);
0695:                    }
0696:
0697:                    if (newFolder != null) {
0698:                        selectedFolder = newFolder;
0699:                    }
0700:                }
0701:
0702:                // Select the project in the wizard
0703:                wizard.init(PlatformUI.getWorkbench(), new StructuredSelection(
0704:                        selectedFolder));
0705:
0706:                // Create the dialog for the wizard
0707:                WizardDialog dialog = new WizardDialog(PDEPlugin
0708:                        .getActiveWorkbenchShell(), wizard);
0709:                dialog.create();
0710:                // Get the wizard page
0711:                IWizardPage wizardPage;
0712:                wizardPage = wizard.getStartingPage();
0713:                if (!(wizardPage instanceof  WizardNewFileCreationPage)) {
0714:                    return null;
0715:                }
0716:
0717:                WizardNewFileCreationPage page = (WizardNewFileCreationPage) wizardPage;
0718:                if (filename != null) {
0719:                    page.setFileName(filename);
0720:                    // Inhibit the error message when the wizard is first opened
0721:                    page.setErrorMessage(null);
0722:                }
0723:
0724:                if (dialog.open() == Window.OK) {
0725:                    return wizard.getNewResource();
0726:                }
0727:
0728:                return null;
0729:            }
0730:
0731:            private IResource findResource(Path resourcePath) {
0732:                IProject pluginProject = fModel.getUnderlyingResource()
0733:                        .getProject();
0734:                return pluginProject.findMember(resourcePath);
0735:            }
0736:
0737:            private void openResource(IResource resource, boolean tocFile) {
0738:                IPath path = resource.getFullPath();
0739:
0740:                if (isFileValidInContext(tocFile, path)) {
0741:                    try {
0742:                        IDE.openEditor(PDEPlugin.getActivePage(),
0743:                                (IFile) resource, true);
0744:                    } catch (PartInitException e) { //suppress exception
0745:                    }
0746:                }
0747:            }
0748:
0749:            private boolean isFileValidInContext(boolean tocFile, IPath path) {
0750:                String message = null;
0751:
0752:                if (tocFile) {
0753:                    if (TocExtensionUtil.isTOCFile(path)) {
0754:                        return true;
0755:                    }
0756:
0757:                    message = PDEUIMessages.TocPage_invalidTocFile;
0758:                } else {
0759:                    if (TocExtensionUtil.hasValidPageExtension(path)) {
0760:                        return true;
0761:                    }
0762:
0763:                    message = PDEUIMessages.TocPage_invalidHTMLFile;
0764:                }
0765:
0766:                MessageDialog.openWarning(PDEPlugin.getActiveWorkbenchShell(),
0767:                        PDEUIMessages.WindowImagesSection_open, message);
0768:
0769:                return false;
0770:            }
0771:
0772:            /**
0773:             * Perform a drop of the specified objects on the target in the widget
0774:             * 
0775:             * @param currentTarget The object that the drop will occur near/on
0776:             * @param dropped The dropped objects
0777:             * @param location The location of the drop relative to the target
0778:             * 
0779:             * @return true iff the drop was successful
0780:             */
0781:            public boolean performDrop(Object currentTarget, Object dropped,
0782:                    int location) {
0783:                if (dropped instanceof  Object[]) {
0784:                    TocObject tocTarget = (TocObject) currentTarget;
0785:                    // Determine the object that the dropped objects will be the
0786:                    // children of
0787:                    TocTopic targetParent = determineParent(tocTarget, location);
0788:
0789:                    if (location == TocDropAdapter.LOCATION_JUST_AFTER
0790:                            && targetParent == tocTarget
0791:                            && !tocTarget.getChildren().isEmpty()
0792:                            && fTocTree.getExpandedState(tocTarget)) { // If the drop occurs just after a parentable object
0793:                        // and it is expanded, then insert the dropped items
0794:                        // as the first children of the parent
0795:                        location = ViewerDropAdapter.LOCATION_BEFORE;
0796:                        tocTarget = (TocObject) tocTarget.getChildren().get(0);
0797:                    }
0798:
0799:                    if (targetParent != null) { // Get the TocObject versions of the dropped objects
0800:                        ArrayList objectsToAdd = getObjectsToAdd(
0801:                                (Object[]) dropped, targetParent);
0802:
0803:                        if (objectsToAdd != null && !objectsToAdd.isEmpty()) {
0804:                            if (fDragAdapter.getDraggedElements() != null
0805:                                    && fDragAdapter.getDraggedElements().size() == 1
0806:                                    && currentTarget == fDragAdapter
0807:                                            .getDraggedElements().get(0)) { // Last-minute check: ignore drops of an object onto/near itself
0808:                                // to avoid unnecessarily dirtying the page
0809:                                return false;
0810:                            }
0811:
0812:                            boolean insertBefore = (location == ViewerDropAdapter.LOCATION_BEFORE);
0813:
0814:                            // Add the objects
0815:                            handleMultiAddAction(objectsToAdd, tocTarget,
0816:                                    insertBefore, targetParent);
0817:                            return true;
0818:                        }
0819:                    }
0820:                }
0821:
0822:                return false;
0823:            }
0824:
0825:            /**
0826:             * Determine the parent object that a drop will occur under,
0827:             * based on the relative location of the drop and the ability
0828:             * of the target to be a parent
0829:             * 
0830:             * @param dropTarget The target that the drop occurs near/on
0831:             * @param dropLocation The location of the drop relative to the target
0832:             * @return
0833:             */
0834:            private TocTopic determineParent(TocObject dropTarget,
0835:                    int dropLocation) {
0836:                //We must determine what object will be the parent of the
0837:                //dropped objects. This is done by looking at the drop location
0838:                //and drop target type
0839:
0840:                if (dropTarget == null
0841:                        || dropTarget.getType() == ITocConstants.TYPE_TOC) { //Since the TOC root has no parent, it must be the target parent
0842:                    return fModel.getToc();
0843:                } else if (!dropTarget.canBeParent()) { //If the object is a leaf, it cannot be the parent
0844:                    //of the new objects,
0845:                    //so the target parent must be its parent
0846:                    return (TocTopic) dropTarget.getParent();
0847:                } else { //In all other cases, it depends on the location of the drop
0848:                    //relative to the drop target
0849:                    switch (dropLocation) {
0850:                    case TocDropAdapter.LOCATION_JUST_AFTER: { //if the drop occured after an expanded node
0851:                        //and all of its children,
0852:                        //make the drop target's parent the target parent object
0853:                        if (!fTocTree.getExpandedState(dropTarget)) {
0854:                            return (TocTopic) dropTarget.getParent();
0855:                        }
0856:                        //otherwise, the target parent is the drop target,
0857:                        //since the drop occured between it and its first child
0858:                    }
0859:                    case ViewerDropAdapter.LOCATION_ON: { //the drop location is directly on the drop target
0860:                        //set the parent object to be the drop target
0861:                        return (TocTopic) dropTarget;
0862:                    }
0863:                    case ViewerDropAdapter.LOCATION_BEFORE:
0864:                    case ViewerDropAdapter.LOCATION_AFTER: { //if the drop is before or after the drop target,
0865:                        //make the drop target's parent the target parent object
0866:                        return (TocTopic) dropTarget.getParent();
0867:                    }
0868:                    }
0869:                }
0870:
0871:                return null;
0872:            }
0873:
0874:            /**
0875:             * Get the TocObject representations of a group of dropped objects.
0876:             * 
0877:             * @param droppings The objects that are dropped; can be file path Strings or
0878:             * deserialized TocObjects
0879:             * 
0880:             * @param targetParent The designated parent of the dropped objects
0881:             * 
0882:             * @return a list of the (reconnected) TocObject representations of the dropped objects
0883:             */
0884:            private ArrayList getObjectsToAdd(Object[] droppings,
0885:                    TocTopic targetParent) {
0886:                ArrayList tocObjects = new ArrayList(droppings.length);
0887:
0888:                if (fDragAdapter.getDraggedElements() != null) { // If there are items in the drag adapter, then the current drag must be from
0889:                    // this section
0890:                    fDragFromHere = fDragAdapter.getDraggedElements().size() == droppings.length;
0891:                }
0892:
0893:                for (int i = 0; i < droppings.length; ++i) {
0894:                    if (droppings[i] instanceof  String) {
0895:                        IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
0896:                                .getRoot();
0897:
0898:                        // If the array contains Strings, we treat them as file paths
0899:                        Path path = new Path((String) droppings[i]);
0900:                        IFile file = root.getFileForLocation(path);
0901:                        if (file == null) {
0902:                            continue;
0903:                        }
0904:
0905:                        // If the path is to a valid TOC file
0906:                        // and it isn't the file in this model
0907:                        // then make a link
0908:                        if (TocExtensionUtil.isTOCFile(path)
0909:                                && !TocExtensionUtil.isCurrentResource(path,
0910:                                        fModel)) {
0911:                            tocObjects.add(makeNewTocLink(targetParent, file));
0912:                        }
0913:                        // If the path is to a file with an HTML page extension, make a topic
0914:                        else if (TocExtensionUtil.hasValidPageExtension(path)) {
0915:                            TocTopic topic = makeNewTocTopic(targetParent, file);
0916:                            String title = generateTitle(targetParent, path);
0917:
0918:                            topic.setFieldLabel(title);
0919:                            tocObjects.add(topic);
0920:                        }
0921:                    } else if (droppings[i] instanceof  TocObject) {
0922:                        ArrayList dragged = fDragAdapter.getDraggedElements();
0923:                        if (fDragFromHere) {
0924:                            TocObject draggedObj = (TocObject) dragged.get(i);
0925:
0926:                            //Nesting an object inside itself or its children
0927:                            //is so stupid and ridiculous that I get a headache
0928:                            //just thinking about it. Thus, this drag is not going to complete.
0929:                            if (targetParent.descendsFrom(draggedObj)) {
0930:                                return null;
0931:                            }
0932:                        }
0933:
0934:                        //Reconnect this TocObject, since it was deserialized
0935:                        ((TocObject) droppings[i]).reconnect(targetParent,
0936:                                fModel);
0937:                        tocObjects.add(droppings[i]);
0938:                    }
0939:                }
0940:
0941:                return tocObjects;
0942:            }
0943:
0944:            /**
0945:             * Generate the title of a Topic created via dragging in an HTML page.
0946:             * Use the title of the HTML page, or generate a name based on the target
0947:             * parent if no title exists.
0948:             * 
0949:             * @param targetParent The designated parent of this topic
0950:             * @param path The path to the HTML file
0951:             * 
0952:             * @return The generated name of the Topic.
0953:             */
0954:            private String generateTitle(TocTopic targetParent, Path path) {
0955:                String title = TocHTMLTitleUtil.findTitle(path.toFile());
0956:                if (title == null) {
0957:                    int numChildren = targetParent.getChildren().size();
0958:                    TocObject[] children = (TocObject[]) targetParent
0959:                            .getChildren().toArray(new TocObject[numChildren]);
0960:
0961:                    String[] tocObjectNames = new String[children.length];
0962:
0963:                    for (int j = 0; j < numChildren; ++j) {
0964:                        tocObjectNames[j] = children[j].getName();
0965:                    }
0966:
0967:                    title = PDELabelUtility.generateName(tocObjectNames,
0968:                            PDEUIMessages.TocPage_TocTopic);
0969:                }
0970:                return title;
0971:            }
0972:
0973:            /**
0974:             * Create a new Topic node using the model's factory.
0975:             *  
0976:             * @param parent The designated parent for the new topic
0977:             * @param path The file that this Topic will link to
0978:             * 
0979:             * @return the newly created topic
0980:             */
0981:            private TocTopic makeNewTocTopic(TocObject parent, IFile file) {
0982:                return fModel.getFactory().createTocTopic(file);
0983:            }
0984:
0985:            /**
0986:             * Create a new Link node using the model's factory.
0987:             *  
0988:             * @param parent The designated parent for the new link
0989:             * @param path The file that this link will be associated with
0990:             * 
0991:             * @return the newly created link
0992:             */
0993:            private TocLink makeNewTocLink(TocObject parent, IFile file) {
0994:                return fModel.getFactory().createTocLink(file);
0995:            }
0996:
0997:            /* (non-Javadoc)
0998:             * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#buttonSelected(int)
0999:             */
1000:            protected void buttonSelected(int index) {
1001:                switch (index) {
1002:                case F_BUTTON_ADD_TOPIC:
1003:                    handleAddAction(fAddTopicAction);
1004:                    break;
1005:                case F_BUTTON_ADD_LINK:
1006:                    handleAddAction(fAddLinkAction);
1007:                    break;
1008:                case F_BUTTON_ADD_ANCHOR:
1009:                    handleAddAction(fAddAnchorAction);
1010:                    break;
1011:                case F_BUTTON_REMOVE:
1012:                    handleDeleteAction();
1013:                    break;
1014:                case F_BUTTON_UP:
1015:                    handleMoveAction(F_UP_FLAG);
1016:                    break;
1017:                case F_BUTTON_DOWN:
1018:                    handleMoveAction(F_DOWN_FLAG);
1019:                    break;
1020:                }
1021:            }
1022:
1023:            /**
1024:             * Handle the addition of an object by preparing and running the
1025:             * specified action.
1026:             * 
1027:             * @param action The action to run for the addition
1028:             */
1029:            private void handleAddAction(TocAddObjectAction action) {
1030:                //Currently, all additions in the TOC editor are semantically similar
1031:                //Thus, all addition operations can follow the same procedure
1032:
1033:                ISelection sel = fTocTree.getSelection();
1034:                Object object = ((IStructuredSelection) sel).getFirstElement();
1035:                if (object == null) {
1036:                    return;
1037:                }
1038:
1039:                TocObject tocObject = (TocObject) object;
1040:
1041:                if (tocObject.canBeParent()) {
1042:                    // If the selected object can be a parent, then add
1043:                    // the new object as a child of this object
1044:                    action.setParentObject(tocObject);
1045:                    action.run();
1046:                } else { // If the selected object cannot be a parent, then add
1047:                    // the new object as a direct sibling of this object
1048:                    action.setParentObject(tocObject.getParent());
1049:                    action.setTargetObject(tocObject);
1050:                    action.run();
1051:                }
1052:            }
1053:
1054:            /**
1055:             * Handle the addition of multiple initialized objects to the TOC.
1056:             * 
1057:             * @param objectsToAdd The objects to be added
1058:             * @param tocTarget The target to add these objects relative to
1059:             * @param insertBefore Whether or not the insertion occurs before the target
1060:             * @param targetParent The parent object of the newly added objects
1061:             */
1062:            private void handleMultiAddAction(List objectsToAdd,
1063:                    TocObject tocTarget, boolean insertBefore,
1064:                    TocObject targetParent) {
1065:                TocObject[] tocObjects = (TocObject[]) objectsToAdd
1066:                        .toArray(new TocObject[objectsToAdd.size()]);
1067:                if (tocObjects == null)
1068:                    return;
1069:
1070:                for (int i = 0; i < tocObjects.length; ++i) {
1071:                    if (tocObjects[i] != null) {
1072:                        if (targetParent != null && targetParent.canBeParent()) {
1073:                            if (tocTarget != null && tocTarget != targetParent) { // Add the object as a direct sibling of the target
1074:                                ((TocTopic) targetParent).addChild(
1075:                                        tocObjects[i], tocTarget, insertBefore);
1076:                            } else { // Add the object as the last child of the target parent
1077:                                ((TocTopic) targetParent)
1078:                                        .addChild(tocObjects[i]);
1079:                            }
1080:                        }
1081:                    }
1082:                }
1083:            }
1084:
1085:            /**
1086:             * Remove the selected objects from the TOC tree
1087:             */
1088:            private void handleDeleteAction() {
1089:                ArrayList objects = new ArrayList(
1090:                        ((IStructuredSelection) fTocTree.getSelection())
1091:                                .toList());
1092:                boolean beep = false;
1093:
1094:                // Iterate through the list of selected objects, removing ones
1095:                // that cannot be removed
1096:                for (Iterator i = objects.iterator(); i.hasNext();) {
1097:                    Object object = i.next();
1098:                    if (object instanceof  TocObject) {
1099:                        TocObject tocObject = (TocObject) object;
1100:
1101:                        if (!tocObject.canBeRemoved()) {
1102:                            i.remove();
1103:                            beep = true;
1104:                        }
1105:                    }
1106:                }
1107:
1108:                if (beep) { // If any object cannot be removed, beep to notify the user			
1109:                    Display.getCurrent().beep();
1110:                }
1111:
1112:                // Remove the remaining objects
1113:                handleRemove(objects);
1114:            }
1115:
1116:            /**
1117:             * Remove the items listed from the TOC.
1118:             * 
1119:             * @param itemsToRemove The list of items to remove from the TOC 
1120:             */
1121:            public void handleRemove(List itemsToRemove) {
1122:                if (!itemsToRemove.isEmpty()) { // Target the objects for removal
1123:                    fRemoveObjectAction.setToRemove((TocObject[]) itemsToRemove
1124:                            .toArray(new TocObject[itemsToRemove.size()]));
1125:
1126:                    // Run the removal action
1127:                    fRemoveObjectAction.run();
1128:                }
1129:            }
1130:
1131:            /**
1132:             * Handle the dragging of objects out of this TOC.
1133:             * 
1134:             * @param itemsDragged The items dragged out of the TOC
1135:             */
1136:            public void handleDrag(List itemsDragged) {
1137:                handleRemove(itemsDragged);
1138:
1139:                // The drag is finished, so there is no intra-editor DND operation occuring now
1140:                fDragFromHere = false;
1141:            }
1142:
1143:            /**
1144:             * Move an object within the TOC.
1145:             * 
1146:             * @param positionFlag The direction that the object will move
1147:             */
1148:            private void handleMoveAction(int positionFlag) {
1149:                IStructuredSelection sel = (IStructuredSelection) fTocTree
1150:                        .getSelection();
1151:
1152:                for (Iterator iter = sel.iterator(); iter.hasNext();) {
1153:                    Object object = iter.next();
1154:                    if (object == null) {
1155:                        return;
1156:                    } else if (object instanceof  TocObject) {
1157:                        TocObject tocObject = (TocObject) object;
1158:                        TocTopic parent = (TocTopic) tocObject.getParent();
1159:
1160:                        // Determine the parent type
1161:                        if (parent != null) { // Move the object up or down one position
1162:                            parent.moveChild(tocObject, positionFlag);
1163:                        }
1164:                    }
1165:                }
1166:            }
1167:
1168:            /* (non-Javadoc)
1169:             * @see org.eclipse.pde.internal.ui.editor.PDESection#modelChanged(org.eclipse.pde.core.IModelChangedEvent)
1170:             */
1171:            public void modelChanged(IModelChangedEvent event) {
1172:                // No need to call super, world changed event handled here
1173:                if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
1174:                    handleModelEventWorldChanged(event);
1175:                } else if (event.getChangeType() == IModelChangedEvent.INSERT) {
1176:                    handleModelInsertType(event);
1177:                } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
1178:                    handleModelRemoveType(event);
1179:                } else if ((event.getChangeType() == IModelChangedEvent.CHANGE)
1180:                        && (event.getChangedProperty()
1181:                                .equals(IDocumentElementNode.F_PROPERTY_CHANGE_TYPE_SWAP))) {
1182:                    handleModelChangeTypeSwap(event);
1183:                } else if (event.getChangeType() == IModelChangedEvent.CHANGE) {
1184:                    handleModelChangeType(event);
1185:                }
1186:            }
1187:
1188:            /**
1189:             * @param event
1190:             */
1191:            private void handleModelChangeTypeSwap(IModelChangedEvent event) {
1192:                // Swap event
1193:                // Get the changed object
1194:                Object[] objects = event.getChangedObjects();
1195:                TocObject object = (TocObject) objects[0];
1196:
1197:                if (object != null) { // Update the element in the tree viewer
1198:                    fTocTree.refresh(object);
1199:                }
1200:            }
1201:
1202:            /**
1203:             * The model is stale, refresh the UI
1204:             * 
1205:             * @param event The world-change event
1206:             */
1207:            private void handleModelEventWorldChanged(IModelChangedEvent event) {
1208:                markStale();
1209:            }
1210:
1211:            /**
1212:             * Handle insertions in the model
1213:             * @param event the insertion event
1214:             */
1215:            private void handleModelInsertType(IModelChangedEvent event) {
1216:                // Insert event
1217:                Object[] objects = event.getChangedObjects();
1218:                TocObject object = (TocObject) objects[0];
1219:                if (object != null) {
1220:                    if (object.getType() != ITocConstants.TYPE_TOC) {
1221:                        // Refresh the parent element in the tree viewer
1222:                        // TODO: Can we get away with an update instead of a refresh here?
1223:                        fTocTree.refresh(object.getParent());
1224:                        // Select the new object in the tree
1225:                        fTocTree.setSelection(new StructuredSelection(object),
1226:                                true);
1227:                    }
1228:                }
1229:            }
1230:
1231:            /**
1232:             * Handle removals in the model
1233:             * 
1234:             * @param event the removal event
1235:             */
1236:            private void handleModelRemoveType(IModelChangedEvent event) {
1237:                // Remove event
1238:                Object[] objects = event.getChangedObjects();
1239:                TocObject object = (TocObject) objects[0];
1240:                if (object != null) {
1241:                    if (object.getType() != ITocConstants.TYPE_TOC) {
1242:                        handleTaskObjectRemove(object);
1243:                    }
1244:                }
1245:            }
1246:
1247:            /**
1248:             * An object was removed, update the UI to respond to the removal
1249:             * 
1250:             * @param object The object that was removed
1251:             */
1252:            private void handleTaskObjectRemove(TocObject object) {
1253:                // Remove the item
1254:                fTocTree.remove(object);
1255:
1256:                // Select the appropriate object
1257:                TocObject tocObject = fRemoveObjectAction.getNextSelection();
1258:                if (tocObject == null) {
1259:                    tocObject = object.getParent();
1260:                }
1261:
1262:                if (tocObject.equals(object.getParent())) {
1263:                    fTocTree.refresh(object.getParent());
1264:                }
1265:
1266:                if (!fDragFromHere) {
1267:                    fTocTree.setSelection(new StructuredSelection(tocObject),
1268:                            true);
1269:                }
1270:            }
1271:
1272:            /**
1273:             * Handle an update to a TocObject's properties
1274:             * @param event the update event
1275:             */
1276:            private void handleModelChangeType(IModelChangedEvent event) {
1277:                // Get the changed object
1278:                Object[] objects = event.getChangedObjects();
1279:                TocObject object = (TocObject) objects[0];
1280:
1281:                if (object != null) { // Update the element in the tree viewer
1282:                    fTocTree.update(object, null);
1283:                }
1284:            }
1285:
1286:            public void refresh() {
1287:                TocModel model = (TocModel) getPage().getModel();
1288:                fTocTree.setInput(model);
1289:                fTocTree.expandToLevel(2);
1290:                fTocTree.setSelection(new StructuredSelection(model.getToc()),
1291:                        true);
1292:                getManagedForm().fireSelectionChanged(this ,
1293:                        fTocTree.getSelection());
1294:                super .refresh();
1295:            }
1296:
1297:            /* (non-Javadoc)
1298:             * @see org.eclipse.pde.internal.ui.editor.TreeSection#createTreeViewer(org.eclipse.swt.widgets.Composite, int)
1299:             */
1300:            protected TreeViewer createTreeViewer(Composite parent, int style) {
1301:                fFilteredTree = new FormFilteredTree(parent, style,
1302:                        new PatternFilter());
1303:                parent.setData("filtered", Boolean.TRUE); //$NON-NLS-1$
1304:                return fFilteredTree.getViewer();
1305:            }
1306:
1307:            /* (non-Javadoc)
1308:             * @see org.eclipse.ui.forms.AbstractFormPart#dispose()
1309:             */
1310:            public void dispose() {
1311:                PDEPlugin.getDefault().getLabelProvider().disconnect(this);
1312:                super.dispose();
1313:            }
1314:        }
w_ww_.___j_a_va_2s__.___c___o___m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.