///******************************************************************************* // * 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; // //import java.io.BufferedWriter; //import java.io.IOException; //import java.io.StringWriter; // //import org.eclipse.core.commands.ParameterizedCommand; //import org.eclipse.jface.util.Util; // ///** // * <p> // * A binding is a link between user input and the triggering of a particular // * command. The most common example of a binding is a keyboard shortcut, but // * there are also mouse and gesture bindings. // * </p> // * <p> // * Bindings are linked to particular conditions within the application. Some of // * these conditions change infrequently (e.g., locale, scheme), while some will // * tend to change quite frequently (e.g., context). This allows the bindings to // * be tailored to particular situations. For example, a set of bindings may be // * appropriate only inside a text editor. Or, perhaps, a set of bindings might // * be appropriate only for a given locale, such as bindings that coexist with // * the Input Method Editor (IME) on Chinese locales. // * </p> // * <p> // * It is also possible to remove a particular binding. This is typically done as // * part of user configuration (e.g., user changing keyboard shortcuts). However, // * it can also be helpful when trying to change a binding on a particular locale // * or platform. An "unbinding" is really just a binding with no command // * identifier. For it to unbind a particular binding, it must match that binding // * in its context identifier and scheme identifier. Subclasses (e.g., // * <code>KeyBinding</code>) may require other properties to match (e.g., // * <code>keySequence</code>). If these properties match, then this is an // * unbinding. Note: the locale and platform can be different. // * </p> // * <p> // * For example, imagine you have a key binding that looks like this: // * </p> // * <code><pre> // * KeyBinding(command, scheme, context, "Ctrl+Shift+F") // * </pre></code> // * <p> // * On GTK+, the "Ctrl+Shift+F" interferes with some native behaviour. To change // * the binding, we first unbind the "Ctrl+Shift+F" key sequence by // * assigning it a null command on the gtk platform. We then create a new binding // * that maps the command to the "Esc Ctrl+F" key sequence. // * </p> // * <code><pre> // * KeyBinding("Ctrl+Shift+F",null,scheme,context,null,gtk,null,SYSTEM) // * KeyBinding("Esc Ctrl+F",parameterizedCommand,scheme,context,null,gtk,SYSTEM) // * </pre></code> // * <p> // * Bindings are intended to be immutable objects. // * </p> // * // * @since 1.0 // */ //public abstract class Binding { // // /** // * The constant integer hash code value meaning the hash code has not yet // * been computed. // */ // private static final int HASH_CODE_NOT_COMPUTED = -1; // // /** // * A factor for computing the hash code for all key bindings. // */ // private final static int HASH_FACTOR = 89; // // /** // * The seed for the hash code for all key bindings. // */ // private final static int HASH_INITIAL = Binding.class.getName().hashCode(); // // /** // * The type of binding that is defined by the system (i.e., by the // * application developer). In the case of an application based on the // * Eclipse workbench, this is the registry. // */ // public static final int SYSTEM = 0; // // /** // * The type of binding that is defined by the user (i.e., by the end user of // * the application). In the case of an application based on the Eclipse // * workbench, this is the preference store. // */ // public static final int USER = 1; // // /** // * The parameterized command to which this binding applies. This value may // * be <code>null</code> if this binding is meant to "unbind" an existing // * binding. // */ // private final ParameterizedCommand command; // // /** // * The context identifier to which this binding applies. This context must // * be active before this key binding becomes active. This value will never // * be <code>null</code>. // */ // private final String contextId; // // /** // * The hash code for this key binding. This value is computed lazily, and // * marked as invalid when one of the values on which it is based changes. // */ // private transient int hashCode = HASH_CODE_NOT_COMPUTED; // // /** // * The locale in which this binding applies. This value may be // * <code>null</code> if this binding is meant to apply to all locales. // * This string should be in the same format returned by // * <code>Locale.getDefault().toString()</code>. // */ // private final String locale; // // /** // * The platform on which this binding applies. This value may be // * <code>null</code> if this binding is meant to apply to all platforms. // * This string should be in the same format returned by // * <code>SWT.getPlatform</code>. // */ // private final String platform; // // /** // * The identifier of the scheme in which this binding applies. This value // * will never be <code>null</code>. // */ // private final String schemeId; // // /** // * The string representation of this binding. This string is for debugging // * purposes only, and is not meant to be displayed to the user. This value // * is computed lazily. // */ // protected transient String string = null; // // /** // * The type of binding this represents. This is used to distinguish between // * different priority levels for bindings. For example, in our case, // * <code>USER</code> bindings override <code>SYSTEM</code> bindings. // */ // private final int type; // // /** // * Constructs a new instance of <code>Binding</code>. // * // * @param command // * The parameterized command to which this binding applies; this // * value may be <code>null</code> if the binding is meant to // * "unbind" a previously defined binding. // * @param schemeId // * The scheme to which this binding belongs; this value must not // * be <code>null</code>. // * @param contextId // * The context to which this binding applies; this value must not // * be <code>null</code>. // * @param locale // * The locale to which this binding applies; this value may be // * <code>null</code> if it applies to all locales. // * @param platform // * The platform to which this binding applies; this value may be // * <code>null</code> if it applies to all platforms. // * @param windowManager // * The window manager to which this binding applies; this value // * may be <code>null</code> if it applies to all window // * managers. This value is currently ignored. // * @param type // * The type of binding. This should be either <code>SYSTEM</code> // * or <code>USER</code>. // */ // protected Binding(final ParameterizedCommand command, // final String schemeId, final String contextId, final String locale, // final String platform, final String windowManager, final int type) { // if (schemeId == null) { // throw new NullPointerException("The scheme cannot be null"); //$NON-NLS-1$ // } // // if (contextId == null) { // throw new NullPointerException("The context cannot be null"); //$NON-NLS-1$ // } // // if ((type != SYSTEM) && (type != USER)) { // throw new IllegalArgumentException( // "The type must be SYSTEM or USER"); //$NON-NLS-1$ // } // // this.command = command; // this.schemeId = schemeId.intern(); // this.contextId = contextId.intern(); // this.locale = (locale == null) ? null : locale.intern(); // this.platform = (platform == null) ? null : platform.intern(); // this.type = type; // } // // /** // * Tests whether this binding is intended to delete another binding. The // * receiver must have a <code>null</code> command identifier. // * // * @param binding // * The binding to test; must not be <code>null</code>. // * This binding must be a <code>SYSTEM</code> binding. // * @return <code>true</code> if the receiver deletes the binding defined by // * the argument. // */ // final boolean deletes(final Binding binding) { // boolean deletes = true; // deletes &= Util.equals(getContextId(), binding.getContextId()); // deletes &= Util.equals(getTriggerSequence(), binding // .getTriggerSequence()); // if (getLocale() != null) { // deletes &= !Util.equals(getLocale(), binding.getLocale()); // } // if (getPlatform() != null) { // deletes &= !Util.equals(getPlatform(), binding.getPlatform()); // } // deletes &= (binding.getType() == SYSTEM); // deletes &= Util.equals(getParameterizedCommand(), null); // // return deletes; // } // // /** // * Tests whether this binding is equal to another object. Bindings are only // * equal to other bindings with equivalent values. // * // * @param object // * The object with which to compare; may be <code>null</code>. // * @return <code>true</code> if the object is a binding with equivalent // * values for all of its properties; <code>false</code> otherwise. // */ // public final boolean equals(final Object object) { // if (this == object) { // return true; // // } // if (!(object instanceof Binding)) { // return false; // } // // final Binding binding = (Binding) object; // if (!Util.equals(getParameterizedCommand(), binding // .getParameterizedCommand())) { // return false; // } // if (!Util.equals(getContextId(), binding.getContextId())) { // return false; // } // if (!Util.equals(getTriggerSequence(), binding.getTriggerSequence())) { // return false; // } // if (!Util.equals(getLocale(), binding.getLocale())) { // return false; // } // if (!Util.equals(getPlatform(), binding.getPlatform())) { // return false; // } // if (!Util.equals(getSchemeId(), binding.getSchemeId())) { // return false; // } // return (getType() != binding.getType()); // } // // /** // * Returns the parameterized command to which this binding applies. If the // * identifier is <code>null</code>, then this binding is "unbinding" an // * existing binding. // * // * @return The fully-parameterized command; may be <code>null</code>. // */ // public final ParameterizedCommand getParameterizedCommand() { // return command; // } // // /** // * Returns the identifier of the context in which this binding applies. // * // * @return The context identifier; never <code>null</code>. // */ // public final String getContextId() { // return contextId; // } // // /** // * Returns the locale in which this binding applies. If the locale is // * <code>null</code>, then this binding applies to all locales. This // * string is the same format as returned by // * <code>Locale.getDefault().toString()</code>. // * // * @return The locale; may be <code>null</code>. // */ // public final String getLocale() { // return locale; // } // // /** // * Returns the platform on which this binding applies. If the platform is // * <code>null</code>, then this binding applies to all platforms. This // * string is the same format as returned by <code>SWT.getPlatform()</code>. // * // * @return The platform; may be <code>null</code>. // */ // public final String getPlatform() { // return platform; // } // // /** // * Returns the identifier of the scheme in which this binding applies. // * // * @return The scheme identifier; never <code>null</code>. // */ // public final String getSchemeId() { // return schemeId; // } // // /** // * Returns the sequence of trigger for a given binding. The triggers can be // * anything, but above all it must be hashable. This trigger sequence is // * used by the binding manager to distinguish between different bindings. // * // * @return The object representing an input event that will trigger this // * binding; must not be <code>null</code>. // */ // public abstract TriggerSequence getTriggerSequence(); // // /** // * Returns the type for this binding. As it stands now, this value will // * either be <code>SYSTEM</code> or <code>USER</code>. In the future, // * more types might be added. // * // * @return The type for this binding. // */ // public final int getType() { // return type; // } // // /** // * Computes the hash code for this key binding based on all of its // * attributes. // * // * @return The hash code for this key binding. // */ // public final int hashCode() { // if (hashCode == HASH_CODE_NOT_COMPUTED) { // hashCode = HASH_INITIAL; // hashCode = hashCode * HASH_FACTOR // + Util.hashCode(getParameterizedCommand()); // hashCode = hashCode * HASH_FACTOR + Util.hashCode(getContextId()); // hashCode = hashCode * HASH_FACTOR // + Util.hashCode(getTriggerSequence()); // hashCode = hashCode * HASH_FACTOR + Util.hashCode(getLocale()); // hashCode = hashCode * HASH_FACTOR + Util.hashCode(getPlatform()); // hashCode = hashCode * HASH_FACTOR + Util.hashCode(getSchemeId()); // hashCode = hashCode * HASH_FACTOR + Util.hashCode(getType()); // if (hashCode == HASH_CODE_NOT_COMPUTED) { // hashCode++; // } // } // // return hashCode; // } // // /** // * The string representation of this binding -- for debugging purposes only. // * This string should not be shown to an end user. This should be overridden // * by subclasses that add properties. // * // * @return The string representation; never <code>null</code>. // */ // public String toString() { // if (string == null) { // // final StringWriter sw = new StringWriter(); // final BufferedWriter stringBuffer = new BufferedWriter(sw); // try { // stringBuffer.write("Binding("); //$NON-NLS-1$ // stringBuffer.write(getTriggerSequence().toString()); // stringBuffer.write(','); // stringBuffer.newLine(); // stringBuffer.write('\t'); // stringBuffer.write(command==null?"":command.toString()); //$NON-NLS-1$ // stringBuffer.write(','); // stringBuffer.newLine(); // stringBuffer.write('\t'); // stringBuffer.write(schemeId); // stringBuffer.write(','); // stringBuffer.newLine(); // stringBuffer.write('\t'); // stringBuffer.write(contextId); // stringBuffer.write(','); // stringBuffer.write(locale==null?"":locale); //$NON-NLS-1$ // stringBuffer.write(','); // stringBuffer.write(platform==null?"":platform); //$NON-NLS-1$ // stringBuffer.write(','); // stringBuffer.write((type == SYSTEM) ? "system" : "user"); //$NON-NLS-1$//$NON-NLS-2$ // stringBuffer.write(')'); // stringBuffer.flush(); // } catch (IOException e) { // // shouldn't get this // } // string = sw.toString(); // } // // return string; // } //}