View | Details | Raw Unified | Return to bug 42035 | Differences between
and this patch

Collapse All | Expand All

(-)Eclipse UI/org/eclipse/ui/internal/Workbench.java (-63 / +82 lines)
Lines 208-219 Link Here
208
				if (shell.getParent() != null)
208
				if (shell.getParent() != null)
209
					return;
209
					return;
210
			}
210
			}
211
			
212
			final KeyStroke[] keyStrokes = new KeyStroke[3];
213
			keyStrokes[0] = KeySupport.convertAcceleratorToKeyStroke(KeySupport.convertEventToAccelerator(event));
214
			keyStrokes[1] = KeySupport.convertAcceleratorToKeyStroke(KeySupport.convertEventToShiftedAccelerator(event));
215
			keyStrokes[2] = KeySupport.convertAcceleratorToKeyStroke(KeySupport.convertEventToShiftedUnmodifierAccelerator(event));
211
216
212
			KeyStroke keyStroke =
217
			if (press(keyStrokes, event)) {
213
				KeySupport.convertAcceleratorToKeyStroke(
214
					KeySupport.convertEventToAccelerator(event));
215
216
			if (press(keyStroke, event)) {
217
				switch (event.type) {
218
				switch (event.type) {
218
					case SWT.KeyDown :
219
					case SWT.KeyDown :
219
						event.doit = false;
220
						event.doit = false;
Lines 413-481 Link Here
413
		return true;
414
		return true;
414
	}
415
	}
415
416
416
	// TODO move this method to CommandManager once getMode() is added to ICommandManager (and triggers and change event)
417
	/**
417
	// TODO remove event parameter once key-modified actions are removed
418
	 * Processes a key press with respect to the key binding architecture.  This
418
	public final boolean press(KeyStroke keyStroke, Event event) {
419
	 * updates the mode of the command manager, and runs the current handler for
419
		final KeySequence modeBeforeKeyStroke = commandManager.getMode();
420
	 * the command that matches the key sequence, if any.
420
		final List keyStrokes =
421
	 * 
421
			new ArrayList(modeBeforeKeyStroke.getKeyStrokes());
422
	 * @param potentialKeyStrokes The key strokes that could potentially match,
422
		keyStrokes.add(keyStroke);
423
	 * in the order of priority; must not be <code>null</code>.
423
		final KeySequence modeAfterKeyStroke =
424
	 * @param event The event to pass to the action; may be <code>null</code>.
424
			KeySequence.getInstance(keyStrokes);
425
	 * 
425
		final Map matchesByKeySequenceForModeBeforeKeyStroke =
426
	 * @return <code>true</code> if a command is executed; <code>false</code>
426
			commandManager.getMatchesByKeySequenceForMode();
427
	 * otherwise.
427
		commandManager.setMode(modeAfterKeyStroke);
428
	 */
428
		final Map matchesByKeySequenceForModeAfterKeyStroke =
429
	public final boolean press(final KeyStroke[] potentialKeyStrokes, final Event event) {
429
			commandManager.getMatchesByKeySequenceForMode();
430
		// TODO move this method to CommandManager once getMode() is added to ICommandManager (and triggers and change event)
430
		boolean consumeKeyStroke = false;
431
		// TODO remove event parameter once key-modified actions are removed
431
432
		
432
		if (!matchesByKeySequenceForModeAfterKeyStroke.isEmpty()) {
433
		// Check every potential key stroke until one matches.
433
			// this key stroke is part of one or more possible completions: consume the keystroke
434
		for (int i = 0; i < potentialKeyStrokes.length; i++) {
434
			updateModeLines(modeAfterKeyStroke);
435
			final KeySequence modeBeforeKeyStroke = commandManager.getMode();
435
			consumeKeyStroke = true;
436
			final List keyStrokes = new ArrayList(modeBeforeKeyStroke.getKeyStrokes());
436
		} else {
437
			keyStrokes.add(potentialKeyStrokes[i]);
437
			// there are no possible longer multi-stroke sequences, allow a completion now if possible
438
			final KeySequence modeAfterKeyStroke = KeySequence.getInstance(keyStrokes);
438
			final Match match =
439
			final Map matchesByKeySequenceForModeBeforeKeyStroke = commandManager.getMatchesByKeySequenceForMode();
439
				(Match) matchesByKeySequenceForModeBeforeKeyStroke.get(
440
			commandManager.setMode(modeAfterKeyStroke);
440
					modeAfterKeyStroke);
441
			final Map matchesByKeySequenceForModeAfterKeyStroke = commandManager.getMatchesByKeySequenceForMode();
441
442
			boolean consumeKeyStroke = false;
442
			if (match != null) {
443
443
				// a completion was found. 
444
			if (!matchesByKeySequenceForModeAfterKeyStroke.isEmpty()) {
444
				final String commandId = match.getCommandId();
445
				// this key stroke is part of one or more possible completions: consume the keystroke
445
				final Map actionsById = commandManager.getActionsById();
446
				updateModeLines(modeAfterKeyStroke);
446
				org.eclipse.ui.commands.IAction action =
447
				consumeKeyStroke = true;
447
					(org.eclipse.ui.commands.IAction) actionsById.get(
448
			} else {
448
						commandId);
449
				// there are no possible longer multi-stroke sequences, allow a completion now if possible
449
450
				final Match match = (Match) matchesByKeySequenceForModeBeforeKeyStroke.get(modeAfterKeyStroke);
450
				if (action != null) {
451
451
					// an action was found corresponding to the completion
452
				if (match != null) {
452
453
					// a completion was found. 
453
					if (action.isEnabled()) {
454
					final String commandId = match.getCommandId();
454
						updateModeLines(modeAfterKeyStroke);
455
					final Map actionsById = commandManager.getActionsById();
455
						try {
456
					org.eclipse.ui.commands.IAction action = (org.eclipse.ui.commands.IAction) actionsById.get(commandId);
456
							action.execute(event);
457
457
						} catch (final Exception e) {
458
					if (action != null) {
458
							// TODO 						
459
						// an action was found corresponding to the completion
460
461
						if (action.isEnabled()) {
462
							updateModeLines(modeAfterKeyStroke);
463
							try {
464
								action.execute(event);
465
							} catch (final Exception e) {
466
								// TODO 						
467
							}
459
						}
468
						}
469
	
470
						// consume the keystroke
471
						consumeKeyStroke = true;
460
					}
472
					}
461
462
					// consume the keystroke
463
					consumeKeyStroke = true;
464
				}
473
				}
474
	
475
				// possibly no completion was found, or no action was found corresponding to the completion, but if we were already in a mode consume the keystroke anyway.									
476
				if (modeBeforeKeyStroke.getKeyStrokes().size() >= 1)
477
					consumeKeyStroke = true;
478
	
479
				// clear mode			
480
				commandManager.setMode(KeySequence.getInstance());
481
				updateModeLines(KeySequence.getInstance());
482
			}
483
	
484
			// TODO is this necessary?		
485
			updateActiveContextIds();
486
			
487
			if (consumeKeyStroke) {
488
				// We found a match, so stop now.
489
				return consumeKeyStroke;
490
			} else {
491
				// Restore the mode, so we can try again.
492
				commandManager.setMode(modeBeforeKeyStroke);
465
			}
493
			}
466
467
			// possibly no completion was found, or no action was found corresponding to the completion, but if we were already in a mode consume the keystroke anyway.									
468
			if (modeBeforeKeyStroke.getKeyStrokes().size() >= 1)
469
				consumeKeyStroke = true;
470
471
			// clear mode			
472
			commandManager.setMode(KeySequence.getInstance());
473
			updateModeLines(KeySequence.getInstance());
474
		}
494
		}
475
495
		
476
		// TODO is this necessary?		
496
		// No key strokes match.
477
		updateActiveContextIds();
497
		return false;
478
		return consumeKeyStroke;
479
	}	
498
	}	
480
	
499
	
481
	/**
500
	/**
(-)Eclipse UI/org/eclipse/ui/internal/keys/KeySupport.java (-18 / +68 lines)
Lines 27-50 Link Here
27
import org.eclipse.ui.keys.SpecialKey;
27
import org.eclipse.ui.keys.SpecialKey;
28
28
29
public final class KeySupport {
29
public final class KeySupport {
30
30
	
31
	public static int convertEventToAccelerator(Event event) {
31
	/**
32
		int key = event.character;
32
	 * Converts the given event into an SWT accelerator value -- considering the
33
33
	 * unmodified character with all modifier keys.  This is the first 
34
		if (key == 0)
34
	 * accelerator value that should be checked.  However, all alphabetic 
35
			key = event.keyCode;
35
	 * characters are considered as their uppercase equivalents.
36
		else {
36
	 *  
37
			if (0 <= key && key <= 0x1F) {
37
	 * @param event The event to be converted; must not be <code>null</code>.
38
				if ((event.stateMask & SWT.CTRL) != 0 && event.keyCode != event.character)
38
	 * @return The combination of the state mask and the unmodified character.
39
					key += 0x40;
39
	 */
40
			} else {
40
	public static final int convertEventToAccelerator(final Event event) {
41
				if ('a' <= key && key <= 'z')
41
		final int modifiers = event.stateMask & SWT.MODIFIER_MASK;
42
					key -= 'a' - 'A';
42
		final int unmodifiedCharacter = Character.toUpperCase((char) event.keyCode);
43
			}
43
		
44
		}
