Logo Search packages:      
Sourcecode: eclipse version File versions  Download package

WorkbenchPage.java

/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.jface.action.CoolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationHistory;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IShowEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
import org.eclipse.ui.internal.dnd.SwtUtil;
import org.eclipse.ui.internal.intro.IIntroConstants;
import org.eclipse.ui.internal.misc.UIListenerLogging;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.internal.part.components.services.IWorkbenchPartFactory;
import org.eclipse.ui.internal.part.services.WorkbenchPartFactory;
import org.eclipse.ui.internal.registry.ActionSetRegistry;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.registry.UIExtensionTracker;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.MultiEditor;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.views.IStickyViewDescriptor;
import org.eclipse.ui.views.IViewRegistry;

/**
 * A collection of views and editors in a workbench.
 */
00110 public class WorkbenchPage extends CompatibleWorkbenchPage implements
        IWorkbenchPage {
      
      // editor matching flags
      public static final int MATCH_NONE = 0;
      public static final int MATCH_INPUT = 1;
      public static final int MATCH_ID = 2;
      public static final int MATCH_BOTH = MATCH_INPUT | MATCH_ID;
      
    private WorkbenchWindow window;

    private IAdaptable input;

    private IWorkingSet workingSet;

    private Composite composite;
    
    //Could be delete. This information is in the active part list;
    private ActivationList activationList = new ActivationList();

    private EditorManager editorMgr;

    private EditorAreaHelper editorPresentation;

    private ListenerList propertyChangeListeners = new ListenerList();

    private PageSelectionService selectionService = new PageSelectionService(
            this);

    private WorkbenchPagePartList partList = new WorkbenchPagePartList(selectionService);

    private IActionBars actionBars;
    
    private ActionSetManager actionSets = new ActionSetManager();
    
    private ViewFactory viewFactory;

    private PerspectiveList perspList = new PerspectiveList();

    private PerspectiveDescriptor deferredActivePersp;

    private NavigationHistory navigationHistory = new NavigationHistory(this);

    //for dynamic UI - saving state for editors, views and perspectives
    private HashMap stateMap = new HashMap();

    private WorkbenchPartFactory partFactory = new WorkbenchPartFactory(this);
    
    /**
     * If we're in the process of activating a part, this points to the new part.
     * Otherwise, this is null.
     */
00162     private IWorkbenchPartReference partBeingActivated = null;
    
    /**
     * Contains a list of perspectives that may be dirty due to plugin 
     * installation and removal. 
     */
00168     private Set dirtyPerspectives = new HashSet();
    
    private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
        /*
         * Remove the working set from the page if the working set is deleted.
         */
        public void propertyChange(PropertyChangeEvent event) {
            String property = event.getProperty();
            if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
                    && event.getOldValue().equals(workingSet)) {
                setWorkingSet(null);
            }
        }
    };

    // a mapping of perspectives to a set of stickyviews that have been activated in that perspective.
    // this map is persisted across sessions
    private Map stickyPerspectives = new HashMap(7);

    private ActionSwitcher actionSwitcher = new ActionSwitcher();

      private IExtensionTracker tracker;
    
    // Deferral count... delays disposing parts and sending certain events if nonzero
    private int deferCount = 0;
    // Parts waiting to be disposed
    private List pendingDisposals = new ArrayList();
    
      private IExtensionChangeHandler perspectiveChangeHandler = new IExtensionChangeHandler() {

            /* (non-Javadoc)
             * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension, java.lang.Object[])
             */
            public void removeExtension(IExtension extension, Object[] objects) {
                  boolean suggestReset = false;
                  for (int i = 0; i < objects.length; i++) {
                        if (objects[i] instanceof DirtyPerspectiveMarker) {
                              String id = ((DirtyPerspectiveMarker)objects[i]).perspectiveId;
                              if (!dirtyPerspectives.remove(id)) //if we are dirty, cancel the dirty state
                                    dirtyPerspectives.add(id); // otherwise we will be dirty
                              PerspectiveDescriptor persp = (PerspectiveDescriptor) getPerspective();
                              if (persp == null || persp.hasCustomDefinition())
                                    continue;
                              if (persp.getId().equals(id))
                                    suggestReset = true;
                        }
                  }
                  if (suggestReset)
                        suggestReset();
            }
        
        /* (non-Javadoc)
         * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker, org.eclipse.core.runtime.IExtension)
         */
        public void addExtension(IExtensionTracker tracker, IExtension extension) {
            if (WorkbenchPage.this != getWorkbenchWindow().getActivePage()) 
                return;
            
            // Get the current perspective.
            PerspectiveDescriptor persp = (PerspectiveDescriptor) getPerspective();
            if (persp == null)
                return;
            String currentId = persp.getId();
            IConfigurationElement[] elements = extension.getConfigurationElements();
            boolean suggestReset = false;
            for (int i = 0; i < elements.length; i++) {
                // If any of these refer to the current perspective, output
                // a message saying this perspective will need to be reset
                // in order to see the changes.  For any other case, the
                // perspective extension registry will be rebuilt anyway so
                // just ignore it.
                String id = elements[i].getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID);
                if (id == null)
                    continue;
                if (id.equals(currentId) && !persp.hasCustomDefinition()) {
                    suggestReset = true;
                }
                else {
                    dirtyPerspectives.add(id);
                }
                DirtyPerspectiveMarker marker = new DirtyPerspectiveMarker(id);
                tracker.registerObject(extension, marker, IExtensionTracker.REF_STRONG);
            }
            if (suggestReset) 
                suggestReset();

        }
      };

      private IExtensionPoint getPerspectiveExtensionPoint() {
            return Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, IWorkbenchConstants.PL_PERSPECTIVE_EXTENSIONS);
      }

    /**
     * Manages editor contributions and action set part associations.
     */
00264     private class ActionSwitcher {
        private IWorkbenchPart activePart;

        private IEditorPart topEditor;

        private ArrayList oldActionSets = new ArrayList();

        /**
         * Updates the contributions given the new part as the active part.
         * 
         * @param newPart
         *            the new active part, may be <code>null</code>
         */
00277         public void updateActivePart(IWorkbenchPart newPart) {
            if (activePart == newPart)
                return;

            boolean isNewPartAnEditor = newPart instanceof IEditorPart;
            if (isNewPartAnEditor) {
                String oldId = null;
                if (topEditor != null)
                    oldId = topEditor.getSite().getId();
                String newId = newPart.getSite().getId();

                // if the active part is an editor and the new editor
                // is the same kind of editor, then we don't have to do
                // anything
                if (activePart == topEditor && newId.equals(oldId)) {
                  activePart = newPart;
                  topEditor = (IEditorPart) newPart;
                    return;
                }

                // remove the contributions of the old editor
                // if it is a different kind of editor
                if (oldId != null && !oldId.equals(newId))
                    deactivateContributions(topEditor, true);

                // if a view was the active part, disable its contributions
                if (activePart != null && activePart != topEditor)
                    deactivateContributions(activePart, true);

                // show (and enable) the contributions of the new editor
                // if it is a different kind of editor or if the
                // old active part was a view
                if (!newId.equals(oldId) || activePart != topEditor)
                    activateContributions(newPart, true);

            } else if (newPart == null) {
                if (activePart != null)
                    // remove all contributions
                    deactivateContributions(activePart, true);
            } else {
                // new part is a view

                // if old active part is a view, remove all contributions,
                // but if old part is an editor only disable
                if (activePart != null)
                    deactivateContributions(activePart,
                            activePart instanceof IViewPart);

                activateContributions(newPart, true);
            }

            ArrayList newActionSets = null;
            if (isNewPartAnEditor
                    || (activePart == topEditor && newPart == null))
                newActionSets = calculateActionSets(newPart, null);
            else
                newActionSets = calculateActionSets(newPart, topEditor);

            if (!updateActionSets(newActionSets))
                updateActionBars();

            if (isNewPartAnEditor) {
                topEditor = (IEditorPart) newPart;
            } else if (activePart == topEditor && newPart == null) {
                // since we removed all the contributions, we clear the top
                // editor
                topEditor = null;
            }

            activePart = newPart;
        }

        /**
         * Updates the contributions given the new part as the topEditor.
         * 
         * @param newEditor
         *            the new top editor, may be <code>null</code>
         */
00355         public void updateTopEditor(IEditorPart newEditor) {
            if (topEditor == newEditor)
                return;

            if (activePart == topEditor) {
                  updateActivePart(newEditor);
                  return;
            }
            
            String oldId = null;
            if (topEditor != null)
                oldId = topEditor.getSite().getId();
            String newId = null;
            if (newEditor != null)
                newId = newEditor.getSite().getId();
            if (oldId == null ? newId == null : oldId.equals(newId)) {
                // we don't have to change anything
                topEditor = newEditor;
                return;
            }

            // Remove the contributions of the old editor
            if (topEditor != null)
                deactivateContributions(topEditor, true);

            // Show (disabled) the contributions of the new editor
            if (newEditor != null)
                activateContributions(newEditor, false);

            ArrayList newActionSets = calculateActionSets(activePart, newEditor);
            if (!updateActionSets(newActionSets))
                updateActionBars();

            topEditor = newEditor;
        }

        /**
         * Activates the contributions of the given part. If <code>enable</code>
         * is <code>true</code> the contributions are visible and enabled,
         * otherwise they are disabled.
         * 
         * @param part
         *            the part whose contributions are to be activated
         * @param enable
         *            <code>true</code> the contributions are to be enabled,
         *            not just visible.
         */
00402         private void activateContributions(IWorkbenchPart part, boolean enable) {
            PartSite site = (PartSite) part.getSite();
            site.activateActionBars(enable);
        }

        /**
         * Deactivates the contributions of the given part. If <code>remove</code>
         * is <code>true</code> the contributions are removed, otherwise they
         * are disabled.
         * 
         * @param part
         *            the part whose contributions are to be deactivated
         * @param remove
         *            <code>true</code> the contributions are to be removed,
         *            not just disabled.
         */
00418         private void deactivateContributions(IWorkbenchPart part, boolean remove) {
            PartSite site = (PartSite) part.getSite();
            site.deactivateActionBars(remove);
        }

        /**
         * Calculates the action sets to show for the given part and editor
         * 
         * @param part
         *            the active part, may be <code>null</code>
         * @param editor
         *            the current editor, may be <code>null</code>, may be
         *            the active part
         * @return the new action sets
         */
00433         private ArrayList calculateActionSets(IWorkbenchPart part,
                IEditorPart editor) {
            ArrayList newActionSets = new ArrayList();
            if (part != null) {
                IActionSetDescriptor[] partActionSets = WorkbenchPlugin
                        .getDefault().getActionSetRegistry().getActionSetsFor(
                                part.getSite().getId());
                for (int i = 0; i < partActionSets.length; i++) {
                    newActionSets.add(partActionSets[i]);
                }
            }
            if (editor != null && editor != part) {
                IActionSetDescriptor[] editorActionSets = WorkbenchPlugin
                        .getDefault().getActionSetRegistry().getActionSetsFor(
                                editor.getSite().getId());
                for (int i = 0; i < editorActionSets.length; i++) {
                    newActionSets.add(editorActionSets[i]);
                }
            }
            return newActionSets;
        }

        /**
         * Updates the actions we are showing for the active part and current
         * editor.
         * 
         * @param newActionSets
         *            the action sets to show
         * @return <code>true</code> if the action sets changed
         */
00463         private boolean updateActionSets(ArrayList newActionSets) {
            if (oldActionSets.equals(newActionSets))
                return false;

            // show the new
            for (int i = 0; i < newActionSets.size(); i++) {
                actionSets.showAction((IActionSetDescriptor) newActionSets
                        .get(i));
            }
            
            // hide the old
            for (int i = 0; i < oldActionSets.size(); i++) {
                actionSets.hideAction((IActionSetDescriptor) oldActionSets
                        .get(i));            }

            oldActionSets = newActionSets;

            Perspective persp = getActivePerspective();
            if (persp == null) {
                return false;
            }
            
            window.updateActionSets(); // this calls updateActionBars
            window.firePerspectiveChanged(WorkbenchPage.this, getPerspective(),
                    CHANGE_ACTION_SET_SHOW);
            return true;
        }

    }

    /**
     * Constructs a new page with a given perspective and input.
     * 
     * @param w
     *            the parent window
     * @param layoutID
     *            must not be <code>null</code>
     * @param input
     *            the page input
     * @throws WorkbenchException on null layout id
     */
00504     public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
            throws WorkbenchException {
        super();
        if (layoutID == null)
            throw new WorkbenchException(WorkbenchMessages.WorkbenchPage_UndefinedPerspective);
        init(w, layoutID, input);
    }

    /**
     * Constructs a page. <code>restoreState(IMemento)</code> should be
     * called to restore this page from data stored in a persistance file.
     * 
     * @param w
     *            the parent window
     * @param input
     *            the page input
     * @throws WorkbenchException 
     */
00522     public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
            throws WorkbenchException {
        super();
        init(w, null, input);
    }

    /**
     * Activates a part. The part will be brought to the front and given focus.
     * 
     * @param part
     *            the part to activate
     */
00534     public void activate(IWorkbenchPart part) {
        // Sanity check.
        if (!certifyPart(part))
            return;

        if (window.isClosing())
            return;

        // If zoomed, unzoom.
        zoomOutIfNecessary(part);

        if (part instanceof MultiEditor) {
            part = ((MultiEditor) part).getActiveEditor();
        }
        // Activate part.
        //if (window.getActivePage() == this) {
        IWorkbenchPartReference ref = getReference(part);
        internalBringToTop(ref);
        setActivePart(part);
    }

    /**
     * Activates a part. The part is given focus, the pane is hilighted.
     */
00558     private void activatePart(final IWorkbenchPart part) {
        Platform.run(new SafeRunnable(WorkbenchMessages.WorkbenchPage_ErrorActivatingView) { 
                    public void run() {
                        if (part != null) {
                            //part.setFocus();
                            PartPane pane = getPane(part);
                            pane.setFocus();
                            PartSite site = (PartSite) part.getSite();
                            pane.showFocus(true);
                            updateTabList(part);
                            SubActionBars bars = (SubActionBars) site
                                    .getActionBars();
                            bars.partChanged(part);
                        }
                    }
                });
    }

    /**
     * Add a fast view.
     */
00579     public void addFastView(IViewReference ref) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;

        if (persp.isFastView(ref)) {
            return;
        }
        
        // Do real work.
        persp.addFastView(ref);

        updateActivePart();
        
        // The view is now invisible.
        // If it is active then deactivate it.

        // Notify listeners.
        window.firePerspectiveChanged(this, getPerspective(), ref,
                CHANGE_FAST_VIEW_ADD);
        window.firePerspectiveChanged(this, getPerspective(),
                CHANGE_FAST_VIEW_ADD);
    }

    /**
     * Adds an IPartListener to the part service.
     */
