KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > views > ViewContextService


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.internal.ui.views;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20 import java.util.StringTokenizer JavaDoc;
21 import java.util.Map.Entry;
22
23 import org.eclipse.core.commands.common.NotDefinedException;
24 import org.eclipse.core.commands.contexts.Context;
25 import org.eclipse.core.commands.contexts.ContextManagerEvent;
26 import org.eclipse.core.commands.contexts.IContextManagerListener;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IConfigurationElement;
29 import org.eclipse.core.runtime.IExtensionPoint;
30 import org.eclipse.core.runtime.Platform;
31 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
32 import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
33 import org.eclipse.debug.core.DebugPlugin;
34 import org.eclipse.debug.core.ILaunch;
35 import org.eclipse.debug.core.ILaunchConfiguration;
36 import org.eclipse.debug.core.ILaunchConfigurationType;
37 import org.eclipse.debug.internal.ui.DebugUIPlugin;
38 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
39 import org.eclipse.debug.internal.ui.contexts.DebugModelContextBindingManager;
40 import org.eclipse.debug.ui.DebugUITools;
41 import org.eclipse.debug.ui.IDebugUIConstants;
42 import org.eclipse.debug.ui.contexts.DebugContextEvent;
43 import org.eclipse.debug.ui.contexts.IDebugContextListener;
44 import org.eclipse.debug.ui.contexts.IDebugContextService;
45 import org.eclipse.jface.viewers.ISelection;
46 import org.eclipse.jface.viewers.IStructuredSelection;
47 import org.eclipse.ui.IPerspectiveDescriptor;
48 import org.eclipse.ui.IPerspectiveListener4;
49 import org.eclipse.ui.IViewPart;
50 import org.eclipse.ui.IViewReference;
51 import org.eclipse.ui.IWorkbenchPage;
52 import org.eclipse.ui.IWorkbenchPartReference;
53 import org.eclipse.ui.IWorkbenchWindow;
54 import org.eclipse.ui.PartInitException;
55 import org.eclipse.ui.PlatformUI;
56 import org.eclipse.ui.console.IConsoleConstants;
57 import org.eclipse.ui.contexts.IContextService;
58 import org.w3c.dom.Document JavaDoc;
59 import org.w3c.dom.Element JavaDoc;
60 import org.w3c.dom.Node JavaDoc;
61 import org.w3c.dom.NodeList JavaDoc;
62
63 /**
64  * Performs view management for a window.
65  *
66  * @since 3.2
67  */

