diff options
| author | Paul Webster | 2013-02-05 20:50:46 +0000 |
|---|---|---|
| committer | Paul Webster | 2013-02-05 20:50:46 +0000 |
| commit | 0fbbfb1bd4d8f09828bc358be83af63c78b2c1cc (patch) | |
| tree | 60958c23671ac2568f44fd59b6294a66bef94769 | |
| parent | 671819c88882506b6e67414c63c808c31ee5de49 (diff) | |
| download | eclipse.platform.ui-0fbbfb1bd4d8f09828bc358be83af63c78b2c1cc.tar.gz eclipse.platform.ui-0fbbfb1bd4d8f09828bc358be83af63c78b2c1cc.tar.xz eclipse.platform.ui-0fbbfb1bd4d8f09828bc358be83af63c78b2c1cc.zip | |
Bug 387728 - [KeyBindings] Changing the keybindings to Emacs+ unstablev20130205-205046
Take binding Scheme into account when calculating conflicts within one
binding table/context.
2 files changed, 179 insertions, 83 deletions
diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTable.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTable.java index a349f1858d6..c8463b6678d 100644 --- a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTable.java +++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTable.java @@ -16,6 +16,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.commands.contexts.Context; @@ -30,32 +31,37 @@ import org.eclipse.jface.bindings.keys.KeyStroke; * manage tables of bindings that can be used to look up commands from keys. */ public class BindingTable { - static class BindingComparator implements Comparator<Binding> { - private String[] activeSchemeIds; - - private final int compareSchemes(final String schemeId1, final String schemeId2) { - if (activeSchemeIds == null || activeSchemeIds.length == 0) { - return 0; - } - if (!schemeId2.equals(schemeId1)) { - for (int i = 0; i < activeSchemeIds.length; i++) { - final String schemePointer = activeSchemeIds[i]; - if (schemeId2.equals(schemePointer)) { - return 1; - } else if (schemeId1.equals(schemePointer)) { - return -1; - } + private static int compareSchemes(String[] activeSchemeIds, final String schemeId1, + final String schemeId2) { + if (activeSchemeIds == null || activeSchemeIds.length == 0) { + return 0; + } + if (!schemeId2.equals(schemeId1)) { + for (int i = 0; i < activeSchemeIds.length; i++) { + final String schemePointer = activeSchemeIds[i]; + if (schemeId2.equals(schemePointer)) { + return 1; + } else if (schemeId1.equals(schemePointer)) { + return -1; } } - return 0; } + return 0; + } + + static class BindingComparator implements Comparator<Binding> { + private String[] activeSchemeIds; public void setActiveSchemes(String[] activeSchemeIds) { this.activeSchemeIds = activeSchemeIds; } + public String[] getActiveSchemes() { + return this.activeSchemeIds; + } + public int compare(Binding o1, Binding o2) { - int rc = compareSchemes(o1.getSchemeId(), o2.getSchemeId()); + int rc = compareSchemes(activeSchemeIds, o1.getSchemeId(), o2.getSchemeId()); if (rc != 0) { return rc; } @@ -121,6 +127,7 @@ public class BindingTable { private Map<ParameterizedCommand, ArrayList<Binding>> bindingsByCommand = new HashMap<ParameterizedCommand, ArrayList<Binding>>(); private Map<TriggerSequence, ArrayList<Binding>> bindingsByPrefix = new HashMap<TriggerSequence, ArrayList<Binding>>(); private Map<TriggerSequence, ArrayList<Binding>> conflicts = new HashMap<TriggerSequence, ArrayList<Binding>>(); + private Map<TriggerSequence, ArrayList<Binding>> orderedBindingsByTrigger = new HashMap<TriggerSequence, ArrayList<Binding>>(); /** * @param context @@ -158,54 +165,68 @@ public class BindingTable { throw new IllegalArgumentException("Binding context " + binding.getContextId() //$NON-NLS-1$ + " does not match " + getId()); //$NON-NLS-1$ } + ArrayList<Binding> bindingList = orderedBindingsByTrigger.get(binding.getTriggerSequence()); + Binding possibleConflict = bindingsByTrigger.get(binding.getTriggerSequence()); + if (bindingList == null || bindingList.isEmpty()) { + if (possibleConflict != null) { + if (bindingList == null) { + bindingList = new ArrayList<Binding>(); + orderedBindingsByTrigger.put(binding.getTriggerSequence(), bindingList); + } + bindingList.add(binding); + bindingList.add(possibleConflict); + Collections.sort(bindingList, BEST_SEQUENCE); + } + } else { + bindingList.add(binding); + Collections.sort(bindingList, BEST_SEQUENCE); + } + + if (possibleConflict != null && bindingList != null && !bindingList.isEmpty() + && bindingList.get(0) != possibleConflict) { + removeBindingSimple(possibleConflict); + possibleConflict = null; + } + + evaluateOrderedBindings(binding.getTriggerSequence(), binding); + } - Binding conflict; - ArrayList<Binding> conflictsList; - boolean isConflict = false; - - // if this binding conflicts with one other active binding - if (bindingsByTrigger.containsKey(binding.getTriggerSequence())) { - // remove the active binding and put it in the conflicts map - conflict = bindingsByTrigger.get(binding.getTriggerSequence()); - removeBinding(conflict); - conflictsList = new ArrayList<Binding>(); - conflictsList.add(conflict); - conflicts.put(binding.getTriggerSequence(), conflictsList); - isConflict = true; + private void addBindingSimple(Binding binding) { + bindings.add(binding); + bindingsByTrigger.put(binding.getTriggerSequence(), binding); + + ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand()); + if (sequences == null) { + sequences = new ArrayList<Binding>(); + bindingsByCommand.put(binding.getParameterizedCommand(), sequences); } - // if this trigger is already in the conflicts map - if (conflicts.containsKey(binding.getTriggerSequence()) - && conflicts.get(binding.getTriggerSequence()).size() > 0) { - - // add this binding to the conflicts map - conflictsList = conflicts.get(binding.getTriggerSequence()); - if (!conflictsList.contains(binding)) { - conflictsList.add(binding); + sequences.add(binding); + Collections.sort(sequences, BEST_SEQUENCE); + + TriggerSequence[] prefs = binding.getTriggerSequence().getPrefixes(); + for (int i = 1; i < prefs.length; i++) { + ArrayList<Binding> bindings = bindingsByPrefix.get(prefs[i]); + if (bindings == null) { + bindings = new ArrayList<Binding>(); + bindingsByPrefix.put(prefs[i], bindings); } - isConflict = true; + bindings.add(binding); } + } - // if there are no conflicts, then add to the table - if (!isConflict) { - bindings.add(binding); - bindingsByTrigger.put(binding.getTriggerSequence(), binding); + private void removeBindingSimple(Binding binding) { + bindings.remove(binding); + bindingsByTrigger.remove(binding.getTriggerSequence()); + ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand()); - ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand()); - if (sequences == null) { - sequences = new ArrayList<Binding>(); - bindingsByCommand.put(binding.getParameterizedCommand(), sequences); - } - sequences.add(binding); - Collections.sort(sequences, BEST_SEQUENCE); - - TriggerSequence[] prefs = binding.getTriggerSequence().getPrefixes(); - for (int i = 1; i < prefs.length; i++) { - ArrayList<Binding> bindings = bindingsByPrefix.get(prefs[i]); - if (bindings == null) { - bindings = new ArrayList<Binding>(); - bindingsByPrefix.put(prefs[i], bindings); - } - bindings.add(binding); + if (sequences != null) { + sequences.remove(binding); + } + TriggerSequence[] prefs = binding.getTriggerSequence().getPrefixes(); + for (int i = 1; i < prefs.length; i++) { + ArrayList<Binding> bindings = bindingsByPrefix.get(prefs[i]); + if (bindings != null) { + bindings.remove(binding); } } } @@ -215,33 +236,79 @@ public class BindingTable { throw new IllegalArgumentException("Binding context " + binding.getContextId() //$NON-NLS-1$ + " does not match " + getId()); //$NON-NLS-1$ } - ArrayList<Binding> conflictBindings = conflicts.get(binding.getTriggerSequence()); - - // if this binding is in the conflicts map, then remove it - if (!bindingsByTrigger.containsKey(binding.getTriggerSequence()) - && conflictBindings != null) { - - conflictBindings.remove(binding); - - // if there is only one binding left in the list, then it's not really a conflict - // binding anymore and can be re-added to the binding table - if (conflictBindings.size() == 1) { - Binding bindingToReAdd = conflictBindings.remove(0); - addBinding(bindingToReAdd); + ArrayList<Binding> bindingList = orderedBindingsByTrigger.get(binding.getTriggerSequence()); + Binding possibleConflict = bindingsByTrigger.get(binding.getTriggerSequence()); + if (possibleConflict == binding) { + removeBindingSimple(binding); + if (bindingList != null) { + bindingList.remove(binding); + if (bindingList.isEmpty()) { + orderedBindingsByTrigger.remove(binding.getTriggerSequence()); + } else { + evaluateOrderedBindings(binding.getTriggerSequence(), null); + } } + } else if (bindingList != null) { + bindingList.remove(binding); + if (bindingList.isEmpty()) { + orderedBindingsByTrigger.remove(binding.getTriggerSequence()); + } else { + evaluateOrderedBindings(binding.getTriggerSequence(), null); + } + } + } - } else { - bindings.remove(binding); - bindingsByTrigger.remove(binding.getTriggerSequence()); - ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand()); - - if (sequences != null) { - sequences.remove(binding); + /** + * @param binding + */ + private void evaluateOrderedBindings(TriggerSequence sequence, Binding binding) { + ArrayList<Binding> bindingList = orderedBindingsByTrigger.get(sequence); + + // calculate binding to be used or any conflicts + if (bindingList != null) { + if (bindingList.isEmpty()) { + orderedBindingsByTrigger.remove(sequence); + } else if (bindingList.size() > 1) { + Binding msb = bindingList.get(0); + Binding lsb = bindingList.get(1); + int rc = compareSchemes(BEST_SEQUENCE.getActiveSchemes(), msb.getSchemeId(), + lsb.getSchemeId()); + if (rc == 0) { + ArrayList<Binding> conflictList = conflicts.get(sequence); + if (conflictList == null) { + conflictList = new ArrayList<Binding>(); + conflicts.put(sequence, conflictList); + } else { + conflictList.clear(); + } + Iterator<Binding> i = bindingList.iterator(); + Binding prev = i.next(); + conflictList.add(prev); + while (i.hasNext() && rc == 0) { + Binding next = i.next(); + rc = compareSchemes(BEST_SEQUENCE.getActiveSchemes(), prev.getSchemeId(), + next.getSchemeId()); + if (rc == 0) { + conflictList.add(next); + } + prev = next; + } + } else { + conflicts.remove(sequence); + if (bindingsByTrigger.get(sequence) == null) { + addBindingSimple(msb); + } + } + } else { + if (bindingsByTrigger.get(sequence) == null) { + addBindingSimple(bindingList.get(0)); + } + orderedBindingsByTrigger.remove(sequence); } - TriggerSequence[] prefs = binding.getTriggerSequence().getPrefixes(); - for (int i = 1; i < prefs.length; i++) { - ArrayList<Binding> bindings = bindingsByPrefix.get(prefs[i]); - bindings.remove(binding); + } else if (binding != null) { + conflicts.remove(sequence); + if (bindingsByTrigger.get(sequence) == null) { + addBindingSimple(binding); } } } diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/util/BindingProcessingAddon.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/util/BindingProcessingAddon.java index 3ada92cf58d..794f8b1c985 100644 --- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/util/BindingProcessingAddon.java +++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/util/BindingProcessingAddon.java @@ -11,6 +11,7 @@ package org.eclipse.e4.ui.workbench.swt.util; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -20,6 +21,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.commands.contexts.Context; import org.eclipse.core.commands.contexts.ContextManager; import org.eclipse.core.runtime.IStatus; @@ -46,6 +48,8 @@ import org.eclipse.e4.ui.workbench.UIEvents; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.bindings.Binding; +import org.eclipse.jface.bindings.BindingManager; +import org.eclipse.jface.bindings.Scheme; import org.eclipse.jface.bindings.TriggerSequence; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; @@ -68,6 +72,9 @@ public class BindingProcessingAddon { private BindingTableManager bindingTables; @Inject + private BindingManager bindingManager; + + @Inject private ECommandService commandService; @Inject @@ -79,11 +86,33 @@ public class BindingProcessingAddon { @PostConstruct public void init() { + final Scheme activeScheme = bindingManager.getActiveScheme(); + if (activeScheme != null) { + bindingTables.setActiveSchemes(getSchemeIds(activeScheme.getId())); + } defineBindingTables(); activateContexts(application); registerModelListeners(); } + private final String[] getSchemeIds(String schemeId) { + final List<String> strings = new ArrayList<String>(); + while (schemeId != null) { + strings.add(schemeId); + try { + schemeId = getScheme(schemeId).getParentId(); + } catch (final NotDefinedException e) { + return new String[0]; + } + } + + return strings.toArray(new String[strings.size()]); + } + + private final Scheme getScheme(String schemeId) { + return bindingManager.getScheme(schemeId); + } + private void activateContexts(Object me) { if (me instanceof MBindings) { MContext contextModel = (MContext) me; |