00606     public void addPartListener(IPartListener l) {
        partList.getPartService().addPartListener(l);
    }

    /**
     * Adds an IPartListener to the part service.
     */
00613     public void addPartListener(IPartListener2 l) {
        partList.getPartService().addPartListener(l);
    }

    /**
     * Implements IWorkbenchPage
     * 
     * @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
     * @since 2.0
     * @deprecated individual views should store a working set if needed and
     *             register a property change listener directly with the
     *             working set manager to receive notification when the view
     *             working set is removed.
     */
00627     public void addPropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.add(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
00634     public void addSelectionListener(ISelectionListener listener) {
        selectionService.addSelectionListener(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
00641     public void addSelectionListener(String partId, ISelectionListener listener) {
        selectionService.addSelectionListener(partId, listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
00648     public void addPostSelectionListener(ISelectionListener listener) {
        selectionService.addPostSelectionListener(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
00655     public void addPostSelectionListener(String partId,
            ISelectionListener listener) {
        selectionService.addPostSelectionListener(partId, listener);
    }
    
    private ILayoutContainer getContainer(IWorkbenchPart part) {
        PartPane pane = getPane(part);
        if (pane == null) {
            return null;
        }
        
        return pane.getContainer();
    }

    private ILayoutContainer getContainer(IWorkbenchPartReference part) {
        PartPane pane = getPane(part);
        if (pane == null) {
            return null;
        }
        
        return pane.getContainer();
    }
    
    private PartPane getPane(IWorkbenchPart part) {
        if (part == null) {
            return null;
        }
        return getPane(getReference(part));
    }
    
    private PartPane getPane(IWorkbenchPartReference part) {
        if (part == null) {
            return null;
        }
        
        return ((WorkbenchPartReference)part).getPane();
    }

    
    /**
     * Brings a part to the front of its stack. Does not update the active part or
     * active editor. This should only be called if the caller knows that the part
     * is not in the same stack as the active part or active editor, or if the caller
     * is prepared to update activation after the call.
     *
     * @param part
     */
00702     private boolean internalBringToTop(IWorkbenchPartReference part) {

        boolean broughtToTop = false;
        
        // Move part.
        if (part instanceof IEditorReference) {
            ILayoutContainer container = getContainer(part);
            if (container instanceof PartStack) {
                PartStack stack = (PartStack)container;
                PartPane newPart = getPane(part);
                if (stack.getSelection() != newPart) {
                    stack.setSelection(newPart);
                }
                broughtToTop = true;
            }
        } else if (part instanceof IViewReference) {
            Perspective persp = getActivePerspective();
            if (persp != null) {
                broughtToTop = persp.bringToTop((IViewReference)part);
            }
        }
        
        // Ensure that this part is considered the most recently activated part
        // in this stack
        activationList.bringToTop(part);
        
        return broughtToTop;
    }

    
    /**
     * Moves a part forward in the Z order of a perspective so it is visible.
     * If the part is in the same stack as the active part, the new part is
     * activated.
     * 
     * @param part
     *            the part to bring to move forward
     */
00740     public void bringToTop(IWorkbenchPart part) {
        // Sanity check.
        Perspective persp = getActivePerspective();
        if (persp == null || !certifyPart(part))
            return;

        String label = null; // debugging only
        if (UIStats.isDebugging(UIStats.BRING_PART_TO_TOP)) {
            label = part != null ? part.getTitle() : "none"; //$NON-NLS-1$
        }
        
        try {
            UIStats.start(UIStats.BRING_PART_TO_TOP, label);
            
            IWorkbenchPartReference ref = getReference(part);
            ILayoutContainer activeEditorContainer = getContainer(getActiveEditor());
            ILayoutContainer activePartContainer = getContainer(getActivePart());
            ILayoutContainer newPartContainer = getContainer(part);
            
            if (newPartContainer == activePartContainer) {
                makeActive(ref);
            } else if (newPartContainer == activeEditorContainer) {
                if (ref instanceof IEditorReference) {
                  if (part!=null) {
                        IWorkbenchPartSite site = part.getSite();
                                    if (site instanceof PartSite) {
                                          ref = ((PartSite) site).getPane()
                                                      .getPartReference();
                                    }
                  }
                    makeActiveEditor((IEditorReference)ref);
                } else {
                    makeActiveEditor(null);
                }
            } else {
                internalBringToTop(ref);
                if (ref != null) {
                    partList.firePartBroughtToTop(ref);
                }
            }
        } finally {
            UIStats.end(UIStats.BRING_PART_TO_TOP, part, label);
        }
    }

    /**
     * Resets the layout for the perspective. The active part in the old layout
     * is activated in the new layout for consistent user context.
     * 
     * Assumes the busy cursor is active.
     */
00791     private void busyResetPerspective() {

        ViewIntroAdapterPart introViewAdapter = ((WorkbenchIntroManager) getWorkbenchWindow()
                .getWorkbench().getIntroManager()).getViewIntroAdapterPart();
        PartPane introPane = null;
        boolean introFullScreen = false;
        if (introViewAdapter != null) {
            introPane = ((PartSite) introViewAdapter.getSite()).getPane();
            introViewAdapter.setHandleZoomEvents(false);
            introFullScreen = introPane.isZoomed();
        }

        //try to prevent intro flicker.
        if (introFullScreen)
            window.getShell().setRedraw(false);

        try {

            // Always unzoom
            if (isZoomed())
                zoomOut();

            // Get the current perspective.
            // This describes the working layout of the page and differs from
            // the original template.
            Perspective oldPersp = getActivePerspective();

            // Map the current perspective to the original template.
            // If the original template cannot be found then it has been deleted.
            // In that case just return. (PR#1GDSABU).
            IPerspectiveRegistry reg = WorkbenchPlugin.getDefault()
                    .getPerspectiveRegistry();
            PerspectiveDescriptor desc = (PerspectiveDescriptor) reg
                    .findPerspectiveWithId(oldPersp.getDesc().getId());
            if (desc == null)
                desc = (PerspectiveDescriptor) reg
                        .findPerspectiveWithId(((PerspectiveDescriptor) oldPersp
                                .getDesc()).getOriginalId());
            if (desc == null)
                return;

            // Notify listeners that we are doing a reset.
            window.firePerspectiveChanged(this, desc, CHANGE_RESET);

            // Create new persp from original template.
            Perspective newPersp = createPerspective(desc);
            if (newPersp == null) {
                // We're not going through with the reset, so it is complete.
                window
                        .firePerspectiveChanged(this, desc,
                                CHANGE_RESET_COMPLETE);
                return;
            }

            // Update the perspective list and shortcut
            perspList.swap(oldPersp, newPersp);

            // Install new persp.
            setPerspective(newPersp);

            // Destroy old persp.
            disposePerspective(oldPersp);

            // Update the Coolbar layout.
            resetToolBarLayout();

            // restore the maximized intro
            if (introViewAdapter != null) {
                try {
                    // ensure that the intro is visible in the new perspective
                    showView(IIntroConstants.INTRO_VIEW_ID);
                    if (introFullScreen)
                        toggleZoom(introPane.getPartReference());
                } catch (PartInitException e) {
                    WorkbenchPlugin.log("Could not restore intro", //$NON-NLS-1$
                            WorkbenchPlugin.getStatus(e));
                } finally {
                    // we want the intro back to a normal state before we fire the event
                    introViewAdapter.setHandleZoomEvents(true);
                }
            }
            // Notify listeners that we have completed our reset.
            window.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
        } finally {
            // reset the handling of zoom events (possibly for the second time) in case there was 
            // an exception thrown
            if (introViewAdapter != null)
                introViewAdapter.setHandleZoomEvents(true);

            if (introFullScreen)
                window.getShell().setRedraw(true);
        }

    }

    /**
     * Implements <code>setPerspective</code>.
     * 
     * Assumes that busy cursor is active.
     * 
     * @param persp
     *            identifies the new perspective.
     */
00894     private void busySetPerspective(IPerspectiveDescriptor desc) {
        // Create new layout.
        String label = desc.getId(); // debugging only
        Perspective newPersp = null;
        try {
            UIStats.start(UIStats.SWITCH_PERSPECTIVE, label);
            PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
            newPersp = findPerspective(realDesc);
            if (newPersp == null) {
                newPersp = createPerspective(realDesc);
                if (newPersp == null)
                    return;
            }

            // Change layout.
            setPerspective(newPersp);
        } finally {
            UIStats.end(UIStats.SWITCH_PERSPECTIVE, desc.getId(), label);
        }
    }

    /**
     * Shows a view.
     * 
     * Assumes that a busy cursor is active.
     */
00920     private IViewPart busyShowView(String viewID, String secondaryID, int mode)
            throws PartInitException {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return null;

        // If this view is already visible just return.
        IViewReference ref = persp.findView(viewID, secondaryID);
        IViewPart view = null;
        if (ref != null)
            view = ref.getView(true);
        if (view != null) {
            busyShowView(view, mode);
            return view;
        }

        // Show the view.
        view = persp.showView(viewID, secondaryID);
        if (view != null) {
            busyShowView(view, mode);
            
            IWorkbenchPartReference partReference = getReference(view);
            PartPane partPane = getPane(partReference);
            partPane.setInLayout(true);

            window.firePerspectiveChanged(this, getPerspective(),
                    partReference, CHANGE_VIEW_SHOW);
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_VIEW_SHOW);
        }
        return view;
    }

    /*
     * Performs showing of the view in the given mode.
     */
    private void busyShowView(IViewPart part, int mode) {
        if (mode == VIEW_ACTIVATE)
            activate(part);
        else if (mode == VIEW_VISIBLE) {
            IWorkbenchPartReference ref = getActivePartReference();
            // if there is no active part or it's not a view, bring to top
            if (ref == null || !(ref instanceof IViewReference))
                bringToTop(part);
            else {
                // otherwise check to see if the we're in the same stack as the active view
                IViewReference activeView = (IViewReference) ref;
                IViewReference[] viewStack = getViewReferenceStack(part);
                for (int i = 0; i < viewStack.length; i++) {
                    if (viewStack[i].equals(activeView))
                        return;
                }
                bringToTop(part);
            }
        }
    }

    /**
     * Returns whether a part exists in the current page.
     */
00980     private boolean certifyPart(IWorkbenchPart part) {
        //Workaround for bug 22325
        if (part != null && !(part.getSite() instanceof PartSite))
            return false;

        if (part instanceof IEditorPart) {
            IEditorReference ref = (IEditorReference) getReference(part);
            return ref != null && getEditorManager().containsEditor(ref);
        }
        if (part instanceof IViewPart) {
            Perspective persp = getActivePerspective();
            return persp != null && persp.containsView((IViewPart) part);
        }
        return false;
    }

    /**
     * Closes the perspective.
     */
00999     public boolean close() {
        final boolean[] ret = new boolean[1];
        BusyIndicator.showWhile(null, new Runnable() {
            public void run() {
                ret[0] = window.closePage(WorkbenchPage.this, true);
            }
        });
        return ret[0];
    }

    /**
     * See IWorkbenchPage
     */
01012     public boolean closeAllSavedEditors() {
        // get the Saved editors
        IEditorReference editors[] = getEditorReferences();
        IEditorReference savedEditors[] = new IEditorReference[editors.length];
        int j = 0;
        for (int i = 0; i < editors.length; i++) {
            IEditorReference editor = editors[i];
            if (!editor.isDirty()) {
                savedEditors[j++] = editor;
            }
        }
        //there are no unsaved editors
        if (j == 0)
            return true;
        IEditorReference[] newSaved = new IEditorReference[j];
        System.arraycopy(savedEditors, 0, newSaved, 0, j);
        return closeEditors(newSaved, false);
    }

    /**
     * See IWorkbenchPage
     */
01034     public boolean closeAllEditors(boolean save) {
        return closeEditors(getEditorReferences(), save);
    }

    private void updateActivePart() {
        
        if (isDeferred()) {
            return;
        }
        
        IWorkbenchPartReference oldActivePart = partList.getActivePartReference();
        IWorkbenchPartReference oldActiveEditor = partList.getActiveEditorReference();
        IWorkbenchPartReference newActivePart = null;
        IEditorReference newActiveEditor = null;
        
        if (!window.isClosing()) {
            // If an editor is active, try to keep an editor active
            if (oldActivePart == oldActiveEditor) {
                newActiveEditor = (IEditorReference)activationList.getActiveReference(true);
                newActivePart = newActiveEditor;
                if (newActivePart == null) {
                    // Only activate a non-editor if there's no editors left
                    newActivePart = activationList.getActiveReference(false);
                }
            } else {
                // If a non-editor is active, activate whatever was activated most recently
                newActivePart = activationList.getActiveReference(false);
                
                if (newActivePart instanceof IEditorReference) {
                    // If that happens to be an editor, make it the active editor as well
                    newActiveEditor = (IEditorReference)newActivePart;
                } else {
                    // Otherwise, select whatever editor was most recently active
                    newActiveEditor = (IEditorReference)activationList.getActiveReference(true);
                }   
            }
        }

        if (newActiveEditor != oldActiveEditor) {
            makeActiveEditor(newActiveEditor);
        }
        
        if (newActivePart != oldActivePart) {
            makeActive(newActivePart);
        }
    }
    
    /**
     * Makes the given part active. Brings it in front if necessary. Permits null 
     * (indicating that no part should be active).
     * 
     * @since 3.1 
     *
     * @param ref new active part (or null)
     */
01089     private void makeActive(IWorkbenchPartReference ref) {
        if (ref == null) {
            setActivePart(null);
        } else {
            IWorkbenchPart newActive = ref.getPart(true);
            if (newActive == null) {
                setActivePart(null);
            } else {
                activate(newActive);
            }
        }
    }
    
    /**
     * Makes the given editor active. Brings it to front if necessary. Permits <code>null</code> 
     * (indicating that no editor is active).
     * 
     * @since 3.1 
     *
     * @param ref the editor to make active, or <code>null</code> for no active editor
     */
01110     private void makeActiveEditor(IEditorReference ref) {
        if (ref == getActiveEditorReference()) {
            return;
        }
        
        IEditorPart part = (ref == null) ? null : ref.getEditor(true);
        
        if (part != null) {
            editorMgr.setVisibleEditor(ref, false);
            navigationHistory.markEditor(part);
        }
        
        actionSwitcher.updateTopEditor(part);

        if (ref != null) {
            activationList.bringToTop(getReference(part));
        }
        
        partList.setActiveEditor(ref);
    }
    
    /**
     * See IWorkbenchPage
     */
01134     public boolean closeEditors(IEditorReference[] refArray, boolean save) {
        if (refArray.length == 0) {
            return true;
        }
        
        // Check if we're being asked to close any parts that are already closed or cannot
        // be closed at this time
        ArrayList toClose = new ArrayList();
        for (int i = 0; i < refArray.length; i++) {
            IEditorReference reference = refArray[i];
            
            // If we're in the middle of creating this part, this is a programming error. Abort the entire
            // close operation. This usually occurs if someone tries to open a dialog in a method that
            // isn't allowed to do so, and a *syncExec tries to close the part. If this shows up in a log
            // file with a dialog's event loop on the stack, then the code that opened the dialog is usually
            // at fault.
            if (reference == partBeingActivated) {
                WorkbenchPlugin.log(new RuntimeException("WARNING: Blocked recursive attempt to close part "  //$NON-NLS-1$
                        + partBeingActivated.getId() + " while still in the middle of activating it")); //$NON-NLS-1$
                return false;
            }
            
            if(reference instanceof WorkbenchPartReference) {
                WorkbenchPartReference ref = (WorkbenchPartReference) reference;
                
                // If we're being asked to close a part that is disposed (ie: already closed),
                // skip it and proceed with closing the remaining parts.
                if (ref.isDisposed()) {
                    continue;
                }
            }
            
            toClose.add(reference);
        }
        
        IEditorReference[] editorRefs = (IEditorReference[]) toClose.toArray(new IEditorReference[toClose.size()]);
        
        if (save) { 
            // Intersect the dirty editors with the editors that are closing
            IEditorPart[] dirty = getDirtyEditors();
            List intersect = new ArrayList();
            for (int i = 0; i < editorRefs.length; i++) {
                IEditorReference reference = editorRefs[i];
                IEditorPart refPart = reference.getEditor(false);
                if (refPart != null) {
                    for (int j = 0; j < dirty.length; j++) {
                        if (refPart.equals(dirty[j]) && refPart.isSaveOnCloseNeeded()) {
                            intersect.add(refPart);
                            break;
                        }
                    }
                }
            }
            // Save parts, exit the method if cancel is pressed.
            if (intersect.size() > 0) {
                // If there is exactly one editor open, show the simpler dialog
                if (intersect.size() == 1) {
                    if (!getEditorManager().saveEditor((IEditorPart)(intersect.get(0)), true)) {
                        return false;
                    }
                } else {
                    if (!EditorManager.saveAll(intersect, true,
                            getWorkbenchWindow()))
                        return false;
                }
            }
        }

        // Fire pre-removal changes 
        for (int i = 0; i < editorRefs.length; i++) {
            IEditorReference ref = editorRefs[i];
            
            // Notify interested listeners before the close
            window.firePerspectiveChanged(this, getPerspective(), ref,
                    CHANGE_EDITOR_CLOSE);
            
        }        
        
        deferUpdates(true);
        try {        
              // Close all editors.
              for (int i = 0; i < editorRefs.length; i++) {
                  IEditorReference ref = editorRefs[i];
                
                  // Remove editor from the presentation
                editorPresentation.closeEditor(ref);
                  
                partRemoved((WorkbenchPartReference)ref);                
              }
        } finally {
            deferUpdates(false);
        }
                        
        // Notify interested listeners after the close
        window.firePerspectiveChanged(this, getPerspective(),
                CHANGE_EDITOR_CLOSE);

        // Return true on success.
        return true;
    }
    
    /**
     * Enables or disables listener notifications. This is used to delay listener notifications until the
     * end of a public method.
     * 
     * @param shouldDefer
     */
01241     private void deferUpdates(boolean shouldDefer) {
        if (shouldDefer) {
            if (deferCount == 0) {
                startDeferring();
            }
            deferCount++;
        } else {
            deferCount--;
            if (deferCount == 0) {
                handleDeferredEvents();
            }
        }
    }
    
    private void startDeferring() {
        editorPresentation.getLayoutPart().deferUpdates(true);
    }

    private void handleDeferredEvents() {
        editorPresentation.getLayoutPart().deferUpdates(false);
        updateActivePart();
        WorkbenchPartReference[] disposals = (WorkbenchPartReference[]) pendingDisposals.toArray(new WorkbenchPartReference[pendingDisposals.size()]);
        pendingDisposals.clear();
        for (int i = 0; i < disposals.length; i++) {
            WorkbenchPartReference reference = disposals[i];
            disposePart(reference);
        }
        
    }
    
    private boolean isDeferred() {
        return deferCount > 0;
    }

    /**
     * See IWorkbenchPage#closeEditor
     */
01278     public boolean closeEditor(IEditorReference editorRef, boolean save) {
        return closeEditors(new IEditorReference[] {editorRef}, save);
    }

    /**
     * See IWorkbenchPage#closeEditor
     */
01285     public boolean closeEditor(IEditorPart editor, boolean save) {
        IWorkbenchPartReference ref = getReference(editor);
        if (ref instanceof IEditorReference) {
            return closeEditors(new IEditorReference[] {(IEditorReference) ref}, save);
        }
        return false;
    }

    /**
     * @see IWorkbenchPage#closePerspective(IPerspectiveDescriptor, boolean, boolean)
     */
01296     public void closePerspective(IPerspectiveDescriptor desc, boolean saveEditors, boolean closePage) {
        Perspective persp = findPerspective(desc);
        if (persp != null)
            closePerspective(persp, saveEditors, closePage);
    }

    /**
     * Closes the specified perspective. If last perspective, then entire page
     * is closed.
     * 
     * @param persp
     *            the perspective to be closed
     * @param saveEditors
     *            whether the page's editors should be save if last perspective
     */
    /* package */
01312     void closePerspective(Perspective persp, boolean saveEditors, boolean closePage) {

        // Always unzoom
        if (isZoomed())
            zoomOut();

        // Close all editors on last perspective close
        if (perspList.size() == 1 && getEditorManager().getEditorCount() > 0) {
            // Close all editors
            if (!closeAllEditors(saveEditors))
                return;
        }

        // Dispose of the perspective
        boolean isActive = (perspList.getActive() == persp);
        if (isActive)
            setPerspective(perspList.getNextActive());
        disposePerspective(persp);
        if (closePage && perspList.size() == 0)
            close();
    }

    /**
     * @see IWorkbenchPage#closeAllPerspectives(boolean, boolean)
     */
01337     public void closeAllPerspectives(boolean saveEditors, boolean closePage) {

        if (perspList.isEmpty())
            return;

        // Always unzoom
        if (isZoomed())
            zoomOut();

        // Close all editors
        if (!closeAllEditors(saveEditors))
            return;

        // Deactivate the active perspective and part
        setPerspective((Perspective) null);

        // Close each perspective in turn
        PerspectiveList oldList = perspList;
        perspList = new PerspectiveList();
        Iterator itr = oldList.iterator();
        while (itr.hasNext())
            closePerspective((Perspective) itr.next(), false, false);
        if (closePage) {
            close();
        }
    }

    /**
     * Creates the client composite.
     */
01367     private void createClientComposite() {
        Composite parent = window.getPageComposite();
        composite = new Composite(parent, SWT.NONE);
        composite.setVisible(false); // Make visible on activate.
        // force the client composite to be layed out
        parent.layout();
    }

    /**
     * Creates a new view set. Return null on failure.
     */
01378     private Perspective createPerspective(PerspectiveDescriptor desc) {
        String label = desc.getId(); // debugging only
        try {
            UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
            Perspective persp = new Perspective(desc, this);
            perspList.add(persp);
            window.firePerspectiveOpened(this, desc);
            //if the perspective is fresh and uncustomzied then it is not dirty
            //no reset will be prompted for
            if (!desc.hasCustomDefinition())
                  dirtyPerspectives.remove(desc.getId());
            return persp;
        } catch (WorkbenchException e) {
            if (!((Workbench) window.getWorkbench()).isStarting()) {
                MessageDialog
                        .openError(
                                window.getShell(),
                                WorkbenchMessages.Error, 
                                NLS.bind(WorkbenchMessages.Workbench_showPerspectiveError,desc.getId() )); 
            }
            return null;
        } finally {
            UIStats.end(UIStats.CREATE_PERSPECTIVE, desc.getId(), label);
        }
    }

    /**
     * Open the tracker to allow the user to move the specified part using
     * keyboard.
     * @param pane the pane to track
     */
01409     public void openTracker(ViewPane pane) {
        Perspective persp = getActivePerspective();
        if (persp != null)
            persp.openTracker(pane);
    }

    /**
     * This is called by child objects after a part has been added to the page.
     * The page will in turn notify its listeners. 
     */
01419     /* package */ void partAdded(WorkbenchPartReference ref) {
        activationList.add(ref);
        partList.addPart(ref);
        updateActivePart();
    }
    
    /**
     * This is called by child objects after a part has been added to the page.
     * The part will be queued for disposal after all listeners have been notified
     */
01429     /* package */ void partRemoved(WorkbenchPartReference ref) {
        activationList.remove(ref);
        disposePart(ref);
    }
    
    private void disposePart(WorkbenchPartReference ref) {
        if (isDeferred()) {
            pendingDisposals.add(ref);
        } else {
            partList.removePart(ref);
            ref.dispose();
        }
    }
    
    /**
     * Deactivates a part. The pane is unhilighted.
     */
01446     private void deactivatePart(IWorkbenchPart part) {
        if (part != null) {
            PartSite site = (PartSite) part.getSite();
            site.getPane().showFocus(false);
        }
    }
    
      /**
       * Detaches a view from the WorkbenchWindow.
       */
01456       public void detachView(IViewReference ref){
            Perspective persp = getActivePerspective();
            PerspectiveHelper presentation = persp.getPresentation();
            
            if(persp == null)
                  return;
            
            presentation.detachPart(ref);
      }
      
      /**
       * Removes a detachedwindow. 
       */
01469       public void attachView(IViewReference ref){
            PerspectiveHelper presentation = getPerspectivePresentation();
            presentation.attachPart(ref);
      }

    /**
     * Cleanup.
     */
01477     public void dispose() {

        // Always unzoom
        if (isZoomed())
            zoomOut();

        makeActiveEditor(null);
        makeActive(null);
        
        // Close and dispose the editors.
        closeAllEditors(false);

        // Get rid of perspectives. This will close the views.
        Iterator itr = perspList.iterator();
        while (itr.hasNext()) {
            Perspective perspective = (Perspective) itr.next();
            window.firePerspectiveClosed(this, perspective.getDesc());
            perspective.dispose();
        }
        perspList = new PerspectiveList();

        // Capture views.
        IViewReference refs[] = viewFactory.getViews();

        if (refs.length > 0) {
            // Dispose views.
            for (int i = 0; i < refs.length; i++) {
                final WorkbenchPartReference ref = (WorkbenchPartReference) refs[i];
                //partList.removePart(ref);
                //firePartClosed(refs[i]);
                Platform.run(new SafeRunnable() {
                    public void run() {
//                        WorkbenchPlugin.log(new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, 
//                                Status.OK, "WorkbenchPage leaked a refcount for view " + ref.getId(), null));  //$NON-NLS-1$//$NON-NLS-2$
                        
                        ref.dispose();
                    }
    
                    public void handleException(Throwable e) {
                    }
                });
            }
        }
        
        activationList = new ActivationList();

        // Get rid of editor presentation.
        editorPresentation.dispose();

        // Get rid of composite.
        composite.dispose();

        navigationHistory.dispose();

        stickyPerspectives.clear();
        
        if (tracker != null) 
            tracker.close();
    }

    /**
     * Dispose a perspective.
     */
01540     private void disposePerspective(Perspective persp) {
        // Get rid of perspective.
        perspList.remove(persp);
        window.firePerspectiveClosed(this, persp.getDesc());
        persp.dispose();

        stickyPerspectives.remove(persp.getDesc().getId());
    }

    /**
     * @return NavigationHistory
     */
01552     public INavigationHistory getNavigationHistory() {
        return navigationHistory;
    }

    /**
     * Edits the action sets.
     */
01559     public boolean editActionSets() {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return false;

        // Create list dialog.
        CustomizePerspectiveDialog dlg = window.createCustomizePerspectiveDialog(persp);
        
        // Open.
        boolean ret = (dlg.open() == Window.OK);
        if (ret) {
            window.updateActionSets();
            window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_RESET_COMPLETE);
        }
        return ret;
    }

    /**
     * Returns the first view manager with given ID.
     */
01581     public Perspective findPerspective(IPerspectiveDescriptor desc) {
        Iterator itr = perspList.iterator();
        while (itr.hasNext()) {
            Perspective mgr = (Perspective) itr.next();
            if (desc.getId().equals(mgr.getDesc().getId()))
                return mgr;
        }
        return null;
    }

    /**
     * See IWorkbenchPage@findView.
     */
01594     public IViewPart findView(String id) {
        IViewReference ref = findViewReference(id);
        if (ref == null)
            return null;
        return ref.getView(true);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage
     */
01606     public IViewReference findViewReference(String viewId) {
        return findViewReference(viewId, null);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage
     */
01615     public IViewReference findViewReference(String viewId, String secondaryId) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return null;
        return persp.findView(viewId, secondaryId);
    }


    /**
     * Notify property change listeners about a property change.
     * 
     * @param changeId
     *            the change id
     * @param oldValue
     *            old property value
     * @param newValue
     *            new property value
     */
01633     private void firePropertyChange(String changeId, Object oldValue,
            Object newValue) {
        
        UIListenerLogging.logPagePropertyChanged(this, changeId, oldValue, newValue);
        
        Object[] listeners = propertyChangeListeners.getListeners();
        PropertyChangeEvent event = new PropertyChangeEvent(this, changeId,
                oldValue, newValue);

        for (int i = 0; i < listeners.length; i++) {
            ((IPropertyChangeListener) listeners[i]).propertyChange(event);
        }
    }

    /*
     * Returns the action bars.
     */
    public IActionBars getActionBars() {
        if (actionBars == null)
            actionBars = new WWinActionBars(window);
        return actionBars;
    }

    /**
     * Returns an array of the visible action sets.
     */
01659     public IActionSetDescriptor[] getActionSets() {
        Collection collection = actionSets.getVisibleItems();
        
        return (IActionSetDescriptor[]) collection.toArray(new IActionSetDescriptor[collection.size()]);
    }

    /**
     * @see IWorkbenchPage
     */
01668     public IEditorPart getActiveEditor() {
        return partList.getActiveEditor();
    }

    /**
     * Returns the reference for the active editor, or <code>null</code> 
     * if there is no active editor.
     * 
     * @return the active editor reference or <code>null</code>
     */
01678     public IEditorReference getActiveEditorReference() {
        return partList.getActiveEditorReference();
    }
    
    /*
     * (non-Javadoc) Method declared on IPartService
     */
01685     public IWorkbenchPart getActivePart() {
        return partList.getActivePart();
    }

    /*
     * (non-Javadoc) Method declared on IPartService
     */
01692     public IWorkbenchPartReference getActivePartReference() {
        return partList.getActivePartReference();
    }

    /**
     * Returns the active perspective for the page, <code>null</code> if
     * none.
     */
01700     public Perspective getActivePerspective() {
        return perspList.getActive();
    }

    /**
     * Returns the client composite.
     */
01707     public Composite getClientComposite() {
        return composite;
    }

    /**
     * Answer the editor manager for this window.
     */
    // for dynamic UI - change access from private to protected
01715     protected EditorManager getEditorManager() {
        return editorMgr;
    }

    /**
     * Answer the perspective presentation.
     */
01722     public PerspectiveHelper getPerspectivePresentation() {
        if (getActivePerspective() != null)
            return getActivePerspective().getPresentation();
        return null;
    }

    /**
     * Answer the editor presentation.
     */
01731     public EditorAreaHelper getEditorPresentation() {
        return editorPresentation;
    }

    /**
     * See IWorkbenchPage.
     */
01738     public IEditorPart[] getEditors() {
        final IEditorReference refs[] = getEditorReferences();
        final ArrayList result = new ArrayList(refs.length);
        Display d = getWorkbenchWindow().getShell().getDisplay();
        //Must be backward compatible.
        d.syncExec(new Runnable() {
            public void run() {
                for (int i = 0; i < refs.length; i++) {
                    IWorkbenchPart part = refs[i].getPart(true);
                    if (part != null)
                        result.add(part);
                }
            }
        });
        final IEditorPart editors[] = new IEditorPart[result.size()];
        return (IEditorPart[]) result.toArray(editors);
    }

01756     public IEditorPart[] getDirtyEditors() {
        return getEditorManager().getDirtyEditors();
    }
      
    public ISaveablePart[] getDirtyParts() {
        List result = new ArrayList(3);
        IWorkbenchPartReference[] allParts = getAllParts();
        for (int i = 0; i < allParts.length; i++) {
            IWorkbenchPartReference reference = allParts[i];
            
            IWorkbenchPart part = reference.getPart(false);
            if (part != null && part instanceof ISaveablePart) {
                ISaveablePart saveable = (ISaveablePart)part;
                if (saveable.isDirty()) {
                    result.add(saveable);
                }
            }
        }
        
        return (ISaveablePart[]) result.toArray(new ISaveablePart[result.size()]);
    }
  

01779     public IEditorPart findEditor(IEditorInput input) {
        return getEditorManager().findEditor(input);
    }

    /**
     * See IWorkbenchPage.
     */
01786     public IEditorReference[] getEditorReferences() {
        return editorPresentation.getEditors();
    }

    /**
     * Returns the docked views.
     */
01793     public IViewReference[] getFastViews() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.getFastViews();
        else
            return new IViewReference[0];
    }

    /**
     * @see IWorkbenchPage
     */
01804     public IAdaptable getInput() {
        return input;
    }

    /**
     * Returns the page label. This is a combination of the page input and
     * active perspective.
     */
01812     public String getLabel() {
        String label = WorkbenchMessages.WorkbenchPage_UnknownLabel;
        if (input != null) {
            IWorkbenchAdapter adapter = (IWorkbenchAdapter) input
                    .getAdapter(IWorkbenchAdapter.class);
            if (adapter != null)
                label = adapter.getLabel(input);
        }
        Perspective persp = getActivePerspective();
        if (persp != null)
            label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,  label, persp.getDesc().getLabel());
        else if (deferredActivePersp != null)
            label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,label, deferredActivePersp.getLabel()); 
        return label;
    }

    /**
     * Returns the perspective.
     */
01831     public IPerspectiveDescriptor getPerspective() {
        if (deferredActivePersp != null)
            return deferredActivePersp;
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.getDesc();
        else
            return null;
    }

    /*
     * (non-Javadoc) Method declared on ISelectionService
     */
01844     public ISelection getSelection() {
        return selectionService.getSelection();
    }

    /*
     * (non-Javadoc) Method declared on ISelectionService
     */
01851     public ISelection getSelection(String partId) {
        return selectionService.getSelection(partId);
    }

    /**
     * Returns the ids of the parts to list in the Show In... prompter. This is
     * a List of Strings.
     */
01859     public ArrayList getShowInPartIds() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.getShowInPartIds();
        else
            return new ArrayList();
    }

    /**
     * The user successfully performed a Show In... action on the specified
     * part. Update the list of Show In items accordingly.
     */
01871     public void performedShowIn(String partId) {
        Perspective persp = getActivePerspective();
        if (persp != null) {
            persp.performedShowIn(partId);
        }
    }

    /**
     * Sorts the given collection of show in target part ids in MRU order.
     */
01881     public void sortShowInPartIds(ArrayList partIds) {
        final Perspective persp = getActivePerspective();
        if (persp != null) {
            Collections.sort(partIds, new Comparator() {
                public int compare(Object a, Object b) {
                    long ta = persp.getShowInTime((String) a);
                    long tb = persp.getShowInTime((String) b);
                    return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
                }
            });
        }
    }

    /**
     * Returns the unprotected window.
     */
01897     protected WorkbenchWindow getUnprotectedWindow() {
        return window;
    }

    /*
     * Returns the view factory.
     */
    public ViewFactory getViewFactory() {
        if (viewFactory == null) {
            viewFactory = new ViewFactory(this, WorkbenchPlugin.getDefault()
                    .getViewRegistry());
        }
        return viewFactory;
    }

    /**
     * See IWorkbenchPage.
     */
01915     public IViewReference[] getViewReferences() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.getViewReferences();
        else
            return new IViewReference[0];
    }

    /**
     * See IWorkbenchPage.
     */
01926     public IViewPart[] getViews() {
            return getViews(null, true);
    }
      
      /**
       * Returns all view parts in the specified perspective
       * 
       * @param persp the perspective
       * @return an array of view parts
       * @since 3.1
       */
01937       /*package*/IViewPart[] getViews(Perspective persp, boolean restore) {               
        if (persp == null)
                  persp = getActivePerspective();
            
        if (persp != null) {
            IViewReference refs[] = persp.getViewReferences();
            ArrayList parts = new ArrayList(refs.length);
            for (int i = 0; i < refs.length; i++) {
                IWorkbenchPart part = refs[i].getPart(restore);
                if (part != null)
                    parts.add(part);
            }
            IViewPart[] result = new IViewPart[parts.size()];
            return (IViewPart[]) parts.toArray(result);
        }
        return new IViewPart[0];
    }

    /**
     * See IWorkbenchPage.
     */
01958     public IWorkbenchWindow getWorkbenchWindow() {
        return window;
    }

    /**
     * Implements IWorkbenchPage
     * 
     * @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
     * @since 2.0
     * @deprecated individual views should store a working set if needed
     */
01969     public IWorkingSet getWorkingSet() {
        return workingSet;
    }

    /**
     * @see IWorkbenchPage
     */
01976     public void hideActionSet(String actionSetID) {
        Perspective persp = getActivePerspective();
        if (persp != null) {
            persp.removeActionSet(actionSetID);
            window.updateActionSets();
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_ACTION_SET_HIDE);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
     */
01991     public void hideView(IViewReference ref) {
        
        // Sanity check.
        if (ref == null)
            return;

        Perspective persp = getActivePerspective();
        if (persp == null)
            return;

        IViewPart view = ref.getView(false);
        if (view != null) {

            if (!certifyPart(view)) {
                return;
            }
            
            // Confirm.
            if (!persp.canCloseView(view))
                return;
        }
        
        // Notify interested listeners before the hide
        window.firePerspectiveChanged(this, persp.getDesc(), ref,
                CHANGE_VIEW_HIDE);

        PartPane pane = getPane(ref);
        pane.setInLayout(false);
        
        updateActivePart();
        
        // Hide the part.
        persp.hideView(ref);

        // Notify interested listeners after the hide
        window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
    }

    /* package */void refreshActiveView() {
        updateActivePart();
    }

    /**
     * See IPerspective
     */
02036     public void hideView(IViewPart view) {
        hideView((IViewReference)getReference(view));
    }

    /**
     * Initialize the page.
     * 
     * @param w
     *            the parent window
     * @param layoutID
     *            may be <code>null</code> if restoring from file
     * @param input
     *            the page input
     */
02050     private void init(WorkbenchWindow w, String layoutID, IAdaptable input)
            throws WorkbenchException {
        // Save args.
        this.window = w;
        this.input = input;

        // Create presentation.
        createClientComposite();
        editorPresentation = new EditorAreaHelper(this);
        editorMgr = new EditorManager(window, this, editorPresentation);

            // add this page as a client to be notified when the UI has re-orded perspectives 
            // so that the order can be properly maintained in the receiver.
            // E.g. a UI might support drag-and-drop and will need to make this known to ensure
            // #saveState and #restoreState do not lose this re-ordering
            w.addPerspectiveReorderListener(new IReorderListener() {
                  public void reorder(Object perspective, int newLoc) {
                        perspList.reorder((IPerspectiveDescriptor)perspective, newLoc);                     
                  }
            });
            
        // Get perspective descriptor.
        if (layoutID != null) {
            PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
                    .getDefault().getPerspectiveRegistry()
                    .findPerspectiveWithId(layoutID);
            if (desc == null)
                throw new WorkbenchException(
                        NLS.bind(WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,layoutID )); 
            Perspective persp = createPerspective(desc);
            if (persp == null)
                return;
            perspList.setActive(persp);
            window.firePerspectiveActivated(this, desc);
        }
        
        getExtensionTracker()
                .registerHandler(
                        perspectiveChangeHandler,
                        ExtensionTracker
                                .createExtensionPointFilter(getPerspectiveExtensionPoint()));
    }

    /**
     * See IWorkbenchPage.
     */
02096     public boolean isPartVisible(IWorkbenchPart part) {
      PartPane pane = getPane(part);
      return pane != null && pane.getVisible();
    }
    
    /**
     * See IWorkbenchPage.
     */
02104     public boolean isEditorAreaVisible() {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return false;
        return persp.isEditorAreaVisible();
    }

    /**
     * Returns whether the view is fast.
     */
02114     public boolean isFastView(IViewReference ref) {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.isFastView(ref);
        else
            return false;
    }
    
    /**
     * Return whether the view is closeable or not.
     * 
     * @param ref the view reference to check.  Must not be <code>null</code>.
     * @return true if the part is closeable.
     * @since 3.1.1
     */
02129     public boolean isCloseable(IViewReference ref) {
            Perspective persp = getActivePerspective();
            if (persp != null)
                  return persp.isCloseable(ref);
            return false;
      }

    /**
     * Return whether the view is moveable or not.
     * 
     * @param ref the view reference to check.  Must not be <code>null</code>.
     * @return true if the part is moveable.
     * @since 3.1.1
     */
02143     public boolean isMoveable(IViewReference ref) {
            Perspective persp = getActivePerspective();
            if (persp != null)
                  return persp.isMoveable(ref);
            return false;
      }

    /**
     * Returns whether the layout of the active
     * perspective is fixed.
     */
02154     public boolean isFixedLayout() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.isFixedLayout();
        else
            return false;
    }

    /**
     * Return the active fast view or null if there are no fast views or if
     * there are all minimized.
     */
02166     public IViewReference getActiveFastView() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            return persp.getActiveFastView();
        else
            return null;
    }

    /**
     * Return true if the perspective has a dirty editor.
     */
