📄 bindingmanager.java
字号:
* @return The active scheme; may be <code>null</code> if there is no * active scheme. If a scheme is returned, it is guaranteed to be * defined. */ public final Scheme getActiveScheme() { return activeScheme; } /** * Gets the best active binding for a command. The best binding is the one * that would be most appropriate to show in a menu. Bindings which belong * to a child scheme are given preference over those in a parent scheme. * Bindings which belong to a particular locale or platform are given * preference over those that do not. The rest of the calculaton is based * most on various concepts of "length", as well as giving some modifier * keys preference (e.g., <code>Alt</code> is less likely to appear than * <code>Ctrl</code>). * * @param commandId * The identifier of the command for which the best active * binding should be retrieved; must not be <code>null</code>. * @return The trigger sequence for the best binding; may be * <code>null</code> if no bindings are active for the given * command. * @since 3.2 */public final TriggerSequence getBestActiveBindingFor(final String commandId) { final Binding[] bindings = getActiveBindingsFor1(commandId); if ((bindings == null) || (bindings.length == 0)) { return null; } Binding bestBinding = bindings[0]; int compareTo; for (int i = 1; i < bindings.length; i++) { final Binding currentBinding = bindings[i]; // Bindings in a child scheme are always given preference. final String bestSchemeId = bestBinding.getSchemeId(); final String currentSchemeId = currentBinding.getSchemeId(); compareTo = compareSchemes(bestSchemeId, currentSchemeId); if (compareTo > 0) { bestBinding = currentBinding; } if (compareTo != 0) { continue; } /* * Bindings with a locale are given preference over those that do * not. */ final String bestLocale = bestBinding.getLocale(); final String currentLocale = currentBinding.getLocale(); if ((bestLocale == null) && (currentLocale != null)) { bestBinding = currentBinding; } if (!(Util.equals(bestLocale, currentLocale))) { continue; } /* * Bindings with a platform are given preference over those that do * not. */ final String bestPlatform = bestBinding.getPlatform(); final String currentPlatform = currentBinding.getPlatform(); if ((bestPlatform == null) && (currentPlatform != null)) { bestBinding = currentBinding; } if (!(Util.equals(bestPlatform, currentPlatform))) { continue; } /* * Check to see which has the least number of triggers in the * trigger sequence. */ final TriggerSequence bestTriggerSequence = bestBinding .getTriggerSequence(); final TriggerSequence currentTriggerSequence = currentBinding .getTriggerSequence(); final Trigger[] bestTriggers = bestTriggerSequence.getTriggers(); final Trigger[] currentTriggers = currentTriggerSequence .getTriggers(); compareTo = bestTriggers.length - currentTriggers.length; if (compareTo > 0) { bestBinding = currentBinding; } if (compareTo != 0) { continue; } /* * Compare the number of keys pressed in each trigger sequence. Some * types of keys count less than others (i.e., some types of * modifiers keys are less likely to be chosen). */ compareTo = countStrokes(bestTriggers) - countStrokes(currentTriggers); if (compareTo > 0) { bestBinding = currentBinding; } if (compareTo != 0) { continue; } // If this is still a tie, then just chose the shortest text. compareTo = bestTriggerSequence.format().length() - currentTriggerSequence.format().length(); if (compareTo > 0) { bestBinding = currentBinding; } } return bestBinding.getTriggerSequence(); } /** * Gets the formatted string representing the best active binding for a * command. The best binding is the one that would be most appropriate to * show in a menu. Bindings which belong to a child scheme are given * preference over those in a parent scheme. The rest of the calculaton is * based most on various concepts of "length", as well as giving some * modifier keys preference (e.g., <code>Alt</code> is less likely to * appear than <code>Ctrl</code>). * * @param commandId * The identifier of the command for which the best active * binding should be retrieved; must not be <code>null</code>. * @return The formatted string for the best binding; may be * <code>null</code> if no bindings are active for the given * command. * @since 3.2 */ public final String getBestActiveBindingFormattedFor(final String commandId) { final TriggerSequence binding = getBestActiveBindingFor(commandId); if (binding != null) { return binding.format(); } return null; } /** * <p> * Returns the set of all bindings managed by this class. * </p> * <p> * This method completes in <code>O(1)</code>. * </p> * * @return The array of all bindings. This value may be <code>null</code> * and it may be empty. */ public final Binding[] getBindings() { if (bindings == null) { return null; } final Binding[] returnValue = new Binding[bindingCount]; System.arraycopy(bindings, 0, returnValue, 0, bindingCount); return returnValue; } /** * <p> * Returns the array of schemes that are defined. * </p> * <p> * This method completes in <code>O(1)</code>. * </p> * * @return The array of defined schemes; this value may be empty or * <code>null</code>. */ public final Scheme[] getDefinedSchemes() { return (Scheme[]) definedHandleObjects .toArray(new Scheme[definedHandleObjects.size()]); } /** * <p> * Returns the active locale for this binding manager. The locale is in the * same format as <code>Locale.getDefault().toString()</code>. * </p> * <p> * This method completes in <code>O(1)</code>. * </p> * * @return The active locale; never <code>null</code>. */ public final String getLocale() { return locale; } /** * <p> * Returns all of the possible bindings that start with the given trigger * (but are not equal to the given trigger). * </p> * <p> * This method completes in <code>O(1)</code>. If the bindings aren't * currently computed, then this completes in <code>O(n)</code>, where * <code>n</code> is the number of bindings. * </p> * * @param trigger * The prefix to look for; must not be <code>null</code>. * @return A map of triggers (<code>TriggerSequence</code>) to bindings (<code>Binding</code>). * This map may be empty, but it is never <code>null</code>. */ public final Map getPartialMatches(final TriggerSequence trigger) { final Map partialMatches = (Map) getPrefixTable().get(trigger); if (partialMatches == null) { return Collections.EMPTY_MAP; } return partialMatches; } /** * <p> * Returns the command identifier for the active binding matching this * trigger, if any. * </p> * <p> * This method completes in <code>O(1)</code>. If the bindings aren't * currently computed, then this completes in <code>O(n)</code>, where * <code>n</code> is the number of bindings. * </p> * * @param trigger * The trigger to match; may be <code>null</code>. * @return The binding that matches, if any; <code>null</code> otherwise. */ public final Binding getPerfectMatch(final TriggerSequence trigger) { return (Binding) getActiveBindings().get(trigger); } /** * <p> * Returns the active platform for this binding manager. The platform is in * the same format as <code>SWT.getPlatform()</code>. * </p> * <p> * This method completes in <code>O(1)</code>. * </p> * * @return The active platform; never <code>null</code>. */ public final String getPlatform() { return platform; } /** * <p> * Returns the prefix table. The caller must not modify the returned map. * </p> * <p> * This method completes in <code>O(1)</code>. If the active bindings are * not yet computed, then this completes in <code>O(n)</code>, where * <code>n</code> is the number of bindings. * </p> * * @return A map of prefixes (<code>TriggerSequence</code>) to a map of * available completions (possibly <code>null</code>, which means * there is an exact match). The available completions is a map of * trigger (<code>TriggerSequence</code>) to binding (<code>Binding</code>). * This value will never be <code>null</code> but may be empty. */ private final Map getPrefixTable() { if (prefixTable == null) { recomputeBindings(); } return prefixTable; } /** * <p> * Gets the scheme with the given identifier. If the scheme does not already * exist, then a new (undefined) scheme is created with that identifier. * This guarantees that schemes will remain unique. * </p> * <p> * This method completes in amortized <code>O(1)</code>. * </p> * * @param schemeId * The identifier for the scheme to retrieve; must not be * <code>null</code>. * @return A scheme with the given identifier. */ public final Scheme getScheme(final String schemeId) { checkId(schemeId); Scheme scheme = (Scheme) handleObjectsById.get(schemeId); if (scheme == null) { scheme = new Scheme(schemeId); handleObjectsById.put(schemeId, scheme); scheme.addSchemeListener(this); } return scheme; } /** * <p> * Ascends all of the parents of the scheme until no more parents are found. * </p> * <p> * This method completes in <code>O(n)</code>, where <code>n</code> is * the height of the context tree. * </p> * * @param schemeId * The id of the scheme for which the parents should be found; * may be <code>null</code>. * @return The array of scheme ids (<code>String</code>) starting with * <code>schemeId</code> and then ascending through its ancestors. */ private final String[] getSchemeIds(String schemeId) { final List strings = new ArrayList(); while (schemeId != null) { strings.add(schemeId); try { schemeId = getScheme(schemeId).getParentId(); } catch (final NotDefinedException e) { Policy.getLog().log( new Status(IStatus.ERROR, Policy.JFACE, IStatus.OK, "Failed ascending scheme parents", //$NON-NLS-1$ e)); return new String[0]; } } return (String[]) strings.toArray(new String[strings.size()]); } /** * <p> * Returns whether the given trigger sequence is a partial match for the * given sequence. * </p> * <p> * This method completes in <code>O(1)</code>. If the bindings aren't * currently computed, then this completes in <code>O(n)</code>, where * <code>n</code> is the number of bindings. * </p> * * @param trigger * The sequence which should be the prefix for some binding; * should not be <code>null</code>. * @return <code>true</code> if the trigger can be found in the active * bindings; <code>false</code> otherwise. */ public final boolean isPartialMatch(final TriggerSequence trigger) { return (getPrefixTable().get(trigger) != null); } /** * <p> * Returns whether the given trigger sequence is a perfect match for the * given sequence. * </p> * <p> * This method completes in <code>O(1)</code>. If the bindings aren't * currently computed, then this completes in <code>O(n)</code>, where * <code>n</code> is the number of bindings. * </p> * * @param trigger * The sequence which should match exactly; should not be * <code>null</code>. * @return <code>true</code> if the trigger can be found in the active * bindings; <code>false</code> otherwise. */ public final boolean isPerfectMatch(final TriggerSequence trigger) { return getActiveBindings().containsKey(trigger); } /** * <p> * Tests whether the locale for the binding matches one of the active * locales. * </p> * <p> * This method completes in <code>O(n)</code>, where <code>n</code> is * the number of active locales. * </p> * * @param binding * The binding with which to test; must not be <code>null</code>. * @return <code>true</code> if the binding's locale matches; * <code>false</code> otherwise. */ private final boolean localeMatches(final Binding binding) { boolean matches = false; final String locale = binding.getLocale(); if (locale == null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -