/******************************************************************************* * Copyright (c) 2000, 2006 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.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.internal.util.Util; /** * The abstract superclass for save actions that depend on the active editor. */ public abstract class BaseSaveAction extends ActiveEditorAction { /* * The view-related code below was added to track the view with focus * in order to support save actions from a view (see bug 10234). */ /** * List of parts (element type: <code>IWorkbenchPart</code>) * against which this class has outstanding property listeners registered. */ private List partsWithListeners = new ArrayList(1); private final IPropertyListener propListener = new IPropertyListener() { public void propertyChanged(Object source, int propId) { if (source == getActiveEditor()) { if (propId == IEditorPart.PROP_DIRTY) { updateState(); } } } }; /** * Creates a new action with the given text. * * @param text the string used as the text for the action, * or <code>null</code> if there is no text * @param window the workbench window this action is * registered with. */ protected BaseSaveAction(String text, IWorkbenchWindow window) { super(text, window); } /* (non-Javadoc) * Method declared on ActiveEditorAction. */ protected void editorActivated(IEditorPart part) { if (part != null) { part.addPropertyListener(propListener); partsWithListeners.add(part); } } /* (non-Javadoc) * Method declared on ActiveEditorAction. */ protected void editorDeactivated(IEditorPart part) { if (part != null) { part.removePropertyListener(propListener); partsWithListeners.remove(part); } } private IViewPart activeView; private final IPropertyListener propListener2 = new IPropertyListener() { public void propertyChanged(Object source, int propId) { if (source == activeView) { if (propId == IEditorPart.PROP_DIRTY) { updateState(); } } } }; /** the active saveable part is tracked in order to listen to its dirty events */ private ISaveablePart activeSaveablePart; private final IPropertyListener propListener3 = new IPropertyListener() { public void propertyChanged(Object source, int propId) { if (source == activeSaveablePart) { if (propId == IEditorPart.PROP_DIRTY) { updateState(); } } } }; /* (non-Javadoc) * Method declared on PageEventAction. */ public void pageActivated(IWorkbenchPage page) { super.pageActivated(page); updateActiveView(); updateState(); } /* (non-Javadoc) * Method declared on PageEventAction. */ public void pageClosed(IWorkbenchPage page) { super.pageClosed(page); updateActiveView(); updateState(); } /* (non-Javadoc) * Method declared on PartEventAction. */ public void partActivated(IWorkbenchPart part) { super.partActivated(part); if (part instanceof IViewPart) { updateActiveView(); updateState(); } } /* (non-Javadoc) * Method declared on PartEventAction. */ public void partClosed(IWorkbenchPart part) { super.partClosed(part); if (part instanceof IViewPart) { updateActiveView(); updateState(); } } /* (non-Javadoc) * Method declared on PartEventAction. */ public void partDeactivated(IWorkbenchPart part) { super.partDeactivated(part); if (part instanceof IViewPart) { updateActiveView(); updateState(); } } /** * Update the active view based on the current * active page. */ private void updateActiveView() { if (getActivePage() == null) { setActiveView(null); } else { setActiveView(getActivePage().getActivePart()); } } /** * */ private void updateActiveSaveablePart() { if (activeSaveablePart instanceof IWorkbenchPart) { ((IWorkbenchPart)activeSaveablePart).removePropertyListener(propListener3); partsWithListeners.remove(activeSaveablePart); } activeSaveablePart = getSaveableView(); if (activeSaveablePart == activeView) { // no need to listen to the same part twice activeSaveablePart = null; } if (activeSaveablePart instanceof IWorkbenchPart) { ((IWorkbenchPart)activeSaveablePart).addPropertyListener(propListener3); partsWithListeners.add(activeSaveablePart); } } /** * Set the active editor */ private void setActiveView(IWorkbenchPart part) { if (activeView == part) { return; } if (activeView != null) { activeView.removePropertyListener(propListener2); partsWithListeners.remove(activeView); } if (part instanceof IViewPart) { activeView = (IViewPart) part; } else { activeView = null; } if (activeView != null) { activeView.addPropertyListener(propListener2); partsWithListeners.add(activeView); } updateActiveSaveablePart(); } protected final ISaveablePart getSaveableView() { if (activeView == null) { return null; } return (ISaveablePart) Util.getAdapter(activeView, ISaveablePart.class); } /* (non-Javadoc) * Method declared on PageEventAction. */ public void dispose() { super.dispose(); for (Iterator it = partsWithListeners.iterator(); it.hasNext();) { IWorkbenchPart part = (IWorkbenchPart) it.next(); part.removePropertyListener(propListener); part.removePropertyListener(propListener2); part.removePropertyListener(propListener3); } partsWithListeners.clear(); } }