02177     protected boolean isSaveNeeded() {
        return getEditorManager().isSaveAllNeeded();
    }

    /**
     * Returns whether the page is zoomed.
     */
02184     public boolean isZoomed() {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return false;
        if (persp.getPresentation() == null)
            return false;
        return persp.getPresentation().isZoomed();
    }

    /**
     * This method is called when the page is activated.
     */
02196     protected void onActivate() {
        composite.setVisible(true);
        Perspective persp = getActivePerspective();

        if (persp != null) {
            persp.onActivate();
            updateVisibility(null, persp);
        }
    }

    /**
     * This method is called when the page is deactivated.
     */
02209     protected void onDeactivate() {
      makeActiveEditor(null);
        makeActive(null);
        if (getActivePerspective() != null)
            getActivePerspective().onDeactivate();
        composite.setVisible(false);
    }

    /**
     * See IWorkbenchPage.
     */
02220     public void reuseEditor(IReusableEditor editor, IEditorInput input) {
        
        // Rather than calling editor.setInput on the editor directly, we do it through the part reference.
        // This case lets us detect badly behaved editors that are not firing a PROP_INPUT event in response
        // to the input change... but if all editors obeyed their API contract, the "else" branch would be
        // sufficient.
        IWorkbenchPartReference ref = getReference(editor);
        if (ref instanceof EditorReference) {
            EditorReference editorRef = (EditorReference) ref;
            
            editorRef.setInput(input);
        } else {
            editor.setInput(input);
        }
    }

    /**
     * See IWorkbenchPage.
     */
