Source code: org/eclipse/ui/internal/WorkbenchPage.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11
12 package org.eclipse.ui.internal;
13
14 import java.lang.reflect.InvocationTargetException;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Comparator;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Set;
23
24 import org.eclipse.core.runtime.IAdaptable;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.MultiStatus;
28 import org.eclipse.core.runtime.Platform;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.jface.action.CoolBarManager;
31 import org.eclipse.jface.action.IContributionItem;
32 import org.eclipse.jface.dialogs.ErrorDialog;
33 import org.eclipse.jface.dialogs.IDialogConstants;
34 import org.eclipse.jface.dialogs.MessageDialog;
35 import org.eclipse.jface.operation.IRunnableWithProgress;
36 import org.eclipse.jface.preference.IPreferenceStore;
37 import org.eclipse.jface.util.IPropertyChangeListener;
38 import org.eclipse.jface.util.ListenerList;
39 import org.eclipse.jface.util.PropertyChangeEvent;
40 import org.eclipse.jface.util.SafeRunnable;
41 import org.eclipse.jface.viewers.ISelection;
42 import org.eclipse.jface.window.Window;
43 import org.eclipse.swt.SWT;
44 import org.eclipse.swt.custom.BusyIndicator;
45 import org.eclipse.swt.events.ControlAdapter;
46 import org.eclipse.swt.events.ControlEvent;
47 import org.eclipse.swt.events.ControlListener;
48 import org.eclipse.swt.graphics.Rectangle;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Display;
52 import org.eclipse.ui.IActionBars;
53 import org.eclipse.ui.IEditorInput;
54 import org.eclipse.ui.IEditorPart;
55 import org.eclipse.ui.IEditorReference;
56 import org.eclipse.ui.IEditorRegistry;
57 import org.eclipse.ui.IMemento;
58 import org.eclipse.ui.INavigationHistory;
59 import org.eclipse.ui.IPartListener;
60 import org.eclipse.ui.IPartListener2;
61 import org.eclipse.ui.IPerspectiveDescriptor;
62 import org.eclipse.ui.IPerspectiveRegistry;
63 import org.eclipse.ui.IReusableEditor;
64 import org.eclipse.ui.ISaveablePart;
65 import org.eclipse.ui.ISelectionListener;
66 import org.eclipse.ui.IViewPart;
67 import org.eclipse.ui.IViewReference;
68 import org.eclipse.ui.IWorkbenchPage;
69 import org.eclipse.ui.IWorkbenchPart;
70 import org.eclipse.ui.IWorkbenchPartReference;
71 import org.eclipse.ui.IWorkbenchPartSite;
72 import org.eclipse.ui.IWorkbenchWindow;
73 import org.eclipse.ui.IWorkingSet;
74 import org.eclipse.ui.IWorkingSetManager;
75 import org.eclipse.ui.PartInitException;
76 import org.eclipse.ui.PlatformUI;
77 import org.eclipse.ui.SubActionBars;
78 import org.eclipse.ui.WorkbenchException;
79 import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
80 import org.eclipse.ui.internal.intro.IIntroConstants;
81 import org.eclipse.ui.internal.misc.StatusUtil;
82 import org.eclipse.ui.internal.misc.UIStats;
83 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
84 import org.eclipse.ui.internal.registry.IStickyViewDescriptor;
85 import org.eclipse.ui.internal.registry.IViewRegistry;
86 import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
87 import org.eclipse.ui.model.IWorkbenchAdapter;
88 import org.eclipse.ui.part.MultiEditor;
89
90 /**
91 * A collection of views and editors in a workbench.
92 */
93 public class WorkbenchPage extends CompatibleWorkbenchPage implements IWorkbenchPage {
94 private WorkbenchWindow window;
95 private IAdaptable input;
96 private IWorkingSet workingSet;
97 private Composite composite;
98 private ControlListener resizeListener;
99 private IWorkbenchPart activePart;
100 //Could be delete. This information is in the active part list;
101 private ActivationList activationList = new ActivationList();
102 private IEditorPart lastActiveEditor;
103 private EditorManager editorMgr;
104 private EditorAreaHelper editorPresentation;
105 private PartListenerList partListeners = new PartListenerList();
106 private PartListenerList2 partListeners2 = new PartListenerList2();
107 private ListenerList propertyChangeListeners = new ListenerList();
108 private PageSelectionService selectionService =
109 new PageSelectionService(this);
110 private IActionBars actionBars;
111 private ViewFactory viewFactory;
112 private PerspectiveList perspList = new PerspectiveList();
113 private PerspectiveDescriptor deferredActivePersp;
114 private NavigationHistory navigationHistory = new NavigationHistory(this);
115 //for dynamic UI - saving state for editors, views and perspectives
116 private HashMap stateMap = new HashMap();
117 private IPropertyChangeListener propertyChangeListener =
118 new IPropertyChangeListener() {
119 /*
120 * Remove the working set from the page if the working set is deleted.
121 */
122 public void propertyChange(PropertyChangeEvent event) {
123 String property = event.getProperty();
124 if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
125 && event.getOldValue().equals(workingSet)) {
126 setWorkingSet(null);
127 } else if (LayoutPart.PROP_VISIBILITY.equals(property)) {
128 WorkbenchPartReference ref =
129 (WorkbenchPartReference) ((PartPane) event.getSource())
130 .getPartReference();
131 //Make sure the new visible part is restored.
132 ref.getPart(Boolean.TRUE.equals(event.getNewValue()));
133 if (ref == null)
134 return;
135 if (Boolean.TRUE.equals(event.getNewValue())) {
136 String label = "visible::" + ref.getTitle(); //$NON-NLS-1$
137 try {
138 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
139 partListeners2.firePartVisible(ref);
140 } finally {
141 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
142 }
143 } else {
144 String label = "hidden::" + ref.getTitle(); //$NON-NLS-1$
145 try {
146 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
147 partListeners2.firePartHidden(ref);
148 } finally {
149 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
150 }
151 }
152 }
153 }
154 };
155
156 // a set of perspectives in which sticky views have already been created.
157 private Set stickyPerspectives = new HashSet(7);
158
159 private ActionSwitcher actionSwitcher = new ActionSwitcher();
160 /**
161 * Manages editor contributions and action set part associations.
162 */
163 private class ActionSwitcher {
164 private IWorkbenchPart activePart;
165 private IEditorPart topEditor;
166 private ArrayList actionSets = new ArrayList();
167
168 /**
169 * Updates the contributions given the new part as the active part.
170 *
171 * @param newPart
172 * the new active part, may be <code>null</code>
173 */
174 public void updateActivePart(IWorkbenchPart newPart) {
175 if (activePart == newPart)
176 return;
177
178 boolean isNewPartAnEditor = newPart instanceof IEditorPart;
179 if (isNewPartAnEditor) {
180 String oldId = null;
181 if (topEditor != null)
182 oldId = topEditor.getSite().getId();
183 String newId = newPart.getSite().getId();
184
185 // if the active part is an editor and the new editor
186 // is the same kind of editor, then we don't have to do
187 // anything
188 if (activePart == topEditor && newId.equals(oldId))
189 return;
190
191 // remove the contributions of the old editor
192 // if it is a different kind of editor
193 if (oldId != null && !oldId.equals(newId))
194 deactivateContributions(topEditor, true);
195
196 // if a view was the active part, disable its contributions
197 if (activePart != null && activePart != topEditor)
198 deactivateContributions(activePart, true);
199
200 // show (and enable) the contributions of the new editor
201 // if it is a different kind of editor or if the
202 // old active part was a view
203 if (!newId.equals(oldId) || activePart != topEditor)
204 activateContributions(newPart, true);
205
206 } else if (newPart == null) {
207 if (activePart != null)
208 // remove all contributions
209 deactivateContributions(activePart, true);
210 } else {
211 // new part is a view
212
213 // if old active part is a view, remove all contributions,
214 // but if old part is an editor only disable
215 if (activePart != null)
216 deactivateContributions(
217 activePart,
218 activePart instanceof IViewPart);
219
220 activateContributions(newPart, true);
221 }
222
223 ArrayList newActionSets = null;
224 if (isNewPartAnEditor
225 || (activePart == topEditor && newPart == null))
226 newActionSets = calculateActionSets(newPart, null);
227 else
228 newActionSets = calculateActionSets(newPart, topEditor);
229
230 if (!updateActionSets(newActionSets))
231 updateActionBars();
232
233 if (isNewPartAnEditor) {
234 topEditor = (IEditorPart) newPart;
235 } else if (activePart == topEditor && newPart == null) {
236 // since we removed all the contributions, we clear the top
237 // editor
238 topEditor = null;
239 }
240
241 activePart = newPart;
242 }
243
244 /**
245 * Updates the contributions given the new part as the topEditor.
246 *
247 * @param newEditor
248 * the new top editor, may be <code>null</code>
249 */
250 public void updateTopEditor(IEditorPart newEditor) {
251 if (topEditor == newEditor)
252 return;
253
254 String oldId = null;
255 if (topEditor != null)
256 oldId = topEditor.getSite().getId();
257 String newId = null;
258 if (newEditor != null)
259 newId = newEditor.getSite().getId();
260 if (oldId == null ? newId == null : oldId.equals(newId)) {
261 // we don't have to change anything
262 topEditor = newEditor;
263 return;
264 }
265
266 // Remove the contributions of the old editor
267 if (topEditor != null)
268 deactivateContributions(topEditor, true);
269
270 // Show (disabled) the contributions of the new editor
271 if (newEditor != null)
272 activateContributions(newEditor, false);
273
274 ArrayList newActionSets =
275 calculateActionSets(activePart, newEditor);
276 if (!updateActionSets(newActionSets))
277 updateActionBars();
278
279 topEditor = newEditor;
280 }
281
282 /**
283 * Activates the contributions of the given part. If <code>enable</code>
284 * is <code>true</code> the contributions are visible and enabled,
285 * otherwise they are disabled.
286 *
287 * @param part
288 * the part whose contributions are to be activated
289 * @param enable
290 * <code>true</code> the contributions are to be enabled,
291 * not just visible.
292 */
293 private void activateContributions(
294 IWorkbenchPart part,
295 boolean enable) {
296 PartSite site = (PartSite) part.getSite();
297 SubActionBars actionBars = (SubActionBars) site.getActionBars();
298 actionBars.activate(enable);
299 }
300
301 /**
302 * Deactivates the contributions of the given part. If <code>remove</code>
303 * is <code>true</code> the contributions are removed, otherwise they
304 * are disabled.
305 *
306 * @param part
307 * the part whose contributions are to be deactivated
308 * @param remove
309 * <code>true</code> the contributions are to be removed,
310 * not just disabled.
311 */
312 private void deactivateContributions(
313 IWorkbenchPart part,
314 boolean remove) {
315 PartSite site = (PartSite) part.getSite();
316 SubActionBars actionBars = (SubActionBars) site.getActionBars();
317 actionBars.deactivate(remove);
318 }
319
320 /**
321 * Calculates the action sets to show for the given part and editor
322 *
323 * @param part
324 * the active part, may be <code>null</code>
325 * @param editor
326 * the current editor, may be <code>null</code>, may be
327 * the active part
328 * @return the new action sets
329 */
330 private ArrayList calculateActionSets(
331 IWorkbenchPart part,
332 IEditorPart editor) {
333 ArrayList newActionSets = new ArrayList();
334 if (part != null) {
335 IActionSetDescriptor[] partActionSets =
336 WorkbenchPlugin
337 .getDefault()
338 .getActionSetRegistry()
339 .getActionSetsFor(
340 part.getSite().getId());
341 for (int i = 0; i < partActionSets.length; i++) {
342 newActionSets.add(partActionSets[i]);
343 }
344 }
345 if (editor != null && editor != part) {
346 IActionSetDescriptor[] editorActionSets =
347 WorkbenchPlugin
348 .getDefault()
349 .getActionSetRegistry()
350 .getActionSetsFor(
351 editor.getSite().getId());
352 for (int i = 0; i < editorActionSets.length; i++) {
353 newActionSets.add(editorActionSets[i]);
354 }
355 }
356 return newActionSets;
357 }
358
359 /**
360 * Updates the actions we are showing for the active part and current
361 * editor.
362 *
363 * @param newActionSets
364 * the action sets to show
365 * @return <code>true</code> if the action sets changed
366 */
367 private boolean updateActionSets(ArrayList newActionSets) {
368 if (actionSets.equals(newActionSets))
369 return false;
370
371 Perspective persp = getActivePerspective();
372 if (persp == null) {
373 actionSets = newActionSets;
374 return false;
375 }
376
377 // hide the old
378 for (int i = 0; i < actionSets.size(); i++) {
379 persp.hideActionSet(
380 ((IActionSetDescriptor) actionSets.get(i)).getId());
381 }
382
383 // show the new
384 for (int i = 0; i < newActionSets.size(); i++) {
385 persp.showActionSet(
386 ((IActionSetDescriptor) newActionSets.get(i)).getId());
387 }
388
389 actionSets = newActionSets;
390
391 window.updateActionSets(); // this calls updateActionBars
392 window.firePerspectiveChanged(
393 WorkbenchPage.this,
394 getPerspective(),
395 CHANGE_ACTION_SET_SHOW);
396 return true;
397 }
398
399 }
400
401 /**
402 * Constructs a new page with a given perspective and input.
403 *
404 * @param w
405 * the parent window
406 * @param layoutID
407 * must not be <code>null</code>
408 * @param input
409 * the page input
410 */
411 public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
412 throws WorkbenchException {
413 super();
414 if (layoutID == null)
415 throw new WorkbenchException(WorkbenchMessages.getString("WorkbenchPage.UndefinedPerspective")); //$NON-NLS-1$
416 init(w, layoutID, input);
417 }
418 /**
419 * Constructs a page. <code>restoreState(IMemento)</code> should be
420 * called to restore this page from data stored in a persistance file.
421 *
422 * @param w
423 * the parent window
424 * @param input
425 * the page input
426 */
427 public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
428 throws WorkbenchException {
429 super();
430 init(w, null, input);
431 }
432
433 /**
434 * Activates a part. The part will be brought to the front and given focus.
435 *
436 * @param part
437 * the part to activate
438 */
439 public void activate(IWorkbenchPart part) {
440 // Sanity check.
441 if (!certifyPart(part))
442 return;
443
444 if (window.isClosing())
445 return;
446
447 // If zoomed, unzoom.
448 if (isZoomed() && partChangeAffectsZoom(getReference(part)))
449 zoomOut();
450
451 if (part instanceof MultiEditor) {
452 part = ((MultiEditor) part).getActiveEditor();
453 }
454 // Activate part.
455 if (window.getActivePage() == this) {
456 bringToTop(part);
457 setActivePart(part);
458 } else {
459 activationList.setActive(part);
460 activePart = part;
461 }
462 }
463
464 /**
465 * Activates a part. The part is given focus, the pane is hilighted.
466 */
467 private void activatePart(final IWorkbenchPart part) {
468 Platform.run(new SafeRunnable(WorkbenchMessages.getString("WorkbenchPage.ErrorActivatingView")) { //$NON-NLS-1$
469 public void run() {
470 if (part != null) {
471 part.setFocus();
472 PartSite site = (PartSite) part.getSite();
473 site.getPane().showFocus(true);
474 updateTabList(part);
475 SubActionBars bars = (SubActionBars) site.getActionBars();
476 bars.partChanged(part);
477 }
478 }
479 });
480 }
481 /**
482 * Add a fast view.
483 */
484 public void addFastView(IViewReference ref) {
485 Perspective persp = getActivePerspective();
486 if (persp == null)
487 return;
488
489 // If view is zoomed unzoom.
490 if (isZoomed() && partChangeAffectsZoom(ref))
491 zoomOut();
492
493 // Do real work.
494 persp.addFastView(ref);
495
496 // The view is now invisible.
497 // If it is active then deactivate it.
498 if (ref.getPart(false) == activePart) {
499 activate(activationList.getActive());
500 }
501
502 // Notify listeners.
503 window.updateFastViewBar();
504 window.firePerspectiveChanged(
505 this,
506 getPerspective(),
507 ref,
508 CHANGE_FAST_VIEW_ADD);
509 window.firePerspectiveChanged(
510 this,
511 getPerspective(),
512 CHANGE_FAST_VIEW_ADD);
513 }
514 /**
515 * Adds an IPartListener to the part service.
516 */
517 public void addPartListener(IPartListener l) {
518 partListeners.addPartListener(l);
519 }
520 /**
521 * Adds an IPartListener to the part service.
522 */
523 public void addPartListener(IPartListener2 l) {
524 partListeners2.addPartListener(l);
525 }
526 /**
527 * Implements IWorkbenchPage
528 *
529 * @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
530 * @since 2.0
531 * @deprecated individual views should store a working set if needed and
532 * register a property change listener directly with the
533 * working set manager to receive notification when the view
534 * working set is removed.
535 */
536 public void addPropertyChangeListener(IPropertyChangeListener listener) {
537 propertyChangeListeners.add(listener);
538 }
539 /*
540 * (non-Javadoc) Method declared on ISelectionListener.
541 */
542 public void addSelectionListener(ISelectionListener listener) {
543 selectionService.addSelectionListener(listener);
544 }
545
546 /*
547 * (non-Javadoc) Method declared on ISelectionListener.
548 */
549 public void addSelectionListener(
550 String partId,
551 ISelectionListener listener) {
552 selectionService.addSelectionListener(partId, listener);
553 }
554 /*
555 * (non-Javadoc) Method declared on ISelectionListener.
556 */
557 public void addPostSelectionListener(ISelectionListener listener) {
558 selectionService.addPostSelectionListener(listener);
559 }
560
561 /*
562 * (non-Javadoc) Method declared on ISelectionListener.
563 */
564 public void addPostSelectionListener(
565 String partId,
566 ISelectionListener listener) {
567 selectionService.addPostSelectionListener(partId, listener);
568 }
569
570 /**
571 * Moves a part forward in the Z order of a perspective so it is visible.
572 *
573 * @param part
574 * the part to bring to move forward
575 */
576 public void bringToTop(IWorkbenchPart part) {
577 // Sanity check.
578 Perspective persp = getActivePerspective();
579 if (persp == null || !certifyPart(part))
580 return;
581
582 // If zoomed then ignore.
583 if (isZoomed() && partChangeAffectsZoom(getReference(part)))
584 return;
585
586 String label = part != null ? part.getTitle() : "none"; //$NON-NLS-1$
587 boolean broughtToTop = false;
588 try {
589 UIStats.start(UIStats.BRING_PART_TO_TOP, label);
590 // Move part.
591 if (part instanceof IEditorPart) {
592 IEditorReference ref = (IEditorReference) getReference(part);
593 broughtToTop = getEditorManager().setVisibleEditor(ref, false);
594 actionSwitcher.updateTopEditor((IEditorPart) part);
595 if (broughtToTop) {
596 lastActiveEditor = null;
597 }
598 } else if (part instanceof IViewPart) {
599 IViewReference ref = (IViewReference) getReference(part);
600 broughtToTop = persp.bringToTop(ref);
601 }
602
603 if (broughtToTop) {
604 // Need to make sure that the part lists are sorted correctly.
605 activationList.setActive(part);
606 firePartBroughtToTop(part);
607 }
608 } finally {
609 UIStats.end(UIStats.BRING_PART_TO_TOP, label);
610 }
611 }
612 /**
613 * Resets the layout for the perspective. The active part in the old layout
614 * is activated in the new layout for consistent user context.
615 *
616 * Assumes the busy cursor is active.
617 */
618 private void busyResetPerspective() {
619
620 ViewIntroAdapterPart introViewAdapter = ((WorkbenchIntroManager)getWorkbenchWindow().getWorkbench().getIntroManager()).getViewIntroAdapterPart();
621 PartPane introPane = null;
622 boolean introFullScreen = false;
623 if (introViewAdapter != null) {
624 introPane = ((PartSite)introViewAdapter.getSite()).getPane();
625 introViewAdapter.setHandleZoomEvents(false);
626 introFullScreen = introPane.isZoomed();
627 }
628
629 //try to prevent intro flicker.
630 if (introFullScreen)
631 window.getShell().setRedraw(false);
632
633 try {
634
635 // Always unzoom
636 if (isZoomed())
637 zoomOut();
638
639 // Get the current perspective.
640 // This describes the working layout of the page and differs from
641 // the original template.
642 Perspective oldPersp = getActivePerspective();
643
644 // Map the current perspective to the original template.
645 // If the original template cannot be found then it has been deleted.
646 // In
647 // that case just return. (PR#1GDSABU).
648 IPerspectiveRegistry reg =
649 WorkbenchPlugin.getDefault().getPerspectiveRegistry();
650 PerspectiveDescriptor desc =
651 (PerspectiveDescriptor) reg.findPerspectiveWithId(
652 oldPersp.getDesc().getId());
653 if (desc == null)
654 desc =
655 (PerspectiveDescriptor) reg.findPerspectiveWithId(
656 ((PerspectiveDescriptor) oldPersp.getDesc())
657 .getOriginalId());
658 if (desc == null)
659 return;
660
661 // Notify listeners that we are doing a reset.
662 window.firePerspectiveChanged(this, desc, CHANGE_RESET);
663
664 // Create new persp from original template.
665 Perspective newPersp = createPerspective(desc);
666 if (newPersp == null) {
667 // We're not going through with the reset, so it is complete.
668 window.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
669 return;
670 }
671
672 // Update the perspective list and shortcut
673 perspList.swap(oldPersp, newPersp);
674
675 IContributionItem item =
676 window.findPerspectiveShortcut(oldPersp.getDesc(), this);
677 if (item != null) {
678 ((PerspectiveBarContributionItem) item).setPerspective(newPersp.getDesc());
679 }
680
681 // Install new persp.
682 setPerspective(newPersp);
683
684 // Destroy old persp.
685 disposePerspective(oldPersp);
686
687 // Update the Coolbar layout.
688 resetToolBarLayout();
689
690 // restore the maximized intro
691 if (introViewAdapter != null) {
692 try {
693 // ensure that the intro is visible in the new perspective
694 showView(IIntroConstants.INTRO_VIEW_ID);
695 if (introFullScreen)
696 toggleZoom(introPane.getPartReference());
697 } catch (PartInitException e) {
698 WorkbenchPlugin.log("Could not restore intro", //$NON-NLS-1$
699 StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e));
700 }
701 finally {
702 // we want the intro back to a normal state before we fire the event
703 introViewAdapter.setHandleZoomEvents(true);
704 }
705 }
706 // Notify listeners that we have completed our reset.
707 window.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
708 }
709 finally {
710 // reset the handling of zoom events (possibly for the second time) in case there was
711 // an exception thrown
712 if (introViewAdapter != null)
713 introViewAdapter.setHandleZoomEvents(true);
714
715 if (introFullScreen)
716 window.getShell().setRedraw(true);
717 }
718
719 }
720 /**
721 * Implements <code>setPerspective</code>.
722 *
723 * Assumes that busy cursor is active.
724 *
725 * @param persp
726 * identifies the new perspective.
727 */
728 private void busySetPerspective(IPerspectiveDescriptor desc) {
729 // Create new layout.
730 String label = desc.getId();
731 try {
732 UIStats.start(UIStats.SWITCH_PERSPECTIVE, label);
733 PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
734 Perspective newPersp = findPerspective(realDesc);
735 if (newPersp == null) {
736 newPersp = createPerspective(realDesc);
737 if (newPersp == null)
738 return;
739 window.addPerspectiveShortcut(realDesc, this);
740 }
741
742 // Change layout.
743 setPerspective(newPersp);
744 } finally {
745 UIStats.end(UIStats.SWITCH_PERSPECTIVE, label);
746 }
747 }
748 /**
749 * Shows a view.
750 *
751 * Assumes that a busy cursor is active.
752 */
753 private IViewPart busyShowView(
754 String viewID,
755 String secondaryID,
756 int mode)
757 throws PartInitException {
758 Perspective persp = getActivePerspective();
759 if (persp == null)
760 return null;
761
762 // If this view is already visible just return.
763 IViewReference ref = persp.findView(viewID, secondaryID);
764 IViewPart view = null;
765 if (ref != null)
766 view = ref.getView(true);
767 if (view != null) {
768 busyShowView(view, mode);
769 return view;
770 }
771
772 // Show the view.
773 view = persp.showView(viewID, secondaryID);
774 if (view != null) {
775 zoomOutIfNecessary(view);
776 busyShowView(view, mode);
777
778 window.firePerspectiveChanged(
779 this,
780 getPerspective(),
781 getReference(view),
782 CHANGE_VIEW_SHOW);
783 window.firePerspectiveChanged(
784 this,
785 getPerspective(),
786 CHANGE_VIEW_SHOW);
787 // Just in case view was fast.
788 window.updateFastViewBar();
789 }
790 return view;
791 }
792
793 /*
794 * Performs showing of the view in the given mode.
795 */
796 private void busyShowView(IViewPart part, int mode) {
797 if (mode == VIEW_ACTIVATE)
798 activate(part);
799 else if (mode == VIEW_VISIBLE){
800 IWorkbenchPartReference ref = getActivePartReference();
801 // if there is no active part or it's not a view, bring to top
802 if (ref == null || !(ref instanceof IViewReference))
803 bringToTop(part);
804 else {
805 // otherwise check to see if the we're in the same stack as the active view
806 IViewReference activeView = (IViewReference) ref;
807 IViewReference [] viewStack = getViewReferenceStack(part);
808 for (int i = 0; i < viewStack.length; i++) {
809 if (viewStack[i].equals(activeView))
810 return;
811 }
812 bringToTop(part);
813 }
814 }
815 }
816
817 /**
818 * Returns whether a part exists in the current page.
819 */
820 private boolean certifyPart(IWorkbenchPart part) {
821 //Workaround for bug 22325
822 if (part != null && !(part.getSite() instanceof PartSite))
823 return false;
824
825 if (part instanceof IEditorPart) {
826 IEditorReference ref = (IEditorReference) getReference(part);
827 return getEditorManager().containsEditor(ref);
828 }
829 if (part instanceof IViewPart) {
830 Perspective persp = getActivePerspective();
831 return persp != null && persp.containsView((IViewPart) part);
832 }
833 return false;
834 }
835 /**
836 * Closes the perspective.
837 */
838 public boolean close() {
839 final boolean[] ret = new boolean[1];
840 BusyIndicator.showWhile(null, new Runnable() {
841 public void run() {
842 ret[0] = window.closePage(WorkbenchPage.this, true);
843 }
844 });
845 return ret[0];
846 }
847 /**
848 * See IWorkbenchPage
849 */
850 public boolean closeAllSavedEditors() {
851 // get the Saved editors
852 IEditorReference editors[] = getEditorReferences();
853 IEditorReference savedEditors[] = new IEditorReference[editors.length];
854 int j = 0;
855 for (int i = 0; i < editors.length; i++) {
856 IEditorReference editor = editors[i];
857 if (!editor.isDirty()) {
858 savedEditors[j++] = editor;
859 }
860 }
861 //there are no unsaved editors
862 if (j == 0)
863 return true;
864 IEditorReference[] newSaved = new IEditorReference[j];
865 System.arraycopy(savedEditors, 0, newSaved, 0, j);
866 return closeEditors(newSaved, false);
867 }
868
869 /**
870 * See IWorkbenchPage
871 */
872 public boolean closeAllEditors(boolean save) {
873 return closeEditors(getEditorReferences(), save);
874 }
875
876 /**
877 * See IWorkbenchPage
878 */
879 public boolean closeEditors(IEditorReference[] editorRefs, boolean save) {
880 if (save) {
881 // Intersect the dirty editors with the editors that are closing
882 IEditorPart[] dirty = getDirtyEditors();
883 List intersect = new ArrayList();
884 for (int i = 0; i < editorRefs.length; i++) {
885 IEditorReference reference = editorRefs[i];
886 IEditorPart refPart = reference.getEditor(false);
887 if (refPart != null) {
888 for (int j = 0; j < dirty.length; j++) {
889 if (refPart.equals(dirty[j])) {
890 intersect.add(refPart);
891 break;
892 }
893 }
894 }
895 }
896 // Save parts, exit the method if cancel is pressed.
897 if (intersect.size() > 0) {
898 if (!EditorManager.saveAll(intersect, true, getWorkbenchWindow()))
899 return false;
900 }
901 }
902
903 // If the user has not cancelled a possible save request
904 // and if part is added or removed always unzoom.
905 if (isZoomed())
906 zoomOut();
907
908
909 // Deactivate part if the active part is being closed.
910 boolean deactivated = false;
911 for (int i=0 ; i < editorRefs.length ; i++) {
912 IWorkbenchPart part = editorRefs[i].getPart(false);
913 if (part == activePart) {
914 deactivated = true;
915 setActivePart(null);
916 }
917 if (lastActiveEditor == part) {
918 lastActiveEditor = null;
919 actionSwitcher.updateTopEditor(null);
920 }
921 }
922
923 // Close all editors.
924 for (int i = 0; i < editorRefs.length; i++) {
925 IEditorReference ref = editorRefs[i];
926 // Notify interested listeners before the close
927 window.firePerspectiveChanged(
928 this,
929 getPerspective(),
930 ref,
931 CHANGE_EDITOR_CLOSE);
932 // Close the editor.
933 getEditorManager().closeEditor(ref);
934 activationList.remove(ref);
935 firePartClosed(ref);
936 disposePart(ref);
937 }
938
939 if (!window.isClosing() && deactivated) {
940 activate(activationList.getActive());
941 }
942
943 // Notify interested listeners after the close
944 window.firePerspectiveChanged(
945 this,
946 getPerspective(),
947 CHANGE_EDITOR_CLOSE);
948
949 // Return true on success.
950 return true;
951 }
952
953 /**
954 * See IWorkbenchPage#closeEditor
955 */
956 public boolean closeEditor(IEditorReference editorRef, boolean save) {
957 IEditorPart editor = editorRef.getEditor(false);
958 if (editor != null)
959 return closeEditor(editor, save);
960 getEditorManager().closeEditor(editorRef);
961 activationList.remove(editorRef);
962 firePartClosed(editorRef);
963 return true;
964 }
965 /**
966 * See IWorkbenchPage#closeEditor
967 */
968 public boolean closeEditor(IEditorPart editor, boolean save) {
969 // Sanity check.
970 if (!certifyPart(editor))
971 return false;
972
973 // Save part.
974 if (save && !getEditorManager().saveEditor(editor, true))
975 return false;
976
977 boolean partWasVisible = (editor == getActiveEditor());
978 IEditorReference ref = (IEditorReference) getReference(editor);
979 activationList.remove(ref);
980 boolean partWasActive = (editor == activePart);
981
982 // Removing following lines to fix:
983 // http://dev.eclipse.org/bugs/show_bug.cgi?id=28031
984 // // Deactivate part.
985 // if (partWasActive)
986 // setActivePart(null);
987 // if (lastActiveEditor == editor) {
988 // actionSwitcher.updateTopEditor(null);
989 // lastActiveEditor = null;
990 // }
991
992 // Notify interested listeners before the close
993 window.firePerspectiveChanged(
994 this,
995 getPerspective(),
996 ref,
997 CHANGE_EDITOR_CLOSE);
998 // Close the part.
999 getEditorManager().closeEditor(ref);
1000 firePartClosed(ref);
1001 disposePart(ref);
1002 // Notify interested listeners after the close
1003 window.firePerspectiveChanged(
1004 this,
1005 getPerspective(),
1006 CHANGE_EDITOR_CLOSE);
1007 // Activate new part.
1008 if (partWasActive) {
1009 IWorkbenchPart top = activationList.getTopEditor();
1010 zoomOutIfNecessary(top);
1011 if (top == null) {
1012 // Fix for bug #31122 (side effect from fix 28031 above)
1013 actionSwitcher.updateTopEditor(null);
1014 if (lastActiveEditor == editor)
1015 lastActiveEditor = null;
1016 // End - Fix for bug #31122
1017 top = activationList.getActive();
1018 }
1019 if (top != null)
1020 activate(top);
1021 else
1022 setActivePart(null);
1023 } else if (partWasVisible) {
1024 IEditorPart top = activationList.getTopEditor();
1025 zoomOutIfNecessary(top);
1026
1027 // The editor we are bringing to top may already the visible
1028 // editor (due to editor manager behavior when it closes and
1029 // editor).
1030 // If this is the case, bringToTop will not call
1031 // firePartBroughtToTop.
1032 // We must fire it from here.
1033 if (top != null) {
1034 boolean isTop = editorMgr.getVisibleEditor() == top;
1035 bringToTop(top);
1036 if (isTop)
1037 firePartBroughtToTop(top);
1038 } else
1039 actionSwitcher.updateTopEditor(top);
1040 }
1041
1042 // Return true on success.
1043 return true;
1044 }
1045 /**
1046 * Closes the specified perspective. If last perspective, then entire page
1047 * is closed.
1048 *
1049 * @param desc
1050 * the descriptor of the perspective to be closed
1051 * @param save
1052 * whether the page's editors should be save if last perspective
1053 */
1054 /* package */
1055 void closePerspective(IPerspectiveDescriptor desc, boolean save) {
1056 Perspective persp = findPerspective(desc);
1057 if (persp != null)
1058 closePerspective(persp, save, true);
1059 }
1060
1061 /**
1062 * Closes the specified perspective. If last perspective, then entire page
1063 * is closed.
1064 *
1065 * @param persp
1066 * the perspective to be closed
1067 * @param save
1068 * whether the page's editors should be save if last perspective
1069 */
1070 /* package */
1071 void closePerspective(Perspective persp, boolean save, boolean closePage) {
1072
1073 // Always unzoom
1074 if (isZoomed())
1075 zoomOut();
1076
1077 // Close all editors on last perspective close
1078 if (perspList.size() == 1 && getEditorManager().getEditorCount() > 0) {
1079 // Close all editors
1080 if (!closeAllEditors(save))
1081 return;
1082 }
1083
1084 // Dispose of the perspective
1085 boolean isActive = (perspList.getActive() == persp);
1086 window.removePerspectiveShortcut(persp.getDesc(), this);
1087 if (isActive)
1088 setPerspective(perspList.getNextActive());
1089 disposePerspective(persp);
1090 if (closePage && perspList.size() == 0)
1091 close();
1092 }
1093
1094 /**
1095 * Closes all perspectives in the page. The page is kept so as not to lose
1096 * the input.
1097 *
1098 * @param save
1099 * whether the page's editors should be saved
1100 */
1101 /* package */
1102 void closeAllPerspectives() {
1103
1104 if (perspList.isEmpty())
1105 return;
1106
1107 // Always unzoom
1108 if (isZoomed())
1109 zoomOut();
1110
1111 // Close all editors
1112 if (!closeAllEditors(true))
1113 return;
1114
1115 // Deactivate the active perspective and part
1116 setPerspective((Perspective) null);
1117
1118 // Close each perspective in turn
1119 PerspectiveList oldList = perspList;
1120 perspList = new PerspectiveList();
1121 Iterator enum = oldList.iterator();
1122 while (enum.hasNext())
1123 closePerspective((Perspective) enum.next(), false, false);
1124 close();
1125 }
1126 /**
1127 * Creates the client composite.
1128 */
1129 private void createClientComposite() {
1130 final Composite parent = window.getPageComposite();
1131 composite = new Composite(parent, SWT.NONE);
1132 composite.setVisible(false); // Make visible on activate.
1133 composite.setBounds(parent.getClientArea());
1134 resizeListener = new ControlAdapter() {
1135 public void controlResized(ControlEvent e) {
1136 composite.setBounds(parent.getClientArea());
1137 }
1138 };
1139 parent.addControlListener(resizeListener);
1140 }
1141 /**
1142 * Creates a new view set. Return null on failure.
1143 */
1144 private Perspective createPerspective(PerspectiveDescriptor desc) {
1145 String label = desc.getId();
1146 try {
1147 UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
1148 Perspective persp = new Perspective(desc, this);
1149 perspList.add(persp);
1150 window.firePerspectiveOpened(this, desc);
1151 IViewReference refs[] = persp.getViewReferences();
1152 for (int i = 0; i < refs.length; i++) {
1153 IViewReference ref = refs[i];
1154 if (ref != null)
1155 addPart(ref);
1156 }
1157 return persp;
1158 } catch (WorkbenchException e) {
1159 if (!((Workbench) window.getWorkbench()).isStarting()) {
1160 MessageDialog.openError(window.getShell(), WorkbenchMessages.getString("Error"), //$NON-NLS-1$
1161 WorkbenchMessages.format("Workbench.showPerspectiveError", new String[] { desc.getId()})); //$NON-NLS-1$
1162 }
1163 return null;
1164 } finally {
1165 UIStats.end(UIStats.CREATE_PERSPECTIVE, label);
1166 }
1167 }
1168 /**
1169 * Open the tracker to allow the user to move the specified part using
1170 * keyboard.
1171 */
1172 public void openTracker(ViewPane pane) {
1173 Perspective persp = getActivePerspective();
1174 if (persp != null)
1175 persp.openTracker(pane);
1176 }
1177 /**
1178 * Add a part to the activation list.
1179 */
1180 protected void addPart(IWorkbenchPartReference ref) {
1181 activationList.add(ref);
1182 }
1183 /**
1184 * Remove a part from the activation list.
1185 */
1186 protected void removePart(IWorkbenchPartReference ref) {
1187 activationList.remove(ref);
1188 }
1189 /**
1190 * Deactivates a part. The pane is unhilighted.
1191 */
1192 private void deactivatePart(IWorkbenchPart part) {
1193 if (part != null) {
1194 PartSite site = (PartSite) part.getSite();
1195 site.getPane().showFocus(false);
1196 }
1197 }
1198 private void disposePart(IWorkbenchPartReference ref) {
1199 final WorkbenchPartReference ref0 = (WorkbenchPartReference) ref;
1200 Platform.run(new SafeRunnable() {
1201 public void run() {
1202 ref0.dispose();
1203 }
1204 public void handleException(Throwable e) {
1205 //Exception has already being logged by Core. Do nothing.
1206 }
1207 });
1208 }
1209 /**
1210 * Cleanup.
1211 */
1212 public void dispose() {
1213
1214 // Always unzoom
1215 if (isZoomed())
1216 zoomOut();
1217
1218 // Close and dispose the editors.
1219 closeAllEditors(false);
1220
1221 // Capture views.
1222 IViewReference refs[] = viewFactory.getViews();
1223
1224 // Get rid of perspectives. This will close the views.
1225 Iterator enum = perspList.iterator();
1226 while (enum.hasNext()) {
1227 Perspective perspective = (Perspective) enum.next();
1228 window.removePerspectiveShortcut(perspective.getDesc(), this);
1229 window.firePerspectiveClosed(this, perspective.getDesc());
1230 perspective.dispose();
1231 }
1232 perspList = new PerspectiveList();
1233
1234 // Dispose views.
1235 final int errors[] = { 0 };
1236 for (int i = 0; i < refs.length; i++) {
1237 final WorkbenchPartReference ref = (WorkbenchPartReference) refs[i];
1238 firePartClosed(refs[i]);
1239 Platform.run(new SafeRunnable() {
1240 public void run() {
1241 ref.dispose();
1242 }
1243 public void handleException(Throwable e) {
1244 errors[0]++;
1245 }
1246 });
1247 }
1248 if (errors[0] > 0) {
1249 String message;
1250 if (errors[0] == 1)
1251 message = WorkbenchMessages.getString("WorkbenchPage.oneErrorClosingPage"); //$NON-NLS-1$
1252 else
1253 message = WorkbenchMessages.getString("WorkbenchPage.multipleErrorsClosingPage"); //$NON-NLS-1$
1254 MessageDialog.openError(null, WorkbenchMessages.getString("Error"), message); //$NON-NLS-1$
1255 }
1256 activePart = null;
1257 activationList = new ActivationList();
1258
1259 // Get rid of editor presentation.
1260 editorPresentation.dispose();
1261
1262 // Get rid of composite.
1263 window.getPageComposite().removeControlListener(resizeListener);
1264 composite.dispose();
1265
1266 navigationHistory.dispose();
1267
1268 stickyPerspectives.clear();
1269 }
1270 /**
1271 * Dispose a perspective.
1272 */
1273 private void disposePerspective(Perspective persp) {
1274 // Get views.
1275 IViewReference refs[] = persp.getViewReferences();
1276
1277 // Get rid of perspective.
1278 perspList.remove(persp);
1279 window.firePerspectiveClosed(this, persp.getDesc());
1280 persp.dispose();
1281
1282 // Loop through the views.
1283 for (int i = 0; i < refs.length; i++) {
1284 IViewReference ref = refs[i];
1285
1286 //If the part is no longer reference then dispose it.
1287 boolean exists = viewFactory.hasView(ref);
1288 if (!exists) {
1289 firePartClosed(ref);
1290 activationList.remove(ref);
1291 disposePart(ref);
1292 }
1293 }
1294 stickyPerspectives.remove(persp.getDesc());
1295 }
1296 /**
1297 * @return NavigationHistory
1298 */
1299 public INavigationHistory getNavigationHistory() {
1300 return navigationHistory;
1301 }
1302
1303 /**
1304 * Edits the action sets.
1305 */
1306 public boolean editActionSets() {
1307 Perspective persp = getActivePerspective();
1308 if (persp == null)
1309 return false;
1310
1311 // Create list dialog.
1312 CustomizePerspectiveDialog dlg =
1313 new CustomizePerspectiveDialog(window.getShell(), persp);
1314
1315 // Open.
1316 boolean ret = (dlg.open() == Window.OK);
1317 if (ret) {
1318 window.updateActionSets();
1319 window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
1320 window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET_COMPLETE);
1321 }
1322 return ret;
1323 }
1324 /**
1325 * Returns the first view manager with given ID.
1326 */
1327 public Perspective findPerspective(IPerspectiveDescriptor desc) {
1328 Iterator enum = perspList.iterator();
1329 while (enum.hasNext()) {
1330 Perspective mgr = (Perspective) enum.next();
1331 if (desc.getId().equals(mgr.getDesc().getId()))
1332 return mgr;
1333 }
1334 return null;
1335 }
1336 /**
1337 * See IWorkbenchPage@findView.
1338 */
1339 public IViewPart findView(String id) {
1340 IViewReference ref = findViewReference(id);
1341 if (ref == null)
1342 return null;
1343 return ref.getView(true);
1344 }
1345
1346 /* (non-Javadoc)
1347 * @see org.eclipse.ui.IWorkbenchPage
1348 */
1349 public IViewReference findViewReference(String viewId) {
1350 return findViewReference(viewId, null);
1351 }
1352
1353 /* (non-Javadoc)
1354 * @see org.eclipse.ui.IWorkbenchPage
1355 */
1356 public IViewReference findViewReference(String viewId, String secondaryId) {
1357 Perspective persp = getActivePerspective();
1358 if (persp == null)
1359 return null;
1360 return persp.findView(viewId, secondaryId);
1361 }
1362
1363 /**
1364 * Fire part activation out.
1365 */
1366 private void firePartActivated(IWorkbenchPart part) {
1367 String label = "activate::" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
1368 try {
1369 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1370 partListeners.firePartActivated(part);
1371 partListeners2.firePartActivated(getReference(part));
1372 selectionService.partActivated(part);
1373 } finally {
1374 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1375 }
1376 }
1377 /**
1378 * Fire part brought to top out.
1379 */
1380 private void firePartBroughtToTop(IWorkbenchPart part) {
1381 String label = "bringToTop::" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
1382 try {
1383 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1384 partListeners.firePartBroughtToTop(part);
1385 partListeners2.firePartBroughtToTop(getReference(part));
1386 selectionService.partBroughtToTop(part);
1387 } finally {
1388 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1389 }
1390 }
1391 /**
1392 * Fire part close out.
1393 */
1394 private void firePartClosed(IWorkbenchPartReference ref) {
1395 String label = "close" + ref.getTitle(); //$NON-NLS-1$
1396 try {
1397 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1398 IWorkbenchPart part = ref.getPart(false);
1399 if (part != null) {
1400 partListeners.firePartClosed(part);
1401 selectionService.partClosed(part);
1402 }
1403 partListeners2.firePartClosed(ref);
1404 } finally {
1405 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1406 }
1407 }
1408 /**
1409 * Fire part deactivation out.
1410 */
1411 private void firePartDeactivated(IWorkbenchPart part) {
1412 String label = "deactivate" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
1413 try {
1414 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1415 partListeners.firePartDeactivated(part);
1416 partListeners2.firePartDeactivated(getReference(part));
1417 selectionService.partDeactivated(part);
1418 } finally {
1419 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1420 }
1421 }
1422 /**
1423 * Fire part open out.
1424 */
1425 public void firePartOpened(IWorkbenchPart part) {
1426 String label = "opened" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
1427 try {
1428 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1429 partListeners.firePartOpened(part);
1430 partListeners2.firePartOpened(getReference(part));
1431 selectionService.partOpened(part);
1432 } finally {
1433 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1434 }
1435 }
1436 /**
1437 * Fire part input changed out.
1438 */
1439 private void firePartInputChanged(IWorkbenchPart part) {
1440 String label = "inputChanged" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
1441 try {
1442 UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
1443 partListeners2.firePartInputChanged(getReference(part));
1444 selectionService.partInputChanged(part);
1445 } finally {
1446 UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
1447 }
1448 }
1449 /**
1450 * Notify property change listeners about a property change.
1451 *
1452 * @param changeId
1453 * the change id
1454 * @param oldValue
1455 * old property value
1456 * @param newValue
1457 * new property value
1458 */
1459 private void firePropertyChange(
1460 String changeId,
1461 Object oldValue,
1462 Object newValue) {
1463 Object[] listeners = propertyChangeListeners.getListeners();
1464 PropertyChangeEvent event =
1465 new PropertyChangeEvent(this, changeId, oldValue, newValue);
1466
1467 for (int i = 0; i < listeners.length; i++) {
1468 ((IPropertyChangeListener) listeners[i]).propertyChange(event);
1469 }
1470 }
1471 /*
1472 * Returns the action bars.
1473 */
1474 public IActionBars getActionBars() {
1475 if (actionBars == null)
1476 actionBars = new WWinActionBars(window);
1477 return actionBars;
1478 }
1479 /**
1480 * Returns an array of the visible action sets.
1481 */
1482 public IActionSetDescriptor[] getActionSets() {
1483 Perspective persp = getActivePerspective();
1484 if (persp != null)
1485 return persp.getActionSets();
1486 else
1487 return new IActionSetDescriptor[0];
1488 }
1489
1490 /**
1491 * @see IWorkbenchPage
1492 */
1493 public IEditorPart getActiveEditor() {
1494 return getEditorManager().getVisibleEditor();
1495 }
1496 /*
1497 * (non-Javadoc) Method declared on IPartService
1498 */
1499 public IWorkbenchPart getActivePart() {
1500 return activePart;
1501 }
1502 /*
1503 * (non-Javadoc) Method declared on IPartService
1504 */
1505 public IWorkbenchPartReference getActivePartReference() {
1506 return getReference(activePart);
1507 }
1508 /**
1509 * Returns the active perspective for the page, <code>null</code> if
1510 * none.
1511 */
1512 public Perspective getActivePerspective() {
1513 return perspList.getActive();
1514 }
1515 /**
1516 * Returns the client composite.
1517 */
1518 public Composite getClientComposite() {
1519 return composite;
1520 }
1521 /**
1522 * Answer the editor manager for this window.
1523 */
1524// for dynamic UI - change access from private to protected
1525 protected EditorManager getEditorManager() {
1526 return editorMgr;
1527 }
1528 /**
1529 * Answer the perspective presentation.
1530 */
1531 public PerspectiveHelper getPerspectivePresentation() {
1532 if (getActivePerspective() != null)
1533 return getActivePerspective().getPresentation();
1534 return null;
1535 }
1536 /**
1537 * Answer the editor presentation.
1538 */
1539 public EditorAreaHelper getEditorPresentation() {
1540 return editorPresentation;
1541 }
1542 /**
1543 * See IWorkbenchPage.
1544 */
1545 public IEditorPart[] getEditors() {
1546 final IEditorReference refs[] = getEditorReferences();
1547 final ArrayList result = new ArrayList(refs.length);
1548 Display d = getWorkbenchWindow().getShell().getDisplay();
1549 //Must be backward compatible.
1550 d.syncExec(new Runnable() {
1551 public void run() {
1552 for (int i = 0; i < refs.length; i++) {
1553 IWorkbenchPart part = refs[i].getPart(true);
1554 if (part != null)
1555 result.add(part);
1556 }
1557 }
1558 });
1559 final IEditorPart editors[] = new IEditorPart[result.size()];
1560 return (IEditorPart[]) result.toArray(editors);
1561 }
1562
1563 public IEditorPart[] getDirtyEditors() {
1564 return getEditorManager().getDirtyEditors();
1565 }
1566 public IEditorPart findEditor(IEditorInput input) {
1567 return getEditorManager().findEditor(input);
1568 }
1569 /**
1570 * See IWorkbenchPage.
1571 */
1572 public IEditorReference[] getEditorReferences() {
1573 return getEditorManager().getEditors();
1574 }
1575 /**
1576 * Returns the docked views.
1577 */
1578 public IViewReference[] getFastViews() {
1579 Perspective persp = getActivePerspective();
1580 if (persp != null)
1581 return persp.getFastViews();
1582 else
1583 return new IViewReference[0];
1584 }
1585 /**
1586 * @see IWorkbenchPage
1587 */
1588 public IAdaptable getInput() {
1589 return input;
1590 }
1591 /**
1592 * Returns the page label. This is a combination of the page input and
1593 * active perspective.
1594 */
1595 public String getLabel() {
1596 String label = WorkbenchMessages.getString("WorkbenchPage.UnknownLabel"); //$NON-NLS-1$
1597 if (input != null) {
1598 IWorkbenchAdapter adapter =
1599 (IWorkbenchAdapter) input.getAdapter(IWorkbenchAdapter.class);
1600 if (adapter != null)
1601 label = adapter.getLabel(input);
1602 }
1603 Perspective persp = getActivePerspective();
1604 if (persp != null)
1605 label = WorkbenchMessages.format("WorkbenchPage.PerspectiveFormat", new Object[] { label, persp.getDesc().getLabel()}); //$NON-NLS-1$
1606 else if (deferredActivePersp != null)
1607 label = WorkbenchMessages.format("WorkbenchPage.PerspectiveFormat", new Object[] { label, deferredActivePersp.getLabel()}); //$NON-NLS-1$
1608 return label;
1609 }
1610 /**
1611 * Returns the new wizard actions the page. This is List of Strings.
1612 */
1613 public ArrayList getNewWizardActionIds() {
1614 Perspective persp = getActivePerspective();
1615 if (persp != null)
1616 return persp.getNewWizardActionIds();
1617 else
1618 return new ArrayList();
1619 }
1620 /**
1621 * Returns the perspective.
1622 */
1623 public IPerspectiveDescriptor getPerspective() {
1624 if (deferredActivePersp != null)
1625 return deferredActivePersp;
1626 Perspective persp = getActivePerspective();
1627 if (persp != null)
1628 return persp.getDesc();
1629 else
1630 return null;
1631 }
1632 /**
1633 * Returns the perspective actions for this page. This is List of Strings.
1634 */
1635 public ArrayList getPerspectiveActionIds() {
1636 Perspective persp = getActivePerspective();
1637 if (persp != null)
1638 return persp.getPerspectiveActionIds();
1639 else
1640 return new ArrayList();
1641 }
1642 /*
1643 * (non-Javadoc) Method declared on ISelectionService
1644 */
1645 public ISelection getSelection() {
1646 return selectionService.getSelection();
1647 }
1648
1649 /*
1650 * (non-Javadoc) Method declared on ISelectionService
1651 */
1652 public ISelection getSelection(String partId) {
1653 return selectionService.getSelection(partId);
1654 }
1655
1656 /**
1657 * Returns the ids of the parts to list in the Show In... prompter. This is
1658 * a List of Strings.
1659 */
1660 public ArrayList getShowInPartIds() {
1661 Perspective persp = getActivePerspective();
1662 if (persp != null)
1663 return persp.getShowInPartIds();
1664 else
1665 return new ArrayList();
1666 }
1667
1668 /**
1669 * The user successfully performed a Show In... action on the specified
1670 * part. Update the list of Show In items accordingly.
1671 */
1672 public void performedShowIn(String partId) {
1673 Perspective persp = getActivePerspective();
1674 if (persp != null) {
1675 persp.performedShowIn(partId);
1676 }
1677 }
1678
1679 /**
1680 * Sorts the given collection of show in target part ids in MRU order.
1681 */
1682 public void sortShowInPartIds(ArrayList partIds) {
1683 final Perspective persp = getActivePerspective();
1684 if (persp != null) {
1685 Collections.sort(partIds, new Comparator() {
1686 public int compare(Object a, Object b) {
1687 long ta = persp.getShowInTime((String) a);
1688 long tb = persp.getShowInTime((String) b);
1689 return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
1690 }
1691 });
1692 }
1693 }
1694
1695 /**
1696 * Returns the show view actions the page. This is a List of Strings.
1697 */
1698 public ArrayList getShowViewActionIds() {
1699 Perspective persp = getActivePerspective();
1700 if (persp != null)
1701 return persp.getShowViewActionIds();
1702 else
1703 return new ArrayList();
1704 }
1705 /**
1706 * Returns the unprotected window.
1707 */
1708 protected WorkbenchWindow getUnprotectedWindow() {
1709 return window;
1710 }
1711 /*
1712 * Returns the view factory.
1713 */
1714 public ViewFactory getViewFactory() {
1715 if (viewFactory == null) {
1716 viewFactory =
1717 new ViewFactory(
1718 this,
1719 WorkbenchPlugin.getDefault().getViewRegistry());
1720 }
1721 return viewFactory;
1722 }
1723
1724 /**
1725 * Returns all parts that are owned by this page
1726 *
1727 * @return
1728 */
1729 IWorkbenchPartReference[] getAllParts() {
1730 IViewReference[] views = viewFactory.getViews();
1731 IEditorReference[] editors = getEditorReferences();
1732
1733 IWorkbenchPartReference[] result = new IWorkbenchPartReference[views.length + editors.length];
1734 int resultIdx = 0;
1735
1736 for (int i = 0; i < views.length; i++) {
1737 result[resultIdx++] = views[i];
1738 }
1739
1740 for (int i = 0; i < editors.length; i++) {
1741 result[resultIdx++] = editors[i];
1742 }
1743
1744 return result;
1745 }
1746
1747 /**
1748 * Returns all open parts that are owned by this page (that is, all parts
1749 * for which a part opened event would have been sent -- these would be
1750 * activated parts whose controls have already been created.
1751 */
1752 IWorkbenchPartReference[] getOpenParts() {
1753 IWorkbenchPartReference[] refs = getAllParts();
1754 List result = new ArrayList();
1755
1756 for (int i = 0; i < refs.length; i++) {
1757 IWorkbenchPartReference reference = refs[i];
1758
1759 IWorkbenchPart part = reference.getPart(false);
1760 if (part != null) {
1761 result.add(reference);
1762 }
1763 }
1764
1765 return (IWorkbenchPartReference[]) result.toArray(new IWorkbenchPartReference[result.size()]);
1766 }
1767
1768 /**
1769 * See IWorkbenchPage.
1770 */
1771 public IViewReference[] getViewReferences() {
1772 Perspective persp = getActivePerspective();
1773 if (persp != null)
1774 return persp.getViewReferences();
1775 else
1776 return new IViewReference[0];
1777 }
1778 /**
1779 * See IWorkbenchPage.
1780 */
1781 public IViewPart[] getViews() {
1782 Perspective persp = getActivePerspective();
1783 if (persp != null) {
1784 IViewReference refs[] = persp.getViewReferences();
1785 ArrayList parts = new ArrayList(refs.length);
1786 for (int i = 0; i < refs.length; i++) {
1787 IWorkbenchPart part = refs[i].getPart(true);
1788 if (part != null)
1789 parts.add(part);
1790 }
1791 IViewPart[] result = new IViewPart[parts.size()];
1792 return (IViewPart[]) parts.toArray(result);
1793 }
1794 return new IViewPart[0];
1795 }
1796 /**
1797 * See IWorkbenchPage.
1798 */
1799 public IWorkbenchWindow getWorkbenchWindow() {
1800 return window;
1801 }
1802 /**
1803 * Implements IWorkbenchPage
1804 *
1805 * @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
1806 * @since 2.0
1807 * @deprecated individual views should store a working set if needed
1808 */
1809 public IWorkingSet getWorkingSet() {
1810 return workingSet;
1811 }
1812
1813 /**
1814 * @see IWorkbenchPage
1815 */
1816 public void hideActionSet(String actionSetID) {
1817 Perspective persp = getActivePerspective();
1818 if (persp != null) {
1819 persp.hideActionSet(actionSetID);
1820 window.updateActionSets();
1821 window.firePerspectiveChanged(
1822 this,
1823 getPerspective(),
1824 CHANGE_ACTION_SET_HIDE);
1825 }
1826 }
1827
1828 /* (non-Javadoc)
1829 * @see org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
1830 */
1831 public void hideView(IViewReference ref) {
1832 if (ref == null)
1833 return;
1834 IWorkbenchPart part = ref.getPart(false);
1835 if (part != null) {
1836 hideView((IViewPart) part);
1837 } else {
1838 hideView(getActivePerspective(), ref);
1839 }
1840 }
1841
1842 /* package */ void refreshActiveView() {
1843 IWorkbenchPart nextActive = activationList.getActive();
1844
1845 if (nextActive != activePart) {
1846 if (nextActive != null) {
1847 activate(nextActive);
1848 } else {
1849 setActivePart(null);
1850 }
1851 }
1852 }
1853
1854 /**
1855 * See IPerspective
1856 */
1857 public void hideView(IViewPart view) {
1858 // Sanity check.
1859 Perspective persp = getActivePerspective();
1860 if (persp == null || !certifyPart(view))
1861 return;
1862
1863 // If part is added / removed always unzoom.
1864 IViewReference ref = (IViewReference) getReference(view);
1865 if (isZoomed() && !isFastView(ref))
1866 zoomOut();
1867
1868 // Confirm.
1869 if (!persp.canCloseView(view))
1870 return;
1871
1872 // Activate new part.
1873 if (view == activePart) {
1874 IWorkbenchPart prevActive = activationList.getPreviouslyActive();
1875 if (prevActive != null)
1876 activate(prevActive);
1877 else
1878 setActivePart(null);
1879 }
1880
1881 hideView(persp, ref);
1882
1883 }
1884 private void hideView(Perspective persp, IViewReference ref) {
1885 // Notify interested listeners before the hide
1886 window.firePerspectiveChanged(this, getPerspective(), ref, CHANGE_VIEW_HIDE);
1887
1888 // Hide the part.
1889 persp.hideView(ref);
1890
1891 // If the part is no longer reference then dispose it.
1892 boolean exists = viewFactory.hasView(ref);
1893 if (!exists) {
1894 firePartClosed(ref);
1895 disposePart(ref);
1896 activationList.remove(ref);
1897
1898 /*
1899 * Bug 42684. A ViewPane instance has been disposed, but an attempt
1900 * is then made to remove focus from it. This happens because the
1901 * ViewPane is still viewed as the active part. The activePart
1902 * should always be modified when the view is changed. activePart
1903 * isn't really needed anymore (see declaration).
1904 */
1905 activePart = activationList.getActive();
1906 }
1907
1908 // Notify interested listeners after the hide
1909 window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
1910
1911 // Just in case view was fast.
1912 window.updateFastViewBar();
1913 }
1914
1915 /**
1916 * Initialize the page.
1917 *
1918 * @param w
1919 * the parent window
1920 * @param layoutID
1921 * may be <code>null</code> if restoring from file
1922 * @param input
1923 * the page input
1924 */
1925 private void init(WorkbenchWindow w, String layoutID, IAdaptable input)
1926 throws WorkbenchException {
1927 // Save args.
1928 this.window = w;
1929 this.input = input;
1930
1931 // Create presentation.
1932 createClientComposite();
1933 editorPresentation = new EditorAreaHelper(this);
1934 editorMgr = new EditorManager(window, this, editorPresentation);
1935
1936 // Get perspective descriptor.
1937 if (layoutID != null) {
1938 PerspectiveDescriptor desc =
1939 (PerspectiveDescriptor) WorkbenchPlugin
1940 .getDefault()
1941 .getPerspectiveRegistry()
1942 .findPerspectiveWithId(layoutID);
1943 if (desc == null)
1944 throw new WorkbenchException(WorkbenchMessages.getString("WorkbenchPage.ErrorRecreatingPerspective")); //$NON-NLS-1$
1945 Perspective persp = createPerspective(desc);
1946 if (persp == null)
1947 return;
1948 perspList.setActive(persp);
1949 window.firePerspectiveActivated(this, desc);
1950 }
1951 }
1952 /**
1953 * See IWorkbenchPage.
1954 */
1955 public boolean isPartVisible(IWorkbenchPart part) {
1956 return ((PartSite) part.getSite()).getPane().isVisible();
1957 }
1958 /**
1959 * See IWorkbenchPage.
1960 */
1961 public boolean isEditorAreaVisible() {
1962 Perspective persp = getActivePerspective();
1963 if (persp == null)
1964 return false;
1965 return persp.isEditorAreaVisible();
1966 }
1967 /**
1968 * Returns whether the view is fast.
1969 */
1970 public boolean isFastView(IViewReference ref) {
1971 Perspective persp = getActivePerspective();
1972 if (persp != null)
1973 return persp.isFastView(ref);
1974 else
1975 return false;
1976 }
1977 /**
1978 * Returns whether the layout of the active
1979 * perspective is fixed.
1980 */
1981 public boolean isFixedLayout() {
1982 Perspective persp = getActivePerspective();
1983 if (persp != null)
1984 return persp.isFixedLayout();
1985 else
1986 return false;
1987 }
1988
1989 /**
1990 * Return the active fast view or null if there are no fast views or if
1991 * there are all minimized.
1992 */
1993 public IViewReference getActiveFastView() {
1994 Perspective persp = getActivePerspective();
1995 if (persp != null)
1996 return persp.getActiveFastView();
1997 else
1998 return null;
1999 }
2000 /**
2001 * Return true if the perspective has a dirty editor.
2002 */
2003 protected boolean isSaveNeeded() {
2004 return getEditorManager().isSaveAllNeeded();
2005 }
2006 /**
2007 * Returns whether the page is zoomed.
2008 */
2009 public boolean isZoomed() {
2010 Perspective persp = getActivePerspective();
2011 if (persp == null)
2012 return false;
2013 if (persp.getPresentation() == null)
2014 return false;
2015 return persp.getPresentation().isZoomed();
2016 }
2017 /**
2018 * Returns <code>true</code> if the window needs to unzoom for the given
2019 * IWorkbenchPart to be seen by the user. Returns false otherwise.
2020 *
2021 * @param part
2022 * the part whose visibility is to be determined
2023 * @return <code>true</code> if the window needs to unzoom for the given
2024 * IWorkbenchPart to be seen by the user, <code>false</code>
2025 * otherwise.
2026 */
2027 private boolean needToZoomOut(IWorkbenchPart part) {
2028 // part is an editor
2029 if (part instanceof IEditorPart) {
2030 if (getActivePart() instanceof IViewPart) {
2031 return true;
2032 }
2033 EditorSite site = (EditorSite) part.getSite();
2034 EditorPane pane = (EditorPane) site.getPane();
2035 EditorStack book = pane.getWorkbook();
2036 return !book.equals(book.getEditorArea().getActiveWorkbook());
2037 }
2038 // part is a view
2039 if (part instanceof IViewPart) {
2040 if (isFastView((IViewReference) getReference(part))
2041 || part.equals(getActivePart()))
2042 return false;
2043 else
2044 return true;
2045 }
2046
2047 return true;
2048 }
2049 /**
2050 * This method is called when the page is activated.
2051 */
2052 protected void onActivate() {
2053 Iterator enum = perspList.iterator();
2054 while (enum.hasNext()) {
2055 Perspective perspective = (Perspective) enum.next();
2056 window.addPerspectiveShortcut(perspective.getDesc(), this);
2057 }
2058 composite.setVisible(true);
2059 Perspective persp = getActivePerspective();
2060
2061 if (persp != null) {
2062 window.selectPerspectiveShortcut(persp.getDesc(), this, true);
2063 persp.onActivate();
2064 updateVisibility(null, persp);
2065 }
2066 if (activePart == null && persp != null) {
2067 IViewReference refs[] = persp.getViewReferences();
2068 for (int i = 0; i < refs.length; i++) {
2069 IViewReference ref = refs[i];
2070 if (ref != null) {
2071 activePart = ref.getPart(false);
2072 if (activePart != null)
2073 break;
2074 }
2075 }
2076 }
2077 if (activePart != null) {
2078 activationList.setActive(activePart);
2079
2080 activatePart(activePart);
2081 actionSwitcher.updateActivePart(activePart);
2082 if (activePart instanceof IEditorPart) {
2083 lastActiveEditor = (IEditorPart) activePart;
2084 actionSwitcher.updateTopEditor((IEditorPart) activePart);
2085 } else {
2086 IEditorPart editor = editorMgr.getVisibleEditor();
2087 if (editor != null) {
2088 actionSwitcher.updateTopEditor(editor);
2089
2090 // inform the site's action bars of the current editor
2091 // (important that this occur during page opening).
2092 PartSite site = (PartSite) editor.getSite();
2093 SubActionBars bars = (SubActionBars) site.getActionBars();
2094 bars.partChanged(editor);
2095 }
2096 }
2097 firePartActivated(activePart);
2098 } else {
2099 composite.setFocus();
2100 }
2101 }
2102 /**
2103 * This method is called when the page is deactivated.
2104 */
2105 protected void onDeactivate() {
2106 if (activePart != null) {
2107 deactivatePart(activePart);
2108 actionSwitcher.updateActivePart(null);
2109 firePartDeactivated(activePart);
2110 }
2111 actionSwitcher.updateTopEditor(null);
2112 lastActiveEditor = null;
2113 if (getActivePerspective() != null)
2114 getActivePerspective().onDeactivate();
2115 composite.setVisible(false);
2116 Iterator enum = perspList.iterator();
2117 while (enum.hasNext()) {
2118 Perspective perspective = (Perspective) enum.next();
2119 window.removePerspectiveShortcut(perspective.getDesc(), this);
2120 }
2121 }
2122 /**
2123 * See IWorkbenchPage.
2124 */
2125 public void reuseEditor(IReusableEditor editor, IEditorInput input) {
2126 editor.setInput(input);
2127 firePartInputChanged(editor);
2128 }
2129 /**
2130 * See IWorkbenchPage.
2131 */
2132 public IEditorPart openEditor(IEditorInput input, String editorID)
2133 throws PartInitException {
2134 return openEditor(input, editorID, true);
2135 }
2136 /**
2137 * See IWorkbenchPage.
2138 */
2139 public IEditorPart openEditor(
2140 final IEditorInput input,
2141 final String editorID,
2142 final boolean activate)
2143 throws PartInitException {
2144 if (input == null || editorID == null) {
2145 throw new IllegalArgumentException();
2146 }
2147
2148 final IEditorPart result[] = new IEditorPart[1];
2149 final PartInitException ex[] = new PartInitException[1];
2150 BusyIndicator
2151 .showWhile(
2152 window.getWorkbench().getDisplay(),
2153 new Runnable() {
2154 public void run() {
2155 try {
2156 result[0] = busyOpenEditor(input, editorID, activate);
2157 } catch (PartInitException e) {
2158 ex[0] = e;
2159 }
2160 }
2161 });
2162 if (ex[0] != null)
2163 throw ex[0];
2164 return result[0];
2165 }
2166 /**
2167 * See IWorkbenchPage.openEditor
2168 */
2169 private IEditorPart busyOpenEditor(IEditorInput input, String editorID,
2170 boolean activate) throws PartInitException {
2171
2172 final Workbench workbench = (Workbench) getWorkbenchWindow()
2173 .getWorkbench();
2174 workbench.largeUpdateStart();
2175
2176 try {
2177 return busyOpenEditorBatched(input, editorID, activate);
2178
2179 } finally {
2180 workbench.largeUpdateEnd();
2181 }
2182 }
2183
2184 /**
2185 * Do not call this method. Use <code>busyOpenEditor</code>.
2186 *
2187 * @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
2188 */
2189 private IEditorPart busyOpenEditorBatched(IEditorInput input,
2190 String editorID, boolean activate) throws PartInitException {
2191
2192 // If an editor already exists for the input use it.
2193 IEditorPart editor = getEditorManager().findEditor(input);
2194 if (editor != null) {
2195 if (IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID.equals(editorID)) {
2196 if (editor.isDirty()) {
2197 MessageDialog dialog = new MessageDialog(getWorkbenchWindow().getShell(), WorkbenchMessages.getString("Save"), //$NON-NLS-1$
2198 null, // accept the default window icon
2199 WorkbenchMessages.format("WorkbenchPage.editorAlreadyOpenedMsg", new String[] { input.getName()}), //$NON-NLS-1$
2200 MessageDialog.QUESTION,
2201 new String[] {
2202 IDialogConstants.YES_LABEL,
2203 IDialogConstants.NO_LABEL,
2204 IDialogConstants.CANCEL_LABEL },
2205 0);
2206 int saveFile = dialog.open();
2207 if (saveFile == 0) {
2208 try {
2209 final IEditorPart editorToSave = editor;
2210 getWorkbenchWindow()
2211 .run(false, false, new IRunnableWithProgress() {
2212 public void run(IProgressMonitor monitor)
2213 throws
2214 InvocationTargetException,
2215 InterruptedException {
2216 editorToSave.doSave(monitor);
2217 }
2218 });
2219 } catch (InvocationTargetException e) {
2220 throw (RuntimeException) e.getTargetException();
2221 } catch (InterruptedException e) {
2222 return null;
2223 }
2224 } else if (saveFile == 2) {
2225 return null;
2226 }
2227 }
2228 } else {
2229 showEditor(activate, editor);
2230 return editor;
2231 }
2232 }
2233
2234 // Disabled turning redraw off, because it causes setFocus
2235 // in activate(editor) to fail.
2236 // getClientComposite().setRedraw(false);
2237
2238 // Remember the old visible editor
2239 IEditorPart oldVisibleEditor = getEditorManager().getVisibleEditor();
2240
2241 // Otherwise, create a new one. This may cause the new editor to
2242 // become the visible (i.e top) editor.
2243 IEditorReference ref = null;
2244 ref = getEditorManager().openEditor(editorID, input, true);
2245 if (ref != null) {
2246 editor = ref.getEditor(true);
2247 addPart(ref);
2248 }
2249
2250 if (editor != null) {
2251 //firePartOpened(editor);
2252 zoomOutIfNecessary(editor);
2253 setEditorAreaVisible(true);
2254 if (activate) {
2255 if (editor instanceof MultiEditor)
2256 activate(((MultiEditor) editor).getActiveEditor());
2257 else
2258 activate(editor);
2259 } else {
2260 activationList.setActive(editor);
2261 if (activePart != null) {
2262 // ensure the activation list is in a valid state
2263 activationList.setActive(activePart);
2264 }
2265 // The previous openEditor call may create a new editor
2266 // and make it visible, so send the notification.
2267 IEditorPart visibleEditor =
2268 getEditorManager().getVisibleEditor();
2269 if ((visibleEditor == editor)
2270 && (oldVisibleEditor != editor)) {
2271 actionSwitcher.updateTopEditor(editor);
2272 firePartBroughtToTop(editor);
2273 } else {
2274 bringToTop(editor);
2275 }
2276 }
2277 window.firePerspectiveChanged(
2278 this,
2279 getPerspective(),
2280 ref,
2281 CHANGE_EDITOR_OPEN);
2282 window.firePerspectiveChanged(
2283 this,
2284 getPerspective(),
2285 CHANGE_EDITOR_OPEN);
2286 }
2287
2288 // getClientComposite().setRedraw(true);
2289
2290 return editor;
2291 }
2292 private void showEditor(boolean activate, IEditorPart editor) {
2293 zoomOutIfNecessary(editor);
2294 setEditorAreaVisible(true);
2295 if (activate)
2296 activate(editor);
2297 else
2298 bringToTop(editor);
2299 }
2300 /**
2301 * See IWorkbenchPage.
2302 */
2303 public boolean isEditorPinned(IEditorPart editor) {
2304 return !((EditorSite) editor.getEditorSite()).getReuseEditor();
2305 }
2306 /**
2307 * Returns whether changes to a part will affect zoom. There are a few
2308 * conditions for this .. - we are zoomed. - the part is contained in the
2309 * main window. - the part is not the zoom part - the part is not a fast
2310 * view - the part and the zoom part are not in the same editor workbook
2311 */
2312 private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
2313 PartPane pane = ((WorkbenchPartReference) ref).getPane();
2314 if (pane instanceof MultiEditorInnerPane)
2315 pane = ((MultiEditorInnerPane) pane).getParentPane();
2316 return getActivePerspective().getPresentation().partChangeAffectsZoom(
2317 pane);
2318 }
2319 /**
2320 * Removes a fast view.
2321 */
2322 public void removeFastView(IViewReference ref) {
2323 Perspective persp = getActivePerspective();
2324 if (persp == null)
2325 return;
2326
2327 // If parts change always update zoom.
2328 if (isZoomed())
2329 zoomOut();
2330
2331 // Do real work.
2332 persp.removeFastView(ref);
2333
2334 // Notify listeners.
2335 window.updateFastViewBar();
2336 window.firePerspectiveChanged(
2337 this,
2338 getPerspective(),
2339 ref,
2340 CHANGE_FAST_VIEW_REMOVE);
2341 window.firePerspectiveChanged(
2342 this,
2343 getPerspective(),
2344 CHANGE_FAST_VIEW_REMOVE);
2345 }
2346 /**
2347 * Removes an IPartListener from the part service.
2348 */
2349 public void removePartListener(IPartListener l) {
2350 partListeners.removePartListener(l);
2351 }
2352 /**
2353 * Removes an IPartListener from the part service.
2354 */
2355 public void removePartListener(IPartListener2 l) {
2356 partListeners2.removePartListener(l);
2357 }
2358 /**
2359 * Implements IWorkbenchPage
2360 *
2361 * @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
2362 * @since 2.0
2363 * @deprecated individual views should store a working set if needed and
2364 * register a property change listener directly with the
2365 * working set manager to receive notification when the view
2366 * working set is removed.
2367 */
2368 public void removePropertyChangeListener(IPropertyChangeListener listener) {
2369 propertyChangeListeners.remove(listener);
2370 }
2371
2372 /*
2373 * (non-Javadoc) Method declared on ISelectionListener.
2374 */
2375 public void removeSelectionListener(ISelectionListener listener) {
2376 selectionService.removeSelectionListener(listener);
2377 }
2378
2379 /*
2380 * (non-Javadoc) Method declared on ISelectionListener.
2381 */
2382 public void removeSelectionListener(
2383 String partId,
2384 ISelectionListener listener) {
2385 selectionService.removeSelectionListener(partId, listener);
2386 }
2387 /*
2388 * (non-Javadoc) Method declared on ISelectionListener.
2389 */
2390 public void removePostSelectionListener(ISelectionListener listener) {
2391 selectionService.removePostSelectionListener(listener);
2392 }
2393
2394 /*
2395 * (non-Javadoc) Method declared on ISelectionListener.
2396 */
2397 public void removePostSelectionListener(
2398 String partId,
2399 ISelectionListener listener) {
2400 selectionService.removePostSelectionListener(partId, listener);
2401 }
2402 /**
2403 * This method is called when a part is activated by clicking within it. In
2404 * response, the part, the pane, and all of its actions will be activated.
2405 *
2406 * In the current design this method is invoked by the part pane when the
2407 * pane, the part, or any children gain focus.
2408 */
2409 public void requestActivation(IWorkbenchPart part) {
2410 // Sanity check.
2411 if (!certifyPart(part))
2412 return;
2413
2414 // Real work.
2415 setActivePart(part);
2416 }
2417 /**
2418 * Resets the layout for the perspective. The active part in the old layout
2419 * is activated in the new layout for consistent user context.
2420 */
2421 public void resetPerspective() {
2422 // Run op in busy cursor.
2423 // Use set redraw to eliminate the "flash" that can occur in the
2424 // coolbar as the perspective is reset.
2425 CoolBarManager mgr = window.getCoolBarManager();
2426 try {
2427 mgr.getControl().setRedraw(false);
2428 BusyIndicator.showWhile(null, new Runnable() {
2429 public void run() {
2430 busyResetPerspective();
2431 }
2432 });
2433 } finally {
2434 mgr.getControl().setRedraw(true);
2435 }
2436 }
2437 /**
2438 * Restore this page from the memento and ensure that the active
2439 * perspective is equals the active descriptor otherwise create a new
2440 * perspective for that descriptor. If activeDescriptor is null active the
2441 * old perspective.
2442 */
2443 public IStatus restoreState(
2444 IMemento memento,
2445 IPerspectiveDescriptor activeDescritor) {
2446 // Restore working set
2447 String pageName = memento.getString(IWorkbenchConstants.TAG_LABEL);
2448 String label = pageName == null ? "" : "::" + pageName; //$NON-NLS-1$ //$NON-NLS-2$
2449
2450 try {
2451 UIStats.start(UIStats.RESTORE_WORKBENCH, "WorkbenchPage" + label); //$NON-NLS-1$
2452 if (pageName == null)
2453 pageName = ""; //$NON-NLS-1$
2454 MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.format("WorkbenchPage.unableToRestorePerspective", new String[] { pageName }), //$NON-NLS-1$
2455 null);
2456
2457 String workingSetName =
2458 memento.getString(IWorkbenchConstants.TAG_WORKING_SET);
2459 if (workingSetName != null) {
2460 WorkingSetManager workingSetManager =
2461 (WorkingSetManager) getWorkbenchWindow()
2462 .getWorkbench()
2463 .getWorkingSetManager();
2464 setWorkingSet(workingSetManager.getWorkingSet(workingSetName));
2465 }
2466
2467 // Restore editor manager.
2468 IMemento childMem =
2469 memento.getChild(IWorkbenchConstants.TAG_EDITORS);
2470 result.merge(getEditorManager().restoreState(childMem));
2471
2472 childMem = memento.getChild(IWorkbenchConstants.TAG_VIEWS);
2473 if (childMem != null)
2474 result.merge(getViewFactory().restoreState(childMem));
2475
2476 // Get persp block.
2477 childMem = memento.getChild(IWorkbenchConstants.TAG_PERSPECTIVES);
2478 String activePartID =
2479 childMem.getString(IWorkbenchConstants.TAG_ACTIVE_PART);
2480 String activePartSecondaryID = null;
2481 if (activePartID != null) {
2482 activePartSecondaryID = ViewFactory.extractSecondaryId(activePartID);
2483 if (activePartSecondaryID != null) {
2484 activePartID = ViewFactory.extractPrimaryId(activePartID);
2485 }
2486 }
2487 String activePerspectiveID =
2488 childMem.getString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE);
2489
2490 // Restore perspectives.
2491 IMemento perspMems[] =
2492 childMem.getChildren(IWorkbenchConstants.TAG_PERSPECTIVE);
2493 Perspective activePerspective = null;
2494 for (int i = 0; i < perspMems.length; i++) {
2495 try {
2496 Perspective persp = new Perspective(null, this);
2497 result.merge(persp.restoreState(perspMems[i]));
2498 IPerspectiveDescriptor desc = persp.getDesc();
2499 if (desc.equals(activeDescritor))
2500 activePerspective = persp;
2501 else if (
2502 (activePerspective == null)
2503 && desc.getId().equals(activePerspectiveID))
2504 activePerspective = persp;
2505 perspList.add(persp);
2506 } catch (WorkbenchException e) {
2507 }
2508 }
2509 boolean restoreActivePerspective = false;
2510 if (activeDescritor == null)
2511 restoreActivePerspective = true;
2512 else if (
2513 activePerspective != null
2514 && activePerspective.getDesc().equals(activeDescritor)) {
2515 restoreActivePerspective = true;
2516 } else {
2517 restoreActivePerspective = false;
2518 activePerspective =
2519 createPerspective((PerspectiveDescriptor) activeDescritor);
2520 if (activePerspective == null) {
2521 result.merge(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, WorkbenchMessages.format("Workbench.showPerspectiveError", new String[] { activeDescritor.getId()}), //$NON-NLS-1$
2522 null));
2523 }
2524 }
2525
2526 perspList.setActive(activePerspective);
2527
2528 // Make sure we have a valid perspective to work with,
2529 // otherwise return.
2530 activePerspective = perspList.getActive();
2531 if (activePerspective == null) {
2532 activePerspective = perspList.getNextActive();
2533 perspList.setActive(activePerspective);
2534 result.merge(activePerspective.restoreState());
2535 }
2536 if (activePerspective != null && restoreActivePerspective)
2537 result.merge(activePerspective.restoreState());
2538
2539 if (activePerspective != null) {
2540 window.firePerspectiveActivated(
2541 this,
2542 activePerspective.getDesc());
2543
2544 // Restore active part.
2545 if (activePartID != null) {
2546 IViewReference ref =
2547 activePerspective.findView(activePartID, activePartSecondaryID);
2548 IViewPart view = null;
2549 if (ref != null)
2550 view = ref.getView(true);
2551 if (view != null)
2552 activePart = view;
2553 }
2554 }
2555
2556 childMem =
2557 memento.getChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY);
2558 if (childMem != null)
2559 navigationHistory.restoreState(childMem);
2560 else if (getActiveEditor() != null)
2561 navigationHistory.markEditor(getActiveEditor());
2562 return result;
2563 } finally {
2564 UIStats.end(UIStats.RESTORE_WORKBENCH, "WorkbenchPage" + label); //$NON-NLS-1$
2565 }
2566 }
2567 /**
2568 * See IWorkbenchPage
2569 */
2570 public boolean saveAllEditors(boolean confirm) {
2571 return getEditorManager().saveAll(confirm, false);
2572 }
2573 /*
2574 * Saves the workbench part.
2575 */
2576 protected boolean savePart(
2577 ISaveablePart saveable,
2578 IWorkbenchPart part,
2579 boolean confirm) {
2580 // Do not certify part do allow editors inside a multipageeditor to
2581 // call this.
2582 return getEditorManager().savePart(saveable, part, confirm);
2583 }
2584 /**
2585 * Saves an editors in the workbench. If <code>confirm</code> is <code>true</code>
2586 * the user is prompted to confirm the command.
2587 *
2588 * @param confirm
2589 * if user confirmation should be sought
2590 * @return <code>true</code> if the command succeeded, or <code>false</code>
2591 * if the user cancels the command
2592 */
2593 public boolean saveEditor(IEditorPart editor, boolean confirm) {
2594 return savePart(editor, editor, confirm);
2595 }
2596 /**
2597 * Saves the current perspective.
2598 */
2599 public void savePerspective() {
2600 Perspective persp = getActivePerspective();
2601 if (persp == null)
2602 return;
2603
2604 // Always unzoom.
2605 if (isZoomed())
2606 zoomOut();
2607
2608 persp.saveDesc();
2609 }
2610 /**
2611 * Saves the perspective.
2612 */
2613 public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
2614 Perspective persp = getActivePerspective();
2615 if (persp == null)
2616 return;
2617 IPerspectiveDescriptor oldDesc = persp.getDesc();
2618
2619 // Always unzoom.
2620 if (isZoomed())
2621 zoomOut();
2622
2623 persp.saveDescAs(newDesc);
2624 window.updatePerspectiveShortcut(oldDesc, newDesc, this);
2625 }
2626 /**
2627 * Save the state of the page.
2628 */
2629 public IStatus saveState(IMemento memento) {
2630 // We must unzoom to get correct layout.
2631 if (isZoomed())
2632 zoomOut();
2633
2634 MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.format("WorkbenchPage.unableToSavePerspective", new String[] { getLabel()}), //$NON-NLS-1$
2635 null);
2636
2637 // Save editor manager.
2638 IMemento childMem =
2639 memento.createChild(IWorkbenchConstants.TAG_EDITORS);
2640 result.merge(editorMgr.saveState(childMem));
2641
2642 childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
2643 result.merge(getViewFactory().saveState(childMem));
2644
2645 // Create persp block.
2646 childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
2647 if (getPerspective() != null)
2648 childMem.putString(
2649 IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
2650 getPerspective().getId());
2651 if (getActivePart() != null) {
2652 if (getActivePart() instanceof IViewPart) {
2653 IViewReference ref = (IViewReference) getReference(getActivePart());
2654 if (ref != null) {
2655 childMem.putString(
2656 IWorkbenchConstants.TAG_ACTIVE_PART,
2657 ViewFactory.getKey(ref));
2658 }
2659 }
2660 else {
2661 childMem.putString(
2662 IWorkbenchConstants.TAG_ACTIVE_PART,
2663 getActivePart().getSite().getId());
2664 }
2665 }
2666
2667 // Save each perspective in opened order
2668 Iterator enum = perspList.iterator();
2669 while (enum.hasNext()) {
2670 Perspective persp = (Perspective) enum.next();
2671 IMemento gChildMem =
2672 childMem.createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
2673 result.merge(persp.saveState(gChildMem));
2674 }
2675 // Save working set if set
2676 if (workingSet != null) {
2677 memento.putString(
2678 IWorkbenchConstants.TAG_WORKING_SET,
2679 workingSet.getName());
2680 }
2681
2682 navigationHistory.saveState(
2683 memento.createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
2684 return result;
2685 }
2686 /**
2687 * Sets the active part.
2688 */
2689 private void setActivePart(IWorkbenchPart newPart) {
2690 // Optimize it.
2691 if (activePart == newPart)
2692 return;
2693
2694 //No need to change the history if the active editor is becoming the
2695 // active part
2696 boolean markLocation = newPart != lastActiveEditor;
2697 String label = newPart != null ? newPart.getTitle() : "none"; //$NON-NLS-1$
2698 try {
2699 UIStats.start(UIStats.ACTIVATE_PART, label);
2700 // Notify perspective. It may deactivate fast view.
2701 Perspective persp = getActivePerspective();
2702 if (persp != null)
2703 persp.partActivated(newPart);
2704
2705 // Deactivate old part
2706 IWorkbenchPart oldPart = activePart;
2707 if (oldPart != null) {
2708 deactivatePart(oldPart);
2709 }
2710
2711 // Set active part.
2712 activePart = newPart;
2713 if (newPart != null) {
2714 activationList.setActive(newPart);
2715 if (newPart instanceof IEditorPart) {
2716 lastActiveEditor = (IEditorPart) newPart;
2717 IEditorReference ref =
2718 (IEditorReference) getReference(lastActiveEditor);
2719 editorMgr.setVisibleEditor(ref, true);
2720 }
2721 }
2722 activatePart(activePart);
2723
2724 if (markLocation
2725 && activePart != null
2726 && activePart instanceof IEditorPart)
2727 navigationHistory.markEditor((IEditorPart) activePart);
2728
2729 // Fire notifications
2730 if (oldPart != null)
2731 firePartDeactivated(oldPart);
2732
2733 // Update actions now so old actions have heard part deactivated
2734 // and
2735 // new actions can hear part activated.
2736 actionSwitcher.updateActivePart(newPart);
2737 if (newPart != null)
2738 firePartActivated(newPart);
2739 } finally {
2740 UIStats.end(UIStats.ACTIVATE_PART, label);
2741 }
2742 }
2743 /**
2744 * See IWorkbenchPage.
2745 */
2746 public void setEditorAreaVisible(boolean showEditorArea) {
2747 Perspective persp = getActivePerspective();
2748 if (persp == null)
2749 return;
2750 if (showEditorArea == persp.isEditorAreaVisible())
2751 return;
2752 // If parts change always update zoom.
2753 if (isZoomed())
2754 zoomOut();
2755 // Update editor area visibility.
2756 if (showEditorArea) {
2757 persp.showEditorArea();
2758 window.firePerspectiveChanged(
2759 this,
2760 getPerspective(),
2761 CHANGE_EDITOR_AREA_SHOW);
2762 } else {
2763 persp.hideEditorArea();
2764 if (activePart instanceof IEditorPart) {
2765 IEditorPart e = (IEditorPart) activePart;
2766 setActivePart(null);
2767 // preserve editor contributions
2768 actionSwitcher.updateTopEditor(e);
2769 }
2770 window.firePerspectiveChanged(
2771 this,
2772 getPerspective(),
2773 CHANGE_EDITOR_AREA_HIDE);
2774 }
2775 }
2776 /**
2777 * Sets the layout of the page. Assumes the new perspective is not null.
2778 * Keeps the active part if possible. Updates the window menubar and
2779 * toolbar if necessary.
2780 */
2781 private void setPerspective(Perspective newPersp) {
2782 // Don't do anything if already active layout
2783 Perspective oldPersp = getActivePerspective();
2784 if (oldPersp == newPersp)
2785 return;
2786
2787 if (newPersp != null) {
2788 IStatus status = newPersp.restoreState();
2789 if (status.getSeverity() != IStatus.OK) {
2790 String title = WorkbenchMessages.getString("WorkbenchPage.problemRestoringTitle"); //$NON-NLS-1$
2791 String msg = WorkbenchMessages.getString("WorkbenchPage.errorReadingState"); //$NON-NLS-1$
2792 ErrorDialog.openError(
2793 getWorkbenchWindow().getShell(),
2794 title,
2795 msg,
2796 status);
2797 }
2798 }
2799
2800 // Deactivate active part.
2801
2802 // ensure the switcher is not showing any action sets
2803 // so it will reshow them in the new perspective
2804 actionSwitcher.updateTopEditor(null);
2805
2806 IWorkbenchPart oldActivePart = activePart;
2807 setActivePart(null);
2808
2809 // Deactivate the old layout
2810 if (oldPersp != null) {
2811 oldPersp.onDeactivate();
2812 window.selectPerspectiveShortcut(oldPersp.getDesc(), this, false);
2813 }
2814
2815 // Activate the new layout
2816 perspList.setActive(newPersp);
2817 if (newPersp != null) {
2818 newPersp.onActivate();
2819
2820 // Notify listeners of activation
2821 window.firePerspectiveActivated(this, newPersp.getDesc());
2822
2823 // Update the shortcut
2824 window.selectPerspectiveShortcut(newPersp.getDesc(), this, true);
2825 } else {
2826 // No need to remember old active part since there
2827 // is no new active perspective to activate it in.
2828 oldActivePart = null;
2829 }
2830
2831 // Update the window
2832 window.updateActionSets();
2833 window.updateFastViewBar();
2834
2835 updateVisibility(oldPersp, newPersp);
2836
2837 // Reactivate active part.
2838 if (oldActivePart != null) {
2839 oldPersp.setOldPartRef(getReference(oldActivePart));
2840 if (oldActivePart instanceof IEditorPart
2841 && isEditorAreaVisible()) {
2842 activate(oldActivePart);
2843 } else if (oldActivePart instanceof IViewPart) {
2844 IEditorPart ed = editorMgr.getVisibleEditor();
2845 if (ed != null)
2846 actionSwitcher.updateTopEditor(ed);
2847 String id = oldActivePart.getSite().getId();
2848 String secondaryId = ((IViewPart) oldActivePart).getViewSite().getSecondaryId();
2849 if (newPersp.findView(id, secondaryId) != null) {
2850 activate(oldActivePart);
2851 } else {
2852 activateOldPart(newPersp);
2853 }
2854 } else {
2855 activateOldPart(newPersp);
2856 }
2857 } else { //no active part
2858 IEditorPart ed = editorMgr.getVisibleEditor();
2859 if (ed != null) {
2860 actionSwitcher.updateTopEditor(ed);
2861 } else {
2862 activateOldPart(newPersp);
2863 }
2864 }
2865 if (getActivePart() == null && activationList.getActive() != null) {
2866 activate(activationList.getActive());
2867 }
2868 if (editorPresentation != null)
2869 editorPresentation.showVisibleEditor();
2870
2871 if (newPersp != null && oldPersp != null ) {
2872 if (!stickyPerspectives.contains(newPersp.getDesc())) {
2873 IViewRegistry viewReg = WorkbenchPlugin.getDefault().getViewRegistry();
2874 IStickyViewDescriptor [] stickyDescs = viewReg.getStickyViews();
2875 for (int i = 0; i < stickyDescs.length; i++) {
2876 try {
2877 // show a sticky view if it was in the last perspective
2878 if (oldPersp.findView(stickyDescs[i].getId()) != null) {
2879 showView(stickyDescs[i].getId(), null, IWorkbenchPage.VIEW_CREATE);
2880 }
2881 }
2882 catch (PartInitException e) {
2883 WorkbenchPlugin.log("Could not open view :" + stickyDescs[i].getId(), new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IStatus.ERROR, "Could not open view :" + stickyDescs[i].getId(), e)); //$NON-NLS-1$ //$NON-NLS-2$
2884 }
2885 }
2886 stickyPerspectives.add(newPersp.getDesc());
2887 }
2888 }
2889 }
2890 /*
2891 * Update visibility state of all views.
2892 */
2893 private void updateVisibility(Perspective oldPersp, Perspective newPersp) {
2894 HashSet set = new HashSet();
2895 IWorkbenchPartReference[] refs;
2896 if (oldPersp != null) {
2897 refs = oldPersp.getViewReferences();
2898 for (int i = 0; i < refs.length; i++) {
2899 PartPane pane = ((WorkbenchPartReference) refs[i]).getPane();
2900 if (pane != null)
2901 set.add(pane);
2902 }
2903 }
2904 if (newPersp != null) {
2905 refs = newPersp.getViewReferences();
2906 for (int i = 0; i < refs.length; i++) {
2907 PartPane pane = ((WorkbenchPartReference) refs[i]).getPane();
2908 if (pane != null)
2909 set.add(pane);
2910 }
2911 PerspectiveHelper pres = newPersp.getPresentation();
2912 for (Iterator iter = set.iterator(); iter.hasNext();) {
2913 PartPane pane = (PartPane) iter.next();
2914 IWorkbenchPartReference partRef = pane.getPartReference();
2915 pane.setVisible(pres.isPartVisible(partRef));
2916 }
2917 } else {
2918 for (Iterator iter = set.iterator(); iter.hasNext();) {
2919 PartPane pane = (PartPane) iter.next();
2920 pane.setVisible(false);
2921 }
2922 }
2923 }
2924
2925 private void activateOldPart(Perspective newPersp) {
2926 if (window.isClosing())
2927 return;
2928 if (newPersp != null) {
2929 IWorkbenchPartReference oldPartRef = newPersp.getOldPartRef();
2930 IWorkbenchPart prevOldPart = null;
2931 if (oldPartRef != null)
2932 prevOldPart = oldPartRef.getPart(false);
2933 if (prevOldPart != null)
2934 activate(prevOldPart);
2935 else if (isEditorAreaVisible())
2936 activate(getActiveEditor());
2937 }
2938 }
2939 /**
2940 * Sets the perspective.
2941 *
2942 * @param persp
2943 * identifies the new perspective.
2944 */
2945 public void setPerspective(final IPerspectiveDescriptor desc) {
2946 // Going from multiple to single rows can make the coolbar
2947 // and its adjacent views appear jumpy as perspectives are
2948 // switched. Turn off redraw to help with this.
2949 CoolBarManager mgr = window.getCoolBarManager();
2950 try {
2951 mgr.getControl().setRedraw(false);
2952 getClientComposite().setRedraw(false);
2953 // Run op in busy cursor.
2954 BusyIndicator.showWhile(null, new Runnable() {
2955 public void run() {
2956 busySetPerspective(desc);
2957 }
2958 });
2959 } finally {
2960 getClientComposite().setRedraw(true);
2961 mgr.getControl().setRedraw(true);
2962 IWorkbenchPart part = getActivePart();
2963 if (part != null)
2964 part.setFocus();
2965 }
2966 }
2967 /**
2968 * Restore the toolbar layout for the active perspective.
2969 */
2970 protected void resetToolBarLayout() {
2971 window.getCoolBarManager().resetItemOrder();
2972 }
2973 /**
2974 * Sets the active working set for the workbench page. Notifies property
2975 * change listener about the change.
2976 *
2977 * @param newWorkingSet
2978 * the active working set for the page. May be null.
2979 * @since 2.0
2980 * @deprecated individual views should store a working set if needed
2981 */
2982 public void setWorkingSet(IWorkingSet newWorkingSet) {
2983 IWorkingSet oldWorkingSet = workingSet;
2984
2985 workingSet = newWorkingSet;
2986 if (oldWorkingSet != newWorkingSet) {
2987 firePropertyChange(
2988 CHANGE_WORKING_SET_REPLACE,
2989 oldWorkingSet,
2990 newWorkingSet);
2991 }
2992 if (newWorkingSet != null) {
2993 WorkbenchPlugin
2994 .getDefault()
2995 .getWorkingSetManager()
2996 .addPropertyChangeListener(
2997 propertyChangeListener);
2998 } else {
2999 WorkbenchPlugin
3000 .getDefault()
3001 .getWorkingSetManager()
3002 .removePropertyChangeListener(propertyChangeListener);
3003 }
3004 }
3005 /**
3006 * @see IWorkbenchPage
3007 */
3008 public void showActionSet(String actionSetID) {
3009 Perspective persp = getActivePerspective();
3010 if (persp != null) {
3011 persp.showActionSet(actionSetID);
3012 window.updateActionSets();
3013 window.firePerspectiveChanged(
3014 this,
3015 getPerspective(),
3016 CHANGE_ACTION_SET_SHOW);
3017 }
3018 }
3019 /**
3020 * See IWorkbenchPage.
3021 */
3022 public IViewPart showView(String viewID) throws PartInitException {
3023 return showView(viewID, null, VIEW_ACTIVATE);
3024 }
3025
3026 /* (non-Javadoc)
3027 * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String, java.lang.String, int)
3028 */
3029 public IViewPart showView(
3030 final String viewID,
3031 final String secondaryID,
3032 final int mode) throws PartInitException {
3033
3034 if (secondaryID != null) {
3035 if (secondaryID.length() == 0 || secondaryID.indexOf(ViewFactory.ID_SEP) != -1)
3036 throw new IllegalArgumentException(WorkbenchMessages.getString("WorkbenchPage.IllegalSecondaryId")); //$NON-NLS-1$
3037 }
3038 if (!certifyMode(mode))
3039 throw new IllegalArgumentException(WorkbenchMessages.getString("WorkbenchPage.IllegalViewMode")); //$NON-NLS-1$
3040
3041 // Run op in busy cursor.
3042 final Object[] result = new Object[1];
3043 BusyIndicator.showWhile(null, new Runnable() {
3044 public void run() {
3045 try {
3046 result[0] = busyShowView(viewID, secondaryID, mode);
3047 } catch (PartInitException e) {
3048 result[0] = e;
3049 }
3050 }
3051 });
3052 if (result[0] instanceof IViewPart)
3053 return (IViewPart) result[0];
3054 else if (result[0] instanceof PartInitException)
3055 throw (PartInitException) result[0];
3056 else
3057 throw new PartInitException(WorkbenchMessages.getString("WorkbenchPage.AbnormalWorkbenchCondition")); //$NON-NLS-1$
3058 }
3059 /**
3060 * @param mode the mode to test
3061 * @return whether the mode is recognized
3062 * @since 3.0
3063 */
3064 private boolean certifyMode(int mode) {
3065 switch(mode) {
3066 case VIEW_ACTIVATE:
3067 case VIEW_VISIBLE:
3068 case VIEW_CREATE:
3069 return true;
3070 default:
3071 return false;
3072 }
3073 }
3074
3075 /**
3076 * Hides the active fast view. Has no effect if there is no fast view active.
3077 */
3078 public void hideFastView() {
3079 Perspective persp = getActivePerspective();
3080 if (persp != null) {
3081 IViewReference ref = persp.getActiveFastView();
3082 if (ref != null) {
3083 toggleFastView(ref);
3084 }
3085 }
3086 }
3087
3088 /**
3089 * Toggles the visibility of a fast view. If the view is active it is
3090 * deactivated. Otherwise, it is activated.
3091 */
3092 public void toggleFastView(IViewReference ref) {
3093 Perspective persp = getActivePerspective();
3094 if (persp != null) {
3095 persp.toggleFastView(ref);
3096 // if the fast view has been deactivated
3097 if (ref != persp.getActiveFastView()) {
3098 IWorkbenchPart previouslyActive =
3099 activationList.getPreviouslyActive();
3100 IEditorPart activeEditor = getActiveEditor();
3101 if (activeEditor != null
3102 && previouslyActive instanceof IEditorPart)
3103 setActivePart(activeEditor);
3104 else
3105 setActivePart(previouslyActive);
3106 }
3107 }
3108 }
3109 /**
3110 * Zoom in on a part. If the part is already in zoom then zoom out.
3111 */
3112 public void toggleZoom(IWorkbenchPartReference ref) {
3113 Perspective persp = getActivePerspective();
3114 if (persp == null)
3115 return;
3116
3117 PartPane pane = ((WorkbenchPartReference) ref).getPane();
3118
3119 // If target part is detached fire the zoom event. Note this doesn't
3120 // actually cause any changes in size and is required to support
3121 // intro state changes. We may want to introduce the notion of a zoomed
3122 // (fullscreen) detached view at a later time.
3123 if (pane.getWindow() instanceof DetachedWindow) {
3124 pane.setZoomed(!pane.isZoomed());
3125 return;
3126 }
3127
3128 if (ref instanceof IViewReference && persp.isFastView((IViewReference)ref)) {
3129 persp.toggleFastViewZoom();
3130 return;
3131 }
3132
3133 // Update zoom status.
3134 if (isZoomed()) {
3135 zoomOut();
3136
3137 return;
3138 } else {
3139 persp.getPresentation().zoomIn(ref);
3140 activate(ref.getPart(true));
3141 }
3142 }
3143 /**
3144 * updateActionBars method comment.
3145 */
3146 public void updateActionBars() {
3147 window.updateActionBars();
3148 }
3149
3150 /**
3151 * Sets the tab list of this page's composite appropriately when a part is
3152 * activated.
3153 */
3154 private void updateTabList(IWorkbenchPart part) {
3155 PartSite site = (PartSite) part.getSite();
3156 PartPane pane = site.getPane();
3157 if (pane instanceof ViewPane) {
3158 ViewPane viewPane = (ViewPane) pane;
3159 Control[] tabList = viewPane.getTabList();
3160 if (pane.getWindow() instanceof DetachedWindow) {
3161 viewPane.getControl().getShell().setTabList(tabList);
3162 } else {
3163 getClientComposite().setTabList(tabList);
3164 }
3165 } else if (pane instanceof EditorPane) {
3166 EditorSashContainer ea = ((EditorPane) pane).getWorkbook().getEditorArea();
3167 ea.updateTabList();
3168 getClientComposite().setTabList(new Control[] { ea.getParent()});
3169 }
3170 }
3171
3172 /**
3173 * The title of the given part has changed. For views, updates the fast
3174 * view button if necessary.
3175 */
3176 public void updateTitle(IViewReference ref) {
3177 if (isFastView(ref)) {
3178 // Would be more efficient to just update label of single tool item
3179 // but we don't have access to it from here.
3180 window.updateFastViewBar();
3181 }
3182 }
3183 /**
3184 * Zooms out a zoomed in part.
3185 */
3186 /* package */
3187 void zoomOut() {
3188 Perspective persp = getActivePerspective();
3189 if (persp != null)
3190 persp.getPresentation().zoomOut();
3191 }
3192 /**
3193 * Zooms out a zoomed in part if it is necessary to do so for the user to
3194 * view the IWorkbenchPart that is the argument. Otherwise, does nothing.
3195 *
3196 * @param part
3197 * the part to be made viewable
3198 */
3199 private void zoomOutIfNecessary(IWorkbenchPart part) {
3200 if (isZoomed() && needToZoomOut(part))
3201 zoomOut();
3202 }
3203 /**
3204 * @see IPageLayout.
3205 */
3206 public int getEditorReuseThreshold() {
3207 IPreferenceStore store =
3208 WorkbenchPlugin.getDefault().getPreferenceStore();
3209 return store.getInt(IPreferenceConstants.REUSE_EDITORS);
3210 }
3211 /**
3212 * @see IPageLayout.
3213 */
3214 public void setEditorReuseThreshold(int openEditors) {
3215 }
3216 /*
3217 * Returns the editors in activation order (oldest first).
3218 */
3219 public IEditorReference[] getSortedEditors() {
3220 return activationList.getEditors();
3221 }
3222 /**
3223 * Returns an iterator over the opened perspectives
3224 */
3225 protected IPerspectiveDescriptor[] getOpenedPerspectives() {
3226 Perspective opened[] = perspList.getOpenedPerspectives();
3227 IPerspectiveDescriptor[] result =
3228 new IPerspectiveDescriptor[opened.length];
3229 for (int i = 0; i < result.length; i++) {
3230 result[i] = opened[i].getDesc();
3231 }
3232 return result;
3233 }
3234 /*
3235 * Returns the perspectives in activation order (oldest first).
3236 */
3237 protected IPerspectiveDescriptor[] getSortedPerspectives() {
3238 Perspective sortedArray[] = perspList.getSortedPerspectives();
3239 IPerspectiveDescriptor[] result =
3240 new IPerspectiveDescriptor[sortedArray.length];
3241 for (int i = 0; i < result.length; i++) {
3242 result[i] = sortedArray[i].getDesc();
3243 }
3244 return result;
3245 }
3246 /*
3247 * Returns the parts in activation order (oldest first).
3248 */
3249 public IWorkbenchPartReference[] getSortedParts() {
3250 return activationList.getParts();
3251 }
3252
3253 public IWorkbenchPartReference getReference(IWorkbenchPart part) {
3254 if (part == null)
3255 return null;
3256 PartPane pane = ((PartSite) part.getSite()).getPane();
3257 if (pane instanceof MultiEditorInnerPane) {
3258 MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
3259 return innerPane.getParentPane().getPartReference();
3260 }
3261 if (pane == null) {
3262 /*
3263 * An error has occurred while creating the view.
3264 */
3265 IViewReference refs[] = getViewReferences();
3266 for (int i = 0; i < refs.length; i++) {
3267 if (refs[i].getPart(false) == part)
3268 return refs[i];
3269 }
3270 return null;
3271 }
3272 return pane.getPartReference();
3273 }
3274
3275 private class ActivationList {
3276 //List of parts in the activation order (oldest first)
3277 List parts = new ArrayList();
3278
3279 /*
3280 * Add/Move the active part to end of the list;
3281 */
3282 void setActive(IWorkbenchPart part) {
3283 if (parts.size() <= 0)
3284 return;
3285 PartPane pane = ((PartSite) part.getSite()).getPane();
3286 if (pane instanceof MultiEditorInnerPane) {
3287 MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
3288 setActive(
3289 innerPane.getParentPane().getPartReference().getPart(true));
3290 } else {
3291 IWorkbenchPartReference ref = getReference(part);
3292 if (ref == parts.get(parts.size() - 1))
3293 return;
3294 parts.remove(ref);
3295 parts.add(ref);
3296 }
3297 pane.addPropertyChangeListener(propertyChangeListener);
3298 }
3299 /*
3300 * Add/Move the active part to end of the list;
3301 */
3302 void setActive(IWorkbenchPartReference ref) {
3303 setActive(ref.getPart(true));
3304 }
3305 /*
3306 * Add the active part to the beginning of the list.
3307 */
3308 void add(IWorkbenchPartReference ref) {
3309 if (parts.indexOf(ref) >= 0)
3310 return;
3311
3312 IWorkbenchPart part = ref.getPart(false);
3313 if (part != null) {
3314 PartPane pane = ((PartSite) part.getSite()).getPane();
3315 if (pane instanceof MultiEditorInnerPane) {
3316 MultiEditorInnerPane innerPane =
3317 (MultiEditorInnerPane) pane;
3318 add(innerPane.getParentPane().getPartReference());
3319 return;
3320 }
3321 }
3322 PartPane pane = ((WorkbenchPartReference) ref).getPane();
3323 if (pane != null)
3324 pane.addPropertyChangeListener(propertyChangeListener);
3325 parts.add(0, ref);
3326 }
3327 /*
3328 * Return the active part. Filter fast views.
3329 */
3330 IWorkbenchPart getActive() {
3331 if (parts.isEmpty())
3332 return null;
3333 return getActive(parts.size() - 1);
3334 }
3335 /*
3336 * Return the previously active part. Filter fast views.
3337 */
3338 IWorkbenchPart getPreviouslyActive() {
3339 if (parts.size() < 2)
3340 return null;
3341 return getActive(parts.size() - 2);
3342 }
3343 /*
3344 * Find a part in the list starting from the end and filter fast views
3345 * and views from other perspectives.
3346 */
3347 private IWorkbenchPart getActive(int start) {
3348 IWorkbenchPartReference[] views = getViewReferences();
3349 for (int i = start; i >= 0; i--) {
3350 IWorkbenchPartReference ref =
3351 (IWorkbenchPartReference) parts.get(i);
3352
3353 // Skip parts whose containers have disabled auto-focus
3354 IWorkbenchPart part = ref.getPart(false);
3355
3356 if (part != null) {
3357 IWorkbenchPartSite site = part.getSite();
3358 if (site instanceof PartSite) {
3359 PartSite partSite = (PartSite)site;
3360
3361 ILayoutContainer container = partSite.getPane().getContainer();
3362 if ((container != null) && (!container.allowsAutoFocus())) {
3363 continue;
3364 }
3365 }
3366 }
3367
3368 // Skip fastviews
3369 if (ref instanceof IViewReference) {
3370 if (!((IViewReference) ref).isFastView() ) {
3371 for (int j = 0; j < views.length; j++) {
3372 if (views[j] == ref) {
3373 return ref.getPart(true);
3374 }
3375 }
3376 }
3377 } else {
3378 return ref.getPart(true);
3379 }
3380 }
3381 return null;
3382 }
3383 /*
3384 * Retuns the index of the part within the activation list. The higher
3385 * the index, the more recent it was used.
3386 */
3387 int indexOf(IWorkbenchPart part) {
3388 return parts.indexOf(getReference(part));
3389 }
3390 /*
3391 * Returns the index of the part reference within the activation list.
3392 * The higher the index, the more recent it was used.
3393 */
3394 int indexOf(IWorkbenchPartReference ref) {
3395 return parts.indexOf(ref);
3396 }
3397 /*
3398 * Remove a part from the list
3399 */
3400 boolean remove(IWorkbenchPartReference ref) {
3401 PartPane pane = ((WorkbenchPartReference) ref).getPane();
3402 if (pane != null)
3403 pane.removePropertyChangeListener(propertyChangeListener);
3404 return parts.remove(ref);
3405 }
3406 /*
3407 * Returns the editors in activation order (oldest first).
3408 */
3409 private IEditorReference[] getEditors() {
3410 ArrayList editors = new ArrayList(parts.size());
3411 for (Iterator i = parts.iterator(); i.hasNext();) {
3412 IWorkbenchPartReference part =
3413 (IWorkbenchPartReference) i.next();
3414 if (part instanceof IEditorReference) {
3415 editors.add(part);
3416 }
3417 }
3418 return (IEditorReference[]) editors.toArray(
3419 new IEditorReference[editors.size()]);
3420 }
3421 /*
3422 * Return a list with all parts (editors and views).
3423 */
3424 private IWorkbenchPartReference[] getParts() {
3425 IWorkbenchPartReference[] views = getViewReferences();
3426 ArrayList resultList = new ArrayList(parts.size());
3427 for (Iterator iterator = parts.iterator(); iterator.hasNext();) {
3428 IWorkbenchPartReference ref =
3429 (IWorkbenchPartReference) iterator.next();
3430 if (ref instanceof IViewReference) {
3431 //Filter views from other perspectives
3432 for (int i = 0; i < views.length; i++) {
3433 if (views[i] == ref) {
3434 resultList.add(ref);
3435 break;
3436 }
3437 }
3438 } else {
3439 resultList.add(ref);
3440 }
3441 }
3442 IWorkbenchPartReference[] result =
3443 new IWorkbenchPartReference[resultList.size()];
3444 return (IWorkbenchPartReference[]) resultList.toArray(result);
3445 }
3446 /*
3447 * Returns the topmost editor on the stack, or null if none.
3448 */
3449 IEditorPart getTopEditor() {
3450 IEditorReference editors[] = getEditors();
3451 if (editors.length > 0) {
3452 return editors[editors.length - 1].getEditor(true);
3453 }
3454 return null;
3455 }
3456 }
3457
3458 /**
3459 * Helper class to keep track of all opened perspective. Both the opened
3460 * and used order is kept.
3461 */
3462 private class PerspectiveList {
3463 /**
3464 * List of perspectives in the order they were opened;
3465 */
3466 private List openedList;
3467
3468 /**
3469 * List of perspectives in the order they were used. Last element is
3470 * the most recently used, and first element is the least recently
3471 * used.
3472 */
3473 private List usedList;
3474
3475 /**
3476 * The perspective explicitly set as being the active one
3477 */
3478 private Perspective active;
3479
3480 /**
3481 * Creates an empty instance of the perspective list
3482 */
3483 public PerspectiveList() {
3484 openedList = new ArrayList(15);
3485 usedList = new ArrayList(15);
3486 }
3487 /**
3488 * Return all perspectives in the order they were activated.
3489 */
3490 public Perspective[] getSortedPerspectives() {
3491 Perspective[] result = new Perspective[usedList.size()];
3492 return (Perspective[]) usedList.toArray(result);
3493 }
3494 /**
3495 * Adds a perspective to the list. No check is done for a duplicate
3496 * when adding.
3497 */
3498 public boolean add(Perspective perspective) {
3499 openedList.add(perspective);
3500 usedList.add(0, perspective);
3501 //It will be moved to top only when activated.
3502 return true;
3503 }
3504
3505 /**
3506 * Returns an iterator on the perspective list in the order they were
3507 * opened.
3508 */
3509 public Iterator iterator() {
3510 return openedList.iterator();
3511 }
3512 /**
3513 * Returns an array with all opened perspectives
3514 */
3515 public Perspective[] getOpenedPerspectives() {
3516 Perspective[] result = new Perspective[openedList.size()];
3517 return (Perspective[]) openedList.toArray(result);
3518 }
3519 /**
3520 * Removes a perspective from the list.
3521 */
3522 public boolean remove(Perspective perspective) {
3523 if (active == perspective)
3524 active = null;
3525 usedList.remove(perspective);
3526 return openedList.remove(perspective);
3527 }
3528
3529 /**
3530 * Swap the opened order of old perspective with the new perspective.
3531 */
3532 public void swap(
3533 Perspective oldPerspective,
3534 Perspective newPerspective) {
3535 int oldIndex = openedList.indexOf(oldPerspective);
3536 int newIndex = openedList.indexOf(newPerspective);
3537
3538 if (oldIndex < 0 || newIndex < 0)
3539 return;
3540
3541 openedList.set(oldIndex, newPerspective);
3542 openedList.set(newIndex, oldPerspective);
3543 }
3544
3545 /**
3546 * Returns whether the list contains any perspectives
3547 */
3548 public boolean isEmpty() {
3549 return openedList.isEmpty();
3550 }
3551
3552 /**
3553 * Returns the most recently used perspective in the list.
3554 */
3555 public Perspective getActive() {
3556 return active;
3557 }
3558
3559 /**
3560 * Returns the next most recently used perspective in the list.
3561 */
3562 public Perspective getNextActive() {
3563 if (active == null) {
3564 if (usedList.isEmpty())
3565 return null;
3566 else
3567 return (Perspective) usedList.get(usedList.size() - 1);
3568 } else {
3569 if (usedList.size() < 2)
3570 return null;
3571 else
3572 return (Perspective) usedList.get(usedList.size() - 2);
3573 }
3574 }
3575
3576 /**
3577 * Returns the number of perspectives opened
3578 */
3579 public int size() {
3580 return openedList.size();
3581 }
3582
3583 /**
3584 * Marks the specified perspective as the most recently used one in the
3585 * list.
3586 */
3587 public void setActive(Perspective perspective) {
3588 if (perspective == active)
3589 return;
3590
3591 active = perspective;
3592
3593 if (perspective != null) {
3594 usedList.remove(perspective);
3595 usedList.add(perspective);
3596 }
3597 }
3598 }
3599
3600 //for dynamic UI
3601 protected HashMap getStateMap() {
3602 return stateMap;
3603 }
3604
3605 //for dynamic UI
3606 protected void addPerspective(Perspective persp) {
3607 perspList.add(persp);
3608 }
3609
3610 /**
3611 * Find the stack of view references stacked with this view part.
3612 *
3613 * @param part the part
3614 * @return the stack of references
3615 * @since 3.0
3616 */
3617 private IViewReference [] getViewReferenceStack(IViewPart part) {
3618 // Sanity check.
3619 Perspective persp = getActivePerspective();
3620 if (persp == null || !certifyPart(part))
3621 return null;
3622
3623 ILayoutContainer container = ((PartSite)part.getSite()).getPane().getContainer();
3624 if (container instanceof ViewStack) {
3625 ViewStack folder = (ViewStack) container;
3626 final ArrayList list = new ArrayList(folder.getChildren().length);
3627 for (int i = 0; i < folder.getChildren().length; i++) {
3628 LayoutPart layoutPart = folder.getChildren()[i];
3629 if (layoutPart instanceof ViewPane) {
3630 IViewReference view = ((ViewPane)layoutPart).getViewReference();
3631 if (view != null)
3632 list.add(view);
3633 }
3634 }
3635
3636 // sort the list by activation order
3637 Collections.sort(list, new Comparator() {
3638 public int compare(Object o1, Object o2) {
3639 int pos1 = (-1) * activationList.indexOf((IWorkbenchPartReference) o1);
3640 int pos2 = (-1) * activationList.indexOf((IWorkbenchPartReference) o2);
3641 return pos1 - pos2;
3642 }});
3643
3644 return (IViewReference []) list.toArray(new IViewReference [list.size()]);
3645 }
3646
3647 return new IViewReference[] { (IViewReference) getReference(part) };
3648 }
3649
3650 /* (non-Javadoc)
3651 * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
3652 */
3653 public IViewPart [] getViewStack(IViewPart part) {
3654 IViewReference [] refStack = getViewReferenceStack(part);
3655 if (refStack == null)
3656 return null;
3657
3658 IViewPart [] stack = new IViewPart[refStack.length];
3659 for (int i = 0; i < refStack.length; i++) {
3660 stack[i] = refStack[i].getView(true);
3661 }
3662
3663 return stack;
3664 }
3665 /**
3666 * Allow for programmatically resizing a part.
3667 * <p>
3668 * <em>EXPERIMENTAL</em>
3669 * </p>
3670 * <p>
3671 * Known limitations:
3672 * <ul>
3673 * <li>currently applies only to views</li>
3674 * <li>has no effect when view is zoomed</li>
3675 * </ul>
3676 */
3677 public void resizeView(IViewPart part, int width, int height) {
3678 SashInfo sashInfo = new SashInfo();
3679 PartPane pane = ((PartSite)part.getSite()).getPane();
3680 ILayoutContainer container = pane.getContainer();
3681 LayoutTree tree = getPerspectivePresentation().getLayout().root.find(((ViewStack)container));
3682
3683 // retrieve our layout sashes from the layout tree
3684 findSashParts(tree, pane.findSashes(), sashInfo);
3685
3686 // first set the width
3687 float deltaWidth = width - pane.getBounds().width;
3688 if (sashInfo.right != null) {
3689 Rectangle rightBounds = sashInfo.rightNode.getBounds();
3690 // set the new ratio
3691 sashInfo.right.setRatio(
3692 ((float) ((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x))
3693 / ((float) rightBounds.width));
3694 // complete the resize
3695 sashInfo.rightNode.setBounds(rightBounds);
3696 }
3697 else if (sashInfo.left != null) {
3698 Rectangle leftBounds = sashInfo.leftNode.getBounds();
3699 // set the ratio
3700 sashInfo.left.setRatio(
3701 (float) ((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
3702 / ((float) leftBounds.width));
3703 // complete the resize
3704 sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
3705 }
3706
3707 // next set the height
3708 float deltaHeight = height - pane.getBounds().height;
3709 if (sashInfo.bottom != null) {
3710 Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
3711 // set the new ratio
3712 sashInfo.bottom.setRatio(
3713 ((float) ((deltaHeight + sashInfo.bottom.getBounds().y) - bottomBounds.y))
3714 / ((float) bottomBounds.height));
3715 // complete the resize
3716 sashInfo.bottomNode.setBounds(bottomBounds);
3717 }
3718 else if (sashInfo.top != null) {
3719 Rectangle topBounds = sashInfo.topNode.getBounds();
3720 // set the ratio
3721 sashInfo.top.setRatio(
3722 (float) ((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
3723 / ((float) topBounds.height));
3724 // complete the resize
3725 sashInfo.topNode.setBounds(topBounds);
3726 }
3727
3728 }
3729 // provides sash information for the given pane
3730 private class SashInfo {
3731 private LayoutPartSash right;
3732 private LayoutPartSash left;
3733 private LayoutPartSash top;
3734 private LayoutPartSash bottom;
3735 private LayoutTreeNode rightNode;
3736 private LayoutTreeNode leftNode;
3737 private LayoutTreeNode topNode;
3738 private LayoutTreeNode bottomNode;
3739 }
3740 private void findSashParts(LayoutTree tree, PartPane.Sashes sashes, SashInfo info) {
3741 LayoutTree parent = tree.getParent();
3742 if (parent == null)
3743 return;
3744
3745 if (parent.part instanceof LayoutPartSash) {
3746 // get the layout part sash from this tree node
3747 LayoutPartSash sash = (LayoutPartSash) parent.part;
3748 // make sure it has a sash control
3749 Control control = sash.getControl();
3750 if (control != null) {
3751 // check for a vertical sash
3752 if (sash.isVertical()) {
3753 if (sashes.left == control) {
3754 info.left = sash;
3755 info.leftNode = parent.findSash(sash);
3756 }
3757 else if (sashes.right == control) {
3758 info.right = sash;
3759 info.rightNode = parent.findSash(sash);
3760 }
3761 }
3762 // check for a horizontal sash
3763 else {
3764 if (sashes.top == control) {
3765 info.top = sash;
3766 info.topNode = parent.findSash(sash);
3767 }
3768 else if (sashes.bottom == control) {
3769 info.bottom = sash;
3770 info.bottomNode = parent.findSash(sash);
3771 }
3772 }
3773 }
3774 }
3775 // recursive call to continue up the tree
3776 findSashParts(parent, sashes, info);
3777 }
3778}