KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > contexts > ws > WorkbenchContextSupport


1 /*******************************************************************************
2  * Copyright (c) 2003, 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 package org.eclipse.ui.internal.contexts.ws;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21 import java.util.WeakHashMap JavaDoc;
22
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.DisposeEvent;
25 import org.eclipse.swt.events.DisposeListener;
26 import org.eclipse.swt.widgets.Display;
27 import org.eclipse.swt.widgets.Event;
28 import org.eclipse.swt.widgets.Listener;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.ui.IPageListener;
31 import org.eclipse.ui.IPartListener;
32 import org.eclipse.ui.IPerspectiveDescriptor;
33 import org.eclipse.ui.IPerspectiveListener;
34 import org.eclipse.ui.IWorkbenchPage;
35 import org.eclipse.ui.IWorkbenchPart;
36 import org.eclipse.ui.IWorkbenchSite;
37 import org.eclipse.ui.IWorkbenchWindow;
38 import org.eclipse.ui.contexts.EnabledSubmission;
39 import org.eclipse.ui.contexts.IContext;
40 import org.eclipse.ui.contexts.IContextManager;
41 import org.eclipse.ui.contexts.IWorkbenchContextSupport;
42 import org.eclipse.ui.contexts.NotDefinedException;
43 import org.eclipse.ui.internal.Workbench;
44 import org.eclipse.ui.internal.contexts.ContextManagerFactory;
45 import org.eclipse.ui.internal.contexts.IMutableContextManager;
46 import org.eclipse.ui.internal.contexts.ProxyContextManager;
47 import org.eclipse.ui.internal.keys.WorkbenchKeyboard;
48 import org.eclipse.ui.internal.misc.Policy;
49
50 /**
51  * Provides support for contexts within the workbench -- including key bindings,
52  * and some default contexts for shell types.
53  *
54  * @since 3.0
55  */

