Source Code Cross Referenced for EditorManager.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » internal » 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 » ui workbench » org.eclipse.ui.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 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.ui.internal;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Arrays;
0014:        import java.util.HashMap;
0015:        import java.util.HashSet;
0016:        import java.util.Iterator;
0017:        import java.util.List;
0018:        import java.util.ListIterator;
0019:        import java.util.Map;
0020:
0021:        import org.eclipse.core.commands.AbstractHandler;
0022:        import org.eclipse.core.commands.ExecutionEvent;
0023:        import org.eclipse.core.commands.IHandler;
0024:        import org.eclipse.core.runtime.Assert;
0025:        import org.eclipse.core.runtime.CoreException;
0026:        import org.eclipse.core.runtime.IConfigurationElement;
0027:        import org.eclipse.core.runtime.IExtension;
0028:        import org.eclipse.core.runtime.IPath;
0029:        import org.eclipse.core.runtime.IProgressMonitor;
0030:        import org.eclipse.core.runtime.IStatus;
0031:        import org.eclipse.core.runtime.MultiStatus;
0032:        import org.eclipse.core.runtime.SafeRunner;
0033:        import org.eclipse.core.runtime.Status;
0034:        import org.eclipse.core.runtime.SubProgressMonitor;
0035:        import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
0036:        import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
0037:        import org.eclipse.jface.dialogs.IDialogConstants;
0038:        import org.eclipse.jface.dialogs.MessageDialog;
0039:        import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
0040:        import org.eclipse.jface.operation.IRunnableContext;
0041:        import org.eclipse.jface.operation.IRunnableWithProgress;
0042:        import org.eclipse.jface.preference.IPreferenceStore;
0043:        import org.eclipse.jface.resource.ImageDescriptor;
0044:        import org.eclipse.jface.resource.ImageRegistry;
0045:        import org.eclipse.jface.resource.JFaceResources;
0046:        import org.eclipse.jface.util.IPropertyChangeListener;
0047:        import org.eclipse.jface.util.PropertyChangeEvent;
0048:        import org.eclipse.jface.util.SafeRunnable;
0049:        import org.eclipse.jface.viewers.ArrayContentProvider;
0050:        import org.eclipse.jface.window.IShellProvider;
0051:        import org.eclipse.osgi.util.NLS;
0052:        import org.eclipse.swt.custom.BusyIndicator;
0053:        import org.eclipse.swt.program.Program;
0054:        import org.eclipse.swt.widgets.Display;
0055:        import org.eclipse.swt.widgets.Shell;
0056:        import org.eclipse.ui.ActiveShellExpression;
0057:        import org.eclipse.ui.IEditorActionBarContributor;
0058:        import org.eclipse.ui.IEditorDescriptor;
0059:        import org.eclipse.ui.IEditorInput;
0060:        import org.eclipse.ui.IEditorLauncher;
0061:        import org.eclipse.ui.IEditorMatchingStrategy;
0062:        import org.eclipse.ui.IEditorPart;
0063:        import org.eclipse.ui.IEditorReference;
0064:        import org.eclipse.ui.IEditorRegistry;
0065:        import org.eclipse.ui.IEditorSite;
0066:        import org.eclipse.ui.IMemento;
0067:        import org.eclipse.ui.IPathEditorInput;
0068:        import org.eclipse.ui.IPersistableEditor;
0069:        import org.eclipse.ui.IPersistableElement;
0070:        import org.eclipse.ui.ISaveablePart;
0071:        import org.eclipse.ui.ISaveablePart2;
0072:        import org.eclipse.ui.ISaveablesLifecycleListener;
0073:        import org.eclipse.ui.ISaveablesSource;
0074:        import org.eclipse.ui.IViewPart;
0075:        import org.eclipse.ui.IWorkbenchPage;
0076:        import org.eclipse.ui.IWorkbenchPart;
0077:        import org.eclipse.ui.IWorkbenchPart3;
0078:        import org.eclipse.ui.IWorkbenchPartReference;
0079:        import org.eclipse.ui.IWorkbenchWindow;
0080:        import org.eclipse.ui.PartInitException;
0081:        import org.eclipse.ui.PlatformUI;
0082:        import org.eclipse.ui.Saveable;
0083:        import org.eclipse.ui.dialogs.ListSelectionDialog;
0084:        import org.eclipse.ui.handlers.IHandlerActivation;
0085:        import org.eclipse.ui.handlers.IHandlerService;
0086:        import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
0087:        import org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor;
0088:        import org.eclipse.ui.internal.editorsupport.ComponentSupport;
0089:        import org.eclipse.ui.internal.misc.ExternalEditor;
0090:        import org.eclipse.ui.internal.misc.StatusUtil;
0091:        import org.eclipse.ui.internal.misc.UIStats;
0092:        import org.eclipse.ui.internal.part.NullEditorInput;
0093:        import org.eclipse.ui.internal.registry.EditorDescriptor;
0094:        import org.eclipse.ui.internal.registry.EditorRegistry;
0095:        import org.eclipse.ui.internal.tweaklets.TabBehaviour;
0096:        import org.eclipse.ui.internal.tweaklets.Tweaklets;
0097:        import org.eclipse.ui.internal.util.Util;
0098:        import org.eclipse.ui.model.WorkbenchPartLabelProvider;
0099:        import org.eclipse.ui.part.MultiEditor;
0100:        import org.eclipse.ui.part.MultiEditorInput;
0101:        import org.eclipse.ui.statushandlers.StatusManager;
0102:
0103:        /**
0104:         * Manage a group of element editors. Prevent the creation of two editors on the
0105:         * same element.
0106:         * 
0107:         * 06/12/00 - DS - Given the ambiguous editor input type, the manager delegates
0108:         * a number of responsibilities to the editor itself.
0109:         * 
0110:         * <ol>
0111:         * <li>The editor should determine its own title.</li>
0112:         * <li>The editor should listen to resource deltas and close itself if the
0113:         * input is deleted. It may also choose to stay open if the editor has dirty
0114:         * state.</li>
0115:         * <li>The editor should persist its own state plus editor input.</li>
0116:         * </ol>
0117:         */
0118:        public class EditorManager implements  IExtensionChangeHandler {
0119:            EditorAreaHelper editorPresentation;
0120:
0121:            WorkbenchWindow window;
0122:
0123:            WorkbenchPage page;
0124:
0125:            private Map actionCache = new HashMap();
0126:
0127:            private static final String PIN_EDITOR_KEY = "PIN_EDITOR"; //$NON-NLS-1$
0128:
0129:            private static final String PIN_EDITOR = "ovr16/pinned_ovr.gif"; //$NON-NLS-1$
0130:
0131:            // When the user removes or adds the close editors automatically preference
0132:            // the icon should be removed or added accordingly
0133:            private IPropertyChangeListener editorPropChangeListnener = null;
0134:
0135:            // Handler for the pin editor keyboard shortcut
0136:            private IHandlerActivation pinEditorHandlerActivation = null;
0137:
0138:            static final String RESOURCES_TO_SAVE_MESSAGE = WorkbenchMessages.EditorManager_saveResourcesMessage;
0139:
0140:            static final String SAVE_RESOURCES_TITLE = WorkbenchMessages.EditorManager_saveResourcesTitle;
0141:
0142:            /**
0143:             * EditorManager constructor comment.
0144:             */
0145:            public EditorManager(WorkbenchWindow window,
0146:                    WorkbenchPage workbenchPage, EditorAreaHelper pres) {
0147:                Assert.isNotNull(window);
0148:                Assert.isNotNull(workbenchPage);
0149:                Assert.isNotNull(pres);
0150:                this .window = window;
0151:                this .page = workbenchPage;
0152:                this .editorPresentation = pres;
0153:
0154:                page.getExtensionTracker().registerHandler(this , null);
0155:            }
0156:
0157:            /**
0158:             * Check to determine if the editor resources are no longer needed removes
0159:             * property change listener for editors removes pin editor keyboard shortcut
0160:             * handler disposes cached images and clears the cached images hash table
0161:             */
0162:            void checkDeleteEditorResources() {
0163:                // get the current number of editors
0164:                IEditorReference[] editors = page.getEditorReferences();
0165:                // If there are no editors
0166:                if (editors.length == 0) {
0167:                    if (editorPropChangeListnener != null) {
0168:                        // remove property change listener for editors
0169:                        IPreferenceStore prefStore = WorkbenchPlugin
0170:                                .getDefault().getPreferenceStore();
0171:                        prefStore
0172:                                .removePropertyChangeListener(editorPropChangeListnener);
0173:                        editorPropChangeListnener = null;
0174:                    }
0175:                    if (pinEditorHandlerActivation != null) {
0176:                        // remove pin editor keyboard shortcut handler
0177:                        final IHandlerService handlerService = (IHandlerService) window
0178:                                .getWorkbench().getService(
0179:                                        IHandlerService.class);
0180:                        handlerService
0181:                                .deactivateHandler(pinEditorHandlerActivation);
0182:                        pinEditorHandlerActivation = null;
0183:                    }
0184:                }
0185:            }
0186:
0187:            /**
0188:             * Check to determine if the property change listener for editors should be
0189:             * created
0190:             */
0191:            void checkCreateEditorPropListener() {
0192:                if (editorPropChangeListnener == null) {
0193:                    // Add a property change listener for closing editors automatically
0194:                    // preference
0195:                    // Add or remove the pin icon accordingly
0196:                    editorPropChangeListnener = new IPropertyChangeListener() {
0197:                        public void propertyChange(PropertyChangeEvent event) {
0198:                            if (event.getProperty().equals(
0199:                                    IPreferenceConstants.REUSE_EDITORS_BOOLEAN)) {
0200:                                IEditorReference[] editors = getEditors();
0201:                                for (int i = 0; i < editors.length; i++) {
0202:                                    ((EditorReference) editors[i])
0203:                                            .pinStatusUpdated();
0204:                                }
0205:                            }
0206:                        }
0207:                    };
0208:                    WorkbenchPlugin.getDefault().getPreferenceStore()
0209:                            .addPropertyChangeListener(
0210:                                    editorPropChangeListnener);
0211:                }
0212:            }
0213:
0214:            /**
0215:             * Check to determine if the handler for the pin editor keyboard shortcut
0216:             * should be created.
0217:             */
0218:            void checkCreatePinEditorShortcutKeyHandler() {
0219:                if (pinEditorHandlerActivation == null) {
0220:                    final Shell shell = window.getShell();
0221:                    final IHandler pinEditorHandler = new AbstractHandler() {
0222:                        public final Object execute(final ExecutionEvent event) {
0223:                            // check if the "Close editors automatically" preference is
0224:                            // set
0225:                            IPreferenceStore store = WorkbenchPlugin
0226:                                    .getDefault().getPreferenceStore();
0227:                            if (store
0228:                                    .getBoolean(IPreferenceConstants.REUSE_EDITORS_BOOLEAN)
0229:                                    || ((TabBehaviour) Tweaklets
0230:                                            .get(TabBehaviour.KEY))
0231:                                            .alwaysShowPinAction()) {
0232:
0233:                                IWorkbenchPartReference ref = editorPresentation
0234:                                        .getVisibleEditor();
0235:                                if (ref instanceof  WorkbenchPartReference) {
0236:                                    WorkbenchPartReference concreteRef = (WorkbenchPartReference) ref;
0237:
0238:                                    concreteRef.setPinned(concreteRef
0239:                                            .isPinned());
0240:                                }
0241:                            }
0242:                            return null;
0243:                        }
0244:                    };
0245:
0246:                    // Assign the handler for the pin editor keyboard shortcut.
0247:                    final IHandlerService handlerService = (IHandlerService) window
0248:                            .getWorkbench().getService(IHandlerService.class);
0249:                    pinEditorHandlerActivation = handlerService
0250:                            .activateHandler(
0251:                                    "org.eclipse.ui.window.pinEditor", pinEditorHandler, //$NON-NLS-1$
0252:                                    new ActiveShellExpression(shell));
0253:                }
0254:            }
0255:
0256:            /**
0257:             * Method to create the editor's pin ImageDescriptor
0258:             * 
0259:             * @return the single image descriptor for the editor's pin icon
0260:             */
0261:            ImageDescriptor getEditorPinImageDesc() {
0262:                ImageRegistry registry = JFaceResources.getImageRegistry();
0263:                ImageDescriptor pinDesc = registry
0264:                        .getDescriptor(PIN_EDITOR_KEY);
0265:                // Avoid registering twice
0266:                if (pinDesc == null) {
0267:                    pinDesc = WorkbenchImages
0268:                            .getWorkbenchImageDescriptor(PIN_EDITOR);
0269:                    registry.put(PIN_EDITOR_KEY, pinDesc);
0270:
0271:                }
0272:                return pinDesc;
0273:            }
0274:
0275:            /**
0276:             * Answer a list of dirty editors.
0277:             */
0278:            private List collectDirtyEditors() {
0279:                List result = new ArrayList(3);
0280:                IEditorReference[] editors = page.getEditorReferences();
0281:                for (int i = 0; i < editors.length; i++) {
0282:                    IEditorPart part = (IEditorPart) editors[i].getPart(false);
0283:                    if (part != null && part.isDirty()) {
0284:                        result.add(part);
0285:                    }
0286:
0287:                }
0288:                return result;
0289:            }
0290:
0291:            /**
0292:             * Returns whether the manager contains an editor.
0293:             */
0294:            public boolean containsEditor(IEditorReference ref) {
0295:                IEditorReference[] editors = page.getEditorReferences();
0296:                for (int i = 0; i < editors.length; i++) {
0297:                    if (ref == editors[i]) {
0298:                        return true;
0299:                    }
0300:                }
0301:                return false;
0302:            }
0303:
0304:            /*
0305:             * Creates the action bars for an editor. Editors of the same type should
0306:             * share a single editor action bar, so this implementation may return an
0307:             * existing action bar vector.
0308:             */
0309:            private EditorActionBars createEditorActionBars(
0310:                    EditorDescriptor desc, final IEditorSite site) {
0311:                // Get the editor type.
0312:                String type = desc.getId();
0313:
0314:                // If an action bar already exists for this editor type return it.
0315:                EditorActionBars actionBars = (EditorActionBars) actionCache
0316:                        .get(type);
0317:                if (actionBars != null) {
0318:                    actionBars.addRef();
0319:                    return actionBars;
0320:                }
0321:
0322:                // Create a new action bar set.
0323:                actionBars = new EditorActionBars(page, site
0324:                        .getWorkbenchWindow(), type);
0325:                actionBars.addRef();
0326:                actionCache.put(type, actionBars);
0327:
0328:                // Read base contributor.
0329:                IEditorActionBarContributor contr = desc
0330:                        .createActionBarContributor();
0331:                if (contr != null) {
0332:                    actionBars.setEditorContributor(contr);
0333:                    contr.init(actionBars, page);
0334:                }
0335:
0336:                // Read action extensions.
0337:                EditorActionBuilder builder = new EditorActionBuilder();
0338:                contr = builder.readActionExtensions(desc);
0339:                if (contr != null) {
0340:                    actionBars.setExtensionContributor(contr);
0341:                    contr.init(actionBars, page);
0342:                }
0343:
0344:                // Return action bars.
0345:                return actionBars;
0346:            }
0347:
0348:            /*
0349:             * Creates the action bars for an editor.
0350:             */
0351:            private EditorActionBars createEmptyEditorActionBars(
0352:                    final IEditorSite site) {
0353:                // Get the editor type.
0354:                String type = String.valueOf(System.currentTimeMillis());
0355:
0356:                // Create a new action bar set.
0357:                // Note: It is an empty set.
0358:                EditorActionBars actionBars = new EditorActionBars(page, site
0359:                        .getWorkbenchWindow(), type);
0360:                actionBars.addRef();
0361:                actionCache.put(type, actionBars);
0362:
0363:                // Return action bars.
0364:                return actionBars;
0365:            }
0366:
0367:            /*
0368:             * Dispose
0369:             */
0370:            void disposeEditorActionBars(EditorActionBars actionBars) {
0371:                actionBars.removeRef();
0372:                if (actionBars.getRef() <= 0) {
0373:                    String type = actionBars.getEditorType();
0374:                    actionCache.remove(type);
0375:                    // refresh the cool bar manager before disposing of a cool item
0376:                    ICoolBarManager2 coolBar = (ICoolBarManager2) window
0377:                            .getCoolBarManager2();
0378:                    if (coolBar != null) {
0379:                        coolBar.refresh();
0380:                    }
0381:                    actionBars.dispose();
0382:                }
0383:            }
0384:
0385:            /**
0386:             * Returns an open editor matching the given editor input. If none match,
0387:             * returns <code>null</code>.
0388:             * 
0389:             * @param input
0390:             *            the editor input
0391:             * @return the matching editor, or <code>null</code> if no match fond
0392:             */
0393:            public IEditorPart findEditor(IEditorInput input) {
0394:                return findEditor(null, input, IWorkbenchPage.MATCH_INPUT);
0395:            }
0396:
0397:            /**
0398:             * Returns an open editor matching the given editor input and/or editor id,
0399:             * as specified by matchFlags. If none match, returns <code>null</code>.
0400:             * 
0401:             * @param editorId
0402:             *            the editor id
0403:             * @param input
0404:             *            the editor input
0405:             * @param matchFlags
0406:             *            flags specifying which aspects to match
0407:             * @return the matching editor, or <code>null</code> if no match fond
0408:             * @since 3.1
0409:             */
0410:            public IEditorPart findEditor(String editorId, IEditorInput input,
0411:                    int matchFlags) {
0412:                IEditorReference[] refs = findEditors(input, editorId,
0413:                        matchFlags);
0414:                if (refs.length == 0) {
0415:                    return null;
0416:                }
0417:                return refs[0].getEditor(true);
0418:            }
0419:
0420:            /**
0421:             * Returns the open editor references matching the given editor input and/or
0422:             * editor id, as specified by matchFlags. If none match, returns an empty
0423:             * array.
0424:             * 
0425:             * @param editorId
0426:             *            the editor id
0427:             * @param input
0428:             *            the editor input
0429:             * @param matchFlags
0430:             *            flags specifying which aspects to match
0431:             * @return the matching editor, or <code>null</code> if no match fond
0432:             * @since 3.1
0433:             */
0434:            public IEditorReference[] findEditors(IEditorInput input,
0435:                    String editorId, int matchFlags) {
0436:                if (matchFlags == IWorkbenchPage.MATCH_NONE) {
0437:                    return new IEditorReference[0];
0438:                }
0439:                List result = new ArrayList();
0440:                ArrayList othersList = new ArrayList(Arrays.asList(page
0441:                        .getEditorReferences()));
0442:                if (!othersList.isEmpty()) {
0443:                    IEditorReference active = page.getActiveEditorReference();
0444:                    if (active != null) {
0445:                        othersList.remove(active);
0446:                        ArrayList activeList = new ArrayList(1);
0447:                        activeList.add(active);
0448:                        findEditors(activeList, input, editorId, matchFlags,
0449:                                result);
0450:                    }
0451:                    findEditors(othersList, input, editorId, matchFlags, result);
0452:                }
0453:                return (IEditorReference[]) result
0454:                        .toArray(new IEditorReference[result.size()]);
0455:            }
0456:
0457:            /**
0458:             * Returns an open editor matching the given editor id and/or editor input.
0459:             * Returns <code>null</code> if none match.
0460:             * 
0461:             * @param editorId
0462:             *            the editor id
0463:             * @param input
0464:             *            the editor input
0465:             * @param editorList
0466:             *            a mutable list containing the references for the editors to
0467:             *            check (warning: items may be removed)
0468:             * @param result
0469:             *            the list to which matching editor references should be added
0470:             * @since 3.1
0471:             */
0472:            private void findEditors(List editorList, IEditorInput input,
0473:                    String editorId, int matchFlags, List result) {
0474:                if (matchFlags == IWorkbenchPage.MATCH_NONE) {
0475:                    return;
0476:                }
0477:
0478:                // Phase 0: Remove editors whose ids don't match (if matching by id)
0479:                if (((matchFlags & IWorkbenchPage.MATCH_ID) != 0)
0480:                        && editorId != null) {
0481:                    for (Iterator i = editorList.iterator(); i.hasNext();) {
0482:                        EditorReference editor = (EditorReference) i.next();
0483:                        if (!editorId.equals(editor.getId())) {
0484:                            i.remove();
0485:                        }
0486:                    }
0487:                }
0488:
0489:                // If not matching on editor input, just return the remaining editors.
0490:                // In practice, this case is never used.
0491:                if ((matchFlags & IWorkbenchPage.MATCH_INPUT) == 0) {
0492:                    result.addAll(editorList);
0493:                    return;
0494:                }
0495:
0496:                // Phase 1: check editors that have their own matching strategy
0497:                for (Iterator i = editorList.iterator(); i.hasNext();) {
0498:                    EditorReference editor = (EditorReference) i.next();
0499:                    IEditorDescriptor desc = editor.getDescriptor();
0500:                    if (desc != null) {
0501:                        IEditorMatchingStrategy matchingStrategy = desc
0502:                                .getEditorMatchingStrategy();
0503:                        if (matchingStrategy != null) {
0504:                            i.remove(); // We're handling this one here, so remove it
0505:                            // from the list.
0506:                            if (matchingStrategy.matches(editor, input)) {
0507:                                result.add(editor);
0508:                            }
0509:                        }
0510:                    }
0511:                }
0512:
0513:                // Phase 2: check materialized editors (without their own matching
0514:                // strategy)
0515:                for (Iterator i = editorList.iterator(); i.hasNext();) {
0516:                    IEditorReference editor = (IEditorReference) i.next();
0517:                    IEditorPart part = (IEditorPart) editor.getPart(false);
0518:                    if (part != null) {
0519:                        i.remove(); // We're handling this one here, so remove it from
0520:                        // the list.
0521:                        if (part.getEditorInput() != null
0522:                                && part.getEditorInput().equals(input)) {
0523:                            result.add(editor);
0524:                        }
0525:                    }
0526:                }
0527:
0528:                // Phase 3: check unmaterialized editors for input equality,
0529:                // delaying plug-in activation further by only restoring the editor
0530:                // input
0531:                // if the editor reference's factory id and name match.
0532:                String name = input.getName();
0533:                IPersistableElement persistable = input.getPersistable();
0534:                if (name == null || persistable == null) {
0535:                    return;
0536:                }
0537:                String id = persistable.getFactoryId();
0538:                if (id == null) {
0539:                    return;
0540:                }
0541:                for (Iterator i = editorList.iterator(); i.hasNext();) {
0542:                    EditorReference editor = (EditorReference) i.next();
0543:                    if (name.equals(editor.getName())
0544:                            && id.equals(editor.getFactoryId())) {
0545:                        IEditorInput restoredInput;
0546:                        try {
0547:                            restoredInput = editor.getEditorInput();
0548:                            if (Util.equals(restoredInput, input)) {
0549:                                result.add(editor);
0550:                            }
0551:                        } catch (PartInitException e1) {
0552:                            WorkbenchPlugin.log(e1);
0553:                        }
0554:                    }
0555:                }
0556:            }
0557:
0558:            /**
0559:             * Returns the SWT Display.
0560:             */
0561:            private Display getDisplay() {
0562:                return window.getShell().getDisplay();
0563:            }
0564:
0565:            /**
0566:             * Answer the number of editors.
0567:             */
0568:            public int getEditorCount() {
0569:                return page.getEditorReferences().length;
0570:            }
0571:
0572:            /*
0573:             * Answer the editor registry.
0574:             */
0575:            private IEditorRegistry getEditorRegistry() {
0576:                return WorkbenchPlugin.getDefault().getEditorRegistry();
0577:            }
0578:
0579:            /*
0580:             * See IWorkbenchPage.
0581:             */
0582:            public IEditorPart[] getDirtyEditors() {
0583:                List dirtyEditors = collectDirtyEditors();
0584:                return (IEditorPart[]) dirtyEditors
0585:                        .toArray(new IEditorPart[dirtyEditors.size()]);
0586:            }
0587:
0588:            /*
0589:             * See IWorkbenchPage.
0590:             */
0591:            public IEditorReference[] getEditors() {
0592:                return page.getEditorReferences();
0593:            }
0594:
0595:            /*
0596:             * See IWorkbenchPage#getFocusEditor
0597:             */
0598:            public IEditorPart getVisibleEditor() {
0599:                IEditorReference ref = editorPresentation.getVisibleEditor();
0600:                if (ref == null) {
0601:                    return null;
0602:                }
0603:                return (IEditorPart) ref.getPart(true);
0604:            }
0605:
0606:            /**
0607:             * Answer true if save is needed in any one of the editors.
0608:             */
0609:            public boolean isSaveAllNeeded() {
0610:                IEditorReference[] editors = page.getEditorReferences();
0611:                for (int i = 0; i < editors.length; i++) {
0612:                    IEditorReference ed = editors[i];
0613:                    if (ed.isDirty()) {
0614:                        return true;
0615:                    }
0616:                }
0617:                return false;
0618:            }
0619:
0620:            /*
0621:             * Prompt the user to save the reusable editor. Return false if a new editor
0622:             * should be opened.
0623:             */
0624:            private IEditorReference findReusableEditor(EditorDescriptor desc) {
0625:                return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
0626:                        .findReusableEditor(page);
0627:            }
0628:
0629:            /**
0630:             * @param editorId
0631:             *            the editor part id
0632:             * @param input
0633:             *            the input
0634:             * @param setVisible
0635:             *            if this is to be created visible ... not used
0636:             * @param editorState
0637:             *            an {@link IMemento} &lt;editorState&gt; for persistable
0638:             *            editors. Can be <code>null</code>.
0639:             * @return a created editor reference
0640:             * @throws PartInitException
0641:             */
0642:            public IEditorReference openEditor(String editorId,
0643:                    IEditorInput input, boolean setVisible, IMemento editorState)
0644:                    throws PartInitException {
0645:                if (editorId == null || input == null) {
0646:                    throw new IllegalArgumentException();
0647:                }
0648:
0649:                IEditorRegistry reg = getEditorRegistry();
0650:                EditorDescriptor desc = (EditorDescriptor) reg
0651:                        .findEditor(editorId);
0652:                if (desc == null) {
0653:                    throw new PartInitException(
0654:                            NLS
0655:                                    .bind(
0656:                                            WorkbenchMessages.EditorManager_unknownEditorIDMessage,
0657:                                            editorId));
0658:                }
0659:
0660:                IEditorReference result = openEditorFromDescriptor(desc, input,
0661:                        editorState);
0662:                return result;
0663:            }
0664:
0665:            /*
0666:             * Open a new editor
0667:             */
0668:            public IEditorReference openEditorFromDescriptor(
0669:                    EditorDescriptor desc, IEditorInput input,
0670:                    IMemento editorState) throws PartInitException {
0671:                IEditorReference result = null;
0672:                if (desc.isInternal()) {
0673:                    result = reuseInternalEditor(desc, input);
0674:                    if (result == null) {
0675:                        result = new EditorReference(this , input, desc,
0676:                                editorState);
0677:                    }
0678:                } else if (desc.getId().equals(
0679:                        IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID)) {
0680:                    if (ComponentSupport.inPlaceEditorSupported()) {
0681:                        result = new EditorReference(this , input, desc);
0682:                    }
0683:                } else if (desc.getId().equals(
0684:                        IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)) {
0685:                    IPathEditorInput pathInput = getPathEditorInput(input);
0686:                    if (pathInput != null) {
0687:                        result = openSystemExternalEditor(pathInput.getPath());
0688:                    } else {
0689:                        throw new PartInitException(
0690:                                WorkbenchMessages.EditorManager_systemEditorError);
0691:                    }
0692:                } else if (desc.isOpenExternal()) {
0693:                    result = openExternalEditor(desc, input);
0694:                } else {
0695:                    // this should never happen
0696:                    throw new PartInitException(NLS.bind(
0697:                            WorkbenchMessages.EditorManager_invalidDescriptor,
0698:                            desc.getId()));
0699:                }
0700:
0701:                if (result != null) {
0702:                    createEditorTab((EditorReference) result, ""); //$NON-NLS-1$
0703:                }
0704:
0705:                Workbench wb = (Workbench) window.getWorkbench();
0706:                wb.getEditorHistory().add(input, desc);
0707:                return result;
0708:            }
0709:
0710:            /**
0711:             * Open a specific external editor on an file based on the descriptor.
0712:             */
0713:            private IEditorReference openExternalEditor(
0714:                    final EditorDescriptor desc, IEditorInput input)
0715:                    throws PartInitException {
0716:                final CoreException ex[] = new CoreException[1];
0717:
0718:                final IPathEditorInput pathInput = getPathEditorInput(input);
0719:                if (pathInput != null && pathInput.getPath() != null) {
0720:                    BusyIndicator.showWhile(getDisplay(), new Runnable() {
0721:                        public void run() {
0722:                            try {
0723:                                if (desc.getLauncher() != null) {
0724:                                    // open using launcher
0725:                                    Object launcher = WorkbenchPlugin
0726:                                            .createExtension(desc
0727:                                                    .getConfigurationElement(),
0728:                                                    "launcher"); //$NON-NLS-1$
0729:                                    ((IEditorLauncher) launcher).open(pathInput
0730:                                            .getPath());
0731:                                } else {
0732:                                    // open using command
0733:                                    ExternalEditor oEditor = new ExternalEditor(
0734:                                            pathInput.getPath(), desc);
0735:                                    oEditor.open();
0736:                                }
0737:                            } catch (CoreException e) {
0738:                                ex[0] = e;
0739:                            }
0740:                        }
0741:                    });
0742:                } else {
0743:                    throw new PartInitException(
0744:                            NLS
0745:                                    .bind(
0746:                                            WorkbenchMessages.EditorManager_errorOpeningExternalEditor,
0747:                                            desc.getFileName(), desc.getId()));
0748:                }
0749:
0750:                if (ex[0] != null) {
0751:                    throw new PartInitException(
0752:                            NLS
0753:                                    .bind(
0754:                                            WorkbenchMessages.EditorManager_errorOpeningExternalEditor,
0755:                                            desc.getFileName(), desc.getId()),
0756:                            ex[0]);
0757:                }
0758:
0759:                // we do not have an editor part for external editors
0760:                return null;
0761:            }
0762:
0763:            /**
0764:             * Create the part and reference for each inner editor.
0765:             * 
0766:             * @param ref
0767:             *            the MultiEditor reference
0768:             * @param part
0769:             *            the part
0770:             * @param input
0771:             *            the MultiEditor input
0772:             * @return the array of inner references to store in the MultiEditor reference
0773:             */
0774:            IEditorReference[] openMultiEditor(final IEditorReference ref,
0775:                    final MultiEditor part, final MultiEditorInput input)
0776:                    throws PartInitException {
0777:
0778:                String[] editorArray = input.getEditors();
0779:                IEditorInput[] inputArray = input.getInput();
0780:
0781:                // find all descriptors
0782:                EditorDescriptor[] descArray = new EditorDescriptor[editorArray.length];
0783:                IEditorReference refArray[] = new IEditorReference[editorArray.length];
0784:                IEditorPart partArray[] = new IEditorPart[editorArray.length];
0785:
0786:                IEditorRegistry reg = getEditorRegistry();
0787:                for (int i = 0; i < editorArray.length; i++) {
0788:                    EditorDescriptor innerDesc = (EditorDescriptor) reg
0789:                            .findEditor(editorArray[i]);
0790:                    if (innerDesc == null) {
0791:                        throw new PartInitException(
0792:                                NLS
0793:                                        .bind(
0794:                                                WorkbenchMessages.EditorManager_unknownEditorIDMessage,
0795:                                                editorArray[i]));
0796:                    }
0797:                    descArray[i] = innerDesc;
0798:                    InnerEditor innerRef = new InnerEditor(ref, inputArray[i],
0799:                            descArray[i]);
0800:                    refArray[i] = innerRef;
0801:                    partArray[i] = innerRef.getEditor(true);
0802:                }
0803:                part.setChildren(partArray);
0804:                return refArray;
0805:            }
0806:
0807:            /*
0808:             * Opens an editor part.
0809:             */
0810:            private void createEditorTab(final EditorReference ref,
0811:                    final String workbookId) throws PartInitException {
0812:
0813:                editorPresentation.addEditor(ref, workbookId);
0814:
0815:            }
0816:
0817:            /*
0818:             * Create the site and initialize it with its action bars.
0819:             */
0820:            EditorSite createSite(final IEditorReference ref,
0821:                    final IEditorPart part, final EditorDescriptor desc,
0822:                    final IEditorInput input) throws PartInitException {
0823:                EditorSite site = new EditorSite(ref, part, page, desc);
0824:                if (desc != null) {
0825:                    site.setActionBars(createEditorActionBars(desc, site));
0826:                } else {
0827:                    site.setActionBars(createEmptyEditorActionBars(site));
0828:                }
0829:                final String label = part.getTitle(); // debugging only
0830:                try {
0831:                    try {
0832:                        UIStats.start(UIStats.INIT_PART, label);
0833:                        part.init(site, input);
0834:                    } finally {
0835:                        UIStats.end(UIStats.INIT_PART, part, label);
0836:                    }
0837:
0838:                    // Sanity-check the site
0839:                    if (part.getSite() != site || part.getEditorSite() != site) {
0840:                        throw new PartInitException(NLS.bind(
0841:                                WorkbenchMessages.EditorManager_siteIncorrect,
0842:                                desc.getId()));
0843:                    }
0844:
0845:                } catch (Exception e) {
0846:                    disposeEditorActionBars((EditorActionBars) site
0847:                            .getActionBars());
0848:                    site.dispose();
0849:                    if (e instanceof  PartInitException) {
0850:                        throw (PartInitException) e;
0851:                    }
0852:
0853:                    throw new PartInitException(
0854:                            WorkbenchMessages.EditorManager_errorInInit, e);
0855:                }
0856:
0857:                return site;
0858:            }
0859:
0860:            /*
0861:             * See IWorkbenchPage.
0862:             */
0863:            private IEditorReference reuseInternalEditor(EditorDescriptor desc,
0864:                    IEditorInput input) throws PartInitException {
0865:
0866:                Assert.isNotNull(desc, "descriptor must not be null"); //$NON-NLS-1$
0867:                Assert.isNotNull(input, "input must not be null"); //$NON-NLS-1$
0868:
0869:                IEditorReference reusableEditorRef = findReusableEditor(desc);
0870:                if (reusableEditorRef != null) {
0871:                    return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
0872:                            .reuseInternalEditor(page, this ,
0873:                                    editorPresentation, desc, input,
0874:                                    reusableEditorRef);
0875:                }
0876:                return null;
0877:            }
0878:
0879:            IEditorPart createPart(final EditorDescriptor desc)
0880:                    throws PartInitException {
0881:                try {
0882:                    IEditorPart result = desc.createEditor();
0883:                    IConfigurationElement element = desc
0884:                            .getConfigurationElement();
0885:                    if (element != null) {
0886:                        page.getExtensionTracker().registerObject(
0887:                                element.getDeclaringExtension(), result,
0888:                                IExtensionTracker.REF_WEAK);
0889:                    }
0890:                    return result;
0891:                } catch (CoreException e) {
0892:                    throw new PartInitException(StatusUtil.newStatus(desc
0893:                            .getPluginID(),
0894:                            WorkbenchMessages.EditorManager_instantiationError,
0895:                            e));
0896:                }
0897:            }
0898:
0899:            /**
0900:             * Open a system external editor on the input path.
0901:             */
0902:            private IEditorReference openSystemExternalEditor(
0903:                    final IPath location) throws PartInitException {
0904:                if (location == null) {
0905:                    throw new IllegalArgumentException();
0906:                }
0907:
0908:                final boolean result[] = { false };
0909:                BusyIndicator.showWhile(getDisplay(), new Runnable() {
0910:                    public void run() {
0911:                        if (location != null) {
0912:                            result[0] = Program.launch(location.toOSString());
0913:                        }
0914:                    }
0915:                });
0916:
0917:                if (!result[0]) {
0918:                    throw new PartInitException(
0919:                            NLS
0920:                                    .bind(
0921:                                            WorkbenchMessages.EditorManager_unableToOpenExternalEditor,
0922:                                            location));
0923:                }
0924:
0925:                // We do not have an editor part for external editors
0926:                return null;
0927:            }
0928:
0929:            ImageDescriptor findImage(EditorDescriptor desc, IPath path) {
0930:                if (desc == null) {
0931:                    // @issue what should be the default image?
0932:                    return ImageDescriptor.getMissingImageDescriptor();
0933:                }
0934:
0935:                if (desc.isOpenExternal() && path != null) {
0936:                    return PlatformUI.getWorkbench().getEditorRegistry()
0937:                            .getImageDescriptor(path.toOSString());
0938:                }
0939:
0940:                return desc.getImageDescriptor();
0941:            }
0942:
0943:            /**
0944:             * @see org.eclipse.ui.IPersistable
0945:             */
0946:            public IStatus restoreState(IMemento memento) {
0947:                // Restore the editor area workbooks layout/relationship
0948:                final MultiStatus result = new MultiStatus(
0949:                        PlatformUI.PLUGIN_ID,
0950:                        IStatus.OK,
0951:                        WorkbenchMessages.EditorManager_problemsRestoringEditors,
0952:                        null);
0953:                final String activeWorkbookID[] = new String[1];
0954:                final ArrayList visibleEditors = new ArrayList(5);
0955:                final IEditorReference activeEditor[] = new IEditorReference[1];
0956:
0957:                IMemento areaMem = memento
0958:                        .getChild(IWorkbenchConstants.TAG_AREA);
0959:                if (areaMem != null) {
0960:                    result.add(editorPresentation.restoreState(areaMem));
0961:                    activeWorkbookID[0] = areaMem
0962:                            .getString(IWorkbenchConstants.TAG_ACTIVE_WORKBOOK);
0963:                }
0964:
0965:                // Loop through the editors.
0966:
0967:                IMemento[] editorMems = memento
0968:                        .getChildren(IWorkbenchConstants.TAG_EDITOR);
0969:                for (int x = 0; x < editorMems.length; x++) {
0970:                    // for dynamic UI - call restoreEditorState to replace code which is
0971:                    // commented out
0972:                    restoreEditorState(editorMems[x], visibleEditors,
0973:                            activeEditor, result);
0974:                }
0975:
0976:                // restore the presentation
0977:                if (areaMem != null) {
0978:                    result.add(editorPresentation
0979:                            .restorePresentationState(areaMem));
0980:                }
0981:                try {
0982:                    StartupThreading.runWithThrowable(new StartupRunnable() {
0983:
0984:                        public void runWithException() throws Throwable {
0985:                            // Update each workbook with its visible editor.
0986:                            for (int i = 0; i < visibleEditors.size(); i++) {
0987:                                setVisibleEditor(
0988:                                        (IEditorReference) visibleEditors
0989:                                                .get(i), false);
0990:                            }
0991:
0992:                            // Update the active workbook
0993:                            if (activeWorkbookID[0] != null) {
0994:                                editorPresentation
0995:                                        .setActiveEditorWorkbookFromID(activeWorkbookID[0]);
0996:                            }
0997:
0998:                            if (activeEditor[0] != null) {
0999:                                IWorkbenchPart editor = activeEditor[0]
1000:                                        .getPart(true);
1001:
1002:                                if (editor != null) {
1003:                                    page.activate(editor);
1004:                                }
1005:                            }
1006:                        }
1007:                    });
1008:                } catch (Throwable t) {
1009:                    // The exception is already logged.
1010:                    result
1011:                            .add(new Status(
1012:                                    IStatus.ERROR,
1013:                                    PlatformUI.PLUGIN_ID,
1014:                                    0,
1015:                                    WorkbenchMessages.EditorManager_exceptionRestoringEditor,
1016:                                    t));
1017:                }
1018:
1019:                return result;
1020:            }
1021:
1022:            /**
1023:             * Save all of the editors in the workbench. Return true if successful.
1024:             * Return false if the user has canceled the command.
1025:             * @param confirm true if the user should be prompted before the save
1026:             * @param closing true if the page is being closed
1027:             * @param addNonPartSources true if saveables from non-part sources should be saved too.
1028:             * @return false if the user canceled or an error occurred while saving
1029:             */
1030:            public boolean saveAll(boolean confirm, boolean closing,
1031:                    boolean addNonPartSources) {
1032:                // Get the list of dirty editors and views. If it is
1033:                // empty just return.
1034:                ISaveablePart[] parts = page.getDirtyParts();
1035:                if (parts.length == 0) {
1036:                    return true;
1037:                }
1038:                // saveAll below expects a mutable list
1039:                List dirtyParts = new ArrayList(parts.length);
1040:                for (int i = 0; i < parts.length; i++) {
1041:                    dirtyParts.add(parts[i]);
1042:                }
1043:
1044:                // If confirmation is required ..
1045:                return saveAll(dirtyParts, confirm, closing, addNonPartSources,
1046:                        window);
1047:            }
1048:
1049:            /**
1050:             * Saves the given dirty editors and views, optionally prompting the user.
1051:             * 
1052:             * @param dirtyParts
1053:             *            the dirty views and editors
1054:             * @param confirm
1055:             *            <code>true</code> to prompt whether to save, <code>false</code>
1056:             *            to save without prompting
1057:             * @param closing
1058:             *            <code>true</code> if the parts are being closed,
1059:             *            <code>false</code> if just being saved without closing
1060:             * @param addNonPartSources true if non-part sources should be saved too
1061:             * @param window
1062:             *            the window to use as the parent for the dialog that prompts to
1063:             *            save multiple dirty editors and views
1064:             * @return <code>true</code> on success, <code>false</code> if the user
1065:             *         canceled the save or an error occurred while saving
1066:             */
1067:            public static boolean saveAll(List dirtyParts, boolean confirm,
1068:                    boolean closing, boolean addNonPartSources,
1069:                    final IWorkbenchWindow window) {
1070:                return saveAll(dirtyParts, confirm, closing, addNonPartSources,
1071:                        window, window);
1072:            }
1073:
1074:            /**
1075:             * Saves the given dirty editors and views, optionally prompting the user.
1076:             * 
1077:             * @param dirtyParts
1078:             *            the dirty views and editors
1079:             * @param confirm
1080:             *            <code>true</code> to prompt whether to save,
1081:             *            <code>false</code> to save without prompting
1082:             * @param closing
1083:             *            <code>true</code> if the parts are being closed,
1084:             *            <code>false</code> if just being saved without closing
1085:             * @param addNonPartSources
1086:             *            true if non-part sources should be saved too
1087:             * @param runnableContext
1088:             *            the context in which to run long-running operations
1089:             * @param shellProvider
1090:             *            providing the shell to use as the parent for the dialog that
1091:             *            prompts to save multiple dirty editors and views
1092:             * @return <code>true</code> on success, <code>false</code> if the user
1093:             *         canceled the save
1094:             */
1095:            public static boolean saveAll(List dirtyParts,
1096:                    final boolean confirm, final boolean closing,
1097:                    boolean addNonPartSources,
1098:                    final IRunnableContext runnableContext,
1099:                    final IShellProvider shellProvider) {
1100:                // clone the input list
1101:                dirtyParts = new ArrayList(dirtyParts);
1102:                List modelsToSave;
1103:                if (confirm) {
1104:                    boolean saveable2Processed = false;
1105:                    // Process all parts that implement ISaveablePart2.
1106:                    // These parts are removed from the list after saving
1107:                    // them. We then need to restore the workbench to
1108:                    // its previous state, for now this is just last
1109:                    // active perspective.
1110:                    // Note that the given parts may come from multiple
1111:                    // windows, pages and perspectives.
1112:                    ListIterator listIterator = dirtyParts.listIterator();
1113:
1114:                    WorkbenchPage currentPage = null;
1115:                    Perspective currentPageOriginalPerspective = null;
1116:                    while (listIterator.hasNext()) {
1117:                        IWorkbenchPart part = (IWorkbenchPart) listIterator
1118:                                .next();
1119:                        if (part instanceof  ISaveablePart2) {
1120:                            WorkbenchPage page = (WorkbenchPage) part.getSite()
1121:                                    .getPage();
1122:                            if (!Util.equals(currentPage, page)) {
1123:                                if (currentPage != null
1124:                                        && currentPageOriginalPerspective != null) {
1125:                                    if (!currentPageOriginalPerspective
1126:                                            .equals(currentPage
1127:                                                    .getActivePerspective())) {
1128:                                        currentPage
1129:                                                .setPerspective(currentPageOriginalPerspective
1130:                                                        .getDesc());
1131:                                    }
1132:                                }
1133:                                currentPage = page;
1134:                                currentPageOriginalPerspective = page
1135:                                        .getActivePerspective();
1136:                            }
1137:                            if (confirm) {
1138:                                if (part instanceof  IViewPart) {
1139:                                    Perspective perspective = page
1140:                                            .getFirstPerspectiveWithView((IViewPart) part);
1141:                                    if (perspective != null) {
1142:                                        page.setPerspective(perspective
1143:                                                .getDesc());
1144:                                    }
1145:                                }
1146:                                // show the window containing the page?
1147:                                IWorkbenchWindow partsWindow = page
1148:                                        .getWorkbenchWindow();
1149:                                if (partsWindow != partsWindow.getWorkbench()
1150:                                        .getActiveWorkbenchWindow()) {
1151:                                    Shell shell = partsWindow.getShell();
1152:                                    if (shell.getMinimized()) {
1153:                                        shell.setMinimized(false);
1154:                                    }
1155:                                    shell.setActive();
1156:                                }
1157:                                page.bringToTop(part);
1158:                            }
1159:                            // try to save the part
1160:                            int choice = SaveableHelper.savePart(
1161:                                    (ISaveablePart2) part, page
1162:                                            .getWorkbenchWindow(), confirm);
1163:                            if (choice == ISaveablePart2.CANCEL) {
1164:                                // If the user cancels, don't restore the previous
1165:                                // workbench state, as that will
1166:                                // be an unexpected switch from the current state.
1167:                                return false;
1168:                            } else if (choice != ISaveablePart2.DEFAULT) {
1169:                                saveable2Processed = true;
1170:                                listIterator.remove();
1171:                            }
1172:                        }
1173:                    }
1174:
1175:                    // try to restore the workbench to its previous state
1176:                    if (currentPage != null
1177:                            && currentPageOriginalPerspective != null) {
1178:                        if (!currentPageOriginalPerspective.equals(currentPage
1179:                                .getActivePerspective())) {
1180:                            currentPage
1181:                                    .setPerspective(currentPageOriginalPerspective
1182:                                            .getDesc());
1183:                        }
1184:                    }
1185:
1186:                    // if processing a ISaveablePart2 caused other parts to be
1187:                    // saved, remove them from the list presented to the user.
1188:                    if (saveable2Processed) {
1189:                        listIterator = dirtyParts.listIterator();
1190:                        while (listIterator.hasNext()) {
1191:                            ISaveablePart part = (ISaveablePart) listIterator
1192:                                    .next();
1193:                            if (!part.isDirty()) {
1194:                                listIterator.remove();
1195:                            }
1196:                        }
1197:                    }
1198:
1199:                    modelsToSave = convertToSaveables(dirtyParts, closing,
1200:                            addNonPartSources);
1201:
1202:                    // If nothing to save, return.
1203:                    if (modelsToSave.isEmpty()) {
1204:                        return true;
1205:                    }
1206:                    boolean canceled = SaveableHelper
1207:                            .waitForBackgroundSaveJobs(modelsToSave);
1208:                    if (canceled) {
1209:                        return false;
1210:                    }
1211:                    // Use a simpler dialog if there's only one
1212:                    if (modelsToSave.size() == 1) {
1213:                        Saveable model = (Saveable) modelsToSave.get(0);
1214:                        String message = NLS
1215:                                .bind(
1216:                                        WorkbenchMessages.EditorManager_saveChangesQuestion,
1217:                                        model.getName());
1218:                        // Show a dialog.
1219:                        String[] buttons = new String[] {
1220:                                IDialogConstants.YES_LABEL,
1221:                                IDialogConstants.NO_LABEL,
1222:                                IDialogConstants.CANCEL_LABEL };
1223:                        MessageDialog d = new MessageDialog(shellProvider
1224:                                .getShell(), WorkbenchMessages.Save_Resource,
1225:                                null, message, MessageDialog.QUESTION, buttons,
1226:                                0);
1227:
1228:                        int choice = SaveableHelper.testGetAutomatedResponse();
1229:                        if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) {
1230:                            choice = d.open();
1231:                        }
1232:
1233:                        // Branch on the user choice.
1234:                        // The choice id is based on the order of button labels
1235:                        // above.
1236:                        switch (choice) {
1237:                        case ISaveablePart2.YES: // yes
1238:                            break;
1239:                        case ISaveablePart2.NO: // no
1240:                            return true;
1241:                        default:
1242:                        case ISaveablePart2.CANCEL: // cancel
1243:                            return false;
1244:                        }
1245:                    } else {
1246:                        ListSelectionDialog dlg = new ListSelectionDialog(
1247:                                shellProvider.getShell(), modelsToSave,
1248:                                new ArrayContentProvider(),
1249:                                new WorkbenchPartLabelProvider(),
1250:                                RESOURCES_TO_SAVE_MESSAGE);
1251:                        dlg.setInitialSelections(modelsToSave.toArray());
1252:                        dlg.setTitle(SAVE_RESOURCES_TITLE);
1253:
1254:                        // this "if" statement aids in testing.
1255:                        if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) {
1256:                            int result = dlg.open();
1257:                            //Just return false to prevent the operation continuing
1258:                            if (result == IDialogConstants.CANCEL_ID) {
1259:                                return false;
1260:                            }
1261:
1262:                            modelsToSave = Arrays.asList(dlg.getResult());
1263:                        }
1264:                    }
1265:                } else {
1266:                    modelsToSave = convertToSaveables(dirtyParts, closing,
1267:                            addNonPartSources);
1268:                }
1269:
1270:                // If the editor list is empty return.
1271:                if (modelsToSave.isEmpty()) {
1272:                    return true;
1273:                }
1274:
1275:                // Create save block.
1276:                final List finalModels = modelsToSave;
1277:                IRunnableWithProgress progressOp = new IRunnableWithProgress() {
1278:                    public void run(IProgressMonitor monitor) {
1279:                        IProgressMonitor monitorWrap = new EventLoopProgressMonitor(
1280:                                monitor);
1281:                        monitorWrap.beginTask("", finalModels.size()); //$NON-NLS-1$
1282:                        for (Iterator i = finalModels.iterator(); i.hasNext();) {
1283:                            Saveable model = (Saveable) i.next();
1284:                            // handle case where this model got saved as a result of saving another
1285:                            if (!model.isDirty()) {
1286:                                monitor.worked(1);
1287:                                continue;
1288:                            }
1289:                            SaveableHelper.doSaveModel(model,
1290:                                    new SubProgressMonitor(monitorWrap, 1),
1291:                                    shellProvider, closing || confirm);
1292:                            if (monitorWrap.isCanceled()) {
1293:                                break;
1294:                            }
1295:                        }
1296:                        monitorWrap.done();
1297:                    }
1298:                };
1299:
1300:                // Do the save.
1301:                return SaveableHelper.runProgressMonitorOperation(
1302:                        WorkbenchMessages.Save_All, progressOp,
1303:                        runnableContext, shellProvider);
1304:            }
1305:
1306:            /**
1307:             * For each part (view or editor) in the given list, attempts to convert it
1308:             * to one or more saveable models. Duplicate models are removed. If closing
1309:             * is true, then models that will remain open in parts other than the given
1310:             * parts are removed.
1311:             * 
1312:             * @param parts
1313:             *            the parts (list of IViewPart or IEditorPart)
1314:             * @param closing
1315:             *            whether the parts are being closed
1316:             * @param addNonPartSources
1317:             *            whether non-part sources should be added (true for the Save
1318:             *            All action, see bug 139004)
1319:             * @return the dirty models
1320:             */
1321:            private static List convertToSaveables(List parts, boolean closing,
1322:                    boolean addNonPartSources) {
1323:                ArrayList result = new ArrayList();
1324:                HashSet seen = new HashSet();
1325:                for (Iterator i = parts.iterator(); i.hasNext();) {
1326:                    IWorkbenchPart part = (IWorkbenchPart) i.next();
1327:                    Saveable[] saveables = getSaveables(part);
1328:                    for (int j = 0; j < saveables.length; j++) {
1329:                        Saveable saveable = saveables[j];
1330:                        if (saveable.isDirty() && !seen.contains(saveable)) {
1331:                            seen.add(saveable);
1332:                            if (!closing
1333:                                    || closingLastPartShowingModel(saveable,
1334:                                            parts, part.getSite().getPage())) {
1335:                                result.add(saveable);
1336:                            }
1337:                        }
1338:                    }
1339:                }
1340:                if (addNonPartSources) {
1341:                    SaveablesList saveablesList = (SaveablesList) PlatformUI
1342:                            .getWorkbench().getService(
1343:                                    ISaveablesLifecycleListener.class);
1344:                    ISaveablesSource[] nonPartSources = saveablesList
1345:                            .getNonPartSources();
1346:                    for (int i = 0; i < nonPartSources.length; i++) {
1347:                        Saveable[] saveables = nonPartSources[i].getSaveables();
1348:                        for (int j = 0; j < saveables.length; j++) {
1349:                            Saveable saveable = saveables[j];
1350:                            if (saveable.isDirty() && !seen.contains(saveable)) {
1351:                                seen.add(saveable);
1352:                                result.add(saveable);
1353:                            }
1354:                        }
1355:                    }
1356:                }
1357:                return result;
1358:            }
1359:
1360:            /**
1361:             * Returns the saveable models provided by the given part.
1362:             * If the part does not provide any models, a default model
1363:             * is returned representing the part.
1364:             * 
1365:             * @param part the workbench part
1366:             * @return the saveable models
1367:             */
1368:            private static Saveable[] getSaveables(IWorkbenchPart part) {
1369:                if (part instanceof  ISaveablesSource) {
1370:                    ISaveablesSource source = (ISaveablesSource) part;
1371:                    return source.getSaveables();
1372:                }
1373:                return new Saveable[] { new DefaultSaveable(part) };
1374:            }
1375:
1376:            /**
1377:             * Returns true if, in the given page, no more parts will reference the
1378:             * given model if the given parts are closed.
1379:             * 
1380:             * @param model
1381:             *            the model
1382:             * @param closingParts
1383:             *            the parts being closed (list of IViewPart or IEditorPart)
1384:             * @param page
1385:             *            the page
1386:             * @return <code>true</code> if no more parts in the page will reference
1387:             *         the given model, <code>false</code> otherwise
1388:             */
1389:            private static boolean closingLastPartShowingModel(Saveable model,
1390:                    List closingParts, IWorkbenchPage page) {
1391:                HashSet closingPartsWithSameModel = new HashSet();
1392:                for (Iterator i = closingParts.iterator(); i.hasNext();) {
1393:                    IWorkbenchPart part = (IWorkbenchPart) i.next();
1394:                    Saveable[] models = getSaveables(part);
1395:                    if (Arrays.asList(models).contains(model)) {
1396:                        closingPartsWithSameModel.add(part);
1397:                    }
1398:                }
1399:                IWorkbenchPartReference[] pagePartRefs = ((WorkbenchPage) page)
1400:                        .getAllParts();
1401:                HashSet pagePartsWithSameModels = new HashSet();
1402:                for (int i = 0; i < pagePartRefs.length; i++) {
1403:                    IWorkbenchPartReference partRef = pagePartRefs[i];
1404:                    IWorkbenchPart part = partRef.getPart(false);
1405:                    if (part != null) {
1406:                        Saveable[] models = getSaveables(part);
1407:                        if (Arrays.asList(models).contains(model)) {
1408:                            pagePartsWithSameModels.add(part);
1409:                        }
1410:                    }
1411:                }
1412:                for (Iterator i = closingPartsWithSameModel.iterator(); i
1413:                        .hasNext();) {
1414:                    IWorkbenchPart part = (IWorkbenchPart) i.next();
1415:                    pagePartsWithSameModels.remove(part);
1416:                }
1417:                return pagePartsWithSameModels.isEmpty();
1418:            }
1419:
1420:            /*
1421:             * Saves the workbench part.
1422:             */
1423:            public boolean savePart(final ISaveablePart saveable,
1424:                    IWorkbenchPart part, boolean confirm) {
1425:                return SaveableHelper.savePart(saveable, part, window, confirm);
1426:            }
1427:
1428:            /**
1429:             * @see IPersistablePart
1430:             */
1431:            public IStatus saveState(final IMemento memento) {
1432:
1433:                final MultiStatus result = new MultiStatus(
1434:                        PlatformUI.PLUGIN_ID, IStatus.OK,
1435:                        WorkbenchMessages.EditorManager_problemsSavingEditors,
1436:                        null);
1437:
1438:                // Save the editor area workbooks layout/relationship
1439:                IMemento editorAreaMem = memento
1440:                        .createChild(IWorkbenchConstants.TAG_AREA);
1441:                result.add(editorPresentation.saveState(editorAreaMem));
1442:
1443:                // Save the active workbook id
1444:                editorAreaMem.putString(
1445:                        IWorkbenchConstants.TAG_ACTIVE_WORKBOOK,
1446:                        editorPresentation.getActiveEditorWorkbookID());
1447:
1448:                // Get each workbook
1449:                ArrayList workbooks = editorPresentation.getWorkbooks();
1450:
1451:                for (Iterator iter = workbooks.iterator(); iter.hasNext();) {
1452:                    EditorStack workbook = (EditorStack) iter.next();
1453:
1454:                    // Use the list of editors found in EditorStack; fix for 24091
1455:                    EditorPane editorPanes[] = workbook.getEditors();
1456:
1457:                    for (int i = 0; i < editorPanes.length; i++) {
1458:                        // Save each open editor.
1459:                        IEditorReference editorReference = editorPanes[i]
1460:                                .getEditorReference();
1461:                        EditorReference e = (EditorReference) editorReference;
1462:                        final IEditorPart editor = editorReference
1463:                                .getEditor(false);
1464:                        if (editor == null) {
1465:                            if (e.getMemento() != null) {
1466:                                IMemento editorMem = memento
1467:                                        .createChild(IWorkbenchConstants.TAG_EDITOR);
1468:                                editorMem.putMemento(e.getMemento());
1469:                            }
1470:                            continue;
1471:                        }
1472:
1473:                        // for dynamic UI - add the next line to replace the subsequent
1474:                        // code which is commented out
1475:                        saveEditorState(memento, e, result);
1476:                    }
1477:                }
1478:                return result;
1479:            }
1480:
1481:            /**
1482:             * Shows an editor. If <code>setFocus == true</code> then give it focus,
1483:             * too.
1484:             * 
1485:             * @return true if the active editor was changed, false if not.
1486:             */
1487:            public boolean setVisibleEditor(IEditorReference newEd,
1488:                    boolean setFocus) {
1489:                return editorPresentation.setVisibleEditor(newEd, setFocus);
1490:            }
1491:
1492:            private IPathEditorInput getPathEditorInput(IEditorInput input) {
1493:                if (input instanceof  IPathEditorInput) {
1494:                    return (IPathEditorInput) input;
1495:                }
1496:
1497:                return (IPathEditorInput) Util.getAdapter(input,
1498:                        IPathEditorInput.class);
1499:            }
1500:
1501:            private class InnerEditor extends EditorReference {
1502:
1503:                private IEditorReference outerEditor;
1504:
1505:                public InnerEditor(IEditorReference outerEditor,
1506:                        IEditorInput input, EditorDescriptor desc) {
1507:                    super (EditorManager.this , input, desc);
1508:                    this .outerEditor = outerEditor;
1509:                }
1510:
1511:                protected PartPane createPane() {
1512:                    return new MultiEditorInnerPane(
1513:                            (EditorPane) ((EditorReference) outerEditor)
1514:                                    .getPane(), this , page, editorPresentation
1515:                                    .getActiveWorkbook());
1516:                }
1517:
1518:            }
1519:
1520:            /*
1521:             * Made public for Mylar in 3.3 - see bug 138666. Can be made private once
1522:             * we have real API for this.
1523:             */
1524:            public void restoreEditorState(IMemento editorMem,
1525:                    ArrayList visibleEditors, IEditorReference[] activeEditor,
1526:                    MultiStatus result) {
1527:                // String strFocus = editorMem.getString(IWorkbenchConstants.TAG_FOCUS);
1528:                // boolean visibleEditor = "true".equals(strFocus); //$NON-NLS-1$
1529:                final EditorReference e = new EditorReference(this , editorMem);
1530:
1531:                // if the editor is not visible, ensure it is put in the correct
1532:                // workbook. PR 24091
1533:
1534:                final String workbookID = editorMem
1535:                        .getString(IWorkbenchConstants.TAG_WORKBOOK);
1536:
1537:                try {
1538:                    StartupThreading
1539:                            .runWithPartInitExceptions(new StartupRunnable() {
1540:
1541:                                public void runWithException() throws Throwable {
1542:                                    createEditorTab(e, workbookID);
1543:                                }
1544:                            });
1545:
1546:                } catch (PartInitException ex) {
1547:                    result.add(ex.getStatus());
1548:                }
1549:
1550:                String strActivePart = editorMem
1551:                        .getString(IWorkbenchConstants.TAG_ACTIVE_PART);
1552:                if ("true".equals(strActivePart)) { //$NON-NLS-1$
1553:                    activeEditor[0] = e;
1554:                }
1555:
1556:                String strFocus = editorMem
1557:                        .getString(IWorkbenchConstants.TAG_FOCUS);
1558:                boolean visibleEditor = "true".equals(strFocus); //$NON-NLS-1$
1559:                if (visibleEditor) {
1560:                    visibleEditors.add(e);
1561:                }
1562:            }
1563:
1564:            // for dynamic UI
1565:            protected void saveEditorState(IMemento mem, IEditorReference ed,
1566:                    MultiStatus res) {
1567:                final EditorReference editorRef = (EditorReference) ed;
1568:                final IEditorPart editor = ed.getEditor(false);
1569:                final IMemento memento = mem;
1570:                final MultiStatus result = res;
1571:                if (!(editor.getEditorSite() instanceof  EditorSite)) {
1572:                    return;
1573:                }
1574:                final EditorSite site = (EditorSite) editor.getEditorSite();
1575:                if (site.getPane() instanceof  MultiEditorInnerPane) {
1576:                    return;
1577:                }
1578:
1579:                SafeRunner.run(new SafeRunnable() {
1580:                    public void run() {
1581:                        // Get the input.
1582:                        IEditorInput input = editor.getEditorInput();
1583:                        IPersistableElement persistable = input
1584:                                .getPersistable();
1585:                        if (persistable == null) {
1586:                            return;
1587:                        }
1588:
1589:                        // Save editor.
1590:                        IMemento editorMem = memento
1591:                                .createChild(IWorkbenchConstants.TAG_EDITOR);
1592:                        editorMem.putString(IWorkbenchConstants.TAG_TITLE,
1593:                                editorRef.getTitle());
1594:                        editorMem.putString(IWorkbenchConstants.TAG_NAME,
1595:                                editorRef.getName());
1596:                        editorMem.putString(IWorkbenchConstants.TAG_ID,
1597:                                editorRef.getId());
1598:                        editorMem.putString(IWorkbenchConstants.TAG_TOOLTIP,
1599:                                editorRef.getTitleToolTip());
1600:
1601:                        editorMem.putString(IWorkbenchConstants.TAG_PART_NAME,
1602:                                editorRef.getPartName());
1603:
1604:                        if (editor instanceof  IWorkbenchPart3) {
1605:                            Map properties = ((IWorkbenchPart3) editor)
1606:                                    .getPartProperties();
1607:                            if (!properties.isEmpty()) {
1608:                                IMemento propBag = editorMem
1609:                                        .createChild(IWorkbenchConstants.TAG_PROPERTIES);
1610:                                Iterator i = properties.entrySet().iterator();
1611:                                while (i.hasNext()) {
1612:                                    Map.Entry entry = (Map.Entry) i.next();
1613:                                    IMemento p = propBag.createChild(
1614:                                            IWorkbenchConstants.TAG_PROPERTY,
1615:                                            (String) entry.getKey());
1616:                                    p.putTextData((String) entry.getValue());
1617:                                }
1618:                            }
1619:                        }
1620:
1621:                        if (editorRef.isPinned()) {
1622:                            editorMem.putString(IWorkbenchConstants.TAG_PINNED,
1623:                                    "true"); //$NON-NLS-1$
1624:                        }
1625:
1626:                        EditorPane editorPane = (EditorPane) ((EditorSite) editor
1627:                                .getEditorSite()).getPane();
1628:                        editorMem.putString(IWorkbenchConstants.TAG_WORKBOOK,
1629:                                editorPane.getWorkbook().getID());
1630:
1631:                        if (editor == page.getActivePart()) {
1632:                            editorMem
1633:                                    .putString(
1634:                                            IWorkbenchConstants.TAG_ACTIVE_PART,
1635:                                            "true"); //$NON-NLS-1$
1636:                        }
1637:
1638:                        if (editorPane == editorPane.getWorkbook()
1639:                                .getSelection()) {
1640:                            editorMem.putString(IWorkbenchConstants.TAG_FOCUS,
1641:                                    "true"); //$NON-NLS-1$
1642:                        }
1643:
1644:                        if (input instanceof  IPathEditorInput) {
1645:                            IPath path = ((IPathEditorInput) input).getPath();
1646:                            if (path != null) {
1647:                                editorMem.putString(
1648:                                        IWorkbenchConstants.TAG_PATH, path
1649:                                                .toString());
1650:                            }
1651:                        }
1652:
1653:                        // Save input.
1654:                        IMemento inputMem = editorMem
1655:                                .createChild(IWorkbenchConstants.TAG_INPUT);
1656:                        inputMem.putString(IWorkbenchConstants.TAG_FACTORY_ID,
1657:                                persistable.getFactoryId());
1658:                        persistable.saveState(inputMem);
1659:
1660:                        // any editors that want to persist state
1661:                        if (editor instanceof  IPersistableEditor) {
1662:                            IMemento editorState = editorMem
1663:                                    .createChild(IWorkbenchConstants.TAG_EDITOR_STATE);
1664:                            ((IPersistableEditor) editor)
1665:                                    .saveState(editorState);
1666:                        }
1667:                    }
1668:
1669:                    public void handleException(Throwable e) {
1670:                        result
1671:                                .add(new Status(
1672:                                        IStatus.ERROR,
1673:                                        PlatformUI.PLUGIN_ID,
1674:                                        0,
1675:                                        NLS
1676:                                                .bind(
1677:                                                        WorkbenchMessages.EditorManager_unableToSaveEditor,
1678:                                                        editorRef.getTitle()),
1679:                                        e));
1680:                    }
1681:                });
1682:            }
1683:
1684:            // for dynamic UI
1685:            public IMemento getMemento(IEditorReference e) {
1686:                if (e instanceof  EditorReference) {
1687:                    return ((EditorReference) e).getMemento();
1688:                }
1689:                return null;
1690:            }
1691:
1692:            /*
1693:             * (non-Javadoc)
1694:             * 
1695:             * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
1696:             *      java.lang.Object[])
1697:             */
1698:            public void removeExtension(IExtension source, Object[] objects) {
1699:                for (int i = 0; i < objects.length; i++) {
1700:                    if (objects[i] instanceof  IEditorPart) {
1701:                        // close the editor and clean up the editor history
1702:
1703:                        IEditorPart editor = (IEditorPart) objects[i];
1704:                        IEditorInput input = editor.getEditorInput();
1705:                        page.closeEditor(editor, true);
1706:                        ((Workbench) window.getWorkbench()).getEditorHistory()
1707:                                .remove(input);
1708:                    }
1709:                }
1710:            }
1711:
1712:            /*
1713:             * (non-Javadoc)
1714:             * 
1715:             * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker,
1716:             *      org.eclipse.core.runtime.IExtension)
1717:             */
1718:            public void addExtension(IExtensionTracker tracker,
1719:                    IExtension extension) {
1720:                // Nothing to do
1721:            }
1722:
1723:            /**
1724:             * @return
1725:             */
1726:            /*package*/IEditorReference openEmptyTab() {
1727:                IEditorInput input = new NullEditorInput();
1728:                EditorDescriptor desc = (EditorDescriptor) ((EditorRegistry) getEditorRegistry())
1729:                        .findEditor(EditorRegistry.EMPTY_EDITOR_ID);
1730:                EditorReference result = new EditorReference(this , input, desc);
1731:                try {
1732:                    createEditorTab(result, ""); //$NON-NLS-1$
1733:                    return result;
1734:                } catch (PartInitException e) {
1735:                    StatusManager.getManager().handle(
1736:                            StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
1737:                                    e));
1738:                }
1739:                return null;
1740:            }
1741:
1742:            public static boolean useIPersistableEditor() {
1743:                IPreferenceStore store = WorkbenchPlugin.getDefault()
1744:                        .getPreferenceStore();
1745:                return store
1746:                        .getBoolean(IPreferenceConstants.USE_IPERSISTABLE_EDITORS);
1747:            }
1748:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.