68 public class ViewContextService implements IDebugContextListener, IPerspectiveListener4, IPropertyChangeListener, IContextManagerListener {
69     
70     /**
71      * Maps the perspectives in this window to its last activated workbench context
72      */

73     private Map JavaDoc fPerspectiveToActiveContext = new HashMap JavaDoc();
74     
75     /**
76      * Map of the perspectives to all workbench contexts activated in that perspective
77      */

78     private Map JavaDoc fPerspectiveToActivatedContexts = new HashMap JavaDoc();
79     
80     /**
81      * Map of context id's to context view bindings
82      */

83     private Map JavaDoc fContextIdsToBindings;
84         
85     /**
86      * List of perspectives that debugging is allowed in
87      */

88     private List JavaDoc fEnabledPerspectives = new ArrayList JavaDoc();
89     
90     /**
91      * Whether to ignore perspective change call backs (set to
92      * true when this class is modifying views).
93      */

94     private boolean fIgnoreChanges = false;
95     
96     /**
97      * The window this service is working for
98      */

99     private IWorkbenchWindow fWindow;
100     
101     private IContextService fContextService;
102     
103     // base debug context
104
public static final String JavaDoc DEBUG_CONTEXT= "org.eclipse.debug.ui.debugging"; //$NON-NLS-1$
105

106     // extension point
107
private static final String JavaDoc ID_CONTEXT_VIEW_BINDINGS= "contextViewBindings"; //$NON-NLS-1$
108

109     // extension attributes
110
private static final String JavaDoc ATTR_CONTEXT_ID= "contextId"; //$NON-NLS-1$
111
private static final String JavaDoc ATTR_VIEW_ID= "viewId"; //$NON-NLS-1$
112
private static final String JavaDoc ATTR_AUTO_OPEN= "autoOpen"; //$NON-NLS-1$
113
private static final String JavaDoc ATTR_AUTO_CLOSE= "autoClose"; //$NON-NLS-1$
114

115     // XML tags
116
private static final String JavaDoc XML_ELEMENT_VIEW_BINDINGS ="viewBindings"; //$NON-NLS-1$
117
private static final String JavaDoc XML_ELEMENT_PERSPECTIVE ="perspective"; //$NON-NLS-1$
118
private static final String JavaDoc XML_ELEMENT_VIEW = "view"; //$NON-NLS-1$
119
private static final String JavaDoc XML_ATTR_ID = "id"; //$NON-NLS-1$
120
private static final String JavaDoc XML_ATTR_USER_ACTION = "userAction"; //$NON-NLS-1$
121
private static final String JavaDoc XML_VALUE_OPENED = "opened"; //$NON-NLS-1$
122
private static final String JavaDoc XML_VALUE_CLOSED = "closed"; //$NON-NLS-1$
123

124     // ids of base debug views in debug perspective that should not be auto-closed
125
private static Set JavaDoc fgBaseDebugViewIds = null;
126     
127     static {
128         fgBaseDebugViewIds = new HashSet JavaDoc();
129         fgBaseDebugViewIds.add(IDebugUIConstants.ID_DEBUG_VIEW);
130         fgBaseDebugViewIds.add(IDebugUIConstants.ID_VARIABLE_VIEW);
131         fgBaseDebugViewIds.add(IDebugUIConstants.ID_BREAKPOINT_VIEW);
132         fgBaseDebugViewIds.add(IConsoleConstants.ID_CONSOLE_VIEW);
133     }
134     
135     private static String JavaDoc[] EMPTY_IDS = new String JavaDoc[0];
136     
137     /**
138      * View bindings for a debug context
139      */

140     private class DebugContextViewBindings {
141         
142         // context id
143
private String JavaDoc fId;
144         
145         // list of view bindings id's specific to this context
146
private String JavaDoc[] fViewBindingIds = EMPTY_IDS;
147         
148         // all bindings including inherited bindings, top down in activation order
149
private String JavaDoc[] fAllViewBindingIds = null;
150         // associated binding to activate
151
private Map JavaDoc fAllViewIdToBindings = new HashMap JavaDoc();
152         // all context id's in this context hierarchy (top down order)
153
private String JavaDoc[] fAllConetxtIds = null;
154
155         // id of parent context
156
private String JavaDoc fParentId;
157         
158         /**
159          * Constructs an empty view binding for the given context.
160          *
161          * @param id context id
162          */

163         public DebugContextViewBindings(String JavaDoc id) {
164             fId = id;
165         }
166         
167         /**
168          * Returns the context id for these view bindings
169          *
170          * @return context id
171          */

172         public String JavaDoc getId() {
173             return fId;
174         }
175         
176         /**
177          * Adds the given view binding to this context
178          *
179          * @param binding view binding to add
180          */

181         public void addBinding(ViewBinding binding) {
182             String JavaDoc[] newBindings = new String JavaDoc[fViewBindingIds.length + 1];
183             System.arraycopy(fViewBindingIds, 0, newBindings, 0, fViewBindingIds.length);
184             newBindings[fViewBindingIds.length] = binding.getViewId();
185             fAllViewIdToBindings.put(binding.getViewId(), binding);
186             fViewBindingIds = newBindings;
187         }
188         
189         /**
190          * Sets the parent id of this view bindings
191          *
192          * @param id parent context id
193          */

194         protected void setParentId(String JavaDoc id) {
195             fParentId = id;
196         }
197         
198         /**
199          * Returns the id of parent context
200          *
201          * @return parent context id
202          */

203         public DebugContextViewBindings getParentContext() {
204             if (fParentId == null) {
205                 return null;
206             }
207             return (DebugContextViewBindings) fContextIdsToBindings.get(fParentId);
208         }
209         
210         /**
211          * Activates the views in this context hierarchy. Views are activated top down, allowing
212          * sub-contexts to override settings in a parent context.
213          */

214         public void activateChain(IWorkbenchPage page) {
215             initializeChain();
216             doActivation(page, fAllViewBindingIds, fAllConetxtIds);
217         }
218         
219         /**
220          * Activates the view bindings for the specified views and the
221          * specified contexts in the given page.
222          *
223          * @param page page to activate views in
224          * @param viewIds id's of views to activate
225          * @param contextIds associated contexts that are activated
226          */

227         private void doActivation(IWorkbenchPage page, String JavaDoc[] viewIds, String JavaDoc[] contextIds) {
228             // note activation of all the relevant contexts
229
for (int i = 0; i < contextIds.length; i++) {
230                 addActivated(contextIds[i]);
231             }
232             // set the active context to be this
233
setActive(page.getPerspective(), getId());
234             // activate the view bindings
235
for (int i = 0; i < viewIds.length; i++) {
236                 String JavaDoc viewId = viewIds[i];
237                 ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
238                 binding.activated(page);
239             }
240             // bring most relevant views to top
241
for (int i = 0; i < viewIds.length; i++) {
242                 String JavaDoc viewId = viewIds[i];
243                 ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
244                 binding.checkZOrder(page, fAllViewBindingIds);
245             }
246         }
247         
248         /**
249          * Builds the top down ordered list of bindings for this context allowing sub-contexts
250          * to override parent settings.
251          */

252         private synchronized void initializeChain() {
253             if (fAllViewBindingIds == null) {
254                 List JavaDoc orderedIds = new ArrayList JavaDoc();
255                 List JavaDoc contexts = new ArrayList JavaDoc();
256                 DebugContextViewBindings context = this;
257                 while (context != null) {
258                     contexts.add(0, context);
259                     context = context.getParentContext();
260                 }
261                 Iterator JavaDoc iterator = contexts.iterator();
262                 fAllConetxtIds = new String JavaDoc[contexts.size()];
263                 int pos = 0;
264                 while (iterator.hasNext()) {
265                     DebugContextViewBindings bindings = (DebugContextViewBindings) iterator.next();
266                     fAllConetxtIds[pos] = bindings.getId();
267                     pos++;
268                     for (int i = 0; i < bindings.fViewBindingIds.length; i++) {
269                         String JavaDoc viewId = bindings.fViewBindingIds[i];
270                         if (bindings == this) {
271                             orderedIds.add(viewId);
272                         }
273                         if (!fAllViewIdToBindings.containsKey(viewId)) {
274                             orderedIds.add(viewId);
275                             fAllViewIdToBindings.put(viewId, bindings.fAllViewIdToBindings.get(viewId));
276                         }
277                     }
278                 }
279                 fAllViewBindingIds = (String JavaDoc[]) orderedIds.toArray(new String JavaDoc[orderedIds.size()]);
280             }
281         }
282         
283         /**
284          * Deactivates this context only (not parents)
285          *
286          * @param page workbench page
287          */

288         public void deactivate(IWorkbenchPage page) {
289             removeActivated(getId());
290             if (isActiveContext(getId())) {
291                 setActive(page.getPerspective(), null);
292             }
293             for (int i = 0; i < fViewBindingIds.length; i++) {
294                 String JavaDoc viewId = fViewBindingIds[i];
295                 ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
296                 binding.deactivated(page);
297             }
298         }
299         
300         /**
301          * Notes when a view is opened/closed manually.
302          *
303          * @param opened opened or closed
304          * @param viewId
305          */

306         public void setViewOpened(boolean opened, String JavaDoc viewId) {
307             initializeChain();
308             ViewBinding binding = (ViewBinding)fAllViewIdToBindings.get(viewId);
309             if (binding != null) {
310                 if (opened) {
311                     binding.userOpened();
312                 } else {
313                     binding.userClosed();
314                 }
315             }
316         }
317
318         public void applyUserSettings(String JavaDoc viewId, Element viewElement) {
319             initializeChain();
320             ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
321             if (binding != null) {
322                 binding.applyUserSettings(viewElement);
323             }
324         }
325         
326         /**
327          * Save view binding settings into XML document.
328          *
329          * @param document
330          * @param root
331          * @param alreadyDone views already done
332          */

333         public void saveBindings(Document JavaDoc document, Element root, Set JavaDoc alreadyDone) {
334             for (int i = 0; i < fViewBindingIds.length; i++) {
335                 String JavaDoc viewId = fViewBindingIds[i];
336                 if (!alreadyDone.contains(viewId)) {
337                     alreadyDone.add(viewId);
338                     ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
339                     binding.saveBindings(document, root);
340                 }
341             }
342         }
343     }
344     
345     /**
346      * Information for a view
347      */

348     private class ViewBinding {
349         private IConfigurationElement fElement;
350         /**
351          * Set of perspectives this view was opened in by the user
352          */

353         private Set JavaDoc fUserOpened = new HashSet JavaDoc();
354         /**
355          * Set of perspectives this view was closed in by the user
356          */

357         private Set JavaDoc fUserClosed = new HashSet JavaDoc();
358         
359         public ViewBinding(IConfigurationElement element) {
360             fElement = element;
361         }
362         
363         /**
364          * Returns the id of the view this binding pertains to.
365          *
366          * @return
367          */

368         public String JavaDoc getViewId() {
369             return fElement.getAttribute(ATTR_VIEW_ID);
370         }
371         
372         /**
373          * Returns whether this view binding is set for auto-open.
374          *
375          * @return
376          */

377         public boolean isAutoOpen() {
378             String JavaDoc autoopen = fElement.getAttribute(ATTR_AUTO_OPEN);
379             return autoopen == null || "true".equals(autoopen); //$NON-NLS-1$
380
}
381         
382         /**
383          * Returns whether this view binding is set for auto-close.
384          *
385          * @return
386          */

387         public boolean isAutoClose() {
388             String JavaDoc autoclose = fElement.getAttribute(ATTR_AUTO_CLOSE);
389             return autoclose == null || "true".equals(autoclose); //$NON-NLS-1$
390
}
391         
392         /**
393          * Returns whether this view was opened by the user in the active perspective.
394          * @return
395          */

396         public boolean isUserOpened() {
397             return fUserOpened.contains(getActivePerspective().getId());
398         }
399         
400         /**
401          * Returns whether this view was closed by the user in the active perspective
402          * @return
403          */

404         public boolean isUserClosed() {
405             return fUserClosed.contains(getActivePerspective().getId());
406         }
407         
408         /**
409          * Returns whether this view is part of the active perspective by default
410          *
411          * TODO: we really need an API to determine which views are
412          * in a perspective by default, but it does not seem to exist.
413          *
414          * @return
415          */

416         public boolean isDefault() {
417             String JavaDoc id = getActivePerspective().getId();
418             if (IDebugUIConstants.ID_DEBUG_PERSPECTIVE.equals(id)) {
419                 return fgBaseDebugViewIds.contains(getViewId());
420             }
421             return false;
422         }
423         
424         protected void userOpened() {
425             if (isTrackingViews()) {
426                 String JavaDoc id = getActivePerspective().getId();
427                 fUserOpened.add(id);
428                 fUserClosed.remove(id);
429                 saveViewBindings();
430             }
431         }
432         
433         protected void userClosed() {
434             if (isTrackingViews()) {
435                 String JavaDoc id = getActivePerspective().getId();
436                 fUserClosed.add(id);
437                 fUserOpened.remove(id);
438                 saveViewBindings();
439             }
440         }
441         
442         /**
443          * Returns whether the preference is set to track user view open/close.
444          *
445          * @return
446          */

447         protected boolean isTrackingViews() {
448             return DebugUITools.getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TRACK_VIEWS);
449         }
450         
451         /**
452          * Context has been activated, open/show as required.
453          *
454          * @param page
455          */

456         public void activated(IWorkbenchPage page) {
457             if (!isUserClosed()) {
458                 if (isAutoOpen()) {
459                     try {
460                         fIgnoreChanges = true;
461                         page.showView(getViewId(), null, IWorkbenchPage.VIEW_CREATE);
462                     } catch (PartInitException e) {
463                         DebugUIPlugin.log(e);
464                     } finally {
465                         fIgnoreChanges = false;
466                     }
467                 }
468             }
469         }
470         
471         /**
472          * Context has been activated. Check the view stack to see if this view
473          * should be made visible.
474          *
475          * @param page
476          */

477         public void checkZOrder(IWorkbenchPage page, String JavaDoc[] relevantViews) {
478             // see if view is open already
479
IViewPart part = page.findView(getViewId());
480             if (part != null) {
481                 IViewPart[] viewStack = page.getViewStack(part);
482                 if (viewStack != null && viewStack.length > 0) {
483                     String JavaDoc top = viewStack[0].getSite().getId();
484                     for (int i = 0; i < relevantViews.length; i++) {
485                         if (relevantViews[i].equals(top)) {
486                             // a relevant view is visible
487
return;
488                         }
489                     }
490                     // an irrelevant view is visible
491
try {
492                         fIgnoreChanges = true;
493                         page.bringToTop(part);
494                     } finally {
495                         fIgnoreChanges = false;
496                     }
497                 }
498             }
499         }
500         
501         /**
502          * Context has been deactivated, close as required.
503          *
504          * @param page
505          */

506         public void deactivated(IWorkbenchPage page) {
507             if (!isUserOpened()) {
508                 if (isAutoClose() && !isDefault()) {
509                     IViewReference reference = page.findViewReference(getViewId());
510                     if (reference != null) {
511                         try {
512                             fIgnoreChanges = true;
513                             page.hideView(reference);
514                         } finally {
515                             fIgnoreChanges = false;
516                         }
517                     }
518                 }
519             }
520         }
521
522         /**
523          * Save view binding settings into XML document.
524          *
525          * @param document
526          * @param root
527          */

528         public void saveBindings(Document JavaDoc document, Element root) {
529             Element viewElement = document.createElement(XML_ELEMENT_VIEW);
530             viewElement.setAttribute(XML_ATTR_ID, getViewId());
531             appendPerspectives(document, viewElement, fUserOpened, XML_VALUE_OPENED);
532             appendPerspectives(document, viewElement, fUserClosed, XML_VALUE_CLOSED);
533             if (viewElement.hasChildNodes()) {
534                 root.appendChild(viewElement);
535             }
536         }
537         
538         private void appendPerspectives(Document JavaDoc document, Element parent, Set JavaDoc perpectives, String JavaDoc xmlValue) {
539             String JavaDoc[] ids = (String JavaDoc[]) perpectives.toArray(new String JavaDoc[perpectives.size()]);
540             for (int i = 0; i < ids.length; i++) {
541                 String JavaDoc id = ids[i];
542                 Element element = document.createElement(XML_ELEMENT_PERSPECTIVE);
543                 element.setAttribute(XML_ATTR_ID, id);
544                 element.setAttribute(XML_ATTR_USER_ACTION, xmlValue);
545                 parent.appendChild(element);
546             }
547         }
548         
549         public void applyUserSettings(Element viewElement) {
550             NodeList JavaDoc list = viewElement.getChildNodes();
551             int length = list.getLength();
552             for (int i = 0; i < length; ++i) {
553                 Node JavaDoc node = list.item(i);
554                 short type = node.getNodeType();
555                 if (type == Node.ELEMENT_NODE) {
556                     Element entry = (Element) node;
557                     if(entry.getNodeName().equalsIgnoreCase(XML_ELEMENT_PERSPECTIVE)){
558                         String JavaDoc id = entry.getAttribute(XML_ATTR_ID);
559                         String JavaDoc setting = entry.getAttribute(XML_ATTR_USER_ACTION);
560                         if (id != null) {
561                             if (XML_VALUE_CLOSED.equals(setting)) {
562                                 fUserClosed.add(id);
563                             } else if (XML_VALUE_OPENED.equals(setting)) {
564                                 fUserOpened.add(id);
565                             }
566                         }
567                     }
568                 }
569             }
570         }
571     }
572     
573     private IDebugContextService getDebugContextService() {
574         return DebugUITools.getDebugContextManager().getContextService(fWindow);
575     }
576     
577     /**
578      * Creates a service for the given window
579      *
580      * @param window
581      */

