001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.List;
015:
016: import org.eclipse.ui.IEditorPart;
017: import org.eclipse.ui.IPropertyListener;
018: import org.eclipse.ui.ISaveablePart;
019: import org.eclipse.ui.IViewPart;
020: import org.eclipse.ui.IWorkbenchPage;
021: import org.eclipse.ui.IWorkbenchPart;
022: import org.eclipse.ui.IWorkbenchWindow;
023: import org.eclipse.ui.internal.util.Util;
024:
025: /**
026: * The abstract superclass for save actions that depend on the active editor.
027: */
028: public abstract class BaseSaveAction extends ActiveEditorAction {
029: /*
030: * The view-related code below was added to track the view with focus
031: * in order to support save actions from a view (see bug 10234).
032: */
033:
034: /**
035: * List of parts (element type: <code>IWorkbenchPart</code>)
036: * against which this class has outstanding property listeners registered.
037: */
038: private List partsWithListeners = new ArrayList(1);
039:
040: private final IPropertyListener propListener = new IPropertyListener() {
041: public void propertyChanged(Object source, int propId) {
042: if (source == getActiveEditor()) {
043: if (propId == IEditorPart.PROP_DIRTY) {
044: updateState();
045: }
046: }
047: }
048: };
049:
050: /**
051: * Creates a new action with the given text.
052: *
053: * @param text the string used as the text for the action,
054: * or <code>null</code> if there is no text
055: * @param window the workbench window this action is
056: * registered with.
057: */
058: protected BaseSaveAction(String text, IWorkbenchWindow window) {
059: super (text, window);
060: }
061:
062: /* (non-Javadoc)
063: * Method declared on ActiveEditorAction.
064: */
065: protected void editorActivated(IEditorPart part) {
066: if (part != null) {
067: part.addPropertyListener(propListener);
068: partsWithListeners.add(part);
069: }
070: }
071:
072: /* (non-Javadoc)
073: * Method declared on ActiveEditorAction.
074: */
075: protected void editorDeactivated(IEditorPart part) {
076: if (part != null) {
077: part.removePropertyListener(propListener);
078: partsWithListeners.remove(part);
079: }
080: }
081:
082: private IViewPart activeView;
083:
084: private final IPropertyListener propListener2 = new IPropertyListener() {
085: public void propertyChanged(Object source, int propId) {
086: if (source == activeView) {
087: if (propId == IEditorPart.PROP_DIRTY) {
088: updateState();
089: }
090: }
091: }
092: };
093:
094: /** the active saveable part is tracked in order to listen to its dirty events */
095: private ISaveablePart activeSaveablePart;
096:
097: private final IPropertyListener propListener3 = new IPropertyListener() {
098: public void propertyChanged(Object source, int propId) {
099: if (source == activeSaveablePart) {
100: if (propId == IEditorPart.PROP_DIRTY) {
101: updateState();
102: }
103: }
104: }
105: };
106:
107: /* (non-Javadoc)
108: * Method declared on PageEventAction.
109: */
110: public void pageActivated(IWorkbenchPage page) {
111: super .pageActivated(page);
112: updateActiveView();
113: updateState();
114: }
115:
116: /* (non-Javadoc)
117: * Method declared on PageEventAction.
118: */
119: public void pageClosed(IWorkbenchPage page) {
120: super .pageClosed(page);
121: updateActiveView();
122: updateState();
123: }
124:
125: /* (non-Javadoc)
126: * Method declared on PartEventAction.
127: */
128: public void partActivated(IWorkbenchPart part) {
129: super .partActivated(part);
130: if (part instanceof IViewPart) {
131: updateActiveView();
132: updateState();
133: }
134: }
135:
136: /* (non-Javadoc)
137: * Method declared on PartEventAction.
138: */
139: public void partClosed(IWorkbenchPart part) {
140: super .partClosed(part);
141: if (part instanceof IViewPart) {
142: updateActiveView();
143: updateState();
144: }
145: }
146:
147: /* (non-Javadoc)
148: * Method declared on PartEventAction.
149: */
150: public void partDeactivated(IWorkbenchPart part) {
151: super .partDeactivated(part);
152: if (part instanceof IViewPart) {
153: updateActiveView();
154: updateState();
155: }
156: }
157:
158: /**
159: * Update the active view based on the current
160: * active page.
161: */
162: private void updateActiveView() {
163: if (getActivePage() == null) {
164: setActiveView(null);
165: } else {
166: setActiveView(getActivePage().getActivePart());
167: }
168: }
169:
170: /**
171: *
172: */
173: private void updateActiveSaveablePart() {
174: if (activeSaveablePart instanceof IWorkbenchPart) {
175: ((IWorkbenchPart) activeSaveablePart)
176: .removePropertyListener(propListener3);
177: partsWithListeners.remove(activeSaveablePart);
178: }
179: activeSaveablePart = getSaveableView();
180: if (activeSaveablePart == activeView) {
181: // no need to listen to the same part twice
182: activeSaveablePart = null;
183: }
184: if (activeSaveablePart instanceof IWorkbenchPart) {
185: ((IWorkbenchPart) activeSaveablePart)
186: .addPropertyListener(propListener3);
187: partsWithListeners.add(activeSaveablePart);
188: }
189: }
190:
191: /**
192: * Set the active editor
193: */
194: private void setActiveView(IWorkbenchPart part) {
195: if (activeView == part) {
196: return;
197: }
198: if (activeView != null) {
199: activeView.removePropertyListener(propListener2);
200: partsWithListeners.remove(activeView);
201: }
202: if (part instanceof IViewPart) {
203: activeView = (IViewPart) part;
204: } else {
205: activeView = null;
206: }
207: if (activeView != null) {
208: activeView.addPropertyListener(propListener2);
209: partsWithListeners.add(activeView);
210: }
211: updateActiveSaveablePart();
212: }
213:
214: protected final ISaveablePart getSaveableView() {
215: if (activeView == null) {
216: return null;
217: }
218:
219: return (ISaveablePart) Util.getAdapter(activeView,
220: ISaveablePart.class);
221: }
222:
223: /* (non-Javadoc)
224: * Method declared on PageEventAction.
225: */
226: public void dispose() {
227: super .dispose();
228: for (Iterator it = partsWithListeners.iterator(); it.hasNext();) {
229: IWorkbenchPart part = (IWorkbenchPart) it.next();
230: part.removePropertyListener(propListener);
231: part.removePropertyListener(propListener2);
232: part.removePropertyListener(propListener3);
233: }
234: partsWithListeners.clear();
235: }
236: }
|