02239     public IEditorPart openEditor(IEditorInput input, String editorID)
            throws PartInitException {
        return openEditor(input, editorID, true, MATCH_INPUT);
    }

    /**
     * See IWorkbenchPage.
     */
02247     public IEditorPart openEditor(IEditorInput input, String editorID,
                  boolean activate) throws PartInitException {
            return openEditor(input, editorID, activate, MATCH_INPUT);
    }
      
    /**
       * Opens an editor, optionally finding an existing one with the same input and/or id,
       * and optionally activating the resulting editor.
       * Shows the busy cursor while opening.
       * 
       * @since 3.1
       */
02259     public IEditorPart openEditor(final IEditorInput input,
            final String editorID, final boolean activate, final int matchFlags)
            throws PartInitException {
        if (input == null || editorID == null) {
            throw new IllegalArgumentException();
        }

        final IEditorPart result[] = new IEditorPart[1];
        final PartInitException ex[] = new PartInitException[1];
        BusyIndicator.showWhile(window.getWorkbench().getDisplay(),
                new Runnable() {
                    public void run() {
                        try {
                            result[0] = busyOpenEditor(input, editorID,
                                    activate, matchFlags);
                        } catch (PartInitException e) {
                            ex[0] = e;
                        }
                    }
                });
        if (ex[0] != null)
            throw ex[0];
        return result[0];
    }

    /**
     * @see #openEditor(IEditorInput, String, boolean, int)
       */