582     ViewContextService(IWorkbenchWindow window) {
583         fWindow = window;
584         fContextService = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
585         loadContextToViewExtensions();
586         applyUserViewBindings();
587         loadPerspectives();
588         window.addPerspectiveListener(this);
589         getDebugContextService().addDebugContextListener(this);
590         DebugUIPlugin.getDefault().getPluginPreferences().addPropertyChangeListener(this);
591         fContextService.addContextManagerListener(this);
592     }
593     
594     public void dispose() {
595         fWindow.removePerspectiveListener(this);
596         getDebugContextService().removeDebugContextListener(this);
597         DebugUIPlugin.getDefault().getPluginPreferences().removePropertyChangeListener(this);
598         fContextService.removeContextManagerListener(this);
599     }
600     
601     /**
602      * Loads extensions which map context id's to view bindings.
603      */

604     private void loadContextToViewExtensions() {
605         fContextIdsToBindings = new HashMap JavaDoc();
606         IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), ID_CONTEXT_VIEW_BINDINGS);
607         IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
608         for (int i = 0; i < configurationElements.length; i++) {
609             IConfigurationElement element = configurationElements[i];
610             String JavaDoc viewId = element.getAttribute(ATTR_VIEW_ID);
611             String JavaDoc contextId = element.getAttribute(ATTR_CONTEXT_ID);
612             if (contextId == null || viewId == null) {
613                 continue;
614             }
615             ViewBinding info = new ViewBinding(element);
616             DebugContextViewBindings bindings = (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
617             if (bindings == null) {
618                 bindings = new DebugContextViewBindings(contextId);
619                 fContextIdsToBindings.put(contextId, bindings);
620             }
621             bindings.addBinding(info);
622         }
623         linkParentContexts();
624     }
625     
626     /**
627      * Applies user settings that modify view binding extensions.
628      */

