1 11 12 package org.eclipse.ui.internal; 13 14 import org.eclipse.core.commands.AbstractHandler; 15 import org.eclipse.core.commands.ExecutionEvent; 16 import org.eclipse.core.commands.ExecutionException; 17 import org.eclipse.core.commands.ParameterizedCommand; 18 import org.eclipse.core.runtime.CoreException; 19 import org.eclipse.core.runtime.IConfigurationElement; 20 import org.eclipse.core.runtime.IExecutableExtension; 21 import org.eclipse.jface.bindings.Trigger; 22 import org.eclipse.jface.bindings.TriggerSequence; 23 import org.eclipse.jface.bindings.keys.KeyStroke; 24 import org.eclipse.jface.bindings.keys.SWTKeySupport; 25 import org.eclipse.jface.preference.IPreferenceStore; 26 import org.eclipse.swt.SWT; 27 import org.eclipse.swt.events.FocusEvent; 28 import org.eclipse.swt.events.FocusListener; 29 import org.eclipse.swt.events.KeyEvent; 30 import org.eclipse.swt.events.KeyListener; 31 import org.eclipse.swt.events.MouseEvent; 32 import org.eclipse.swt.events.MouseListener; 33 import org.eclipse.swt.events.TraverseEvent; 34 import org.eclipse.swt.events.TraverseListener; 35 import org.eclipse.swt.graphics.Rectangle; 36 import org.eclipse.swt.layout.FillLayout; 37 import org.eclipse.swt.widgets.Display; 38 import org.eclipse.swt.widgets.Shell; 39 import org.eclipse.swt.widgets.Table; 40 import org.eclipse.swt.widgets.TableColumn; 41 import org.eclipse.swt.widgets.TableItem; 42 import org.eclipse.ui.IEditorReference; 43 import org.eclipse.ui.IPerspectiveDescriptor; 44 import org.eclipse.ui.IWorkbenchPage; 45 import org.eclipse.ui.IWorkbenchPart; 46 import org.eclipse.ui.IWorkbenchPartReference; 47 import org.eclipse.ui.IWorkbenchWindow; 48 import org.eclipse.ui.contexts.IContextService; 49 import org.eclipse.ui.handlers.HandlerUtil; 50 import org.eclipse.ui.keys.IBindingService; 51 52 58 59 public abstract class CycleBaseHandler extends AbstractHandler implements 60 IExecutableExtension { 61 private Object selection; 62 protected IWorkbenchWindow window; 63 protected boolean gotoDirection; 65 protected IWorkbenchPart activePart; 66 70 private TriggerSequence[] backwardTriggerSequences = null; 71 72 protected ParameterizedCommand commandBackward = null; 73 74 protected ParameterizedCommand commandForward = null; 75 79 private TriggerSequence[] forwardTriggerSequences = null; 80 81 86 87 90 protected abstract void addItems(Table table, WorkbenchPage page); 91 92 95 protected abstract ParameterizedCommand getBackwardCommand(); 96 97 100 protected abstract ParameterizedCommand getForwardCommand(); 101 102 public Object execute(ExecutionEvent event) throws ExecutionException { 103 window = HandlerUtil.getActiveWorkbenchWindowChecked(event); 104 105 IWorkbenchPage page = window.getActivePage(); 106 activePart = page.getActivePart(); 107 openDialog((WorkbenchPage) page); 108 activate(page, selection); 109 110 return null; 111 } 112 113 116 protected void openDialog(WorkbenchPage page) { 117 final int MAX_ITEMS = 22; 118 119 selection = null; 120 final Shell dialog = new Shell(window.getShell(), SWT.MODELESS); 121 Display display = dialog.getDisplay(); 122 dialog.setLayout(new FillLayout()); 123 124 final Table table = new Table(dialog, SWT.SINGLE | SWT.FULL_SELECTION); 125 table.setHeaderVisible(true); 126 table.setLinesVisible(true); 127 TableColumn tc = new TableColumn(table, SWT.NONE); 128 tc.setResizable(false); 129 tc.setText(getTableHeader()); 130 addItems(table, page); 131 int tableItemCount = table.getItemCount(); 132 133 switch (tableItemCount) { 134 case 0: 135 break; 137 case 1: 138 table.setSelection(0); 139 break; 140 default: 141 table.setSelection(gotoDirection ? 1 : table.getItemCount() - 1); 142 } 143 144 tc.pack(); 145 table.pack(); 146 dialog.pack(); 147 148 Rectangle tableBounds = table.getBounds(); 149 tableBounds.height = Math.min(tableBounds.height, table.getItemHeight() 150 * MAX_ITEMS); 151 table.setBounds(tableBounds); 152 153 dialog.setBounds(dialog.computeTrim(tableBounds.x, tableBounds.y, 154 tableBounds.width, tableBounds.height)); 155 156 tc.setWidth(table.getClientArea().width); 157 table.setFocus(); 158 table.addFocusListener(new FocusListener() { 159 public void focusGained(FocusEvent e) { 160 } 162 163 public void focusLost(FocusEvent e) { 164 cancel(dialog); 165 } 166 }); 167 168 Rectangle dialogBounds = dialog.getBounds(); 169 Rectangle parentBounds = dialog.getParent().getBounds(); 170 171 Rectangle monitorBounds = activePart == null ? display 173 .getPrimaryMonitor().getBounds() : ((PartSite) activePart 174 .getSite()).getPane().getControl().getMonitor().getBounds(); 175 176 dialogBounds.x = parentBounds.x 178 + ((parentBounds.width - dialogBounds.width) / 2); 179 dialogBounds.y = parentBounds.y 180 + ((parentBounds.height - dialogBounds.height) / 2); 181 if (!monitorBounds.contains(dialogBounds.x, dialogBounds.y) 182 || !monitorBounds.contains(dialogBounds.x + dialogBounds.width, 183 dialogBounds.y + dialogBounds.height)) { 184 dialogBounds.x = monitorBounds.x 187 + (monitorBounds.width - dialogBounds.width) / 2; 188 dialogBounds.y = monitorBounds.y 189 + (monitorBounds.height - dialogBounds.height) / 2; 190 } 191 192 dialog.setLocation(dialogBounds.x, dialogBounds.y); 193 194 199 commandForward = getForwardCommand(); 200 commandBackward = getBackwardCommand(); 201 206 final IBindingService bindingService = (IBindingService) window 207 .getWorkbench().getService(IBindingService.class); 208 forwardTriggerSequences = bindingService 209 .getActiveBindingsFor(commandForward); 210 backwardTriggerSequences = bindingService 211 .getActiveBindingsFor(commandBackward); 212 213 final IContextService contextService = (IContextService) window 214 .getWorkbench().getService(IContextService.class); 215 try { 216 dialog.open(); 217 addMouseListener(table, dialog); 218 contextService.registerShell(dialog, IContextService.TYPE_NONE); 219 addKeyListener(table, dialog); 220 addTraverseListener(table); 221 222 while (!dialog.isDisposed()) { 223 if (!display.readAndDispatch()) { 224 display.sleep(); 225 } 226 } 227 } finally { 228 if (!dialog.isDisposed()) { 229 cancel(dialog); 230 } 231 contextService.unregisterShell(dialog); 232 forwardTriggerSequences = null; 233 backwardTriggerSequences = null; 234 } 235 } 236 237 protected void addKeyListener(final Table table, final Shell dialog) { 238 table.addKeyListener(new KeyListener() { 239 private boolean firstKey = true; 240 241 private boolean quickReleaseMode = false; 242 243 public void keyPressed(KeyEvent e) { 244 int keyCode = e.keyCode; 245 char character = e.character; 246 int accelerator = SWTKeySupport 247 .convertEventToUnmodifiedAccelerator(e); 248 KeyStroke keyStroke = SWTKeySupport 249 .convertAcceleratorToKeyStroke(accelerator); 250 251 boolean acceleratorForward = false; 252 boolean acceleratorBackward = false; 253 254 if (commandForward != null) { 255 if (forwardTriggerSequences != null) { 256 final int forwardCount = forwardTriggerSequences.length; 257 for (int i = 0; i < forwardCount; i++) { 258 final TriggerSequence triggerSequence = forwardTriggerSequences[i]; 259 260 final Trigger[] triggers = triggerSequence 262 .getTriggers(); 263 final int triggersLength = triggers.length; 264 if ((triggersLength > 0) 265 && (triggers[triggersLength - 1] 266 .equals(keyStroke))) { 267 acceleratorForward = true; 268 break; 269 } 270 } 271 } 272 } 273 274 if (commandBackward != null) { 275 if (backwardTriggerSequences != null) { 276 final int backwardCount = backwardTriggerSequences.length; 277 for (int i = 0; i < backwardCount; i++) { 278 final TriggerSequence triggerSequence = backwardTriggerSequences[i]; 279 280 final Trigger[] triggers = triggerSequence 282 .getTriggers(); 283 final int triggersLength = triggers.length; 284 if ((triggersLength > 0) 285 && (triggers[triggersLength - 1] 286 .equals(keyStroke))) { 287 acceleratorBackward = true; 288 break; 289 } 290 } 291 } 292 } 293 294 if (character == SWT.CR || character == SWT.LF) { 295 ok(dialog, table); 296 } else if (acceleratorForward) { 297 if (firstKey && e.stateMask != 0) { 298 quickReleaseMode = true; 299 } 300 301 int index = table.getSelectionIndex(); 302 table.setSelection((index + 1) % table.getItemCount()); 303 } else if (acceleratorBackward) { 304 if (firstKey && e.stateMask != 0) { 305 quickReleaseMode = true; 306 } 307 308 int index = table.getSelectionIndex(); 309 table.setSelection(index >= 1 ? index - 1 : table 310 .getItemCount() - 1); 311 } else if (keyCode != SWT.ALT && keyCode != SWT.COMMAND 312 && keyCode != SWT.CTRL && keyCode != SWT.SHIFT 313 && keyCode != SWT.ARROW_DOWN && keyCode != SWT.ARROW_UP 314 && keyCode != SWT.ARROW_LEFT 315 && keyCode != SWT.ARROW_RIGHT) { 316 cancel(dialog); 317 } 318 319 firstKey = false; 320 } 321 322 public void keyReleased(KeyEvent e) { 323 int keyCode = e.keyCode; 324 int stateMask = e.stateMask; 325 326 final IPreferenceStore store = WorkbenchPlugin.getDefault() 327 .getPreferenceStore(); 328 final boolean stickyCycle = store 329 .getBoolean(IPreferenceConstants.STICKY_CYCLE); 330 if ((!stickyCycle && (firstKey || quickReleaseMode)) 331 && keyCode == stateMask) { 332 ok(dialog, table); 333 } 334 } 335 }); 336 } 337 338 345 protected final void addTraverseListener(final Table table) { 346 table.addTraverseListener(new TraverseListener() { 347 353 public final void keyTraversed(final TraverseEvent event) { 354 event.doit = false; 355 } 356 }); 357 } 358 359 367 protected void activate(IWorkbenchPage page, Object selectedItem) { 368 if (selectedItem != null) { 369 if (selectedItem instanceof IEditorReference) { 370 page.setEditorAreaVisible(true); 371 } 372 if (selectedItem instanceof IWorkbenchPartReference) { 373 IWorkbenchPart part = ((IWorkbenchPartReference) selectedItem) 374 .getPart(true); 375 if (part != null) { 376 page.activate(part); 377 } 378 } 379 380 if (selectedItem instanceof IPerspectiveDescriptor){ 381 IPerspectiveDescriptor persp = (IPerspectiveDescriptor) selectedItem; 382 page.setPerspective(persp); 383 } 384 385 } 386 } 387 388 391 protected void cancel(Shell dialog) { 392 selection = null; 393 dialog.close(); 394 } 395 396 399 protected void ok(Shell dialog, final Table table) { 400 TableItem[] items = table.getSelection(); 401 402 if (items != null && items.length == 1) { 403 selection = items[0].getData(); 404 } 405 406 dialog.close(); 407 } 408 409 412 protected void addMouseListener(final Table table, final Shell dialog) { 413 table.addMouseListener(new MouseListener() { 414 public void mouseDoubleClick(MouseEvent e) { 415 ok(dialog, table); 416 } 417 418 public void mouseDown(MouseEvent e) { 419 ok(dialog, table); 420 } 421 422 public void mouseUp(MouseEvent e) { 423 ok(dialog, table); 424 } 425 }); 426 } 427 428 protected abstract String getTableHeader(); 429 430 432 public Object getSelection() { 433 return selection; 434 } 435 436 public IWorkbenchWindow getWindow() { 437 return window; 438 } 439 440 public TriggerSequence[] getBackwardTriggerSequences() { 441 return backwardTriggerSequences; 442 } 443 444 public TriggerSequence[] getForwardTriggerSequences() { 445 return forwardTriggerSequences; 446 } 447 448 454 public void setInitializationData(IConfigurationElement config, 455 String propertyName, Object data) throws CoreException { 456 gotoDirection = "true".equals(data); } 458 } 459 | Popular Tags |