1 11 package org.eclipse.ui.internal; 12 13 import org.eclipse.core.commands.Command; 14 import org.eclipse.core.commands.ParameterizedCommand; 15 import org.eclipse.jface.action.Action; 16 import org.eclipse.jface.bindings.Trigger; 17 import org.eclipse.jface.bindings.TriggerSequence; 18 import org.eclipse.jface.bindings.keys.KeyStroke; 19 import org.eclipse.jface.bindings.keys.SWTKeySupport; 20 import org.eclipse.jface.preference.IPreferenceStore; 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.events.FocusEvent; 23 import org.eclipse.swt.events.FocusListener; 24 import org.eclipse.swt.events.HelpEvent; 25 import org.eclipse.swt.events.HelpListener; 26 import org.eclipse.swt.events.KeyEvent; 27 import org.eclipse.swt.events.KeyListener; 28 import org.eclipse.swt.events.MouseEvent; 29 import org.eclipse.swt.events.MouseListener; 30 import org.eclipse.swt.events.TraverseEvent; 31 import org.eclipse.swt.events.TraverseListener; 32 import org.eclipse.swt.graphics.Rectangle; 33 import org.eclipse.swt.layout.FillLayout; 34 import org.eclipse.swt.widgets.Display; 35 import org.eclipse.swt.widgets.Event; 36 import org.eclipse.swt.widgets.Shell; 37 import org.eclipse.swt.widgets.Table; 38 import org.eclipse.swt.widgets.TableColumn; 39 import org.eclipse.swt.widgets.TableItem; 40 import org.eclipse.ui.IEditorReference; 41 import org.eclipse.ui.IWorkbenchPage; 42 import org.eclipse.ui.IWorkbenchPart; 43 import org.eclipse.ui.IWorkbenchPartReference; 44 import org.eclipse.ui.IWorkbenchWindow; 45 import org.eclipse.ui.PlatformUI; 46 import org.eclipse.ui.commands.ICommandService; 47 import org.eclipse.ui.contexts.IContextService; 48 import org.eclipse.ui.keys.IBindingService; 49 50 53 public class CyclePartAction extends PageEventAction { 54 55 59 private TriggerSequence[] backwardTriggerSequences = null; 60 61 private ParameterizedCommand commandBackward = null; 62 63 private ParameterizedCommand commandForward = null; 64 65 protected boolean forward; 66 67 71 private TriggerSequence[] forwardTriggerSequences = null; 72 73 private Object selection; 74 75 84 public CyclePartAction(IWorkbenchWindow window, boolean next) { 85 super("", window); forward = next; 87 setText(); 88 updateState(); 89 } 90 91 99 public void activate(IWorkbenchPage page, Object selectedItem) { 100 if (selectedItem != null) { 101 if (selectedItem instanceof IEditorReference) { 102 page.setEditorAreaVisible(true); 103 } 104 105 IWorkbenchPart part = ((IWorkbenchPartReference) selectedItem) 106 .getPart(true); 107 108 if (part != null) { 109 page.activate(part); 110 } 111 } 112 } 113 114 117 protected void addItems(Table table, WorkbenchPage page) { 118 IWorkbenchPartReference refs[] = page.getSortedParts(); 119 boolean includeEditor = true; 120 121 for (int i = refs.length - 1; i >= 0; i--) { 122 if (refs[i] instanceof IEditorReference) { 123 if (includeEditor) { 124 IEditorReference activeEditor = (IEditorReference) refs[i]; 125 TableItem item = new TableItem(table, SWT.NONE); 126 item.setText(WorkbenchMessages.CyclePartAction_editor); 127 item.setImage(activeEditor.getTitleImage()); 128 item.setData(activeEditor); 129 includeEditor = false; 130 } 131 } else { 132 TableItem item = new TableItem(table, SWT.NONE); 133 item.setText(refs[i].getTitle()); 134 item.setImage(refs[i].getTitleImage()); 135 item.setData(refs[i]); 136 } 137 } 138 } 139 140 private void addKeyListener(final Table table, final Shell dialog) { 141 table.addKeyListener(new KeyListener() { 142 private boolean firstKey = true; 143 144 private boolean quickReleaseMode = false; 145 146 public void keyPressed(KeyEvent e) { 147 int keyCode = e.keyCode; 148 char character = e.character; 149 int accelerator = SWTKeySupport 150 .convertEventToUnmodifiedAccelerator(e); 151 KeyStroke keyStroke = SWTKeySupport 152 .convertAcceleratorToKeyStroke(accelerator); 153 154 160 boolean acceleratorForward = false; 161 boolean acceleratorBackward = false; 162 163 if (commandForward != null) { 164 if (forwardTriggerSequences != null) { 165 final int forwardCount = forwardTriggerSequences.length; 166 for (int i = 0; i < forwardCount; i++) { 167 final TriggerSequence triggerSequence = forwardTriggerSequences[i]; 168 169 final Trigger[] triggers = triggerSequence 171 .getTriggers(); 172 final int triggersLength = triggers.length; 173 if ((triggersLength > 0) 174 && (triggers[triggersLength - 1] 175 .equals(keyStroke))) { 176 acceleratorForward = true; 177 break; 178 } 179 } 180 } 181 } 182 183 if (commandBackward != null) { 184 if (backwardTriggerSequences != null) { 185 final int backwardCount = backwardTriggerSequences.length; 186 for (int i = 0; i < backwardCount; i++) { 187 final TriggerSequence triggerSequence = backwardTriggerSequences[i]; 188 189 final Trigger[] triggers = triggerSequence 191 .getTriggers(); 192 final int triggersLength = triggers.length; 193 if ((triggersLength > 0) 194 && (triggers[triggersLength - 1] 195 .equals(keyStroke))) { 196 acceleratorBackward = true; 197 break; 198 } 199 } 200 } 201 } 202 203 if (character == SWT.CR || character == SWT.LF) { 204 ok(dialog, table); 205 } else if (acceleratorForward) { 206 if (firstKey && e.stateMask != 0) { 207 quickReleaseMode = true; 208 } 209 210 int index = table.getSelectionIndex(); 211 table.setSelection((index + 1) % table.getItemCount()); 212 } else if (acceleratorBackward) { 213 if (firstKey && e.stateMask != 0) { 214 quickReleaseMode = true; 215 } 216 217 int index = table.getSelectionIndex(); 218 table.setSelection(index >= 1 ? index - 1 : table 219 .getItemCount() - 1); 220 } else if (keyCode != SWT.ALT && keyCode != SWT.COMMAND 221 && keyCode != SWT.CTRL && keyCode != SWT.SHIFT 222 && keyCode != SWT.ARROW_DOWN && keyCode != SWT.ARROW_UP 223 && keyCode != SWT.ARROW_LEFT 224 && keyCode != SWT.ARROW_RIGHT) { 225 cancel(dialog); 226 } 227 228 firstKey = false; 229 } 230 231 public void keyReleased(KeyEvent e) { 232 int keyCode = e.keyCode; 233 int stateMask = e.stateMask; 234 238 244 final IPreferenceStore store = WorkbenchPlugin.getDefault() 245 .getPreferenceStore(); 246 final boolean stickyCycle = store 247 .getBoolean(IPreferenceConstants.STICKY_CYCLE); 248 if ((!stickyCycle && (firstKey || quickReleaseMode)) 249 && keyCode == stateMask) { 250 ok(dialog, table); 251 } 252 } 253 }); 254 } 255 256 259 private void addMouseListener(final Table table, final Shell dialog) { 260 table.addMouseListener(new MouseListener() { 261 public void mouseDoubleClick(MouseEvent e) { 262 ok(dialog, table); 263 } 264 265 public void mouseDown(MouseEvent e) { 266 ok(dialog, table); 267 } 268 269 public void mouseUp(MouseEvent e) { 270 ok(dialog, table); 271 } 272 }); 273 } 274 275 282 private final void addTraverseListener(final Table table) { 283 table.addTraverseListener(new TraverseListener() { 284 290 public final void keyTraversed(final TraverseEvent event) { 291 event.doit = false; 292 } 293 }); 294 } 295 296 299 private void cancel(Shell dialog) { 300 selection = null; 301 dialog.close(); 302 } 303 304 309 public String getBackwardActionDefinitionId() { 310 return commandBackward.getCommand().getId(); 311 } 312 313 318 public String getForwardActionDefinitionId() { 319 return commandForward.getCommand().getId(); 320 } 321 322 325 protected String getTableHeader() { 326 return WorkbenchMessages.CyclePartAction_header; 327 } 328 329 338 341 private void ok(Shell dialog, final Table table) { 342 TableItem[] items = table.getSelection(); 343 344 if (items != null && items.length == 1) { 345 selection = items[0].getData(); 346 } 347 348 dialog.close(); 349 } 350 351 354 private void openDialog(WorkbenchPage page) { 355 final int MAX_ITEMS = 22; 356 357 selection = null; 358 final Shell dialog = new Shell(getWorkbenchWindow().getShell(), 359 SWT.MODELESS); 360 Display display = dialog.getDisplay(); 361 dialog.setLayout(new FillLayout()); 362 363 final Table table = new Table(dialog, SWT.SINGLE | SWT.FULL_SELECTION); 364 table.setHeaderVisible(true); 365 table.setLinesVisible(true); 366 TableColumn tc = new TableColumn(table, SWT.NONE); 367 tc.setResizable(false); 368 tc.setText(getTableHeader()); 369 addItems(table, page); 370 int tableItemCount = table.getItemCount(); 371 372 switch (tableItemCount) { 373 case 0: 374 break; 376 case 1: 377 table.setSelection(0); 378 break; 379 default: 380 table.setSelection(forward ? 1 : table.getItemCount() - 1); 381 } 382 383 tc.pack(); 384 table.pack(); 385 dialog.pack(); 386 387 Rectangle tableBounds = table.getBounds(); 388 tableBounds.height = Math.min(tableBounds.height, table.getItemHeight() 389 * MAX_ITEMS); 390 table.setBounds(tableBounds); 391 392 dialog.setBounds(dialog.computeTrim(tableBounds.x, tableBounds.y, 393 tableBounds.width, tableBounds.height)); 394 395 tc.setWidth(table.getClientArea().width); 396 table.setFocus(); 397 table.addFocusListener(new FocusListener() { 398 public void focusGained(FocusEvent e) { 399 } 401 402 public void focusLost(FocusEvent e) { 403 cancel(dialog); 404 } 405 }); 406 407 Rectangle dialogBounds = dialog.getBounds(); 408 Rectangle displayBounds = display.getClientArea(); 409 Rectangle parentBounds = dialog.getParent().getBounds(); 410 411 dialogBounds.x = parentBounds.x 413 + ((parentBounds.width - dialogBounds.width) / 2); 414 dialogBounds.y = parentBounds.y 415 + ((parentBounds.height - dialogBounds.height) / 2); 416 if (!displayBounds.contains(dialogBounds.x, dialogBounds.y) 417 || !displayBounds.contains(dialogBounds.x + dialogBounds.width, 418 dialogBounds.y + dialogBounds.height)) { 419 dialogBounds.x = (displayBounds.width - dialogBounds.width) / 2; 422 dialogBounds.y = (displayBounds.height - dialogBounds.height) / 2; 423 } 424 425 dialog.setLocation(dialogBounds.x, dialogBounds.y); 426 427 table.removeHelpListener(getHelpListener()); 428 table.addHelpListener(new HelpListener() { 429 public void helpRequested(HelpEvent event) { 430 } 432 }); 433 434 439 final IBindingService bindingService = (IBindingService) PlatformUI 440 .getWorkbench().getAdapter(IBindingService.class); 441 forwardTriggerSequences = bindingService 442 .getActiveBindingsFor(commandForward); 443 backwardTriggerSequences = bindingService 444 .getActiveBindingsFor(commandBackward); 445 446 final IContextService contextService = (IContextService) page 447 .getWorkbenchWindow().getWorkbench().getAdapter( 448 IContextService.class); 449 try { 450 dialog.open(); 451 addMouseListener(table, dialog); 452 contextService.registerShell(dialog, 453 IContextService.TYPE_NONE); 454 addKeyListener(table, dialog); 455 addTraverseListener(table); 456 457 while (!dialog.isDisposed()) { 458 if (!display.readAndDispatch()) { 459 display.sleep(); 460 } 461 } 462 } finally { 463 if (!dialog.isDisposed()) { 464 cancel(dialog); 465 } 466 contextService.unregisterShell(dialog); 467 forwardTriggerSequences = null; 468 backwardTriggerSequences = null; 469 } 470 } 471 472 475 public void pageActivated(IWorkbenchPage page) { 476 super.pageActivated(page); 477 updateState(); 478 } 479 480 483 public void pageClosed(IWorkbenchPage page) { 484 super.pageClosed(page); 485 updateState(); 486 } 487 488 491 public void partClosed(IWorkbenchPart part) { 492 super.partClosed(part); 493 updateState(); 494 } 495 496 499 public void partOpened(IWorkbenchPart part) { 500 super.partOpened(part); 501 updateState(); 502 } 503 504 507 public void runWithEvent(Event e) { 508 if (getWorkbenchWindow() == null) { 509 return; 511 } 512 IWorkbenchPage page = getActivePage(); 513 openDialog((WorkbenchPage) page); 514 activate(page, selection); 515 } 516 517 523 public void setBackwardActionDefinitionId(String actionDefinitionId) { 524 final ICommandService commandService = (ICommandService) getWorkbenchWindow() 525 .getWorkbench().getAdapter(ICommandService.class); 526 final Command command = commandService.getCommand(actionDefinitionId); 527 commandBackward = new ParameterizedCommand(command, null); 528 } 529 530 536 public void setForwardActionDefinitionId(String actionDefinitionId) { 537 final ICommandService commandService = (ICommandService) getWorkbenchWindow() 538 .getWorkbench().getAdapter(ICommandService.class); 539 final Command command = commandService.getCommand(actionDefinitionId); 540 commandForward = new ParameterizedCommand(command, null); 541 } 542 543 546 protected void setText() { 547 if (forward) { 549 setText(WorkbenchMessages.CyclePartAction_next_text); 550 setToolTipText(WorkbenchMessages.CyclePartAction_next_toolTip); 551 getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(this, 553 IWorkbenchHelpContextIds.CYCLE_PART_FORWARD_ACTION); 554 setActionDefinitionId("org.eclipse.ui.window.nextView"); } else { 556 setText(WorkbenchMessages.CyclePartAction_prev_text); 557 setToolTipText(WorkbenchMessages.CyclePartAction_prev_toolTip); 558 getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(this, 560 IWorkbenchHelpContextIds.CYCLE_PART_BACKWARD_ACTION); 561 setActionDefinitionId("org.eclipse.ui.window.previousView"); } 563 } 564 565 568 protected void updateState() { 569 IWorkbenchPage page = getActivePage(); 570 if (page == null) { 571 setEnabled(false); 572 return; 573 } 574 int count = page.getViewReferences().length; 577 if (page.getEditorReferences().length > 0) { 578 ++count; 579 } 580 setEnabled(count >= 1); 581 } 582 583 } 584 | Popular Tags |