001: /*******************************************************************************
002: * Copyright (c) 2005, 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 org.eclipse.core.runtime.Assert;
013: import org.eclipse.ui.IEditorPart;
014: import org.eclipse.ui.IEditorReference;
015: import org.eclipse.ui.IPropertyListener;
016: import org.eclipse.ui.ISaveablesLifecycleListener;
017: import org.eclipse.ui.IWorkbenchPart;
018: import org.eclipse.ui.IWorkbenchPartConstants;
019: import org.eclipse.ui.IWorkbenchPartReference;
020: import org.eclipse.ui.IWorkbenchPartSite;
021: import org.eclipse.ui.part.MultiEditor;
022:
023: public abstract class PartList {
024: private IWorkbenchPartReference activePartReference;
025:
026: private IEditorReference activeEditorReference;
027:
028: // private List parts = new ArrayList();
029:
030: private IPropertyListener listener = new IPropertyListener() {
031: public void propertyChanged(Object source, int propId) {
032: WorkbenchPartReference ref = (WorkbenchPartReference) source;
033:
034: switch (propId) {
035: case WorkbenchPartReference.INTERNAL_PROPERTY_OPENED:
036: partOpened(ref);
037: break;
038: case WorkbenchPartReference.INTERNAL_PROPERTY_CLOSED:
039: partClosed(ref);
040: break;
041: case WorkbenchPartReference.INTERNAL_PROPERTY_VISIBLE: {
042: if (ref.getVisible()) {
043: partVisible(ref);
044: } else {
045: partHidden(ref);
046: }
047: break;
048: }
049: case IWorkbenchPartConstants.PROP_INPUT: {
050: partInputChanged(ref);
051: break;
052: }
053: }
054: }
055: };
056:
057: public IWorkbenchPartReference getActivePartReference() {
058: return activePartReference;
059: }
060:
061: public IEditorReference getActiveEditorReference() {
062: return activeEditorReference;
063: }
064:
065: public IEditorPart getActiveEditor() {
066: return activeEditorReference == null ? null
067: : activeEditorReference.getEditor(false);
068: }
069:
070: public IWorkbenchPart getActivePart() {
071: return activePartReference == null ? null : activePartReference
072: .getPart(false);
073: }
074:
075: public void addPart(WorkbenchPartReference ref) {
076: Assert.isNotNull(ref);
077:
078: ref.addInternalPropertyListener(listener);
079:
080: // parts.add(ref);
081: firePartAdded(ref);
082:
083: // If this part is already open, fire the "part opened" event
084: // immediately
085: if (ref.getPart(false) != null) {
086: partOpened(ref);
087: }
088:
089: // If this part is already visible, fire the visibility event
090: // immediately
091: if (ref.getVisible()) {
092: partVisible(ref);
093: }
094: }
095:
096: /**
097: * Sets the active part.
098: *
099: * @param ref
100: */
101: public void setActivePart(IWorkbenchPartReference ref) {
102: if (ref == activePartReference) {
103: return;
104: }
105:
106: IWorkbenchPartReference oldPart = activePartReference;
107:
108: // A part can't be activated until it is added
109: // Assert.isTrue(ref == null || parts.contains(ref));
110:
111: if (ref != null) {
112: IWorkbenchPart part = ref.getPart(true);
113: Assert.isNotNull(part);
114: if (part instanceof MultiEditor) {
115: IWorkbenchPartSite site = ((MultiEditor) part)
116: .getActiveEditor().getSite();
117: if (site instanceof PartSite) {
118: ref = ((PartSite) site).getPane()
119: .getPartReference();
120: }
121: }
122: }
123:
124: activePartReference = ref;
125:
126: fireActivePartChanged(oldPart, ref);
127: }
128:
129: public void setActiveEditor(IEditorReference ref) {
130: if (ref == activeEditorReference) {
131: return;
132: }
133:
134: // A part can't be activated until it is added
135: // Assert.isTrue(ref == null || parts.contains(ref));
136:
137: if (ref != null) {
138: IWorkbenchPart part = ref.getPart(true);
139: Assert.isNotNull(part);
140: if (part instanceof MultiEditor) {
141: IWorkbenchPartSite site = ((MultiEditor) part)
142: .getActiveEditor().getSite();
143: if (site instanceof PartSite) {
144: ref = (IEditorReference) ((PartSite) site)
145: .getPane().getPartReference();
146: }
147: }
148: }
149:
150: activeEditorReference = ref;
151:
152: fireActiveEditorChanged(ref);
153: }
154:
155: /**
156: * In order to remove a part, it must first be deactivated.
157: */
158: public void removePart(WorkbenchPartReference ref) {
159: Assert.isNotNull(ref);
160: // It is an error to remove a part that isn't in the list
161: // Assert.isTrue(parts.contains(ref));
162: // We're not allowed to remove the active part. We must deactivate it
163: // first.
164: Assert.isTrue(ref != activePartReference);
165: // We're not allowed to remove the active editor. We must deactivate it
166: // first.
167: Assert.isTrue(ref != activeEditorReference);
168:
169: if (ref.getVisible()) {
170: ref.setVisible(false);
171: }
172:
173: // If this part is currently open, fire the "part closed" event before
174: // removal
175: if (ref.getPart(false) != null) {
176: partClosed(ref);
177: }
178:
179: ref.removeInternalPropertyListener(listener);
180:
181: firePartRemoved(ref);
182: }
183:
184: private void partInputChanged(WorkbenchPartReference ref) {
185: firePartInputChanged(ref);
186: }
187:
188: private void partHidden(WorkbenchPartReference ref) {
189: // Part should not be null
190: Assert.isNotNull(ref);
191: // This event should only be fired if the part is actually visible
192: Assert.isTrue(!ref.getVisible());
193: // We shouldn't be receiving events from parts until they are in the
194: // list
195: // Assert.isTrue(parts.contains(ref));
196:
197: firePartHidden(ref);
198: }
199:
200: private void partOpened(WorkbenchPartReference ref) {
201: Assert.isNotNull(ref);
202:
203: IWorkbenchPart actualPart = ref.getPart(false);
204: // We're firing the event that says "the part was just created"... so
205: // there better be a part there.
206: Assert.isNotNull(actualPart);
207: // Must be called after the part is inserted into the part list
208: // Assert.isTrue(parts.contains(ref));
209: // The active part must be opened before it is activated, so we should
210: // never get an
211: // open event for a part that is already active. (This either indicates
212: // that a redundant
213: // open event was fired or that a closed part was somehow activated)
214: Assert.isTrue(activePartReference != ref);
215: // The active editor must be opened before it is activated, so we should
216: // never get an
217: // open event for an editor that is already active. (This either
218: // indicates that a redundant
219: // open event was fired or that a closed editor was somehow activated)
220: Assert.isTrue(activeEditorReference != ref);
221:
222: SaveablesList modelManager = (SaveablesList) actualPart
223: .getSite()
224: .getService(ISaveablesLifecycleListener.class);
225: modelManager.postOpen(actualPart);
226:
227: // Fire the "part opened" event
228: firePartOpened(ref);
229: }
230:
231: /**
232: * Called when a concrete part is about to be destroyed. This is called
233: * BEFORE disposal happens, so the part should still be accessable from the
234: * part reference.
235: *
236: * @param ref
237: */
238: private void partClosed(WorkbenchPartReference ref) {
239: Assert.isNotNull(ref);
240:
241: IWorkbenchPart actualPart = ref.getPart(false);
242: // Called before the part is disposed, so the part should still be
243: // there.
244: Assert.isNotNull(actualPart);
245: // Must be called before the part is actually removed from the part list
246: // Assert.isTrue(parts.contains(ref));
247: // Not allowed to close the active part. The part must be deactivated
248: // before it may
249: // be closed.
250: Assert.isTrue(activePartReference != ref);
251: // Not allowed to close the active editor. The editor must be
252: // deactivated before it may
253: // be closed.
254: Assert.isTrue(activeEditorReference != ref);
255:
256: firePartClosed(ref);
257: }
258:
259: private void partVisible(WorkbenchPartReference ref) {
260: // Part should not be null
261: Assert.isNotNull(ref);
262: // This event should only be fired if the part is actually visible
263: Assert.isTrue(ref.getVisible());
264: // We shouldn't be receiving events from parts until they are in the
265: // list
266: // Assert.isTrue(parts.contains(ref));
267: // Part must be open before it can be made visible
268: Assert.isNotNull(ref.getPart(false));
269:
270: firePartVisible(ref);
271: }
272:
273: /**
274: * Fire the event indicating that a part reference was just realized. That
275: * is, the concrete IWorkbenchPart has been attached to the part reference.
276: *
277: * @param part
278: * the reference that was create
279: */
280: protected abstract void firePartOpened(IWorkbenchPartReference part);
281:
282: /**
283: * Fire the event indicating that a part reference was just realized. That
284: * is, the concrete IWorkbenchPart has been attached to the part reference.
285: *
286: * @param part
287: * the reference that was create
288: */
289: protected abstract void firePartClosed(IWorkbenchPartReference part);
290:
291: /**
292: * Indicates that a new part reference was added to the list.
293: *
294: * @param part
295: */
296: protected abstract void firePartAdded(IWorkbenchPartReference part);
297:
298: /**
299: * Indicates that a part reference was removed from the list
300: *
301: * @param part
302: */
303: protected abstract void firePartRemoved(IWorkbenchPartReference part);
304:
305: /**
306: * Indicates that the active editor changed
307: *
308: * @param part
309: * active part reference or null if none
310: */
311: protected abstract void fireActiveEditorChanged(
312: IWorkbenchPartReference ref);
313:
314: /**
315: * Indicates that the active part has changed
316: *
317: * @param part
318: * active part reference or null if none
319: */
320: protected abstract void fireActivePartChanged(
321: IWorkbenchPartReference oldPart,
322: IWorkbenchPartReference newPart);
323:
324: /**
325: * Indicates that the part has been made visible
326: *
327: * @param ref
328: */
329: protected abstract void firePartVisible(IWorkbenchPartReference ref);
330:
331: /**
332: * Indicates that the part has been hidden
333: *
334: * @param ref
335: */
336: protected abstract void firePartHidden(IWorkbenchPartReference ref);
337:
338: /**
339: * Indicates that the part input has changed
340: *
341: * @param ref
342: */
343: protected abstract void firePartInputChanged(
344: IWorkbenchPartReference ref);
345:
346: protected abstract void firePartBroughtToTop(
347: IWorkbenchPartReference ref);
348: }
|