629     private void applyUserViewBindings() {
630         String JavaDoc xml = DebugUITools.getPreferenceStore().getString(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS);
631         if (xml.length() > 0) {
632             try {
633                 Element root = DebugPlugin.parseDocument(xml);
634                 NodeList JavaDoc list = root.getChildNodes();
635                 int length = list.getLength();
636                 for (int i = 0; i < length; ++i) {
637                     Node JavaDoc node = list.item(i);
638                     short type = node.getNodeType();
639                     if (type == Node.ELEMENT_NODE) {
640                         Element entry = (Element) node;
641                         if(entry.getNodeName().equalsIgnoreCase(XML_ELEMENT_VIEW)){
642                             String JavaDoc id = entry.getAttribute(XML_ATTR_ID);
643                             Iterator JavaDoc bindings = fContextIdsToBindings.values().iterator();
644                             while (bindings.hasNext()) {
645                                 DebugContextViewBindings binding = (DebugContextViewBindings) bindings.next();
646                                 binding.applyUserSettings(id, entry);
647                             }
648                         }
649                     }
650                 }
651             } catch (CoreException e) {
652                 DebugUIPlugin.log(e);
653             }
654         }
655     }
656     
657     /**
658      * Load the collection of perspectives in which view management will occur from the preference store.
659      */