02287     private IEditorPart busyOpenEditor(IEditorInput input, String editorID,
            boolean activate, int matchFlags) throws PartInitException {

        final Workbench workbench = (Workbench) getWorkbenchWindow()
                .getWorkbench();
        workbench.largeUpdateStart();

        try {
            return busyOpenEditorBatched(input, editorID, activate, matchFlags);

        } finally {
            workbench.largeUpdateEnd();
        }
    }

    /**
     * Do not call this method.  Use <code>busyOpenEditor</code>.
     * 
     * @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
     */
02307     private IEditorPart busyOpenEditorBatched(IEditorInput input,
            String editorID, boolean activate,  int matchFlags) throws PartInitException {

        // If an editor already exists for the input, use it.
            IEditorPart editor = getEditorManager().findEditor(editorID, input, matchFlags);
        if (editor != null) {
            if (IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID.equals(editorID)) {
                if (editor.isDirty()) {
                    MessageDialog dialog = new MessageDialog(
                            getWorkbenchWindow().getShell(),
                            WorkbenchMessages.Save, 
                            null, // accept the default window icon
                            NLS.bind(WorkbenchMessages.WorkbenchPage_editorAlreadyOpenedMsg,  input.getName()), 
                            MessageDialog.QUESTION, new String[] {
                                    IDialogConstants.YES_LABEL,
                                    IDialogConstants.NO_LABEL,
                                    IDialogConstants.CANCEL_LABEL }, 0);
                    int saveFile = dialog.open();
                    if (saveFile == 0) {
                        try {
                            final IEditorPart editorToSave = editor;
                            getWorkbenchWindow().run(false, false,
                                    new IRunnableWithProgress() {
                                        public void run(IProgressMonitor monitor)
                                                throws InvocationTargetException,
                                                InterruptedException {
                                            editorToSave.doSave(monitor);
                                        }
                                    });
                        } catch (InvocationTargetException e) {
                            throw (RuntimeException) e.getTargetException();
                        } catch (InterruptedException e) {
                            return null;
                        }
                    } else if (saveFile == 2) {
                        return null;
                    }
                }
            } else {
                // do the IShowEditorInput notification before showing the editor
                // to reduce flicker
                if (editor instanceof IShowEditorInput) {
                    ((IShowEditorInput) editor).showEditorInput(input);
                }
                showEditor(activate, editor);
                return editor;
            }
        }


        // Otherwise, create a new one. This may cause the new editor to
        // become the visible (i.e top) editor.
        IEditorReference ref = null;
        ref = getEditorManager().openEditor(editorID, input, true);
        if (ref != null) {
            editor = ref.getEditor(true);
        }

        if (editor != null) {
            setEditorAreaVisible(true);
            if (activate) {
                if (editor instanceof MultiEditor)
                    activate(((MultiEditor) editor).getActiveEditor());
                else
                    activate(editor);
            } else {
                bringToTop(editor);
            }
            window.firePerspectiveChanged(this, getPerspective(), ref,
                    CHANGE_EDITOR_OPEN);
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_EDITOR_OPEN);
        }

        return editor;
    }

    private void showEditor(boolean activate, IEditorPart editor) {
        zoomOutIfNecessary(editor);
        setEditorAreaVisible(true);
        if (activate)
            activate(editor);
        else
            bringToTop(editor);
    }

    /**
     * See IWorkbenchPage.
     */
02396     public boolean isEditorPinned(IEditorPart editor) {
      WorkbenchPartReference ref = (WorkbenchPartReference)getReference(editor); 
        return ref != null && ref.isPinned();
    }
    
    /**
     * Returns whether changes to a part will affect zoom. There are a few
     * conditions for this .. - we are zoomed. - the part is contained in the
     * main window. - the part is not the zoom part - the part is not a fast
     * view - the part and the zoom part are not in the same editor workbook
     */
02407     private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
        PartPane pane = ((WorkbenchPartReference) ref).getPane();
        if (pane instanceof MultiEditorInnerPane)
            pane = ((MultiEditorInnerPane) pane).getParentPane();
        return getActivePerspective().getPresentation().partChangeAffectsZoom(
                pane);
    }

    /**
     * Removes a fast view.
     */
02418     public void removeFastView(IViewReference ref) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;

        if (!persp.isFastView(ref)) {
            return;
        }

        // Do real work.
        persp.removeFastView(ref);

        // Notify listeners.
        window.firePerspectiveChanged(this, getPerspective(), ref,
                CHANGE_FAST_VIEW_REMOVE);
        window.firePerspectiveChanged(this, getPerspective(),
                CHANGE_FAST_VIEW_REMOVE);
    }

    /**
     * Removes an IPartListener from the part service.
     */
02440     public void removePartListener(IPartListener l) {
        partList.getPartService().removePartListener(l);
    }

    /**
     * Removes an IPartListener from the part service.
     */
02447     public void removePartListener(IPartListener2 l) {
        partList.getPartService().removePartListener(l);
    }

    /**
     * Implements IWorkbenchPage
     * 
     * @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
     * @since 2.0
     * @deprecated individual views should store a working set if needed and
     *             register a property change listener directly with the
     *             working set manager to receive notification when the view
     *             working set is removed.
     */
02461     public void removePropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.remove(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
02468     public void removeSelectionListener(ISelectionListener listener) {
        selectionService.removeSelectionListener(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
02475     public void removeSelectionListener(String partId,
            ISelectionListener listener) {
        selectionService.removeSelectionListener(partId, listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
02483     public void removePostSelectionListener(ISelectionListener listener) {
        selectionService.removePostSelectionListener(listener);
    }

    /*
     * (non-Javadoc) Method declared on ISelectionListener.
     */
02490     public void removePostSelectionListener(String partId,
            ISelectionListener listener) {
        selectionService.removePostSelectionListener(partId, listener);
    }

    /**
     * This method is called when a part is activated by clicking within it. In
     * response, the part, the pane, and all of its actions will be activated.
     * 
     * In the current design this method is invoked by the part pane when the
     * pane, the part, or any children gain focus.
     */
02502     public void requestActivation(IWorkbenchPart part) {        
        // Sanity check.
        if (!certifyPart(part))
            return;

        if (part instanceof MultiEditor) {
            part = ((MultiEditor) part).getActiveEditor();
        }

        // Real work.
        setActivePart(part);
    }

    /**
     * Resets the layout for the perspective. The active part in the old layout
     * is activated in the new layout for consistent user context.
     */
02519     public void resetPerspective() {
        // Run op in busy cursor.
        // Use set redraw to eliminate the "flash" that can occur in the
        // coolbar as the perspective is reset.
        CoolBarManager mgr = window.getCoolBarManager();
        try {
            mgr.getControl().setRedraw(false);
            BusyIndicator.showWhile(null, new Runnable() {
                public void run() {
                    busyResetPerspective();
                }
            });
        } finally {
            mgr.getControl().setRedraw(true);
        }
    }

    /**
     * Restore this page from the memento and ensure that the active
     * perspective is equals the active descriptor otherwise create a new
     * perspective for that descriptor. If activeDescriptor is null active the
     * old perspective.
     */
02542     public IStatus restoreState(IMemento memento,
            IPerspectiveDescriptor activeDescriptor) {
        
        deferUpdates(true);
        try {
            // Restore working set
            String pageName = memento.getString(IWorkbenchConstants.TAG_LABEL);
            
            String label = null; // debugging only
            if (UIStats.isDebugging(UIStats.RESTORE_WORKBENCH)) {
                label = pageName == null ? "" : "::" + pageName; //$NON-NLS-1$ //$NON-NLS-2$
            }
    
            try {
                UIStats.start(UIStats.RESTORE_WORKBENCH, "WorkbenchPage" + label); //$NON-NLS-1$
                if (pageName == null)
                    pageName = ""; //$NON-NLS-1$
                MultiStatus result = new MultiStatus(
                        PlatformUI.PLUGIN_ID,
                        IStatus.OK,
                        NLS.bind(WorkbenchMessages.WorkbenchPage_unableToRestorePerspective, pageName ), 
                        null);
    
                String workingSetName = memento
                        .getString(IWorkbenchConstants.TAG_WORKING_SET);
                if (workingSetName != null) {
                    WorkingSetManager workingSetManager = (WorkingSetManager) getWorkbenchWindow()
                            .getWorkbench().getWorkingSetManager();
                    setWorkingSet(workingSetManager.getWorkingSet(workingSetName));
                }
    
                // Restore editor manager.
                IMemento childMem = memento
                        .getChild(IWorkbenchConstants.TAG_EDITORS);
                result.merge(getEditorManager().restoreState(childMem));
    
                childMem = memento.getChild(IWorkbenchConstants.TAG_VIEWS);
                if (childMem != null)
                    result.merge(getViewFactory().restoreState(childMem));
    
                // Get persp block.
                childMem = memento.getChild(IWorkbenchConstants.TAG_PERSPECTIVES);
                String activePartID = childMem
                        .getString(IWorkbenchConstants.TAG_ACTIVE_PART);
                String activePartSecondaryID = null;
                if (activePartID != null) {
                    activePartSecondaryID = ViewFactory
                            .extractSecondaryId(activePartID);
                    if (activePartSecondaryID != null) {
                        activePartID = ViewFactory.extractPrimaryId(activePartID);
                    }
                }
                String activePerspectiveID = childMem
                        .getString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE);
    
                // Restore perspectives.
                IMemento perspMems[] = childMem
                        .getChildren(IWorkbenchConstants.TAG_PERSPECTIVE);
                Perspective activePerspective = null;
                for (int i = 0; i < perspMems.length; i++) {
                    try {
                        Perspective persp = new Perspective(null, this);
                        result.merge(persp.restoreState(perspMems[i]));
                        IPerspectiveDescriptor desc = persp.getDesc();
                        if (desc.equals(activeDescriptor))
                            activePerspective = persp;
                        else if ((activePerspective == null)
                                && desc.getId().equals(activePerspectiveID))
                            activePerspective = persp;
                        perspList.add(persp);
                        window.firePerspectiveOpened(this, desc);
                    } catch (WorkbenchException e) {
                    }
                }
                boolean restoreActivePerspective = false;
                if (activeDescriptor == null)
                    restoreActivePerspective = true;
                else if (activePerspective != null
                        && activePerspective.getDesc().equals(activeDescriptor)) {
                    restoreActivePerspective = true;
                } else {
                    restoreActivePerspective = false;
                    activePerspective = createPerspective((PerspectiveDescriptor) activeDescriptor);
                    if (activePerspective == null) {
                        result
                                .merge(new Status(
                                        IStatus.ERROR,
                                        PlatformUI.PLUGIN_ID,
                                        0,
                                        NLS.bind(WorkbenchMessages.Workbench_showPerspectiveError, activeDescriptor.getId() ), 
                                        null));
                    }
                }
    
                perspList.setActive(activePerspective);
    
                // Make sure we have a valid perspective to work with,
                // otherwise return.
                activePerspective = perspList.getActive();
                if (activePerspective == null) {
                    activePerspective = perspList.getNextActive();
                    perspList.setActive(activePerspective);
                    result.merge(activePerspective.restoreState());
                }
                if (activePerspective != null && restoreActivePerspective)
                    result.merge(activePerspective.restoreState());
    
                if (activePerspective != null) {
                    window.firePerspectiveActivated(this, activePerspective
                            .getDesc());
    
                    // Restore active part.
                    if (activePartID != null) {
                        IViewReference ref = activePerspective.findView(
                                activePartID, activePartSecondaryID);
                        
                        if (ref != null) {
                            activationList.setActive(ref);
                        }
                    }
                }
    
                childMem = memento
                        .getChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY);
                if (childMem != null)
                    navigationHistory.restoreState(childMem);
                else if (getActiveEditor() != null)
                    navigationHistory.markEditor(getActiveEditor());
                
                IMemento stickyState = memento
                                    .getChild(IWorkbenchConstants.TAG_STICKY_STATE);
                        // restore the sticky activation state

                        if (stickyState != null) {
                              IMemento[] stickyPerspMems = stickyState
                                          .getChildren(IWorkbenchConstants.TAG_PERSPECTIVE);
                              for (int i = 0; i < stickyPerspMems.length; i++) {
                                    String perspectiveId = stickyPerspMems[i].getID();
                                    Set viewState = new HashSet(7);
                                    stickyPerspectives.put(perspectiveId, viewState);
                                    IMemento[] viewStateMementos = stickyPerspMems[i]
                                                .getChildren(IWorkbenchConstants.TAG_VIEW);
                                    for (int j = 0; j < viewStateMementos.length; j++) {
                                          viewState.add(viewStateMementos[j].getID());
                                    }
                              }

                        }                
                return result;
            } finally {
                  String blame = activeDescriptor == null ? pageName : activeDescriptor.getId();
                UIStats.end(UIStats.RESTORE_WORKBENCH, blame, "WorkbenchPage" + label); //$NON-NLS-1$
            }
        } finally {
            deferUpdates(false);
        }
    }

    /**
     * See IWorkbenchPage
     */
02703     public boolean saveAllEditors(boolean confirm) {
        return getEditorManager().saveAll(confirm, false);
    }

    /*
     * Saves the workbench part.
     */
    protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
            boolean confirm) {
        // Do not certify part do allow editors inside a multipageeditor to
        // call this.
        return getEditorManager().savePart(saveable, part, confirm);
    }

    /**
     * Saves an editors in the workbench. If <code>confirm</code> is <code>true</code>
     * the user is prompted to confirm the command.
     * 
     * @param confirm
     *            if user confirmation should be sought
     * @return <code>true</code> if the command succeeded, or <code>false</code>
     *         if the user cancels the command
     */
02726     public boolean saveEditor(IEditorPart editor, boolean confirm) {
        return savePart(editor, editor, confirm);
    }

    /**
     * Saves the current perspective.
     */
02733     public void savePerspective() {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;

        // Always unzoom.
        if (isZoomed())
            zoomOut();

        persp.saveDesc();
    }

    /**
     * Saves the perspective.
     */
02748     public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;
        IPerspectiveDescriptor oldDesc = persp.getDesc();

        // Always unzoom.
        if (isZoomed())
            zoomOut();

        persp.saveDescAs(newDesc);
        window.firePerspectiveSavedAs(this, oldDesc, newDesc);
    }

    /**
     * Save the state of the page.
     */
02765     public IStatus saveState(IMemento memento) {
        // We must unzoom to get correct layout.
        if (isZoomed())
            zoomOut();

        MultiStatus result = new MultiStatus(
                PlatformUI.PLUGIN_ID,
                IStatus.OK,
                NLS.bind(WorkbenchMessages.WorkbenchPage_unableToSavePerspective, getLabel()), 
                null);

        // Save editor manager.
        IMemento childMem = memento
                .createChild(IWorkbenchConstants.TAG_EDITORS);
        result.merge(editorMgr.saveState(childMem));

        childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
        result.merge(getViewFactory().saveState(childMem));

        // Create persp block.
        childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
        if (getPerspective() != null)
            childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
                    getPerspective().getId());
        if (getActivePart() != null) {
            if (getActivePart() instanceof IViewPart) {
                IViewReference ref = (IViewReference) getReference(getActivePart());
                if (ref != null) {
                    childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
                            ViewFactory.getKey(ref));
                }
            } else {
                childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
                        getActivePart().getSite().getId());
            }
        }

        // Save each perspective in opened order
        Iterator itr = perspList.iterator();
        while (itr.hasNext()) {
            Perspective persp = (Perspective) itr.next();
            IMemento gChildMem = childMem
                    .createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
            result.merge(persp.saveState(gChildMem));
        }
        // Save working set if set
        if (workingSet != null) {
            memento.putString(IWorkbenchConstants.TAG_WORKING_SET, workingSet
                    .getName());
        }

        navigationHistory.saveState(memento
                .createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
        
        IMemento stickyState = memento
                        .createChild(IWorkbenchConstants.TAG_STICKY_STATE);
            // save the sticky activation state
            itr = stickyPerspectives.entrySet().iterator();
            while (itr.hasNext()) {
                  Map.Entry entry = (Map.Entry) itr.next();
                  String perspectiveId = (String) entry.getKey();
                  Set activatedViewIds = (Set) entry.getValue();
                  IMemento perspectiveState = stickyState.createChild(
                              IWorkbenchConstants.TAG_PERSPECTIVE, perspectiveId);
                  for (Iterator i = activatedViewIds.iterator(); i.hasNext();) {
                        String viewId = (String) i.next();
                        perspectiveState.createChild(IWorkbenchConstants.TAG_VIEW,
                                    viewId);
                  }
            }
            return result;
    }
    
    private String getId(IWorkbenchPart part) {
        return getId(getReference(part));
    }
    
    private String getId(IWorkbenchPartReference ref) {
        if (ref == null) {
            return "null"; //$NON-NLS-1$
        } return ref.getId();
    }

    /**
     * Sets the active part.
     */