56 public class WorkbenchContextSupport implements IWorkbenchContextSupport {
57
58     /**
59      * Whether the workbench context support should kick into debugging mode.
60      * This causes the list of context identifier to the be reported before
61      * every call to change the context identifiers.
62      */

63     private static final boolean DEBUG = Policy.DEBUG_CONTEXTS;
64
65     /**
66      * The number of stack trace elements to show when the contexts have
67      * changed. This is used for debugging purposes to show what caused a
68      * context switch to occur.
69      */

70     private static final int DEBUG_STACK_LENGTH_TO_SHOW = 5;
71
72     /**
73      * Whether the workbench context support should kick into verbose debugging
74      * mode. This causes each context change to print out a bit of the current
75      * stack -- letting you know what caused the context change to occur.
76      */

77     private static final boolean DEBUG_VERBOSE = Policy.DEBUG_CONTEXTS_VERBOSE;
78     
79     /**
80      * Creates a tree of context identifiers, representing the hierarchical
81      * structure of the given contexts. The tree is structured as a mapping from
82      * child to parent.
83      *
84      * @param contextIds
85      * The set of context identifiers to be converted into a tree;
86      * must not be <code>null</code>.
87      * @return The tree of contexts to use; may be empty, but never
88      * <code>null</code>. The keys and values are both strings.
89      */

90     private final Map JavaDoc createContextTreeFor(final Set JavaDoc contextIds) {
91         final Map JavaDoc contextTree = new HashMap JavaDoc();
92         final IContextManager contextManager = getContextManager();
93
94         final Iterator JavaDoc contextIdItr = contextIds.iterator();
95         while (contextIdItr.hasNext()) {
96             String JavaDoc childContextId = (String JavaDoc) contextIdItr.next();
97             while (childContextId != null) {
98                 final IContext childContext = contextManager
99                         .getContext(childContextId);
100
101                 try {
102                     final String JavaDoc parentContextId = childContext.getParentId();
103                     contextTree.put(childContextId, parentContextId);
104                     childContextId = parentContextId;
105                 } catch (final NotDefinedException e) {
106                     break; // stop ascending
107
}
108             }
109         }
110
111         return contextTree;
112     }
113     
114     /**
115      * <p>
116      * Creates a tree of context identifiers, representing the hierarchical
117      * structure of the given contexts. The tree is structured as a mapping from
118      * child to parent. In this tree, the key binding specific filtering of
119      * contexts will have taken place.
120      * </p>
121      * <p>
122      * This method is intended for internal use only.
123      * </p>
124      *
125      * @param contextIds
126      * The set of context identifiers to be converted into a tree;
127      * must not be <code>null</code>.
128      * @return The tree of contexts to use; may be empty, but never
129      * <code>null</code>. The keys and values are both strings.
130      */

131     public final Map JavaDoc createFilteredContextTreeFor(final Set JavaDoc contextIds) {
132         // Check to see whether a dialog or window is active.
133
boolean dialog = false;
134         boolean window = false;
135         Iterator JavaDoc contextIdItr = contextIds.iterator();
136         while (contextIdItr.hasNext()) {
137             final String JavaDoc contextId = (String JavaDoc) contextIdItr.next();
138             if (CONTEXT_ID_DIALOG.equals(contextId)) {
139                 dialog = true;
140                 continue;
141             }
142             if (CONTEXT_ID_WINDOW.equals(contextId)) {
143                 window = true;
144                 continue;
145             }
146         }
147
148         /*
149          * Remove all context identifiers for contexts whose parents are dialog
150          * or window, and the corresponding dialog or window context is not
151          * active.
152          */

153         try {
154             contextIdItr = contextIds.iterator();
155             while (contextIdItr.hasNext()) {
156                 String JavaDoc contextId = (String JavaDoc) contextIdItr.next();
157                 IContext context = mutableContextManager.getContext(contextId);
158                 String JavaDoc parentId = context.getParentId();
159                 while (parentId != null) {
160                     if (CONTEXT_ID_DIALOG.equals(parentId)) {
161                         if (!dialog) {
162                             contextIdItr.remove();
163                         }
164                         break;
165                     }
166                     if (CONTEXT_ID_WINDOW.equals(parentId)) {
167                         if (!window) {
168                             contextIdItr.remove();
169                         }
170                         break;
171                     }
172                     if (CONTEXT_ID_DIALOG_AND_WINDOW.equals(parentId)) {
173                         if ((!window) && (!dialog)) {
174                             contextIdItr.remove();
175                         }
176                         break;
177                     }
178
179                     context = mutableContextManager.getContext(parentId);
180                     parentId = context.getParentId();
181                 }
182             }
183         } catch (NotDefinedException e) {
184             if (DEBUG) {
185                 System.out.println("CONTEXTS >>> NotDefinedException('" //$NON-NLS-1$
186
+ e.getMessage()
187                         + "') while filtering dialog/window contexts"); //$NON-NLS-1$
188
}
189         }
190
191         return createContextTreeFor(contextIds);
192     }
193
194     /**
195      * Listens for shell activation events, and updates the list of enabled
196      * contexts appropriately. This is used to keep the enabled contexts
197      * synchronized with respect to the <code>activeShell</code> condition.
198      */

199     private Listener activationListener = new Listener() {
200
201         /*
202          * (non-Javadoc)
203          *
204          * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
205          */

206         public void handleEvent(Event event) {
207             checkWindowType(event.display.getActiveShell());
208         }
209     };
210
211     /**
212      * The currently active shell. This value is never <code>null</code>.
213      */

214     private Shell activeShell;
215
216     private IWorkbenchSite activeWorkbenchSite;
217
218     /**
219      * The workbench window on which the listeners are currently attached.
220      */

221     private IWorkbenchWindow activeWorkbenchWindow;
222
223     private Map JavaDoc enabledSubmissionsByContextId = new HashMap JavaDoc();
224
225     /**
226      * The key binding support for the contexts. In the workbench, key bindings
227      * are intimately tied to the context mechanism.
228      */

229     private WorkbenchKeyboard keyboard;
230
231     /**
232      * Whether the key binding service is currently active. That is, whether it
233      * is currently listening for (and possibly eating) key events on the
234      * display.
235      */

236     private volatile boolean keyFilterEnabled;
237
238     private IMutableContextManager mutableContextManager;
239
240     private IPageListener pageListener = new IPageListener() {
241
242         public void pageActivated(IWorkbenchPage workbenchPage) {
243             processEnabledSubmissions(false);
244         }
245
246         public void pageClosed(IWorkbenchPage workbenchPage) {
247             processEnabledSubmissions(false);
248         }
249
250         public void pageOpened(IWorkbenchPage workbenchPage) {
251             processEnabledSubmissions(false);
252         }
253     };
254
255     private IPartListener partListener = new IPartListener() {
256
257         public void partActivated(IWorkbenchPart workbenchPart) {
258             processEnabledSubmissions(false);
259         }
260
261         public void partBroughtToTop(IWorkbenchPart workbenchPart) {
262             processEnabledSubmissions(false);
263         }
264
265         public void partClosed(IWorkbenchPart workbenchPart) {
266             processEnabledSubmissions(false);
267         }
268
269         public void partDeactivated(IWorkbenchPart workbenchPart) {
270             processEnabledSubmissions(false);
271         }
272
273         public void partOpened(IWorkbenchPart workbenchPart) {
274             processEnabledSubmissions(false);
275         }
276     };
277
278     private IPerspectiveListener perspectiveListener = new IPerspectiveListener() {
279
280         public void perspectiveActivated(IWorkbenchPage workbenchPage,
281                 IPerspectiveDescriptor perspectiveDescriptor) {
282             processEnabledSubmissions(false);
283         }
284
285         public void perspectiveChanged(IWorkbenchPage workbenchPage,
286                 IPerspectiveDescriptor perspectiveDescriptor, String JavaDoc changeId) {
287             processEnabledSubmissions(false);
288         }
289     };
290     
291     /**
292      * Whether the context support should process enabled submissions. If it is
293      * not processing enabled submissions, then it will update the listeners,
294      * but do no further work. This flag is used to avoid excessive updating
295      * when the workbench is performing some large change (e.g., opening an
296      * editor, starting up, shutting down, switching perspectives, etc.)
297      */

298     private boolean processing = true;
299
300     private ProxyContextManager proxyContextManager;
301
302     /**
303      * This is a map of shell to a list of submissions. When a shell is
304      * registered, it is added to this map with the list of submissions that
305      * should be submitted when the shell is active. When the shell is
306      * deactivated, this same list should be withdrawn. A shell is removed from
307      * this map using the {@link #unregisterShell(Shell)}method. This value may
308      * be empty, but is never <code>null</code>. The <code>null</code> key
309      * is reserved for active shells that have not been registered but have a
310      * parent (i.e., default dialog service).
311      */

312     private final Map JavaDoc registeredWindows = new WeakHashMap JavaDoc();
313
314     private Workbench workbench;
315
316     /**
317      * Constructs a new instance of <code>WorkbenchCommandSupport</code>.
318      * This attaches the key binding support, and adds a global shell activation
319      * filter.
320      *
321      * @param workbenchToSupport
322      * The workbench that needs to be supported by this instance;
323      * must not be <code>null</code>.
324      */

325     public WorkbenchContextSupport(final Workbench workbenchToSupport) {
326         workbench = workbenchToSupport;
327         mutableContextManager = ContextManagerFactory
328                 .getMutableContextManager();
329         proxyContextManager = new ProxyContextManager(mutableContextManager);
330
331         // And hook up a shell activation filter.
332
workbenchToSupport.getDisplay().addFilter(SWT.Activate,
333                 activationListener);
334     }
335
336     public void addEnabledSubmission(EnabledSubmission enabledSubmission) {
337         addEnabledSubmissionReal(enabledSubmission);
338         processEnabledSubmissions(true);
339     }
340
341     /**
342      * Adds a single enabled submission without causing the submissions to be
343      * reprocessed. This is an internal method used by the two API methods.
344      *
345      * @param enabledSubmission
346      * The enabled submission to add; must not be <code>null</code>.
347      */

348     private final void addEnabledSubmissionReal(
349             EnabledSubmission enabledSubmission) {
350         final String JavaDoc contextId = enabledSubmission.getContextId();
351         List JavaDoc enabledSubmissions2 = (List JavaDoc) enabledSubmissionsByContextId
352                 .get(contextId);
353
354         if (enabledSubmissions2 == null) {
355             enabledSubmissions2 = new ArrayList JavaDoc();
356             enabledSubmissionsByContextId.put(contextId, enabledSubmissions2);
357         }
358
359         enabledSubmissions2.add(enabledSubmission);
360     }
361
362     public void addEnabledSubmissions(Collection JavaDoc enabledSubmissions) {
363         final Iterator JavaDoc submissionItr = enabledSubmissions.iterator();
364         while (submissionItr.hasNext()) {
365             addEnabledSubmissionReal((EnabledSubmission) submissionItr.next());
366         }
367         processEnabledSubmissions(true);
368     }
369
370     /**
371      * Checks whether the new active shell is registered. If it is already
372      * registered, then it does no work. If it is not registered, then it checks
373      * what type of contexts the shell should have by default. This is
374      * determined by parenting. A shell with no parent receives no contexts. A
375      * shell with a parent, receives the dialog contexts.
376      *
377      * @param newShell
378      * The newly active shell; may be <code>null</code> or
379      * disposed.
380      */

381     private final void checkWindowType(final Shell newShell) {
382         boolean submissionsProcessed = false;
383         final Shell oldShell = activeShell;
384
385         if (newShell != oldShell) {
386             /*
387              * If the previous active shell was recognized as a dialog by
388              * default, then remove its submissions.
389              */

390             List JavaDoc oldSubmissions = (List JavaDoc) registeredWindows.get(oldShell);
391             if (oldSubmissions == null) {
392                 /*
393                  * The old shell wasn't registered. So, we need to check if it
394                  * was considered a dialog by default.
395                  */

396                 oldSubmissions = (List JavaDoc) registeredWindows.get(null);
397                 if (oldSubmissions != null) {
398                     removeEnabledSubmissions(oldSubmissions);
399                     submissionsProcessed = true;
400                 }
401             }
402
403             /*
404              * If the new active shell is recognized as a dialog by default,
405              * then create some submissions, remember them, and submit them for
406              * processing.
407              */

408             if ((newShell != null) && (!newShell.isDisposed())) {
409                 final List JavaDoc newSubmissions;
410
411                 if ((newShell.getParent() != null)
412                         && (registeredWindows.get(newShell) == null)) {
413                     // This is a dialog by default.
414
newSubmissions = new ArrayList JavaDoc();
415                     newSubmissions.add(new EnabledSubmission(null, newShell,
416                             null, CONTEXT_ID_DIALOG_AND_WINDOW));
417                     newSubmissions.add(new EnabledSubmission(null, newShell,
418                             null, CONTEXT_ID_DIALOG));
419                     registeredWindows.put(null, newSubmissions);
420
421                     /*
422                      * Make sure the submissions will be removed in event of
423                      * disposal. This is really just a paranoid check. The
424                      * "oldSubmissions" code above should take care of this.
425                      */

426                     newShell.addDisposeListener(new DisposeListener() {
427
428                         /*
429                          * (non-Javadoc)
430                          *
431                          * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
432                          */

433                         public void widgetDisposed(DisposeEvent e) {
434                             registeredWindows.remove(null);
435                             removeEnabledSubmissions(newSubmissions);
436                             newShell.removeDisposeListener(this);
437                         }
438                     });
439
440                 } else {
441                     // Shells that are not dialogs by default must register.
442
newSubmissions = (List JavaDoc) registeredWindows.get(newShell);
443                     
444                 }
445
446                 if (newSubmissions != null) {
447                     addEnabledSubmissions(newSubmissions);
448                     submissionsProcessed = true;
449                 }
450             }
451         }
452
453         // If we still haven't reprocessed the submissions, then do it now.
454
if (!submissionsProcessed) {
455             processEnabledSubmissions(false, newShell);
456         }
457     }
458
459     public IContextManager getContextManager() {
460         return proxyContextManager;
461     }
462
463     /**
464      * An accessor for the underlying key binding support. This method is
465      * internal, and is not intended to be used by clients. It is currently only
466      * used for testing purposes.
467      *
468      * @return A reference to the key binding support; never <code>null</code>.
469      */

470     public final WorkbenchKeyboard getKeyboard() {
471         return keyboard;
472     }
473     
474     /**
475      * Initializes the key binding support.
476      */

477     public final void initialize() {
478         // Hook up the key binding support.
479
keyboard = new WorkbenchKeyboard(workbench, workbench
480                 .getActivitySupport().getActivityManager(), workbench
481                 .getCommandSupport().getCommandManager());
482         setKeyFilterEnabled(true);
483     }
484
485     /*
486      * (non-Javadoc)
487      *
488      * @see org.eclipse.ui.contexts.IWorkbenchContextSupport#isKeyFilterEnabled()
489      */

490     public boolean isKeyFilterEnabled() {
491         synchronized (keyboard) {
492             return keyFilterEnabled;
493         }
494     }
495
496     private void processEnabledSubmissions(boolean force) {
497         processEnabledSubmissions(force, workbench.getDisplay()
498                 .getActiveShell());
499     }
500
501     /**
502      * TODO See WorkbenchKeyboard. Switch to private when Bug 56231 is resolved.
503      */

504     public void processEnabledSubmissions(boolean force,
505             final Shell newActiveShell) {
506
507         // If we are not currently processing, then wait.
508
if (!processing) { return; }
509         
510         IWorkbenchSite newActiveWorkbenchSite = null;
511         final IWorkbenchWindow newActiveWorkbenchWindow = workbench
512                 .getActiveWorkbenchWindow();
513         boolean update = false;
514
515         // Update the active shell, and swap the listener.
516
if (activeShell != newActiveShell) {
517             activeShell = newActiveShell;
518             update = true;
519         }
520
521         // Update the active workbench window, and swap the listeners.
522
if (activeWorkbenchWindow != newActiveWorkbenchWindow) {
523             if (activeWorkbenchWindow != null) {
524                 activeWorkbenchWindow.removePageListener(pageListener);
525                 activeWorkbenchWindow
526                         .removePerspectiveListener(perspectiveListener);
527                 activeWorkbenchWindow.getPartService().removePartListener(
528                         partListener);
529             }
530
531             if (newActiveWorkbenchWindow != null) {
532                 newActiveWorkbenchWindow.addPageListener(pageListener);
533                 newActiveWorkbenchWindow
534                         .addPerspectiveListener(perspectiveListener);
535                 newActiveWorkbenchWindow.getPartService().addPartListener(
536                         partListener);
537             }
538
539             activeWorkbenchWindow = newActiveWorkbenchWindow;
540             update = true;
541         }
542
543         /*
544          * Get a reference to the active workbench site on the new active
545          * workbench window.
546          */

547         if (newActiveWorkbenchWindow != null) {
548             IWorkbenchPage activeWorkbenchPage = newActiveWorkbenchWindow
549                     .getActivePage();
550
551             if (activeWorkbenchPage != null) {
552                 IWorkbenchPart activeWorkbenchPart = activeWorkbenchPage
553                         .getActivePart();
554
555                 if (activeWorkbenchPart != null)
556                         newActiveWorkbenchSite = activeWorkbenchPart.getSite();
557             }
558         }
559
560         if (force || update || (activeWorkbenchSite != newActiveWorkbenchSite)) {
561             activeWorkbenchSite = newActiveWorkbenchSite;
562             final Set JavaDoc enabledContextIds = new HashSet JavaDoc();
563
564             for (Iterator JavaDoc iterator = enabledSubmissionsByContextId.entrySet()
565                     .iterator(); iterator.hasNext();) {
566                 final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
567                 final String JavaDoc contextId = (String JavaDoc) entry.getKey();
568                 final List JavaDoc enabledSubmissions = (List JavaDoc) entry.getValue();
569
570                 for (int i = 0; i < enabledSubmissions.size(); i++) {
571                     EnabledSubmission enabledSubmission = (EnabledSubmission) enabledSubmissions
572                             .get(i);
573
574                     Shell activeShell2 = enabledSubmission.getActiveShell();
575
576                     if (activeShell2 != null && activeShell2 != newActiveShell)
577                             continue;
578
579                     IWorkbenchSite activeWorkbenchSite2 = enabledSubmission
580                             .getActiveWorkbenchPartSite();
581
582                     if (activeWorkbenchSite2 != null
583                             && activeWorkbenchSite2 != newActiveWorkbenchSite)
584                             continue;
585
586                     enabledContextIds.add(contextId);
587                     break;
588                 }
589             }
590
591             if ((DEBUG)
592                     && (!mutableContextManager.getEnabledContextIds().equals(
593                             enabledContextIds))) {
594                 System.out.println("CONTEXTS >>> " + enabledContextIds); //$NON-NLS-1$
595
if (DEBUG_VERBOSE) {
596                     final Exception JavaDoc exception = new Exception JavaDoc();
597                     exception.fillInStackTrace();
598                     final StackTraceElement JavaDoc[] stackTrace = exception
599                             .getStackTrace();
600                     final int elementsToShow = (stackTrace.length < DEBUG_STACK_LENGTH_TO_SHOW) ? stackTrace.length
601                             : DEBUG_STACK_LENGTH_TO_SHOW;
602                     for (int i = 0; i < elementsToShow; i++) {
603                         final StackTraceElement JavaDoc element = stackTrace[i];
604                         System.out.println("CONTEXTS >>> " //$NON-NLS-1$
605
+ element.toString());
606                     }
607                 }
608             }
609
610             // Set the list of enabled identifiers to be the stripped list.
611
mutableContextManager.setEnabledContextIds(enabledContextIds);
612         }
613     }
614
615     /*
616      * (non-Javadoc)
617      *
618      * @see org.eclipse.ui.contexts.IWorkbenchContextSupport#registerShell(org.eclipse.swt.widgets.Shell,
619      * int)
620      */

621     public boolean registerShell(final Shell shell, final int type) {
622         // We do not allow null shell registration. It is reserved.
623
if (shell == null) { throw new NullPointerException JavaDoc(
624                 "The shell was null"); //$NON-NLS-1$
625
}
626
627         // Build the list of submissions.
628
final List JavaDoc submissions = new ArrayList JavaDoc();
629         switch (type) {
630         case TYPE_DIALOG:
631             submissions.add(new EnabledSubmission(null, shell, null,
632                     CONTEXT_ID_DIALOG_AND_WINDOW));
633             submissions.add(new EnabledSubmission(null, shell, null,
634                     CONTEXT_ID_DIALOG));
635             break;
636         case TYPE_NONE:
637             break;
638         case TYPE_WINDOW:
639             submissions.add(new EnabledSubmission(null, shell, null,
640                     CONTEXT_ID_DIALOG_AND_WINDOW));
641             submissions.add(new EnabledSubmission(null, shell, null,
642                     CONTEXT_ID_WINDOW));
643             break;
644         default:
645             throw new IllegalArgumentException JavaDoc("The type is not recognized: " //$NON-NLS-1$
646
+ type);
647         }
648
649         // Check to see if the submissions are already present.
650
boolean returnValue = false;
651         List JavaDoc previousSubmissions = (List JavaDoc) registeredWindows.get(shell);
652         if (previousSubmissions != null) {
653             returnValue = true;
654             removeEnabledSubmissions(previousSubmissions);
655         }
656
657         // Add the new submissions, and force some reprocessing to occur.
658
registeredWindows.put(shell, submissions);
659         addEnabledSubmissions(submissions);
660
661         // Make sure the submissions will be removed in event of disposal.
662
shell.addDisposeListener(new DisposeListener() {
663
664             /*
665              * (non-Javadoc)
666              *
667              * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
668              */

669             public void widgetDisposed(DisposeEvent e) {
670                 registeredWindows.remove(shell);
671                 removeEnabledSubmissions(submissions);
672             }
673         });
674
675         return returnValue;
676     }
677
678     public void removeEnabledSubmission(EnabledSubmission enabledSubmission) {
679         removeEnabledSubmissionReal(enabledSubmission);
680         processEnabledSubmissions(true);
681     }
682
683     /**
684      * Removes a single enabled submission without causing all of the
685      * submissions to be reprocessed. This is used by the two API methods to
686      * carry out work.
687      *
688      * @param enabledSubmission
689      * The submission to remove; must not be <code>null</code>.
690      */

691     private final void removeEnabledSubmissionReal(
692             EnabledSubmission enabledSubmission) {
693         final String JavaDoc contextId = enabledSubmission.getContextId();
694         final List JavaDoc enabledSubmissions2 = (List JavaDoc) enabledSubmissionsByContextId
695                 .get(contextId);
696
697         if (enabledSubmissions2 != null) {
698             enabledSubmissions2.remove(enabledSubmission);
699
700             if (enabledSubmissions2.isEmpty())
701                     enabledSubmissionsByContextId.remove(contextId);
702         }
703     }
704
705     public void removeEnabledSubmissions(Collection JavaDoc enabledSubmissions) {
706         final Iterator JavaDoc submissionItr = enabledSubmissions.iterator();
707         while (submissionItr.hasNext()) {
708             removeEnabledSubmissionReal((EnabledSubmission) submissionItr
709                     .next());
710         }
711         processEnabledSubmissions(true);
712     }
713
714     /*
715      * (non-Javadoc)
716      *
717      * @see org.eclipse.ui.contexts.IWorkbenchContextSupport#setKeyFilterEnabled(boolean)
718      */

719     public void setKeyFilterEnabled(boolean enabled) {
720         synchronized (keyboard) {
721             Display currentDisplay = Display.getCurrent();
722             Listener keyFilter = keyboard.getKeyDownFilter();
723
724             if (enabled) {
725                 currentDisplay.addFilter(SWT.KeyDown, keyFilter);
726                 currentDisplay.addFilter(SWT.Traverse, keyFilter);
727             } else {
728                 currentDisplay.removeFilter(SWT.KeyDown, keyFilter);
729                 currentDisplay.removeFilter(SWT.Traverse, keyFilter);
730             }
731
732             keyFilterEnabled = enabled;
733         }
734     }
735
736     /*
737      * (non-Javadoc)
738      *
739      * @see org.eclipse.ui.contexts.IWorkbenchContextSupport#unregisterShell(org.eclipse.swt.widgets.Shell)
740      */

741     public boolean unregisterShell(Shell shell) {
742         // Don't allow this method to play with the special null slot.
743
if (shell == null) { return false; }
744
745         List JavaDoc previousSubmissions = (List JavaDoc) registeredWindows.get(shell);
746         if (previousSubmissions != null) {
747             registeredWindows.remove(shell);
748             removeEnabledSubmissions(previousSubmissions);
749             return true;
750         }
751
752         return false;
753     }
754     
755     /**
756      * Sets whether the workbench's context support should process enabled
757      * submissions. The workbench should not allow the event loop to spin unless
758      * this value is set to <code>true</code>. If the value changes from
759      * <code>false</code> to <code>true</code>, this automatically triggers
760      * a re-processing of the enabled submissions.
761      *
762      * @param processing
763      * Whether to process enabled submissions
764      */

765     public final void setProcessing(final boolean processing) {
766         final boolean reprocess = !this.processing && processing;
767         this.processing = processing;
768         if (reprocess) {
769             processEnabledSubmissions(true);
770         }
771     }
772 }
773
Popular Tags