blob: 373b9bcb40953f476e296642248d101dcddec969 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 Xored Software Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
public class KeysAndButtons {
private static String POINT_ID = UtilPlugin.PLUGIN_ID + ".keysExtension"; //$NON-NLS-1$
private static IKeysAndButtonExtension extension;
public static final String BUTTON_LEFT = "Left";
public static final String BUTTON_RIGHT = "Right";
public static final String BUTTON_MIDDLE = "Middle";
public static final String BUTTON_4 = "Button4";
public static final String BUTTON_5 = "Button5";
private static Map<Integer, String> MODIFIERS = null;
private static int[] ORDERED_MODIFIERS = null;
private static int[] REVERSE_MODIFIERS = null;
private static Map<Integer, String> BUTTON_NAMES_BY_MASK = null;
private static Map<String, Integer> BUTTON_NUMBERS = null;
private static int[] BUTTON_MASKS_BY_NUMBER = null;
public static int[] getOrderedModifiers() {
if (ORDERED_MODIFIERS == null) {
IKeysAndButtonExtension extension = getExtension();
ORDERED_MODIFIERS = new int[] { extension.getMod1(), extension.getMod2(), extension.getMod3(),
extension.getMod4() };
}
return ORDERED_MODIFIERS;
}
public static int[] getReverseModifiers() {
if (REVERSE_MODIFIERS == null) {
int[] ordered = getOrderedModifiers();
int size = ordered.length - 1;
REVERSE_MODIFIERS = new int[ordered.length];
for (int i = size; i >= 0; i--) {
REVERSE_MODIFIERS[size - i] = ordered[i];
}
}
return REVERSE_MODIFIERS;
}
public static Map<Integer, String> getModifiers() {
if (MODIFIERS == null) {
final IKeysAndButtonExtension extension = getExtension();
final Map<Integer, String> current = new LinkedHashMap<Integer, String>();
current.put(extension.getMod1(), "M1"); //$NON-NLS-1$
current.put(extension.getMod2(), "M2"); //$NON-NLS-1$
current.put(extension.getMod3(), "M3"); //$NON-NLS-1$
current.put(extension.getMod4(), "M4"); //$NON-NLS-1$
MODIFIERS = Collections.unmodifiableMap(current);
}
return MODIFIERS;
}
private static Map<Integer, String> getButtonNamesByMask() {
if (BUTTON_NAMES_BY_MASK == null) {
final IKeysAndButtonExtension extension = getExtension();
final Map<Integer, String> current = new LinkedHashMap<Integer, String>();
current.put(extension.getButton1(), BUTTON_LEFT);
current.put(extension.getButton2(), BUTTON_MIDDLE);
current.put(extension.getButton3(), BUTTON_RIGHT);
current.put(extension.getButton4(), BUTTON_4);
current.put(extension.getButton5(), BUTTON_5);
BUTTON_NAMES_BY_MASK = Collections.unmodifiableMap(current);
}
return BUTTON_NAMES_BY_MASK;
}
private static final Map<String, Integer> STATES_BY_NAME = new HashMap<String, Integer>();
static {
for (Entry<Integer, String> entry : getModifiers().entrySet()) {
STATES_BY_NAME.put(entry.getValue(), entry.getKey());
}
for (Entry<Integer, String> entry : getButtonNamesByMask().entrySet()) {
STATES_BY_NAME.put(entry.getValue(), entry.getKey());
}
}
private static final String[] BUTTON_NAMES = { null, BUTTON_LEFT,
BUTTON_MIDDLE, BUTTON_RIGHT, BUTTON_4, BUTTON_5 };
private static Map<String, Integer> getButtonNumbers() {
if (BUTTON_NUMBERS == null) {
final Map<String, Integer> current = new HashMap<String, Integer>();
current.put(BUTTON_LEFT, 1);
current.put(BUTTON_MIDDLE, 2);
current.put(BUTTON_RIGHT, 3);
current.put(BUTTON_4, 4);
current.put(BUTTON_5, 5);
BUTTON_NUMBERS = Collections.unmodifiableMap(current);
}
return BUTTON_NUMBERS;
}
private static int[] getButtonMasksByNumber() {
if (BUTTON_MASKS_BY_NUMBER == null) {
final IKeysAndButtonExtension extension = getExtension();
BUTTON_MASKS_BY_NUMBER = new int[] { 0, extension.getButton1(), extension.getButton2(),
extension.getButton3(), extension.getButton4(), extension.getButton5() };
}
return BUTTON_MASKS_BY_NUMBER;
}
public static int getButtonMask(int button) throws CoreException {
if (button <= 0 || button >= getButtonMasksByNumber().length) {
throw new CoreException(new Status(IStatus.ERROR,
UtilPlugin.PLUGIN_ID, String.format(
"Cannot find button mast for button #%d", button)));
}
return getButtonMasksByNumber()[button];
}
public static int getButtonMaskSafe(int button) {
if (button <= 0 || button >= getButtonMasksByNumber().length) {
return 0;
}
return getButtonMasksByNumber()[button];
}
public static String getButtonName(int button) throws CoreException {
if (button <= 0 || button >= BUTTON_NAMES.length) {
throw new CoreException(new Status(IStatus.ERROR,
UtilPlugin.PLUGIN_ID, String.format(
"Cannot find button name for button #%d", button)));
}
return BUTTON_NAMES[button];
}
public static String getButtonNameSafe(int button, String def) {
if (button <= 0 || button >= BUTTON_NAMES.length) {
return def;
}
return BUTTON_NAMES[button];
}
public static String getButtonNameSafe(int button) {
return getButtonNameSafe(button, BUTTON_LEFT);
}
public static int getButtonNumber(String name) throws CoreException {
if (name != null && name.length() > 0) {
// format name to pascal case
name = String.format("%c%s", name.charAt(0), name.substring(1)
.toLowerCase());
}
if (!getButtonNumbers().containsKey(name)) {
throw new CoreException(new Status(IStatus.ERROR,
UtilPlugin.PLUGIN_ID, String.format(
"Unknown button name '%s'", name)));
}
return getButtonNumbers().get(name);
}
public static String stateMaskToStr(int stateMask) {
List<String> result = new ArrayList<String>();
processMap(getModifiers(), stateMask, result);
processMap(getButtonNamesByMask(), stateMask, result);
return StringUtils.join('+', result);
}
/**
* Returns string like
*
* @param str
* @param safe
* @return
* @throws CoreException
*/
public static int stateMaskFromStr(String str) throws CoreException {
if (str == null || str.length() == 0) {
return 0;
}
String errorMessage = validateStateStr(str);
if (errorMessage != null) {
throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.ui",
errorMessage));
}
int result = 0;
for (String entry : StringUtils.split('+', str)) {
result |= STATES_BY_NAME.get(entry);
}
return result;
}
public static String validateStateStr(String state) {
if (state == null || state.length() == 0) {
return null;
}
for (String entry : StringUtils.split('+', state)) {
if (!STATES_BY_NAME.containsKey(entry)) {
return String.format(
"Cannot parse state '%s': unknown entry '%s'", state,
entry);
}
}
return null;
}
private static void processMap(Map<Integer, String> map, int stateMask,
List<String> acc) {
for (Entry<Integer, String> entry : map.entrySet()) {
if ((stateMask & entry.getKey()) != 0) {
acc.add(entry.getValue());
}
}
}
private static IKeysAndButtonExtension getExtension() {
if (extension == null) {
IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(POINT_ID);
if (elements.length < 1) {
return null;
}
try {
extension = (IKeysAndButtonExtension) elements[0].createExecutableExtension("class");//$NON-NLS-1$
} catch (CoreException e) {
UtilPlugin.log("Error while get key stroke extension.", e); //$NON-NLS-1$
}
}
return extension;
}
public interface IKeysAndButtonExtension {
int getMod1();
int getMod2();
int getMod3();
int getMod4();
int getButton1();
int getButton2();
int getButton3();
int getButton4();
int getButton5();
}
}