02851     private void setActivePart(IWorkbenchPart newPart) {
        // Optimize it.
        if (getActivePart() == newPart) {
            return;
        }
        
        if (partBeingActivated != null) {
            if (partBeingActivated.getPart(false) != newPart) {
                WorkbenchPlugin.log(new RuntimeException(NLS.bind(
                        "WARNING: Prevented recursive attempt to activate part {0} while still in the middle of activating part {1}", //$NON-NLS-1$
                        getId(newPart), getId(partBeingActivated))));
            }
            return;
        }

        //No need to change the history if the active editor is becoming the
        // active part
        String label = null; // debugging only
        if (UIStats.isDebugging(UIStats.ACTIVATE_PART)) {
            label = newPart != null ? newPart.getTitle() : "none"; //$NON-NLS-1$
        }
        try {
            IWorkbenchPartReference partref = getReference(newPart);
            IWorkbenchPartReference realPartRef = null;
                  if (newPart != null) {
                        IWorkbenchPartSite site = newPart.getSite();
                        if (site instanceof PartSite) {
                              realPartRef = ((PartSite) site).getPane()
                                          .getPartReference();
                        }
                  }

            partBeingActivated = realPartRef;
            
            UIStats.start(UIStats.ACTIVATE_PART, label);
            // Notify perspective. It may deactivate fast view.
            Perspective persp = getActivePerspective();
            if (persp != null)
                persp.partActivated(newPart);

            // Deactivate old part
            IWorkbenchPart oldPart = getActivePart();
            if (oldPart != null) {
                deactivatePart(oldPart);
            }
            
            // Set active part.
            if (newPart != null) {
                activationList.setActive(newPart);
                if (newPart instanceof IEditorPart) {
                              // IEditorReference ref = (IEditorReference)
                              // getReference(newPart);
                              makeActiveEditor((IEditorReference)realPartRef);
                        }
            }
            activatePart(newPart);
            
            actionSwitcher.updateActivePart(newPart);
            
            partList.setActivePart(partref);
        } finally {
            partBeingActivated = null;
            Object blame = newPart == null ? (Object)this : newPart;
            UIStats.end(UIStats.ACTIVATE_PART, blame, label);
        }
    }

    /**
     * See IWorkbenchPage.
     */
02921     public void setEditorAreaVisible(boolean showEditorArea) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;
        if (showEditorArea == persp.isEditorAreaVisible())
            return;
        // If parts change always update zoom.
        if (isZoomed())
            zoomOut();
        // Update editor area visibility.
        if (showEditorArea) {
            persp.showEditorArea();
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_EDITOR_AREA_SHOW);
        } else {
            persp.hideEditorArea();
            updateActivePart();
            window.firePerspectiveChanged(this, getPerspective(),
                    CHANGE_EDITOR_AREA_HIDE);
        }
    }

    /**
     * Sets the layout of the page. Assumes the new perspective is not null.
     * Keeps the active part if possible. Updates the window menubar and
     * toolbar if necessary.
     */
02948     private void setPerspective(Perspective newPersp) {
        // Don't do anything if already active layout
        Perspective oldPersp = getActivePerspective();
        if (oldPersp == newPersp)
            return;

        window.largeUpdateStart();
        try {
              
              if (newPersp != null) {
                  IStatus status = newPersp.restoreState();
                  if (status.getSeverity() != IStatus.OK) {
                      String title = WorkbenchMessages.WorkbenchPage_problemRestoringTitle; 
                      String msg = WorkbenchMessages.WorkbenchPage_errorReadingState;
                      ErrorDialog.openError(getWorkbenchWindow().getShell(), title,
                              msg, status);
                  }
              }
      
      
              // Deactivate the old layout
              if (oldPersp != null) {
                  oldPersp.onDeactivate();
                
                // Notify listeners of deactivation
                window.firePerspectiveDeactivated(this, oldPersp.getDesc());
              }
      
              // Activate the new layout
              perspList.setActive(newPersp);
              if (newPersp != null) {
                  newPersp.onActivate();
      
                  // Notify listeners of activation
                  window.firePerspectiveActivated(this, newPersp.getDesc());
              }
      
              updateVisibility(oldPersp, newPersp);
      
            // Update the window
            window.updateActionSets();

              if (newPersp != null && oldPersp != null) {
                        Set activatedStickyViewsInThisPerspective = (Set) stickyPerspectives.get(newPersp.getDesc().getId());
                        if (activatedStickyViewsInThisPerspective == null) {
                              activatedStickyViewsInThisPerspective = new HashSet(7);
                              stickyPerspectives.put(newPersp.getDesc().getId(), activatedStickyViewsInThisPerspective);
                        }
                  
                IViewRegistry viewReg = WorkbenchPlugin.getDefault()
                        .getViewRegistry();
                IStickyViewDescriptor[] stickyDescs = viewReg.getStickyViews();
                for (int i = 0; i < stickyDescs.length; i++) {
                    final String viewId = stickyDescs[i].getId();
                              try {
                        // show a sticky view if it was in the last perspective and hasn't already been activated in this one
                        if (oldPersp.findView(viewId) != null
                                                && !activatedStickyViewsInThisPerspective
                                                            .contains(viewId)) {
                                          showView(viewId, null,
                                                      IWorkbenchPage.VIEW_CREATE);
                                          activatedStickyViewsInThisPerspective.add(viewId);
                                    }
                    } catch (PartInitException e) {
                        WorkbenchPlugin
                                .log(
                                        "Could not open view :" + viewId, new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IStatus.ERROR, "Could not open view :" + viewId, e)); //$NON-NLS-1$ //$NON-NLS-2$
                    }
                }
            }
        } finally {
            window.largeUpdateEnd();
            if (newPersp == null)
                  return;
            IPerspectiveDescriptor desc = newPersp.getDesc();
            if (desc == null)
                  return;
            if (dirtyPerspectives.remove(desc.getId())) {
                  suggestReset();
            }
        }
    }

    void perspectiveActionSetChanged(Perspective perspective, IActionSetDescriptor descriptor, int changeType) {
        if (perspective == getActivePerspective()) {
            actionSets.change(descriptor, changeType);
        }
    }
    
      /*
     * Update visibility state of all views.
     */
    private void updateVisibility(Perspective oldPersp, Perspective newPersp) {
        
        // Flag all parts in the old perspective
        IWorkbenchPartReference[] oldRefs = new IWorkbenchPartReference[0];
        if (oldPersp != null) {
            oldRefs = oldPersp.getViewReferences();
            for (int i = 0; i < oldRefs.length; i++) {
                PartPane pane = ((WorkbenchPartReference) oldRefs[i]).getPane();
                pane.setInLayout(false);
            }
        }
        
        PerspectiveHelper pres = null;
        // Make parts in the new perspective visible
        if (newPersp != null) {
            pres = newPersp.getPresentation();
            IWorkbenchPartReference[] newRefs = newPersp.getViewReferences();
            for (int i = 0; i < newRefs.length; i++) {
                WorkbenchPartReference ref = (WorkbenchPartReference)newRefs[i];
                PartPane pane = ref.getPane();
                if (pres.isPartVisible(ref)) {
                    pane.setVisible(true);
                    activationList.bringToTop(ref);
                }

                pane.setInLayout(true);
            }
        }

        updateActivePart();

        // Hide any parts in the old perspective that are no longer visible
        for (int i = 0; i < oldRefs.length; i++) {
            WorkbenchPartReference ref = (WorkbenchPartReference)oldRefs[i];
               
            PartPane pane = ref.getPane();
            if (pres == null || !pres.isPartVisible(ref)) {
                pane.setVisible(false);
            }
        }
    }

    /**
     * Sets the perspective.
     * 
     * @param desc
     *            identifies the new perspective.
     */
03088     public void setPerspective(final IPerspectiveDescriptor desc) {
      if (Util.equals(getPerspective(), desc)) {
            return;
      }
        // Going from multiple to single rows can make the coolbar
        // and its adjacent views appear jumpy as perspectives are
        // switched. Turn off redraw to help with this.
        CoolBarManager mgr = window.getCoolBarManager();
        try {
            mgr.getControl().setRedraw(false);
            getClientComposite().setRedraw(false);
            // Run op in busy cursor.
            BusyIndicator.showWhile(null, new Runnable() {
                public void run() {
                    busySetPerspective(desc);
                }
            });
        } finally {
            getClientComposite().setRedraw(true);
            mgr.getControl().setRedraw(true);
            IWorkbenchPart part = getActivePart();
            if (part != null)
                part.setFocus();
        }
    }
    
    public IWorkbenchPartFactory getPartFactory() {
      return partFactory;
    }

    /**
     * Restore the toolbar layout for the active perspective.
     */
03121     protected void resetToolBarLayout() {
        window.getCoolBarManager().resetItemOrder();
    }

    /**
     * Sets the active working set for the workbench page. Notifies property
     * change listener about the change.
     * 
     * @param newWorkingSet
     *            the active working set for the page. May be null.
     * @since 2.0
     * @deprecated individual views should store a working set if needed
     */
03134     public void setWorkingSet(IWorkingSet newWorkingSet) {
        IWorkingSet oldWorkingSet = workingSet;

        workingSet = newWorkingSet;
        if (oldWorkingSet != newWorkingSet) {
            firePropertyChange(CHANGE_WORKING_SET_REPLACE, oldWorkingSet,
                    newWorkingSet);
        }
        if (newWorkingSet != null) {
            WorkbenchPlugin.getDefault().getWorkingSetManager()
                    .addPropertyChangeListener(propertyChangeListener);
        } else {
            WorkbenchPlugin.getDefault().getWorkingSetManager()
                    .removePropertyChangeListener(propertyChangeListener);
        }
    }

    /**
     * @see IWorkbenchPage
     */
03154     public void showActionSet(String actionSetID) {
        Perspective persp = getActivePerspective();
        if (persp != null) {
            ActionSetRegistry reg = WorkbenchPlugin.getDefault()
                 .getActionSetRegistry();
            
            IActionSetDescriptor desc = reg.findActionSet(actionSetID);
            if (desc != null) {
                persp.addActionSet(desc);
                window.updateActionSets();
                window.firePerspectiveChanged(this, getPerspective(),
                        CHANGE_ACTION_SET_SHOW);
            }
        }
    }

    /**
     * See IWorkbenchPage.
     */
03173     public IViewPart showView(String viewID) throws PartInitException {
        return showView(viewID, null, VIEW_ACTIVATE);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String,
     *      java.lang.String, int)
     */
    public IViewPart showView(final String viewID, final String secondaryID,
            final int mode) throws PartInitException {

        if (secondaryID != null) {
            if (secondaryID.length() == 0
                    || secondaryID.indexOf(ViewFactory.ID_SEP) != -1)
                throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalSecondaryId); 
        }
        if (!certifyMode(mode))
            throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalViewMode);

        // Run op in busy cursor.
        final Object[] result = new Object[1];
        BusyIndicator.showWhile(null, new Runnable() {
            public void run() {
                try {
                    result[0] = busyShowView(viewID, secondaryID, mode);
                } catch (PartInitException e) {
                    result[0] = e;
                }
            }
        });
        if (result[0] instanceof IViewPart)
            return (IViewPart) result[0];
        else if (result[0] instanceof PartInitException)
            throw (PartInitException) result[0];
        else
            throw new PartInitException(WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition); 
    }

    /**
     * @param mode the mode to test
     * @return whether the mode is recognized
     * @since 3.0
     */
03218     private boolean certifyMode(int mode) {
        switch (mode) {
        case VIEW_ACTIVATE:
        case VIEW_VISIBLE:
        case VIEW_CREATE:
            return true;
        default:
            return false;
        }
    }

    /**
     * Hides the active fast view. Has no effect if there is no fast view active.
     */
03232     public void hideFastView() {
        Perspective persp = getActivePerspective();
        if (persp != null) {
            IViewReference ref = persp.getActiveFastView();
            if (ref != null) {
                toggleFastView(ref);
            }
        }
    }

    /**
     * Toggles the visibility of a fast view. If the view is active it is
     * deactivated. Otherwise, it is activated.
     */
03246     public void toggleFastView(IViewReference ref) {
        Perspective persp = getActivePerspective();
        if (persp != null) {
            persp.toggleFastView(ref);
            // if the fast view has been deactivated
            if (ref != persp.getActiveFastView()) {
                IWorkbenchPart previouslyActive = activationList
                        .getPreviouslyActive();
                IEditorPart activeEditor = getActiveEditor();
                if (activeEditor != null
                        && previouslyActive instanceof IEditorPart)
                    setActivePart(activeEditor);
                else
                    setActivePart(previouslyActive);
            }
        }
    }

    /**
     * Sets the state of the given part.
     * 
     * @param ref part whose state should be modified (not null)
     * @param newState one of the IStackPresentationSite.STATE_* constants
     */
