1 11 package org.eclipse.ui.internal.contexts.ws; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Set ; 21 import java.util.WeakHashMap ; 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 56 public class WorkbenchContextSupport implements IWorkbenchContextSupport { 57 58 63 private static final boolean DEBUG = Policy.DEBUG_CONTEXTS; 64 65 70 private static final int DEBUG_STACK_LENGTH_TO_SHOW = 5; 71 72 77 private static final boolean DEBUG_VERBOSE = Policy.DEBUG_CONTEXTS_VERBOSE; 78 79 90 private final Map createContextTreeFor(final Set contextIds) { 91 final Map contextTree = new HashMap (); 92 final IContextManager contextManager = getContextManager(); 93 94 final Iterator contextIdItr = contextIds.iterator(); 95 while (contextIdItr.hasNext()) { 96 String childContextId = (String ) contextIdItr.next(); 97 while (childContextId != null) { 98 final IContext childContext = contextManager 99 .getContext(childContextId); 100 101 try { 102 final String parentContextId = childContext.getParentId(); 103 contextTree.put(childContextId, parentContextId); 104 childContextId = parentContextId; 105 } catch (final NotDefinedException e) { 106 break; } 108 } 109 } 110 111 return contextTree; 112 } 113 114 131 public final Map createFilteredContextTreeFor(final Set contextIds) { 132 boolean dialog = false; 134 boolean window = false; 135 Iterator contextIdItr = contextIds.iterator(); 136 while (contextIdItr.hasNext()) { 137 final String contextId = (String ) 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 153 try { 154 contextIdItr = contextIds.iterator(); 155 while (contextIdItr.hasNext()) { 156 String contextId = (String ) contextIdItr.next(); 157 IContext context = mutableContextManager.getContext(contextId); 158 String 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('" + e.getMessage() 187 + "') while filtering dialog/window contexts"); } 189 } 190 191 return createContextTreeFor(contextIds); 192 } 193 194 199 private Listener activationListener = new Listener() { 200 201 206 public void handleEvent(Event event) { 207 checkWindowType(event.display.getActiveShell()); 208 } 209 }; 210 211 214 private Shell activeShell; 215 216 private IWorkbenchSite activeWorkbenchSite; 217 218 221 private IWorkbenchWindow activeWorkbenchWindow; 222 223 private Map enabledSubmissionsByContextId = new HashMap (); 224 225 229 private WorkbenchKeyboard keyboard; 230 231 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 changeId) { 287 processEnabledSubmissions(false); 288 } 289 }; 290 291 298 private boolean processing = true; 299 300 private ProxyContextManager proxyContextManager; 301 302 312 private final Map registeredWindows = new WeakHashMap (); 313 314 private Workbench workbench; 315 316 325 public WorkbenchContextSupport(final Workbench workbenchToSupport) { 326 workbench = workbenchToSupport; 327 mutableContextManager = ContextManagerFactory 328 .getMutableContextManager(); 329 proxyContextManager = new ProxyContextManager(mutableContextManager); 330 331 workbenchToSupport.getDisplay().addFilter(SWT.Activate, 333 activationListener); 334 } 335 336 public void addEnabledSubmission(EnabledSubmission enabledSubmission) { 337 addEnabledSubmissionReal(enabledSubmission); 338 processEnabledSubmissions(true); 339 } 340 341 348 private final void addEnabledSubmissionReal( 349 EnabledSubmission enabledSubmission) { 350 final String contextId = enabledSubmission.getContextId(); 351 List enabledSubmissions2 = (List ) enabledSubmissionsByContextId 352 .get(contextId); 353 354 if (enabledSubmissions2 == null) { 355 enabledSubmissions2 = new ArrayList (); 356 enabledSubmissionsByContextId.put(contextId, enabledSubmissions2); 357 } 358 359 enabledSubmissions2.add(enabledSubmission); 360 } 361 362 public void addEnabledSubmissions(Collection enabledSubmissions) { 363 final Iterator submissionItr = enabledSubmissions.iterator(); 364 while (submissionItr.hasNext()) { 365 addEnabledSubmissionReal((EnabledSubmission) submissionItr.next()); 366 } 367 processEnabledSubmissions(true); 368 } 369 370 381 private final void checkWindowType(final Shell newShell) { 382 boolean submissionsProcessed = false; 383 final Shell oldShell = activeShell; 384 385 if (newShell != oldShell) { 386 390 List oldSubmissions = (List ) registeredWindows.get(oldShell); 391 if (oldSubmissions == null) { 392 396 oldSubmissions = (List ) registeredWindows.get(null); 397 if (oldSubmissions != null) { 398 removeEnabledSubmissions(oldSubmissions); 399 submissionsProcessed = true; 400 } 401 } 402 403 408 if ((newShell != null) && (!newShell.isDisposed())) { 409 final List newSubmissions; 410 411 if ((newShell.getParent() != null) 412 && (registeredWindows.get(newShell) == null)) { 413 newSubmissions = new ArrayList (); 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 426 newShell.addDisposeListener(new DisposeListener() { 427 428 433 public void widgetDisposed(DisposeEvent e) { 434 registeredWindows.remove(null); 435 removeEnabledSubmissions(newSubmissions); 436 newShell.removeDisposeListener(this); 437 } 438 }); 439 440 } else { 441 newSubmissions = (List ) registeredWindows.get(newShell); 443 444 } 445 446 if (newSubmissions != null) { 447 addEnabledSubmissions(newSubmissions); 448 submissionsProcessed = true; 449 } 450 } 451 } 452 453 if (!submissionsProcessed) { 455 processEnabledSubmissions(false, newShell); 456 } 457 } 458 459 public IContextManager getContextManager() { 460 return proxyContextManager; 461 } 462 463 470 public final WorkbenchKeyboard getKeyboard() { 471 return keyboard; 472 } 473 474 477 public final void initialize() { 478 keyboard = new WorkbenchKeyboard(workbench, workbench 480 .getActivitySupport().getActivityManager(), workbench 481 .getCommandSupport().getCommandManager()); 482 setKeyFilterEnabled(true); 483 } 484 485 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 504 public void processEnabledSubmissions(boolean force, 505 final Shell newActiveShell) { 506 507 if (!processing) { return; } 509 510 IWorkbenchSite newActiveWorkbenchSite = null; 511 final IWorkbenchWindow newActiveWorkbenchWindow = workbench 512 .getActiveWorkbenchWindow(); 513 boolean update = false; 514 515 if (activeShell != newActiveShell) { 517 activeShell = newActiveShell; 518 update = true; 519 } 520 521 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 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 enabledContextIds = new HashSet (); 563 564 for (Iterator iterator = enabledSubmissionsByContextId.entrySet() 565 .iterator(); iterator.hasNext();) { 566 final Map.Entry entry = (Map.Entry ) iterator.next(); 567 final String contextId = (String ) entry.getKey(); 568 final List enabledSubmissions = (List ) 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); if (DEBUG_VERBOSE) { 596 final Exception exception = new Exception (); 597 exception.fillInStackTrace(); 598 final StackTraceElement [] 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 element = stackTrace[i]; 604 System.out.println("CONTEXTS >>> " + element.toString()); 606 } 607 } 608 } 609 610 mutableContextManager.setEnabledContextIds(enabledContextIds); 612 } 613 } 614 615 621 public boolean registerShell(final Shell shell, final int type) { 622 if (shell == null) { throw new NullPointerException ( 624 "The shell was null"); } 626 627 final List submissions = new ArrayList (); 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 ("The type is not recognized: " + type); 647 } 648 649 boolean returnValue = false; 651 List previousSubmissions = (List ) registeredWindows.get(shell); 652 if (previousSubmissions != null) { 653 returnValue = true; 654 removeEnabledSubmissions(previousSubmissions); 655 } 656 657 registeredWindows.put(shell, submissions); 659 addEnabledSubmissions(submissions); 660 661 shell.addDisposeListener(new DisposeListener() { 663 664 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 691 private final void removeEnabledSubmissionReal( 692 EnabledSubmission enabledSubmission) { 693 final String contextId = enabledSubmission.getContextId(); 694 final List enabledSubmissions2 = (List ) 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 enabledSubmissions) { 706 final Iterator submissionItr = enabledSubmissions.iterator(); 707 while (submissionItr.hasNext()) { 708 removeEnabledSubmissionReal((EnabledSubmission) submissionItr 709 .next()); 710 } 711 processEnabledSubmissions(true); 712 } 713 714 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 741 public boolean unregisterShell(Shell shell) { 742 if (shell == null) { return false; } 744 745 List previousSubmissions = (List ) 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 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 |