44
		return modifiers + unmodifiedCharacter;
45
45
	}
46
		int modifiers = event.stateMask & SWT.MODIFIER_MASK;
46
	
47
		return modifiers + key;
47
	/**
48
	 * Converts the given event into an SWT accelerator value -- considering the
49
	 * modified character without the shift modifier.  This is the second
50
	 * accelerator value that should be checked.
51
	 * 
52
	 * @param event The event to be converted; must not be <code>null</code>.
53
	 * @return The combination of the state mask without shift, and the modified
54
	 * character.
55
	 */
56
	public static final int convertEventToShiftedAccelerator(final Event event) {
57
		final int modifiers = event.stateMask & (SWT.MODIFIER_MASK ^ SWT.SHIFT);
58
		final int modifiedCharacter = topKey(event);
59
		return modifiers + modifiedCharacter;
60
	}
61
	
62
	/**
63
	 * Converts the given event into an SWT accelerator value -- considering the
64
	 * modified character without the shift modifier.  This is the third
65
	 * accelerator value that should be checked.
66
	 * 
67
	 * @param event The event to be converted; must not be <code>null</code>.
68
	 * @return The combination of the state mask and the unmodified character.
69
	 */
70
	public static final int convertEventToShiftedUnmodifierAccelerator(final Event event) {
71
		final int modifiers = event.stateMask & SWT.MODIFIER_MASK;
72
		final int modifiedCharacter = topKey(event);
73
		return modifiers + modifiedCharacter;
48
	}