03270     public void setState(IWorkbenchPartReference ref, int newState) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return;

        PartPane pane = ((WorkbenchPartReference) ref).getPane();

        // If target part is detached fire the zoom event.  Note this doesn't 
        // actually cause any changes in size and is required to support 
        // intro state changes.  We may want to introduce the notion of a zoomed
        // (fullscreen) detached view at a later time.
        if (!pane.isDocked()) {
            pane.setZoomed(newState == IStackPresentationSite.STATE_MAXIMIZED);
            return;
        }

        if (ref instanceof IViewReference
                && persp.isFastView((IViewReference) ref)) {
            persp.setFastViewState(newState);
            return;
        }

        boolean wasZoomed = isZoomed();
        boolean isZoomed = newState == IStackPresentationSite.STATE_MAXIMIZED;
            
        // Update zoom status.
        if (wasZoomed && !isZoomed) {
            zoomOut();
        } else if (!wasZoomed && isZoomed) {
            persp.getPresentation().zoomIn(ref);
            activate(ref.getPart(true));
        }
      
        PartStack parent = ((PartStack)pane.getContainer());
        
        if (parent != null) {
            parent.setMinimized(newState == IStackPresentationSite.STATE_MINIMIZED);
        }
    }
    
    /**
     * Returns the maximized/minimized/restored state of the given part reference
     * 
     * @param ref part to query (not null)
     * @return one of the IStackPresentationSite.STATE_* constants
     */
03316     int getState(IWorkbenchPartReference ref) {
        Perspective persp = getActivePerspective();
        if (persp == null)
            return IStackPresentationSite.STATE_RESTORED;

        PartPane pane = ((WorkbenchPartReference) ref).getPane();
      
        if (ref instanceof IViewReference
                && persp.isFastView((IViewReference) ref)) {
            return persp.getFastViewState();
        }         
        
        PartStack parent = ((PartStack)pane.getContainer());
        
        if (parent != null) {
            return parent.getState();
        }
        
        return IStackPresentationSite.STATE_RESTORED;
    }
    
    /**
     * Zoom in on a part. If the part is already in zoom then zoom out.
     */
03340     public void toggleZoom(IWorkbenchPartReference ref) {
      int oldState = getState(ref);
      boolean shouldZoom = oldState != IStackPresentationSite.STATE_MAXIMIZED;
      int newState = shouldZoom ? IStackPresentationSite.STATE_MAXIMIZED : IStackPresentationSite.STATE_RESTORED;
      
      setState(ref, newState);
    }

    /**
     * updateActionBars method comment.
     */
03351     public void updateActionBars() {
        window.updateActionBars();
    }

    /**
     * Sets the tab list of this page's composite appropriately when a part is
     * activated.
     */
03359     private void updateTabList(IWorkbenchPart part) {
        PartSite site = (PartSite) part.getSite();
        PartPane pane = site.getPane();
        if (pane instanceof ViewPane) {
            ViewPane viewPane = (ViewPane) pane;
            Control[] tabList = viewPane.getTabList();
            if (!pane.isDocked()) {
                viewPane.getControl().getShell().setTabList(tabList);
            } else {
                getClientComposite().setTabList(tabList);
            }
        } else if (pane instanceof EditorPane) {
            EditorSashContainer ea = ((EditorPane) pane).getWorkbook()
                    .getEditorArea();
            ea.updateTabList();
            getClientComposite().setTabList(new Control[] { ea.getParent() });
        }
    }

    /**
     * Zooms out a zoomed in part.
     */
    /* package */
03382     void zoomOut() {
        Perspective persp = getActivePerspective();
        if (persp != null)
            persp.getPresentation().zoomOut();
    }

    /**
     * Zooms out a zoomed in part if it is necessary to do so for the user to
     * view the IWorkbenchPart that is the argument. Otherwise, does nothing.
     * 
     * @param part
     *            the part to be made viewable
     */
03395     private void zoomOutIfNecessary(IWorkbenchPart part) {
        if (isZoomed() && partChangeAffectsZoom(((PartSite)part.getSite()).getPartReference()))
            zoomOut();
    }

    /**
     * @see IPageLayout.
     */
03403     public int getEditorReuseThreshold() {
        IPreferenceStore store = WorkbenchPlugin.getDefault()
                .getPreferenceStore();
        return store.getInt(IPreferenceConstants.REUSE_EDITORS);
    }

    /**
     * @see IPageLayout.
     */
03412     public void setEditorReuseThreshold(int openEditors) {
    }

    /*
     * Returns the editors in activation order (oldest first).
     */
    public IEditorReference[] getSortedEditors() {
        return activationList.getEditors();
    }

    /**
     * @see IWorkbenchPage#getOpenPerspectives()
     */
03425     public IPerspectiveDescriptor[] getOpenPerspectives() {
        Perspective opened[] = perspList.getOpenedPerspectives();
        IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[opened.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = opened[i].getDesc();
        }
        return result;
    }
    
    /**
     * Return all open Perspective objects.
     * 
     * @return all open Perspective objects
     * @since 3.1
     */
03440     /*package*/Perspective [] getOpenInternalPerspectives() {
        return perspList.getOpenedPerspectives();
    }
      
    /**
     * Returns the perspectives in activation order (oldest first).
     * 
     * @return all open Perspective objects
     * @since 3.1
     */
03450     /*package*/Perspective [] getSortedInternalPerspectives() {
        return perspList.getSortedPerspectives();
    }
            
      /**
       * Checks perspectives in the order they were activiated
       * for the specfied part.  The first sorted perspective 
       * that contains the specified part is returned.
       * 
       * @param part specified part to search for
       * @return the first sorted perspespective containing the part
       * @since 3.1
       */
03463       /*package*/Perspective getFirstPerspectiveWithView(IViewPart part) {
            Perspective [] perspectives = perspList.getSortedPerspectives();
            for (int i=0; i<perspectives.length; i++)
                  if (perspectives[i].containsView(part))
                        return perspectives[i];
            // we should never get here
            return null;
      }

    /**
     * Returns the perspectives in activation order (oldest first).
     */
03475     public IPerspectiveDescriptor[] getSortedPerspectives() {
        Perspective sortedArray[] = perspList.getSortedPerspectives();
        IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[sortedArray.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = sortedArray[i].getDesc();
        }
        return result;
    }

    /*
     * Returns the parts in activation order (oldest first).
     */
    public IWorkbenchPartReference[] getSortedParts() {
        return activationList.getParts();
    }

    /**
     * Returns the reference to the given part, or <code>null</code> if it has no reference 
     * (i.e. it is not a top-level part in this workbench page).
     * 
     * @param part the part
     * @return the part's reference or <code>null</code> if the given part does not belong 
     * to this workbench page
     */
03499     public IWorkbenchPartReference getReference(IWorkbenchPart part) {
        if (part == null) {
            return null;
        }
        IWorkbenchPartSite site = part.getSite();
        if (!(site instanceof PartSite)) {
            return null;
        }
        PartSite partSite = ((PartSite) site);
        PartPane pane = partSite.getPane();
        if (pane instanceof MultiEditorInnerPane) {
            MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
            return innerPane.getParentPane().getPartReference();
        }
        return partSite.getPartReference();
    }

    private class ActivationList {
        //List of parts in the activation order (oldest first)
        List parts = new ArrayList();

        /*
         * Add/Move the active part to end of the list;
         */
        void setActive(IWorkbenchPart part) {
            if (parts.size() <= 0)
                        return;
                  IWorkbenchPartReference ref = getReference(part);
                  if (ref != null) {
                        if (ref == parts.get(parts.size() - 1))
                              return;
                        parts.remove(ref);
                        parts.add(ref);
                  }
        }
        
        /*
         * Ensures that the given part appears AFTER any other part in the same
         * container.
         */
        void bringToTop(IWorkbenchPartReference ref) {
            ILayoutContainer targetContainer = getContainer(ref);
            
            int newIndex = lastIndexOfContainer(targetContainer);
            if (ref == parts.get(newIndex))
                return;
            parts.remove(ref);
            parts.add(newIndex, ref);
        }
        
        /*
         * Returns the last (most recent) index of the given container in the activation list, or returns
         * -1 if the given container does not appear in the activation list.
         */
        int lastIndexOfContainer(ILayoutContainer container) {
            for (int i = parts.size() - 1; i >= 0; i--) {
                IWorkbenchPartReference ref = (IWorkbenchPartReference)parts.get(i);

                ILayoutContainer cnt = getContainer(ref);
                if (cnt == container) {
                    return i; 
                }
            }
            
            return -1;
        }

        /*
         * Add/Move the active part to end of the list;
         */
        void setActive(IWorkbenchPartReference ref) {
            setActive(ref.getPart(true));
        }

        /*
         * Add the active part to the beginning of the list.
         */
        void add(IWorkbenchPartReference ref) {
            if (parts.indexOf(ref) >= 0)
                return;

            IWorkbenchPart part = ref.getPart(false);
            if (part != null) {
                PartPane pane = ((PartSite) part.getSite()).getPane();
                if (pane instanceof MultiEditorInnerPane) {
                    MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
                    add(innerPane.getParentPane().getPartReference());
                    return;
                }
            }
            parts.add(0, ref);
        }

        /*
         * Return the active part. Filter fast views.
         */
        IWorkbenchPart getActive() {
            if (parts.isEmpty())
                return null;
            return getActive(parts.size() - 1);
        }

        /*
         * Return the previously active part. Filter fast views.
         */
        IWorkbenchPart getPreviouslyActive() {
            if (parts.size() < 2)
                return null;
            return getActive(parts.size() - 2);
        }

        private IWorkbenchPart getActive(int start) {
            IWorkbenchPartReference ref = getActiveReference(start, false);
            
            if (ref == null) {
                return null;
            }
            
            return ref.getPart(true);
        }
        
        public IWorkbenchPartReference getActiveReference(boolean editorsOnly) {
            return getActiveReference(parts.size() - 1, editorsOnly);
        }
        
        private IWorkbenchPartReference getActiveReference(int start, boolean editorsOnly) {
            // First look for parts that aren't obscured by the current zoom state
            IWorkbenchPartReference nonObscured = getActiveReference(start, editorsOnly, true);
            
            if (nonObscured != null) {
                return nonObscured;
            }
            
            // Now try all the rest of the parts
            return getActiveReference(start, editorsOnly, false);
        }
        
        /*
         * Find a part in the list starting from the end and filter fast views
         * and views from other perspectives.
         */
        private IWorkbenchPartReference getActiveReference(int start, boolean editorsOnly, boolean skipPartsObscuredByZoom) {
            IWorkbenchPartReference[] views = getViewReferences();
            for (int i = start; i >= 0; i--) {
                WorkbenchPartReference ref = (WorkbenchPartReference) parts
                        .get(i);

                if (editorsOnly && !(ref instanceof IEditorReference)) {
                    continue;
                }
                
                // Skip parts whose containers have disabled auto-focus
                PartPane pane = ref.getPane();

                if (pane != null) {
                    if (!pane.allowsAutoFocus()) {
                        continue;
                    }
                    
                    if (skipPartsObscuredByZoom) {
                        if (pane.isObscuredByZoom()) {
                            continue;
                        }
                    }
                }

                // Skip fastviews
                if (ref instanceof IViewReference) {
                    if (!((IViewReference) ref).isFastView()) {
                        for (int j = 0; j < views.length; j++) {
                            if (views[j] == ref) {
                                return ref;
                            }
                        }
                    }
                } else {
                    return ref;
                }
            }
            return null;
        }

        /*
         * Retuns the index of the part within the activation list. The higher
         * the index, the more recently it was used.
         */
        int indexOf(IWorkbenchPart part) {
            IWorkbenchPartReference ref = getReference(part);
            if (ref == null) {
                  return -1;
            }
            return parts.indexOf(ref);
        }

        /*
         * Returns the index of the part reference within the activation list.  
         * The higher the index, the more recent it was used.
         */
        int indexOf(IWorkbenchPartReference ref) {
            return parts.indexOf(ref);
        }

        /*
         * Remove a part from the list
         */
        boolean remove(IWorkbenchPartReference ref) {
            return parts.remove(ref);
        }

        /*
         * Returns the editors in activation order (oldest first).
         */
        private IEditorReference[] getEditors() {
            ArrayList editors = new ArrayList(parts.size());
            for (Iterator i = parts.iterator(); i.hasNext();) {
                IWorkbenchPartReference part = (IWorkbenchPartReference) i
                        .next();
                if (part instanceof IEditorReference) {
                    editors.add(part);
                }
            }
            return (IEditorReference[]) editors
                    .toArray(new IEditorReference[editors.size()]);
        }

        /*
         * Return a list with all parts (editors and views).
         */
        private IWorkbenchPartReference[] getParts() {
            IWorkbenchPartReference[] views = getViewReferences();
            ArrayList resultList = new ArrayList(parts.size());
            for (Iterator iterator = parts.iterator(); iterator.hasNext();) {
                IWorkbenchPartReference ref = (IWorkbenchPartReference) iterator
                        .next();
                if (ref instanceof IViewReference) {
                    //Filter views from other perspectives
                    for (int i = 0; i < views.length; i++) {
                        if (views[i] == ref) {
                            resultList.add(ref);
                            break;
                        }
                    }
                } else {
                    resultList.add(ref);
                }
            }
            IWorkbenchPartReference[] result = new IWorkbenchPartReference[resultList
                    .size()];
            return (IWorkbenchPartReference[]) resultList.toArray(result);
        }

        /*
         * Returns the topmost editor on the stack, or null if none.
         */
        IEditorPart getTopEditor() {
            IEditorReference editor = (IEditorReference)getActiveReference(parts.size() - 1, true);
            
            if (editor == null) {
                return null;
            }
            
            return editor.getEditor(true);
        }
    }

    /**
     * Helper class to keep track of all opened perspective. Both the opened
     * and used order is kept.
     */
