1 11 package org.eclipse.ui.internal.commands.ws; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.widgets.Event; 23 import org.eclipse.swt.widgets.Listener; 24 import org.eclipse.swt.widgets.Shell; 25 import org.eclipse.ui.IPageListener; 26 import org.eclipse.ui.IPartListener; 27 import org.eclipse.ui.IPerspectiveDescriptor; 28 import org.eclipse.ui.IPerspectiveListener; 29 import org.eclipse.ui.IWorkbenchPage; 30 import org.eclipse.ui.IWorkbenchPart; 31 import org.eclipse.ui.IWorkbenchSite; 32 import org.eclipse.ui.IWorkbenchWindow; 33 import org.eclipse.ui.commands.HandlerSubmission; 34 import org.eclipse.ui.commands.ICommandManager; 35 import org.eclipse.ui.commands.IWorkbenchCommandSupport; 36 import org.eclipse.ui.commands.Priority; 37 import org.eclipse.ui.contexts.IWorkbenchContextSupport; 38 import org.eclipse.ui.internal.Workbench; 39 import org.eclipse.ui.internal.commands.CommandManagerFactory; 40 import org.eclipse.ui.internal.commands.IMutableCommandManager; 41 import org.eclipse.ui.internal.commands.MutableCommandManager; 42 import org.eclipse.ui.internal.contexts.ws.WorkbenchContextSupport; 43 import org.eclipse.ui.internal.misc.Policy; 44 import org.eclipse.ui.internal.util.Util; 45 import org.eclipse.ui.keys.KeyFormatterFactory; 46 import org.eclipse.ui.keys.SWTKeySupport; 47 48 53 public class WorkbenchCommandSupport implements IWorkbenchCommandSupport { 54 55 60 private static final boolean DEBUG = Policy.DEBUG_HANDLERS; 61 62 67 private static final boolean DEBUG_VERBOSE = Policy.DEBUG_HANDLERS 68 && Policy.DEBUG_HANDLERS_VERBOSE; 69 70 73 private static final String DEBUG_VERBOSE_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID; 74 75 79 private static final int MATCH_ANY = 0; 80 81 86 private static final int MATCH_PARTIAL = 1; 87 88 91 private static final int MATCH_EXACT = 2; 92 93 static { 94 MutableCommandManager.DEBUG_HANDLERS = Policy.DEBUG_HANDLERS 95 && Policy.DEBUG_HANDLERS_VERBOSE; 96 MutableCommandManager.DEBUG_HANDLERS_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID; 97 MutableCommandManager.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_KEY_BINDINGS_VERBOSE; 98 } 99 100 114 private static final int compareWindows(final Shell shellToMatch, 115 final Shell activeShell) { 116 if (shellToMatch == null) { 117 return MATCH_ANY; 118 } else if (shellToMatch == activeShell) { return MATCH_EXACT; } 119 120 return MATCH_PARTIAL; 121 } 122 123 128 private Listener activationListener = new Listener() { 129 130 135 public void handleEvent(Event event) { 136 processHandlerSubmissions(false, event.display.getActiveShell()); 137 } 138 }; 139 140 143 private Shell activeShell; 144 145 150 private IWorkbenchSite activeWorkbenchSite; 151 152 157 private IWorkbenchWindow activeWorkbenchWindow; 158 159 165 private final Map handlerSubmissionsByCommandId = new HashMap (); 166 167 171 private final IMutableCommandManager mutableCommandManager; 172 173 177 private final IPageListener pageListener = new IPageListener() { 178 179 public void pageActivated(IWorkbenchPage workbenchPage) { 180 processHandlerSubmissions(false); 181 } 182 183 public void pageClosed(IWorkbenchPage workbenchPage) { 184 processHandlerSubmissions(false); 185 } 186 187 public void pageOpened(IWorkbenchPage workbenchPage) { 188 processHandlerSubmissions(false); 189 } 190 }; 191 192 196 private final IPartListener partListener = new IPartListener() { 197 198 public void partActivated(IWorkbenchPart workbenchPart) { 199 processHandlerSubmissions(false); 200 } 201 202 public void partBroughtToTop(IWorkbenchPart workbenchPart) { 203 processHandlerSubmissions(false); 204 } 205 206 public void partClosed(IWorkbenchPart workbenchPart) { 207 processHandlerSubmissions(false); 208 } 209 210 public void partDeactivated(IWorkbenchPart workbenchPart) { 211 processHandlerSubmissions(false); 212 } 213 214 public void partOpened(IWorkbenchPart workbenchPart) { 215 processHandlerSubmissions(false); 216 } 217 }; 218 219 223 private final IPerspectiveListener perspectiveListener = new IPerspectiveListener() { 224 225 public void perspectiveActivated(IWorkbenchPage workbenchPage, 226 IPerspectiveDescriptor perspectiveDescriptor) { 227 processHandlerSubmissions(false); 228 } 229 230 public void perspectiveChanged(IWorkbenchPage workbenchPage, 231 IPerspectiveDescriptor perspectiveDescriptor, String changeId) { 232 processHandlerSubmissions(false); 233 } 234 }; 235 236 243 private boolean processing = true; 244 245 249 private final Workbench workbench; 250 251 258 public WorkbenchCommandSupport(final Workbench workbenchToSupport) { 259 workbench = workbenchToSupport; 260 mutableCommandManager = CommandManagerFactory 261 .getMutableCommandManager(); 262 KeyFormatterFactory.setDefault(SWTKeySupport 263 .getKeyFormatterForPlatform()); 264 265 workbenchToSupport.getDisplay().addFilter(SWT.Activate, 267 activationListener); 268 269 final List submissions = new ArrayList (); 270 final MutableCommandManager commandManager = (MutableCommandManager) mutableCommandManager; 271 final Set handlers = commandManager.getDefinedHandlers(); 272 final Iterator handlerItr = handlers.iterator(); 273 274 while (handlerItr.hasNext()) { 275 final HandlerProxy proxy = (HandlerProxy) handlerItr.next(); 276 final String commandId = proxy.getCommandId(); 277 final HandlerSubmission submission = new HandlerSubmission(null, 278 null, null, commandId, proxy, Priority.LOW); 279 submissions.add(submission); 280 } 281 282 if (!submissions.isEmpty()) { 283 addHandlerSubmissions(submissions); 284 } 285 } 287 288 public void addHandlerSubmission(HandlerSubmission handlerSubmission) { 289 addHandlerSubmissionReal(handlerSubmission); 290 processHandlerSubmissions(true); 291 } 292 293 300 private final void addHandlerSubmissionReal( 301 final HandlerSubmission handlerSubmission) { 302 final String commandId = handlerSubmission.getCommandId(); 303 List handlerSubmissions2 = (List ) handlerSubmissionsByCommandId 304 .get(commandId); 305 306 if (handlerSubmissions2 == null) { 307 handlerSubmissions2 = new ArrayList (); 308 handlerSubmissionsByCommandId.put(commandId, handlerSubmissions2); 309 } 310 311 handlerSubmissions2.add(handlerSubmission); 312 } 313 314 public void addHandlerSubmissions(Collection handlerSubmissions) { 315 final Iterator submissionItr = handlerSubmissions.iterator(); 316 while (submissionItr.hasNext()) { 317 addHandlerSubmissionReal((HandlerSubmission) submissionItr.next()); 318 } 319 320 processHandlerSubmissions(true); 321 } 322 323 328 public ICommandManager getCommandManager() { 329 return mutableCommandManager; 331 } 332 333 342 private void processHandlerSubmissions(boolean force) { 343 processHandlerSubmissions(force, workbench.getDisplay() 344 .getActiveShell()); 345 } 346 347 360 public void processHandlerSubmissions(boolean force, 361 final Shell newActiveShell) { 362 363 if (!processing) { return; } 365 366 IWorkbenchSite newWorkbenchSite = null; 367 IWorkbenchWindow newWorkbenchWindow = workbench 368 .getActiveWorkbenchWindow(); 369 boolean update = false; 370 371 if (activeShell != newActiveShell) { 373 activeShell = newActiveShell; 374 update = true; 375 } 376 377 if (activeWorkbenchWindow != newWorkbenchWindow) { 378 if (activeWorkbenchWindow != null) { 379 activeWorkbenchWindow.removePageListener(pageListener); 380 activeWorkbenchWindow 381 .removePerspectiveListener(perspectiveListener); 382 activeWorkbenchWindow.getPartService().removePartListener( 383 partListener); 384 } 385 386 if (newWorkbenchWindow != null) { 387 newWorkbenchWindow.addPageListener(pageListener); 388 newWorkbenchWindow.addPerspectiveListener(perspectiveListener); 389 newWorkbenchWindow.getPartService().addPartListener( 390 partListener); 391 } 392 393 activeWorkbenchWindow = newWorkbenchWindow; 394 395 update = true; 396 } 397 398 if (newWorkbenchWindow != null) { 399 IWorkbenchPage activeWorkbenchPage = newWorkbenchWindow 400 .getActivePage(); 401 402 if (activeWorkbenchPage != null) { 403 IWorkbenchPart activeWorkbenchPart = activeWorkbenchPage 404 .getActivePart(); 405 406 if (activeWorkbenchPart != null) { 407 newWorkbenchSite = activeWorkbenchPart.getSite(); 408 } 409 } 410 } else { 411 newWorkbenchSite = null; 412 } 413 414 if (force || update || (activeWorkbenchSite != newWorkbenchSite)) { 415 activeWorkbenchSite = newWorkbenchSite; 416 Map handlersByCommandId = new HashMap (); 417 final WorkbenchContextSupport contextSupport = (WorkbenchContextSupport) workbench 418 .getContextSupport(); 419 final Map contextTree = contextSupport 420 .createFilteredContextTreeFor(contextSupport 421 .getContextManager().getEnabledContextIds()); 422 final boolean dialogOpen = contextTree 423 .containsKey(IWorkbenchContextSupport.CONTEXT_ID_DIALOG); 424 425 for (Iterator iterator = handlerSubmissionsByCommandId.entrySet() 426 .iterator(); iterator.hasNext();) { 427 Map.Entry entry = (Map.Entry ) iterator.next(); 428 String commandId = (String ) entry.getKey(); 429 List handlerSubmissions = (List ) entry.getValue(); 430 Iterator submissionItr = handlerSubmissions.iterator(); 431 HandlerSubmission bestHandlerSubmission = null; 432 boolean conflict = false; 433 434 while (submissionItr.hasNext()) { 435 HandlerSubmission handlerSubmission = (HandlerSubmission) submissionItr 436 .next(); 437 IWorkbenchSite activeWorkbenchSite2 = handlerSubmission 438 .getActiveWorkbenchPartSite(); 439 440 if (activeWorkbenchSite2 != null 441 && activeWorkbenchSite2 != newWorkbenchSite) 442 continue; 443 444 final Shell activeShell2 = handlerSubmission 445 .getActiveShell(); 446 final Shell wbWinShell; 447 if (activeWorkbenchWindow == null) { 448 wbWinShell = null; 449 } else { 450 wbWinShell = activeWorkbenchWindow.getShell(); 451 } 452 453 if ((activeShell2 != null) && (activeShell2 != activeShell) 454 && ((activeShell2 != wbWinShell) || dialogOpen)) 455 continue; 456 457 if (bestHandlerSubmission == null) { 458 bestHandlerSubmission = handlerSubmission; 459 } else { 460 int compareTo = Util.compareIdentity( 461 activeWorkbenchSite2, bestHandlerSubmission 462 .getActiveWorkbenchPartSite()); 463 final int currentMatch = compareWindows(activeShell2, 464 activeShell); 465 final Shell bestMatchingShell = bestHandlerSubmission 466 .getActiveShell(); 467 final int bestMatch = compareWindows(bestMatchingShell, 468 activeShell); 469 470 if ((bestHandlerSubmission.getHandler() instanceof HandlerProxy) 471 && (currentMatch <= MATCH_PARTIAL) 472 && (dialogOpen)) { 473 488 compareTo = -1; 489 490 if ((DEBUG_VERBOSE) 491 && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID 492 .equals(commandId)))) { 493 System.out 494 .println("HANDLERS >>> A handler contributed via XML will win over a less than exact match: " + bestHandlerSubmission.getHandler()); 496 } 497 498 } else if ((handlerSubmission.getHandler() instanceof HandlerProxy) 499 && (bestMatch <= MATCH_PARTIAL) && (dialogOpen)) { 500 515 compareTo = 1; 516 if ((DEBUG_VERBOSE) 517 && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID 518 .equals(commandId)))) { 519 System.out 520 .println("HANDLERS >>> A handler contributed via XML will win over a less than exact match: " + handlerSubmission.getHandler()); 522 } 523 524 } else if ((currentMatch > bestMatch) 525 || (compareTo == 0)) { 526 527 530 compareTo = currentMatch - bestMatch; 531 532 if (compareTo == 0) 533 compareTo = Util 534 .compare(handlerSubmission 535 .getPriority(), 536 bestHandlerSubmission 537 .getPriority()); 538 } 539 540 if (compareTo > 0) { 541 if ((DEBUG_VERBOSE) 542 && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID 543 .equals(commandId)))) { 544 System.out 545 .println("HANDLERS >>> Resolved conflict detected between "); System.out.println("HANDLERS >>> win: " + handlerSubmission); 548 System.out.println("HANDLERS >>> lose: " + bestHandlerSubmission); 550 } 551 conflict = false; 552 bestHandlerSubmission = handlerSubmission; 553 } else if ((compareTo == 0) 554 && (bestHandlerSubmission.getHandler() != handlerSubmission 555 .getHandler())) { 556 if (DEBUG) { 557 System.out 558 .println("HANDLERS >>> Unresolved conflict detected for " + commandId); 560 } 561 conflict = true; 562 } else if ((DEBUG_VERBOSE) 563 && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID 564 .equals(commandId)))) { 565 System.out 566 .println("HANDLERS >>> Resolved conflict detected between "); System.out.println("HANDLERS >>> win: " + bestHandlerSubmission); 569 System.out.println("HANDLERS >>> lose: " + handlerSubmission); 571 } 572 } 573 } 574 575 if (bestHandlerSubmission != null && !conflict) 576 handlersByCommandId.put(commandId, 577 bestHandlerSubmission.getHandler()); 578 } 579 580 mutableCommandManager.setHandlersByCommandId(handlersByCommandId); 581 } 582 } 583 584 public void removeHandlerSubmission(HandlerSubmission handlerSubmission) { 585 removeHandlerSubmissionReal(handlerSubmission); 586 processHandlerSubmissions(true); 587 } 588 589 596 private final void removeHandlerSubmissionReal( 597 final HandlerSubmission handlerSubmission) { 598 final String commandId = handlerSubmission.getCommandId(); 599 final List handlerSubmissions2 = (List ) handlerSubmissionsByCommandId 600 .get(commandId); 601 602 if (handlerSubmissions2 != null) { 603 handlerSubmissions2.remove(handlerSubmission); 604 605 if (handlerSubmissions2.isEmpty()) { 606 handlerSubmissionsByCommandId.remove(commandId); 607 } 608 } 609 } 610 611 public void removeHandlerSubmissions(Collection handlerSubmissions) { 612 final Iterator submissionItr = handlerSubmissions.iterator(); 613 while (submissionItr.hasNext()) { 614 removeHandlerSubmissionReal((HandlerSubmission) submissionItr.next()); 615 } 616 617 processHandlerSubmissions(true); 618 } 619 620 630 public void setActiveContextIds(Map activeContextIds) { 631 mutableCommandManager.setActiveContextIds(activeContextIds); 632 } 633 634 644 public final void setProcessing(final boolean processing) { 645 final boolean reprocess = !this.processing && processing; 646 this.processing = processing; 647 if (reprocess) { 648 processHandlerSubmissions(true); 649 } 650 } 651 } 652 | Popular Tags |