74
	}
49
75
50
	public static KeyStroke convertAcceleratorToKeyStroke(int accelerator) {
76
	public static KeyStroke convertAcceleratorToKeyStroke(int accelerator) {
Lines 273-278 Link Here
273
			stringBuffer.append(KeyStroke.getInstance(naturalKey).format());
299
			stringBuffer.append(KeyStroke.getInstance(naturalKey).format());
274
					
300
					
275
		return stringBuffer.toString();
301
		return stringBuffer.toString();
302
	}
303
	
304
	/**
305
	 * Makes sure that a fully-modified character is converted to the normal
306
	 * form.  This means that "Ctrl+" key strokes must reverse the modification
307
	 * caused by control-escaping.  Also, all lower case letters are converted
308
	 * to uppercase.
309
	 * 
310
	 * @param event The event from which the fully-modified character should be
311
	 * pulled.
312
	 * 
313
	 * @return The modified character, uppercase and without control-escaping.
314
	 */
315
	private static final int topKey(final Event event) {
316
		final boolean ctrlDown = (event.stateMask & SWT.CTRL) != 0;
317
		
318
		final char modifiedCharacter;
319
		if ((ctrlDown) && (event.character != event.keyCode)) {
320
			modifiedCharacter = (char) (event.character + 0x40);
321
		} else {
322
			modifiedCharacter = event.character;
323
		}
324
		
325
		return Character.toUpperCase(modifiedCharacter);
276
	}
326
	}
277
327
278
	private KeySupport() {
328
	private KeySupport() {

Return to bug 42035