660     private void loadPerspectives() {
661         String JavaDoc prefString = DebugUIPlugin.getDefault().getPreferenceStore().getString(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES);
662         fEnabledPerspectives = parseList(prefString);
663     }
664     
665     /* (non-Javadoc)
666      * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
667      */

668     public void propertyChange(PropertyChangeEvent event) {
669         if (!fIgnoreChanges) {
670             if (IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES.equals(event.getProperty())) {
671                 loadPerspectives();
672             } else if (IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS.equals(event.getProperty())) {
673                 loadContextToViewExtensions();
674                 applyUserViewBindings();
675                 // clear activations to re-enable activation based on new settings
676
fPerspectiveToActivatedContexts.clear();
677                 ISelection selection = getDebugContextService().getActiveContext();
678                 contextActivated(selection);
679             }
680         }
681     }
682     
683     /**
684      * Returns whether this service's window's active perspective supports view management.
685      *
686      * @return whether this service's window's active perspective supports view management
687      */

688     private boolean isEnabledPerspective() {
689         IPerspectiveDescriptor perspective = getActivePerspective();
690         if (perspective != null) {
691             return fEnabledPerspectives.contains(perspective.getId());
692         }
693         return false;
694     }
695     
696     /**
697      * Returns the active perspective in this service's window, or <code>null</code>
698      *
699      * @return active perspective or <code>null</code>
700      */

