blob: 67c65018e90a73a43d1bf747fb63c1daca5206c9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.bindings.keys;
import org.eclipse.jface.bindings.keys.formatting.IKeyFormatter;
import org.eclipse.jface.bindings.keys.formatting.NativeKeyFormatter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Event;
/**
* <p>
* A utility class for converting SWT events into key strokes.
* </p>
*
* @since 3.1
*/
public final class SWTKeySupport {
/**
* A formatter that displays key sequences in a style native to the
* platform.
*/
private static final IKeyFormatter NATIVE_FORMATTER = new NativeKeyFormatter();
/**
* Given an SWT accelerator value, provide the corresponding key stroke.
*
* @param accelerator
* The accelerator to convert; should be a valid SWT accelerator
* value.
* @return The equivalent key stroke; never <code>null</code>.
*/
public static final KeyStroke convertAcceleratorToKeyStroke(int accelerator) {
final int modifierKeys = accelerator & SWT.MODIFIER_MASK;
final int naturalKey;
if (accelerator == modifierKeys) {
naturalKey = KeyStroke.NO_KEY;
} else {
naturalKey = accelerator - modifierKeys;
}
return KeyStroke.getInstance(modifierKeys, naturalKey);
}
/**
* <p>
* Converts the given event into an SWT accelerator value -- considering the
* modified character with the shift modifier. This is the third accelerator
* value that should be checked when processing incoming key events.
* </p>
* <p>
* For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
* "Ctrl+Shift+%".
* </p>
*
* @param event
* The event to be converted; must not be <code>null</code>.
* @return The combination of the state mask and the unmodified character.
*/
public static final int convertEventToModifiedAccelerator(final Event event) {
int modifiers = event.stateMask & SWT.MODIFIER_MASK;
char character = topKey(event);
return modifiers + toUpperCase(character);
}
/**
* <p>
* Converts the given event into an SWT accelerator value -- considering the
* unmodified character with all modifier keys. This is the first
* accelerator value that should be checked when processing incoming key
* events. However, all alphabetic characters are considered as their
* uppercase equivalents.
* </p>
* <p>
* For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
* "Ctrl+Shift+5".
* </p>
*
* @param event
* The event to be converted; must not be <code>null</code>.
* @return The combination of the state mask and the unmodified character.
*/
public static final int convertEventToUnmodifiedAccelerator(
final Event event) {
return convertEventToUnmodifiedAccelerator(event.stateMask,
event.keyCode);
}
/**
* <p>
* Converts the given state mask and key code into an SWT accelerator value --
* considering the unmodified character with all modifier keys. All
* alphabetic characters are considered as their uppercase equivalents.
* </p>
* <p>
* For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
* "Ctrl+Shift+5".
* </p>
*
* @param stateMask
* The integer mask of modifiers keys depressed when this was
* pressed.
* @param keyCode
* The key that was pressed, before being modified.
* @return The combination of the state mask and the unmodified character.
*/
private static final int convertEventToUnmodifiedAccelerator(
final int stateMask, final int keyCode) {
int modifiers = stateMask & SWT.MODIFIER_MASK;
int character = keyCode;
return modifiers + toUpperCase(character);
}
/**
* <p>
* Converts the given event into an SWT accelerator value -- considering the
* unmodified character with all modifier keys. This is the first
* accelerator value that should be checked. However, all alphabetic
* characters are considered as their uppercase equivalents.
* </p>
* <p>
* For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
* "Ctrl+%".
* </p>
*
* @param event
* The event to be converted; must not be <code>null</code>.
* @return The combination of the state mask and the unmodified character.
*/
public static final int convertEventToUnmodifiedAccelerator(
final KeyEvent event) {
return convertEventToUnmodifiedAccelerator(event.stateMask,
event.keyCode);
}
/**
* Converts the given event into an SWT accelerator value -- considering the
* modified character without the shift modifier. This is the second
* accelerator value that should be checked when processing incoming key
* events. Key strokes with alphabetic natural keys are run through
* <code>convertEventToUnmodifiedAccelerator</code>.
*
* @param event
* The event to be converted; must not be <code>null</code>.
* @return The combination of the state mask without shift, and the modified
* character.
*/
public static final int convertEventToUnshiftedModifiedAccelerator(
final Event event) {
// Disregard alphabetic key strokes.
if (Character.isLetter((char) event.keyCode)) {
return convertEventToUnmodifiedAccelerator(event);
}
int modifiers = event.stateMask & (SWT.MODIFIER_MASK ^ SWT.SHIFT);
char character = topKey(event);
return modifiers + toUpperCase(character);
}
/**
* Given a key stroke, this method provides the equivalent SWT accelerator
* value. The functional inverse of
* <code>convertAcceleratorToKeyStroke</code>.
*
* @param keyStroke
* The key stroke to convert; must not be <code>null</code>.
* @return The SWT accelerator value
*/
public static final int convertKeyStrokeToAccelerator(
final KeyStroke keyStroke) {
return keyStroke.getModifierKeys() + keyStroke.getNaturalKey();
}
/**
* Provides an instance of <code>IKeyFormatter</code> appropriate for the
* current instance.
*
* @return an instance of <code>IKeyFormatter</code> appropriate for the
* current instance; never <code>null</code>.
*/
public static IKeyFormatter getKeyFormatterForPlatform() {
return NATIVE_FORMATTER;
}
/**
* Makes sure that a fully-modified character is converted to the normal
* form. This means that "Ctrl+" key strokes must reverse the modification
* caused by control-escaping. Also, all lower case letters are converted to
* uppercase.
*
* @param event
* The event from which the fully-modified character should be
* pulled.
* @return The modified character, uppercase and without control-escaping.
*/
private static final char topKey(final Event event) {
char character = event.character;
boolean ctrlDown = (event.stateMask & SWT.CTRL) != 0;
if (ctrlDown && event.character != event.keyCode
&& event.character < 0x20)
character += 0x40;
return character;
}
/**
* Makes the given character uppercase if it is a letter.
*
* @param keyCode
* The character to convert.
* @return The uppercase equivalent, if any; otherwise, the character
* itself.
*/
private static final int toUpperCase(int keyCode) {
// Will this key code be truncated?
if (keyCode > 0xFFFF) {
return keyCode;
}
// Downcast in safety. Only make characters uppercase.
final char character = (char) keyCode;
return Character.isLetter(character) ? Character.toUpperCase(character)
: keyCode;
}
/**
* This class should never be instantiated.
*/
protected SWTKeySupport() {
// This class should never be instantiated.
}
}