03768     private class PerspectiveList {
        /**
         * List of perspectives in the order they were opened;
         */
03772         private List openedList;

        /**
         * List of perspectives in the order they were used. Last element is
         * the most recently used, and first element is the least recently
         * used.
         */
03779         private List usedList;

        /**
         * The perspective explicitly set as being the active one
         */
03784         private Perspective active;

        /**
         * Creates an empty instance of the perspective list
         */
03789         public PerspectiveList() {
            openedList = new ArrayList();
            usedList = new ArrayList();
        }

        /**
         * Update the order of the perspectives in the opened list
         *
         * @param perspective
         * @param newLoc
         */
03800         public void reorder(IPerspectiveDescriptor perspective, int newLoc) {
                  int oldLocation = 0;
                  Perspective movedPerspective = null;
                  for (Iterator iterator = openedList.iterator(); iterator.hasNext();) {
                        Perspective openPerspective = (Perspective) iterator.next();
                        if (openPerspective.getDesc().equals(perspective)) {
                              oldLocation = openedList.indexOf(openPerspective);
                              movedPerspective = openPerspective;
                        }
                  }
                  
                  if (oldLocation == newLoc)
                        return;
                  
                  openedList.remove(oldLocation);
                  openedList.add(newLoc, movedPerspective);
                  
            }

            /**
         * Return all perspectives in the order they were activated.
         * @return an array of perspectives sorted by activation order
         */
03823         public Perspective[] getSortedPerspectives() {
            Perspective[] result = new Perspective[usedList.size()];
            return (Perspective[]) usedList.toArray(result);
        }

        /**
         * Adds a perspective to the list. No check is done for a duplicate when
         * adding.
         * @param perspective the perspective to add
         * @return boolean <code>true</code> if the perspective was added
         */
03834         public boolean add(Perspective perspective) {
            openedList.add(perspective);
            usedList.add(0, perspective);
            //It will be moved to top only when activated.
            return true;
        }

        /**
         * Returns an iterator on the perspective list in the order they were
         * opened.
         */
03845         public Iterator iterator() {
            return openedList.iterator();
        }

        /**
         * Returns an array with all opened perspectives
         */
03852         public Perspective[] getOpenedPerspectives() {
            Perspective[] result = new Perspective[openedList.size()];
            return (Perspective[]) openedList.toArray(result);
        }

        /**
         * Removes a perspective from the list.
         */
03860         public boolean remove(Perspective perspective) {
            if (active == perspective) {
                updateActionSets(active, null);
                active = null;
            }
            usedList.remove(perspective);
            return openedList.remove(perspective);
        }

        /**
         * Swap the opened order of old perspective with the new perspective.
         */
03872         public void swap(Perspective oldPerspective, Perspective newPerspective) {
            int oldIndex = openedList.indexOf(oldPerspective);
            int newIndex = openedList.indexOf(newPerspective);

            if (oldIndex < 0 || newIndex < 0)
                return;

            openedList.set(oldIndex, newPerspective);
            openedList.set(newIndex, oldPerspective);
        }

        /**
         * Returns whether the list contains any perspectives
         */
03886         public boolean isEmpty() {
            return openedList.isEmpty();
        }

        /**
         * Returns the most recently used perspective in the list.
         */
03893         public Perspective getActive() {
            return active;
        }

        /**
         * Returns the next most recently used perspective in the list.
         */
03900         public Perspective getNextActive() {
            if (active == null) {
                if (usedList.isEmpty())
                    return null;
                else
                    return (Perspective) usedList.get(usedList.size() - 1);
            } else {
                if (usedList.size() < 2)
                    return null;
                else
                    return (Perspective) usedList.get(usedList.size() - 2);
            }
        }

        /**
         * Returns the number of perspectives opened
         */
03917         public int size() {
            return openedList.size();
        }

        /**
         * Marks the specified perspective as the most recently used one in the
         * list.
         */
03925         public void setActive(Perspective perspective) {
            if (perspective == active)
                return;

            updateActionSets(active, perspective);
            active = perspective;

            if (perspective != null) {
                usedList.remove(perspective);
                usedList.add(perspective);
            }
        }
        
        private void updateActionSets(Perspective oldPersp, Perspective newPersp) {
            // Update action sets
            if (newPersp != null) {
                IActionSetDescriptor[] newAlwaysOn = newPersp.getAlwaysOnActionSets();
                for (int i = 0; i < newAlwaysOn.length; i++) {
                    IActionSetDescriptor descriptor = newAlwaysOn[i];
                    
                    actionSets.showAction(descriptor);
                }
                
                IActionSetDescriptor[] newAlwaysOff = newPersp.getAlwaysOffActionSets();
                for (int i = 0; i < newAlwaysOff.length; i++) {
                    IActionSetDescriptor descriptor = newAlwaysOff[i];
                    
                    actionSets.maskAction(descriptor);
                }
            }
            
            if (oldPersp != null) {
                IActionSetDescriptor[] newAlwaysOn = oldPersp.getAlwaysOnActionSets();
                for (int i = 0; i < newAlwaysOn.length; i++) {
                    IActionSetDescriptor descriptor = newAlwaysOn[i];
                    
                    actionSets.hideAction(descriptor);
                }
                
                IActionSetDescriptor[] newAlwaysOff = oldPersp.getAlwaysOffActionSets();
                for (int i = 0; i < newAlwaysOff.length; i++) {
                    IActionSetDescriptor descriptor = newAlwaysOff[i];
                    
                    actionSets.unmaskAction(descriptor);
                }
            }
        }
    }

    //for dynamic UI
    protected HashMap getStateMap() {
        return stateMap;
    }

    //for dynamic UI
    protected void addPerspective(Perspective persp) {
        perspList.add(persp);
        window.firePerspectiveOpened(this, persp.getDesc());
    }

    /**
     * Find the stack of view references stacked with this view part.
     * 
     * @param part the part
     * @return the stack of references
     * @since 3.0
     */
03992     private IViewReference[] getViewReferenceStack(IViewPart part) {
        // Sanity check.
        Perspective persp = getActivePerspective();
        if (persp == null || !certifyPart(part))
            return null;

        ILayoutContainer container = ((PartSite) part.getSite()).getPane()
                .getContainer();
        if (container instanceof ViewStack) {
            ViewStack folder = (ViewStack) container;
            final ArrayList list = new ArrayList(folder.getChildren().length);
            for (int i = 0; i < folder.getChildren().length; i++) {
                LayoutPart layoutPart = folder.getChildren()[i];
                if (layoutPart instanceof ViewPane) {
                    IViewReference view = ((ViewPane) layoutPart)
                            .getViewReference();
                    if (view != null)
                        list.add(view);
                }
            }

            // sort the list by activation order (most recently activated first)
            Collections.sort(list, new Comparator() {
                public int compare(Object o1, Object o2) {
                    int pos1 = (-1)
                            * activationList
                                    .indexOf((IWorkbenchPartReference) o1);
                    int pos2 = (-1)
                            * activationList
                                    .indexOf((IWorkbenchPartReference) o2);
                    return pos1 - pos2;
                }
            });

            return (IViewReference[]) list.toArray(new IViewReference[list
                    .size()]);
        }

        return new IViewReference[] { (IViewReference) getReference(part) };
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
     */
04038     public IViewPart[] getViewStack(IViewPart part) {
        IViewReference[] refStack = getViewReferenceStack(part);
        if (refStack == null)
            return null;

        List result = new ArrayList();
       
        for (int i = 0; i < refStack.length; i++) {
            IViewPart next = refStack[i].getView(false);
            if (next != null) {
                result.add(next);
            }
        }

        return (IViewPart[]) result.toArray(new IViewPart[result.size()]);
    }

    /**
     * Allow for programmatically resizing a part.
     * <p>
     * <em>EXPERIMENTAL</em>
     * </p>
     * <p>
     * Known limitations:
     * <ul>
     * <li>currently applies only to views</li>
     * <li>has no effect when view is zoomed</li>
     * </ul> 
     */
04067     public void resizeView(IViewPart part, int width, int height) {
        SashInfo sashInfo = new SashInfo();
        PartPane pane = ((PartSite) part.getSite()).getPane();
        ILayoutContainer container = pane.getContainer();
        LayoutTree tree = getPerspectivePresentation().getLayout().root
                .find(((ViewStack) container));

        // retrieve our layout sashes from the layout tree
        findSashParts(tree, pane.findSashes(), sashInfo);

        // first set the width
        float deltaWidth = width - pane.getBounds().width;
        if (sashInfo.right != null) {
            Rectangle rightBounds = sashInfo.rightNode.getBounds();
            // set the new ratio 
            sashInfo.right.setRatio(((float) ((deltaWidth + sashInfo.right
                    .getBounds().x) - rightBounds.x))
                    / ((float) rightBounds.width));
            // complete the resize
            sashInfo.rightNode.setBounds(rightBounds);
        } else if (sashInfo.left != null) {
            Rectangle leftBounds = sashInfo.leftNode.getBounds();
            // set the ratio
            sashInfo.left
                    .setRatio((float) ((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
                            / ((float) leftBounds.width));
            // complete the resize
            sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
        }

        // next set the height
        float deltaHeight = height - pane.getBounds().height;
        if (sashInfo.bottom != null) {
            Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
            // set the new ratio 
            sashInfo.bottom.setRatio(((float) ((deltaHeight + sashInfo.bottom
                    .getBounds().y) - bottomBounds.y))
                    / ((float) bottomBounds.height));
            // complete the resize
            sashInfo.bottomNode.setBounds(bottomBounds);
        } else if (sashInfo.top != null) {
            Rectangle topBounds = sashInfo.topNode.getBounds();
            // set the ratio
            sashInfo.top
                    .setRatio((float) ((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
                            / ((float) topBounds.height));
            // complete the resize
            sashInfo.topNode.setBounds(topBounds);
        }

    }

    // provides sash information for the given pane
    private class SashInfo {
        private LayoutPartSash right;

        private LayoutPartSash left;

        private LayoutPartSash top;

        private LayoutPartSash bottom;

        private LayoutTreeNode rightNode;

        private LayoutTreeNode leftNode;

        private LayoutTreeNode topNode;

        private LayoutTreeNode bottomNode;
    }

    private void findSashParts(LayoutTree tree, PartPane.Sashes sashes,
            SashInfo info) {
        LayoutTree parent = tree.getParent();
        if (parent == null)
            return;

        if (parent.part instanceof LayoutPartSash) {
            // get the layout part sash from this tree node
            LayoutPartSash sash = (LayoutPartSash) parent.part;
            // make sure it has a sash control
            Control control = sash.getControl();
            if (control != null) {
                // check for a vertical sash
                if (sash.isVertical()) {
                    if (sashes.left == control) {
                        info.left = sash;
                        info.leftNode = parent.findSash(sash);
                    } else if (sashes.right == control) {
                        info.right = sash;
                        info.rightNode = parent.findSash(sash);
                    }
                }
                // check for a horizontal sash
                else {
                    if (sashes.top == control) {
                        info.top = sash;
                        info.topNode = parent.findSash(sash);
                    } else if (sashes.bottom == control) {
                        info.bottom = sash;
                        info.bottomNode = parent.findSash(sash);
                    }
                }
            }
        }
        // recursive call to continue up the tree
        findSashParts(parent, sashes, info);
    }
    
      /**
       * Returns all parts that are owned by this page
       * 
       * @return
       */
04181       IWorkbenchPartReference[] getAllParts() {
            IViewReference[] views = viewFactory.getViews();
            IEditorReference[] editors = getEditorReferences();
            
            IWorkbenchPartReference[] result = new IWorkbenchPartReference[views.length + editors.length];
            int resultIdx = 0;
            
            for (int i = 0; i < views.length; i++) {
                  result[resultIdx++] = views[i];
            }
            
            for (int i = 0; i < editors.length; i++) {
                  result[resultIdx++] = editors[i];
            }
            
            return result;
      }
      
      /**
       * Returns all open parts that are owned by this page (that is, all parts
       * for which a part opened event would have been sent -- these would be
       * activated parts whose controls have already been created.
       */
04204       IWorkbenchPartReference[] getOpenParts() {
            IWorkbenchPartReference[] refs = getAllParts();
            List result = new ArrayList();
            
            for (int i = 0; i < refs.length; i++) {
                  IWorkbenchPartReference reference = refs[i];
                  
                  IWorkbenchPart part = reference.getPart(false);
                  if (part != null) {
                        result.add(reference);
                  }
            }
            
            return (IWorkbenchPartReference[]) result.toArray(new IWorkbenchPartReference[result.size()]);
      }     
    
    /**
     * Sanity-checks the objects in this page. Throws an Assertation exception
     * if an object's internal state is invalid. ONLY INTENDED FOR USE IN THE 
     * UI TEST SUITES. 
     */
04225     public void testInvariants() {
        Perspective persp = getActivePerspective();
        
        if (persp != null) {

            persp.testInvariants();
            
            // When we have widgets, ensure that there is no situation where the editor area is visible
            // and the perspective doesn't want an editor area. 
            if (!SwtUtil.isDisposed(getClientComposite()) && editorPresentation.getLayoutPart().isVisible()) {
                Assert.isTrue(persp.isEditorAreaVisible());
            }
        }
        
    }

      /* (non-Javadoc)
       * @see org.eclipse.ui.IWorkbenchPage#getExtensionTracker()
       */
04244       public IExtensionTracker getExtensionTracker() {
            if (tracker == null) {
                  tracker = new UIExtensionTracker(getWorkbenchWindow().getWorkbench().getDisplay());
            }
            return tracker;         
      }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#getNewWizardShortcuts()
     */
04256     public String[] getNewWizardShortcuts() {
        Perspective persp = getActivePerspective();
        if (persp == null) {
            return new String[0];
        }
        return persp.getNewWizardShortcuts();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#getPerspectiveShortcuts()
     */
04269     public String[] getPerspectiveShortcuts() {
        Perspective persp = getActivePerspective();
        if (persp == null) {
            return new String[0];
        }
        return persp.getPerspectiveShortcuts();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPage#getShowViewShortcuts()
     */
04282     public String[] getShowViewShortcuts() {
        Perspective persp = getActivePerspective();
        if (persp == null) {
            return new String[0];
        }
        return persp.getShowViewShortcuts();
    }
    
    /**
       * @since 3.1
       */
04293       private void suggestReset() {
            final IWorkbench workbench = getWorkbenchWindow().getWorkbench();
        workbench.getDisplay().asyncExec(new Runnable() {
            public void run() {
                Shell parentShell = null;
                
                        IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
                if (window == null) {
                    if (workbench.getWorkbenchWindowCount() == 0)
                        return;
                    window = workbench.getWorkbenchWindows()[0];
                }

                parentShell = window.getShell();

                if (MessageDialog
                        .openQuestion(
                                parentShell,
                                WorkbenchMessages.Dynamic_resetPerspectiveTitle, 
                                WorkbenchMessages.Dynamic_resetPerspectiveMessage)) { 
                    IWorkbenchPage page = window.getActivePage();
                    if (page == null)
                        return;
                    page.resetPerspective();
                }
            }
        });

            
      } 
    
    public boolean isPartVisible(IWorkbenchPartReference reference) {        
        IWorkbenchPart part = reference.getPart(false);
        // Can't be visible if it isn't created yet
        if (part == null) {
            return false;
        }
        
        return isPartVisible(part);
    }
}

Generated by  Doxygen 1.6.0   Back to index