701     private IPerspectiveDescriptor getActivePerspective() {
702         IWorkbenchPage activePage = fWindow.getActivePage();
703         if (activePage != null) {
704             return activePage.getPerspective();
705         }
706         return null;
707     }
708     
709     /**
710      * Parses the comma separated string into a list of strings
711      *
712      * @return list
713      */

714     public static List JavaDoc parseList(String JavaDoc listString) {
715         List JavaDoc list = new ArrayList JavaDoc(10);
716         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(listString, ","); //$NON-NLS-1$
717
while (tokenizer.hasMoreTokens()) {
718             String JavaDoc token = tokenizer.nextToken();
719             list.add(token);
720         }
721         return list;
722     }
723     
724     public void contextActivated(ISelection selection) {
725         if (isEnabledPerspective()) {
726             if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
727                 IStructuredSelection ss = (IStructuredSelection) selection;
728                 Iterator JavaDoc iterator = ss.iterator();
729                 while (iterator.hasNext()) {
730                     Object JavaDoc target = iterator.next();
731                     ILaunch launch = DebugModelContextBindingManager.getLaunch(target);
732                     if (launch != null) {
733                         ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
734                         if (launchConfiguration != null) {
735                             try {
736                                 ILaunchConfigurationType type = launchConfiguration.getType();
737                                 // check if this perspective is enabled for the launch type
738
// Include the word '.internal.' so the context is filtered from the key binding pref page (Bug 144019) also see PerspectiveManager.handleBreakpointHit()
739
if (fContextService.getActiveContextIds().contains(type.getIdentifier() + ".internal." + getActivePerspective().getId())) { //$NON-NLS-1$
740
// get the leaf contexts to be activated
741
List JavaDoc workbenchContexts = DebugModelContextBindingManager.getDefault().getWorkbenchContextsForDebugContext(target);
742                                     // TODO: do we need to check if contexts are actually enabled in workbench first?
743
if (!workbenchContexts.isEmpty()) {
744                                         // if all contexts already activate and last context is already active context == done
745
Iterator JavaDoc contexts = workbenchContexts.iterator();
746                                         while (contexts.hasNext()) {
747                                             String JavaDoc contextId = (String JavaDoc)contexts.next();
748                                             if (!isActivated(contextId)) {
749                                                 activateChain(contextId);
750                                             }
751                                             // ensure last context gets top priority
752
if (!contexts.hasNext()) {
753                                                 if (!isActiveContext(contextId)) {
754                                                     activateChain(contextId);
755                                                 }
756                                             }
757                                         }
758                                     }
759                                     
760                                 }
761                             } catch (CoreException e) {
762                                 DebugUIPlugin.log(e);
763                             }
764                         }
765                     }
766                 }
767             }
768         }
769     }
770     
771     /**
772      * Returns whether the given context is the active context in the active perspective.
773      *
774      * @param contextId
775      * @return
776      */

777     private boolean isActiveContext(String JavaDoc contextId) {
778         IPerspectiveDescriptor activePerspective = getActivePerspective();
779         if (activePerspective != null) {
780             String JavaDoc activeId = (String JavaDoc) fPerspectiveToActiveContext.get(activePerspective);
781             return contextId.equals(activeId);
782         }
783         return false;
784     }
785     
786     /**
787      * Returns whether the given context is activated in the active perspective.
788      *
789      * @param contextId
790      * @return
791      */

792     private boolean isActivated(String JavaDoc contextId) {
793         IPerspectiveDescriptor activePerspective = getActivePerspective();
794         if (activePerspective != null) {
795             Set JavaDoc contexts = (Set JavaDoc) fPerspectiveToActivatedContexts.get(activePerspective);
796             if (contexts != null) {
797                 return contexts.contains(contextId);
798             }
799         }
800         return false;
801     }
802     
803     private void addActivated(String JavaDoc contextId) {
804         IPerspectiveDescriptor activePerspective = getActivePerspective();
805         if (activePerspective != null) {
806             Set JavaDoc contexts = (Set JavaDoc) fPerspectiveToActivatedContexts.get(activePerspective);
807             if (contexts == null) {
808                 contexts = new HashSet JavaDoc();
809                 fPerspectiveToActivatedContexts.put(activePerspective, contexts);
810             }
811             contexts.add(contextId);
812         }
813     }
814     
815     private void removeActivated(String JavaDoc contextId) {
816         IPerspectiveDescriptor activePerspective = getActivePerspective();
817         if (activePerspective != null) {
818             Set JavaDoc contexts = (Set JavaDoc) fPerspectiveToActivatedContexts.get(activePerspective);
819             if (contexts != null) {
820                 contexts.remove(contextId);
821             }
822         }
823     }
824
825     public void debugContextChanged(DebugContextEvent event) {
826         if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
827             contextActivated(event.getContext());
828         }
829     }
830
831     /* (non-Javadoc)
832      * @see org.eclipse.ui.IPerspectiveListener3#perspectiveOpened(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
833      */

834     public void perspectiveOpened(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
835     }
836
837     /* (non-Javadoc)
838      * @see org.eclipse.ui.IPerspectiveListener3#perspectiveClosed(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
839      */

840     public void perspectiveClosed(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
841     }
842
843     /* (non-Javadoc)
844      * @see org.eclipse.ui.IPerspectiveListener3#perspectiveDeactivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
845      */

846     public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
847     }
848     
849     /**
850      * Closes all auto-opened views.
851      *
852      * @param page
853      * @param perspective
854      */

855     private void clean(IPerspectiveDescriptor perspective) {
856         Set JavaDoc contexts = (Set JavaDoc) fPerspectiveToActivatedContexts.remove(perspective);
857         fPerspectiveToActiveContext.remove(perspective);
858         if (contexts != null) {
859             Iterator JavaDoc iterator = contexts.iterator();
860             while (iterator.hasNext()) {
861                 String JavaDoc id = (String JavaDoc) iterator.next();
862                 deactivate(id);
863             }
864         }
865     }
866
867     /* (non-Javadoc)
868      * @see org.eclipse.ui.IPerspectiveListener3#perspectiveSavedAs(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IPerspectiveDescriptor)
869      */

870     public void perspectiveSavedAs(IWorkbenchPage page, IPerspectiveDescriptor oldPerspective, IPerspectiveDescriptor newPerspective) {
871     }
872
873     /* (non-Javadoc)
874      * @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
875      */

876     public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String JavaDoc changeId) {
877         if (!fIgnoreChanges && page.getWorkbenchWindow().equals(fWindow)) {
878             if(partRef != null) {
879                 if (IWorkbenchPage.CHANGE_VIEW_SHOW == changeId || IWorkbenchPage.CHANGE_VIEW_HIDE == changeId) {
880                     Iterator JavaDoc iterator = fContextIdsToBindings.values().iterator();
881                     while (iterator.hasNext()) {
882                         DebugContextViewBindings bindings = (DebugContextViewBindings) iterator.next();
883                         bindings.setViewOpened(IWorkbenchPage.CHANGE_VIEW_SHOW == changeId, partRef.getId());
884                     }
885                 }
886             }
887         }
888     }
889
890     /* (non-Javadoc)
891      * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
892      */

893     public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
894         if (page.getWorkbenchWindow().equals(fWindow)) {
895             ISelection activeContext = getDebugContextService().getActiveContext();
896             if (activeContext != null) {
897                 contextActivated(activeContext);
898             }
899         }
900     }
901
902     /* (non-Javadoc)
903      * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
904      */

905     public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String JavaDoc changeId) {
906     }
907     
908     /**
909      * Activates all parent contexts of the given context, top down.
910      *
911      * @param contextId
912      */

