Bug 335985 - Adapt the KeyController model to the e4 model
Preliminary approach using the runtime system only
diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/EBindingService.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/EBindingService.java
index 6462efd..308884b 100644
--- a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/EBindingService.java
+++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/EBindingService.java
@@ -19,8 +19,10 @@
public static final String DIALOG_CONTEXT_ID = "org.eclipse.ui.contexts.dialog"; //$NON-NLS-1$
+ // TODO perhaps use a map of attributes for things
+ // that aren't important to the model
Binding createBinding(TriggerSequence sequence, ParameterizedCommand command, String schemeId,
- String contextId);
+ String contextId, String locale, String platform, int bindingType);
void activateBinding(Binding binding);
diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingCopies.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingCopies.java
new file mode 100644
index 0000000..0d38038
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingCopies.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.e4.ui.bindings.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.jface.bindings.Binding;
+import org.eclipse.jface.bindings.TriggerSequence;
+
+public class BindingCopies {
+
+ private static Collection<Binding> sysBindings;
+ private static Collection<Binding> inactiveSystemBindings;
+ private static Collection<Binding> userBindings;
+
+ public static void init() {
+ inactiveSystemBindings = new ArrayList<Binding>();
+ userBindings = new ArrayList<Binding>();
+ }
+
+ public static void setDefaultSysBindings(Collection<Binding> newSysBindings) {
+ sysBindings = newSysBindings;
+ }
+
+ public static Collection<Binding> getSystemBindings() {
+ return sysBindings;
+ }
+
+ public static void addInactiveSysBinding(Binding binding) {
+ inactiveSystemBindings.add(binding);
+ }
+
+ public static Binding[] getInactiveSysBindings() {
+ return inactiveSystemBindings.toArray(new Binding[inactiveSystemBindings.size()]);
+ }
+
+ public static void removeInactiveSysBinding(Binding binding) {
+ inactiveSystemBindings.remove(binding);
+ }
+
+ public static void addUserBinding(Binding b) {
+ userBindings.add(b);
+ }
+
+ public static Binding[] getUserDefinedBindings() {
+ return userBindings.toArray(new Binding[userBindings.size()]);
+ }
+
+ public static boolean isUserBinding(TriggerSequence sequence, ParameterizedCommand command,
+ String schemeId, String contextId) {
+ boolean isUserBinding = false;
+ Binding currBinding;
+ Iterator<Binding> iter = userBindings.iterator();
+ while (iter.hasNext() && !isUserBinding) {
+ currBinding = iter.next();
+ if (currBinding.getTriggerSequence().equals(sequence)
+ && currBinding.getParameterizedCommand().equals(command)
+ && currBinding.getSchemeId().equals(schemeId)
+ && currBinding.getContextId().equals(contextId)) {
+ isUserBinding = true;
+ }
+ }
+ return isUserBinding;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingServiceImpl.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingServiceImpl.java
index 183a956..6f60e53 100644
--- a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingServiceImpl.java
+++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingServiceImpl.java
@@ -53,9 +53,10 @@
* java.lang.String)
*/
public Binding createBinding(TriggerSequence sequence, ParameterizedCommand command,
- String schemeId, String contextId) {
- return new KeyBinding((KeySequence) sequence, command, schemeId, contextId, null, null,
- null, Binding.SYSTEM);
+ String schemeId, String contextId, String locale, String platform, int bindingType) {
+
+ return new KeyBinding((KeySequence) sequence, command, schemeId, contextId, locale,
+ platform, null, bindingType);
}
/*
@@ -70,7 +71,6 @@
BindingTable table = manager.getTable(contextId);
if (table == null) {
System.err.println("No binding table for " + contextId); //$NON-NLS-1$
- return;
}
table.addBinding(binding);
}
@@ -87,7 +87,6 @@
BindingTable table = manager.getTable(contextId);
if (table == null) {
System.err.println("No binding table for " + contextId); //$NON-NLS-1$
- return;
}
table.removeBinding(binding);
}
@@ -201,4 +200,5 @@
}
contextSet = manager.createContextSet(contexts);
}
+
}
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 db071c1..d4491f3 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
@@ -86,7 +86,6 @@
};
private Context tableId;
-
private ArrayList<Binding> bindings = new ArrayList<Binding>();
private Map<TriggerSequence, Binding> bindingsByTrigger = new HashMap<TriggerSequence, Binding>();
private Map<ParameterizedCommand, ArrayList<Binding>> bindingsByCommand = new HashMap<ParameterizedCommand, ArrayList<Binding>>();
@@ -143,7 +142,10 @@
bindings.remove(binding);
bindingsByTrigger.remove(binding.getTriggerSequence());
ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand());
- sequences.remove(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]);
@@ -176,4 +178,8 @@
return bindingsByPrefix.get(seq) != null;
}
+ public Collection<Binding> getBindings() {
+ return Collections.unmodifiableCollection(bindings);
+ }
+
}
diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTableManager.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTableManager.java
index 951e834..d5e3b2e 100644
--- a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTableManager.java
+++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/internal/BindingTableManager.java
@@ -11,16 +11,16 @@
package org.eclipse.e4.ui.bindings.internal;
-import org.eclipse.e4.core.contexts.IEclipseContext;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import javax.inject.Inject;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.TriggerSequence;
@@ -31,6 +31,8 @@
@Inject
private IEclipseContext eclipseContext;
+ HashSet<String> definedTables = new HashSet<String>();
+
public void addTable(BindingTable table) {
String contextId = table.getId();
if (eclipseContext.containsKey(contextId)) {
@@ -38,6 +40,7 @@
// throw new IllegalArgumentException("Already contains table " + contextId); //$NON-NLS-1$
}
eclipseContext.set(contextId, table);
+ definedTables.add(contextId);
}
public void removeTable(BindingTable table) {
@@ -46,12 +49,26 @@
throw new IllegalArgumentException("Does not contains table " + contextId); //$NON-NLS-1$
}
eclipseContext.remove(contextId);
+ definedTables.remove(contextId);
}
public BindingTable getTable(String id) {
return (BindingTable) eclipseContext.get(id);
}
+ // we're just going through each binding table, and returning a
+ // flat list of bindings here
+ public Collection<Binding> getActiveBindings() {
+ ArrayList<Binding> bindings = new ArrayList<Binding>();
+ for (String id : definedTables) {
+ Object obj = eclipseContext.get(id);
+ if (obj instanceof BindingTable) {
+ bindings.addAll(((BindingTable) obj).getBindings());
+ }
+ }
+ return bindings;
+ }
+
public ContextSet createContextSet(Collection<Context> contexts) {
return new ContextSet(contexts);
}
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 820ab50..5259784 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,10 @@
package org.eclipse.e4.ui.workbench.swt.util;
+import org.eclipse.e4.ui.model.application.commands.MBindingContext;
+
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -26,6 +30,7 @@
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.bindings.EBindingService;
+import org.eclipse.e4.ui.bindings.internal.BindingCopies;
import org.eclipse.e4.ui.bindings.internal.BindingTable;
import org.eclipse.e4.ui.bindings.internal.BindingTableManager;
import org.eclipse.e4.ui.internal.workbench.Activator;
@@ -79,6 +84,7 @@
@PostConstruct
public void init() {
defineBindingTables();
+ cleanTables();
activateContexts(application);
registerModelListeners();
}
@@ -107,6 +113,71 @@
}
}
+ // goes through the entire active bindings list and replaces SYSTEM
+ // bindings with any USER bindings that were persisted
+ private void cleanTables() {
+ ArrayList<Binding> dirtyBindings = new ArrayList<Binding>();
+ Binding dirtyBinding;
+
+ Binding[] userBindings = BindingCopies.getUserDefinedBindings();
+ Binding curr;
+
+ // go through all USER bindings and check if there is an "equal" SYSTEM
+ // binding
+ for (int i = 0; i < userBindings.length; i++) {
+ curr = userBindings[i];
+
+ // they should all be USER bindings, but double check anyway
+ if (curr.getType() == Binding.USER) {
+ dirtyBinding = checkDirty(curr);
+
+ // if the SYSTEM binding is marked as dirty, then throw it in a
+ // list and we'll remove it later
+ if (dirtyBinding != null) {
+ dirtyBindings.add(dirtyBinding);
+ }
+ }
+ }
+
+ //System.out.println("@@@ dirty bindings -> " + dirtyBindings.size());
+
+ // go through the list of bindings that are marked as dirty (if any) and
+ // remove them from the BindingTableManager
+ for (int i = 0; i < dirtyBindings.size(); i++) {
+ dirtyBinding = dirtyBindings.get(i);
+ bindingTables.getTable(dirtyBinding.getContextId()).removeBinding(
+ dirtyBinding);
+ }
+ }
+
+ private Binding checkDirty(Binding b) {
+ Collection<Binding> activeBindings = bindingTables.getActiveBindings();
+ Iterator<Binding> iter = activeBindings.iterator();
+ Binding curr;
+ Binding dirtyBinding = null;
+
+ while (iter.hasNext() && dirtyBinding == null) {
+ curr = iter.next();
+
+ // make sure we're only comparing SYSTEM bindings so that we don't
+ // remove the wrong ones, and make sure the bindings we're comparing
+ // actually have a command
+ if (curr.getType() == Binding.SYSTEM
+ && curr.getParameterizedCommand() != null
+ && b.getParameterizedCommand() != null) {
+ if (curr.getContextId().equals(b.getContextId())
+ && curr.getParameterizedCommand().equals(
+ b.getParameterizedCommand())
+ && curr.getSchemeId().equals(b.getSchemeId())) {
+
+ // mark this binding as dirty, and it will be removed
+ dirtyBinding = curr;
+ }
+ }
+ }
+ return dirtyBinding;
+ }
+
private void defineBindingTables() {
Activator.trace(Policy.DEBUG_CMDS,
"Initialize binding tables from model", null); //$NON-NLS-1$
@@ -142,6 +213,7 @@
binding.getCommand(), binding.getParameters(),
binding.getKeySequence(), binding);
if (keyBinding != null) {
+ // if (keyBinding.getType() == Binding.USER)
bindingTable.addBinding(keyBinding);
}
}
@@ -168,11 +240,22 @@
System.err.println("Failed to handle binding: " + binding); //$NON-NLS-1$
} else {
try {
+ int bindingType = Binding.SYSTEM;
+
+ // go thru the copied list of USER defined bindings to see if
+ // this particular binding being created matches any of them
+ if (BindingCopies.isUserBinding(sequence, cmd,
+ "org.eclipse.ui.defaultAcceleratorConfiguration",
+ bindingContext.getId())) {
+ bindingType = Binding.USER;
+ }
+
+ // TODO: NEED TO CHANGE THIS!!!
keyBinding = bindingService
.createBinding(
sequence,
cmd,
- "org.eclipse.ui.defaultAcceleratorConfiguration", bindingContext.getId()); //$NON-NLS-1$
+ "org.eclipse.ui.defaultAcceleratorConfiguration", bindingContext.getId(), null, null, bindingType); //$NON-NLS-1$
} catch (IllegalArgumentException e) {
Activator.trace(Policy.DEBUG_MENUS,
"failed to create: " + binding, e); //$NON-NLS-1$
diff --git a/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/BindingLookupTest.java b/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/BindingLookupTest.java
index ecad5cf..633fba6 100644
--- a/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/BindingLookupTest.java
+++ b/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/BindingLookupTest.java
@@ -473,9 +473,8 @@
private Binding createDefaultBinding(EBindingService bs,
TriggerSequence sequence, ParameterizedCommand command,
String contextId) {
- return bs.createBinding(sequence, command,
- "org.eclipse.ui.defaultAcceleratorConfiguration", //$NON-NLS-1$
- contextId);
+ return bs.createBinding(sequence, command, "org.eclipse.ui.defaultAcceleratorConfiguration",
+ contextId, null, null, Binding.SYSTEM);
}
}
diff --git a/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/KeyDispatcherTest.java b/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/KeyDispatcherTest.java
index 2dd2422..65d9279 100644
--- a/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/KeyDispatcherTest.java
+++ b/tests/org.eclipse.e4.ui.bindings.tests/src/org/eclipse/e4/ui/bindings/tests/KeyDispatcherTest.java
@@ -98,9 +98,7 @@
private Binding createDefaultBinding(EBindingService bs,
TriggerSequence sequence, ParameterizedCommand command) {
- return bs.createBinding(sequence, command,
- "org.eclipse.ui.defaultAcceleratorConfiguration", //$NON-NLS-1$
- ID_WINDOW);
+ return bs.createBinding(sequence, command, "org.eclipse.ui.defaultAcceleratorConfiguration", ID_WINDOW, null, null, Binding.SYSTEM);
}
@Override