913     private void activateChain(String JavaDoc contextId) {
914         IWorkbenchPage page = fWindow.getActivePage();
915         if (page != null) {
916             DebugContextViewBindings bindings= (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
917             if (bindings != null) {
918                 bindings.activateChain(page);
919             }
920         }
921     }
922     
923     /**
924      * Links each debug context view bindings with its parent context bindings
925      */

926     private void linkParentContexts() {
927         Iterator JavaDoc iterator = fContextIdsToBindings.entrySet().iterator();
928         while (iterator.hasNext()) {
929             Entry entry = (Entry)iterator.next();
930             String JavaDoc contextId = (String JavaDoc) entry.getKey();
931             DebugContextViewBindings bindings = (DebugContextViewBindings) entry.getValue();
932             if (!bindings.getId().equals(DEBUG_CONTEXT)) {
933                 Context context = fContextService.getContext(contextId);
934                 try {
935                     bindings.setParentId(context.getParentId());
936                 } catch (NotDefinedException e) {
937                     DebugUIPlugin.log(e);
938                 }
939             }
940         }
941     }
942     
943     /**
944      * Sets the active context in the given perspective, or removes
945      * when <code>null</code>.
946      *
947      * @param perspective
948      * @param contextId
949      */

950     private void setActive(IPerspectiveDescriptor perspective, String JavaDoc contextId) {
951         if (contextId == null) {
952             fPerspectiveToActiveContext.remove(perspective);
953         } else {
954             fPerspectiveToActiveContext.put(perspective, contextId);
955         }
956     }
957
958     /* (non-Javadoc)
959      * @see org.eclipse.core.commands.contexts.IContextManagerListener#contextManagerChanged(org.eclipse.core.commands.contexts.ContextManagerEvent)
960      */

961     public void contextManagerChanged(ContextManagerEvent event) {
962         if (event.isActiveContextsChanged()) {
963             Set JavaDoc disabledContexts = getDisabledContexts(event);
964             if (!disabledContexts.isEmpty()) {
965                 Iterator JavaDoc contexts = disabledContexts.iterator();
966                 while (contexts.hasNext()) {
967                     String JavaDoc contextId = (String JavaDoc)contexts.next();
968                     if (isViewConetxt(contextId)) {
969                         if (isActivated(contextId)) {
970                             deactivate(contextId);
971                         }
972                     }
973                 }
974             }
975         }
976     }
977     
978     private void deactivate(String JavaDoc contextId) {
979         IWorkbenchPage page = fWindow.getActivePage();
980         if (page != null) {
981             DebugContextViewBindings bindings = (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
982             if (bindings != null) {
983                 bindings.deactivate(page);
984             }
985         }
986     }
987     
988     /**
989      * Returns a set of contexts disabled in the given event, possibly empty.
990      *
991      * @param event
992      * @return disabled context id's
993      */

994     private Set JavaDoc getDisabledContexts(ContextManagerEvent event) {
995         Set JavaDoc prev = new HashSet JavaDoc(event.getPreviouslyActiveContextIds());
996         Set JavaDoc activeContextIds = event.getContextManager().getActiveContextIds();
997         if (activeContextIds != null) {
998             prev.removeAll(activeContextIds);
999         }
1000        return prev;
1001    }
1002
1003    /**
1004     * Returns whether the given context has view bindings.
1005     *
1006     * @param id
1007     * @return whether the given context has view bindings
1008     */

1009    private boolean isViewConetxt(String JavaDoc id) {
1010        return fContextIdsToBindings.containsKey(id);
1011    }
1012    
1013    /**
1014     * Save view binding settings that differ from extension settings
1015     */

1016    private void saveViewBindings() {
1017        try {
1018            Document JavaDoc document = DebugPlugin.newDocument();
1019            Element root = document.createElement(XML_ELEMENT_VIEW_BINDINGS);
1020            document.appendChild(root);
1021            Set JavaDoc done = new HashSet JavaDoc();
1022            Iterator JavaDoc bindings = fContextIdsToBindings.values().iterator();
1023            while (bindings.hasNext()) {
1024                DebugContextViewBindings binding = (DebugContextViewBindings) bindings.next();
1025                binding.saveBindings(document, root, done);
1026            }
1027            String JavaDoc prefValue = ""; //$NON-NLS-1$
1028
if (root.hasChildNodes()) {
1029                prefValue = DebugPlugin.serializeDocument(document);
1030            }
1031            fIgnoreChanges = true;
1032            DebugUITools.getPreferenceStore().setValue(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS, prefValue);
1033        } catch (CoreException e) {
1034            DebugUIPlugin.log(e);
1035        } finally {
1036            fIgnoreChanges = false;
1037        }
1038
1039    }
1040    
1041    /**
1042     * Returns the perspectives in which debugging is enabled.
1043     *
1044     * @return
1045     */

1046    public String JavaDoc[] getEnabledPerspectives() {
1047        return (String JavaDoc[]) fEnabledPerspectives.toArray(new String JavaDoc[fEnabledPerspectives.size()]);
1048    }
1049    
1050    /**
1051     * Show the view without effecting user preferences
1052     *
1053     * @param viewId
1054     */

1055    public void showViewQuiet(String JavaDoc viewId) {
1056        IWorkbenchPage page = fWindow.getActivePage();
1057        if (page != null) {
1058            try {
1059                fIgnoreChanges = true;
1060                IViewPart part = page.showView(viewId, null, IWorkbenchPage.VIEW_VISIBLE);
1061                if (!page.isPartVisible(part)) {
1062                    page.bringToTop(part);
1063                }
1064            } catch (PartInitException e) {
1065                DebugUIPlugin.log(e);
1066            } finally {
1067                fIgnoreChanges = false;
1068            }
1069        }
1070    }
1071
1072    /* (non-Javadoc)
1073     * @see org.eclipse.ui.IPerspectiveListener4#perspectivePreDeactivate(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
1074     */

1075    public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
1076        if (page.getWorkbenchWindow().equals(fWindow)) {
1077            clean(perspective);
1078        }
1079    }
1080}
1081
Popular Tags