Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Schindl2013-04-17 21:48:21 +0000
committerTom Schindl2013-04-17 21:48:21 +0000
commit7532784c9261b274db2720cb165b9457dc7891a3 (patch)
tree251f649fe1d4c33a80823953e996c59320e8a798
parent13eeec7ef2ef84813824bb20036d89e3dc3cbf0c (diff)
downloadorg.eclipse.efxclipse-7532784c9261b274db2720cb165b9457dc7891a3.tar.gz
org.eclipse.efxclipse-7532784c9261b274db2720cb165b9457dc7891a3.tar.xz
org.eclipse.efxclipse-7532784c9261b274db2720cb165b9457dc7891a3.zip
initial check in
-rw-r--r--bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.DS_Storebin0 -> 6148 bytes
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.classpath7
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.gitignore2
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.project28
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.resources.prefs2
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.runtime.prefs2
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.jdt.core.prefs7
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/IP-TODO.txt1
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/META-INF/MANIFEST.MF20
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/build.properties4
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/pom.xml34
-rw-r--r--bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/.DS_Storebin0 -> 6148 bytes
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingProcessingAddon.java414
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingServiceAddon.java40
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/EBindingService.java60
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceCreationFunction.java36
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceImpl.java263
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTable.java291
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTableManager.java270
-rwxr-xr-xbundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/ContextSet.java108
-rwxr-xr-xreleng/org.eclipse.fx.releng/pom.xml1
21 files changed, 1590 insertions, 0 deletions
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.DS_Store b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.DS_Store
new file mode 100644
index 000000000..9a874b576
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.DS_Store
Binary files differ
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.classpath b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.classpath
new file mode 100755
index 000000000..b1dabee38
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.gitignore b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.gitignore
new file mode 100755
index 000000000..4dc009173
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.project b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.project
new file mode 100755
index 000000000..716dff67e
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.ui.keybindings.e4</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.resources.prefs b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.resources.prefs
new file mode 100755
index 000000000..99f26c020
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.runtime.prefs b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.runtime.prefs
new file mode 100755
index 000000000..deae05a97
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\r\n
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.jdt.core.prefs b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 000000000..f42de363a
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/IP-TODO.txt b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/IP-TODO.txt
new file mode 100755
index 000000000..42b873032
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/IP-TODO.txt
@@ -0,0 +1 @@
+API extracted/ported/copied from from JFace & e4 \ No newline at end of file
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/META-INF/MANIFEST.MF b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/META-INF/MANIFEST.MF
new file mode 100755
index 000000000..cecfbda9c
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: E4
+Bundle-SymbolicName: org.eclipse.fx.ui.keybindings.e4
+Bundle-Version: 0.8.1.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.eclipse.fx.ui.keybindings;bundle-version="0.8.1",
+ org.eclipse.e4.core.contexts;bundle-version="1.1.0",
+ org.eclipse.e4.core.di;bundle-version="1.1.0",
+ org.eclipse.core.commands;bundle-version="3.6.0",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.10.1",
+ org.eclipse.osgi.services;bundle-version="3.3.0",
+ org.eclipse.e4.core.commands;bundle-version="0.10.1",
+ org.eclipse.e4.core.services;bundle-version="1.0.0",
+ org.eclipse.e4.ui.services;bundle-version="0.10.1",
+ org.eclipse.e4.ui.workbench;bundle-version="0.10.2",
+ org.eclipse.fx.core;bundle-version="0.8.1"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0"
+Export-Package: org.eclipse.fx.ui.keybindings.e4
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/build.properties b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/build.properties
new file mode 100755
index 000000000..34d2e4d2d
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/pom.xml b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/pom.xml
new file mode 100755
index 000000000..b9a2528cc
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/pom.xml
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <name>e(fx)clipse - Runtime - e4 - e4 keybinding system</name>
+ <groupId>org.eclipse.fx</groupId>
+ <artifactId>org.eclipse.fx.ui.keybindings.e4</artifactId>
+ <packaging>eclipse-plugin</packaging>
+
+ <parent>
+ <groupId>org.eclipse.fx</groupId>
+ <artifactId>releng</artifactId>
+ <relativePath>../../../releng/org.eclipse.fx.releng/pom.xml</relativePath>
+ <version>0.8.1-SNAPSHOT</version>
+ </parent>
+
+ <build>
+ <resources>
+ <!-- to ensure that the feature lookup of the ui test works -->
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>META-INF/</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/.DS_Store b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/.DS_Store
new file mode 100644
index 000000000..5df2016a4
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/.DS_Store
Binary files differ
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingProcessingAddon.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingProcessingAddon.java
new file mode 100755
index 000000000..c8efd6f0b
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingProcessingAddon.java
@@ -0,0 +1,414 @@
+/*******************************************************************************
+ * Copyright (c) 2012 BestSolution.at 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:
+ * Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.ui.keybindings.e4;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MBindingContext;
+import org.eclipse.e4.ui.model.application.commands.MBindingTable;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MKeyBinding;
+import org.eclipse.e4.ui.model.application.commands.MParameter;
+import org.eclipse.e4.ui.model.application.ui.MContext;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
+import org.eclipse.e4.ui.services.EContextService;
+import org.eclipse.e4.ui.workbench.UIEvents;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.fx.core.log.Log;
+import org.eclipse.fx.core.log.Logger;
+import org.eclipse.fx.ui.keybindings.Binding;
+import org.eclipse.fx.ui.keybindings.TriggerSequence;
+import org.eclipse.fx.ui.keybindings.e4.internal.BindingTable;
+import org.eclipse.fx.ui.keybindings.e4.internal.BindingTableManager;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/**
+ * Process contexts in the model, feeding them into the command service.
+ */
+@SuppressWarnings("restriction")
+public class BindingProcessingAddon {
+
+ @Inject
+ private MApplication application;
+
+ @Inject
+ private IEventBroker broker;
+
+ @Inject
+ private ContextManager contextManager;
+
+ @Inject
+ private BindingTableManager bindingTables;
+
+ @Inject
+ private ECommandService commandService;
+
+ @Inject
+ private EBindingService bindingService;
+
+ @Inject
+ @Log
+ private Logger logger;
+
+ private EventHandler additionHandler;
+
+ private EventHandler contextHandler;
+
+ @PostConstruct
+ public void init() {
+ defineBindingTables();
+ activateContexts(application);
+ registerModelListeners();
+ }
+
+ private void activateContexts(Object me) {
+ if (me instanceof MBindings) {
+ MContext contextModel = (MContext) me;
+ MBindings container = (MBindings) me;
+ List<MBindingContext> bindingContexts = container
+ .getBindingContexts();
+ IEclipseContext context = contextModel.getContext();
+ if (context != null && !bindingContexts.isEmpty()) {
+ EContextService cs = context.get(EContextService.class);
+ for (MBindingContext element : bindingContexts) {
+ cs.activateContext(element.getElementId());
+ }
+ }
+ }
+ if (me instanceof MElementContainer) {
+ List<MUIElement> children = ((MElementContainer) me).getChildren();
+ Iterator<MUIElement> i = children.iterator();
+ while (i.hasNext()) {
+ MUIElement e = i.next();
+ activateContexts(e);
+ }
+ }
+ }
+
+ private void defineBindingTables() {
+ for (MBindingTable bindingTable : application.getBindingTables()) {
+ defineBindingTable(bindingTable);
+ }
+ }
+
+ /**
+ * @param bindingTable
+ */
+ private void defineBindingTable(MBindingTable bindingTable) {
+ final Context bindingContext = contextManager.getContext(bindingTable
+ .getBindingContext().getElementId());
+ BindingTable table = bindingTables.getTable(bindingTable
+ .getBindingContext().getElementId());
+ if (table == null) {
+ table = new BindingTable(bindingContext);
+ bindingTables.addTable(table);
+ }
+ for (MKeyBinding binding : bindingTable.getBindings()) {
+ defineBinding(table, bindingContext, binding);
+ }
+ }
+
+ /**
+ * @param bindingTable
+ * @param binding
+ */
+ private void defineBinding(BindingTable bindingTable,
+ Context bindingContext, MKeyBinding binding) {
+ Binding keyBinding = createBinding(bindingContext,
+ binding.getCommand(), binding.getParameters(),
+ binding.getKeySequence(), binding);
+ if (keyBinding != null
+ && !binding.getTags().contains(
+ EBindingService.DELETED_BINDING_TAG)) {
+ bindingTable.addBinding(keyBinding);
+ }
+ }
+
+ private Binding createBinding(Context bindingContext, MCommand cmdModel,
+ List<MParameter> modelParms, String keySequence, MKeyBinding binding) {
+ Binding keyBinding = null;
+
+ if (binding.getTransientData()
+ .get(EBindingService.MODEL_TO_BINDING_KEY) != null) {
+ try {
+ keyBinding = (Binding) binding.getTransientData().get(
+ EBindingService.MODEL_TO_BINDING_KEY);
+ return keyBinding;
+ } catch (ClassCastException cce) {
+ System.err
+ .println("Invalid type stored in transient data with the key "
+ + EBindingService.MODEL_TO_BINDING_KEY);
+ return null;
+ }
+ }
+
+ if (cmdModel == null) {
+ return null;
+ }
+ Map<String, Object> parameters = null;
+ if (modelParms != null && !modelParms.isEmpty()) {
+ parameters = new HashMap<String, Object>();
+ for (MParameter mParm : modelParms) {
+ parameters.put(mParm.getName(), mParm.getValue());
+ }
+ }
+ ParameterizedCommand cmd = commandService.createCommand(
+ cmdModel.getElementId(), parameters);
+ TriggerSequence sequence = null;
+ sequence = bindingService.createSequence(keySequence);
+
+ if (cmd == null) {
+ logger.error("Failed to find command for binding: " + binding); //$NON-NLS-1$
+ } else if (sequence == null) {
+ logger.error("Failed to map binding: " + binding); //$NON-NLS-1$
+ } else {
+ try {
+ String schemeId = null;
+ String locale = null;
+ String platform = null;
+
+ Map<String, String> attrs = new HashMap<String, String>();
+ List<String> tags = binding.getTags();
+ for (String tag : tags) {
+ // remember to skip the ':' in each tag!
+ if (tag.startsWith(EBindingService.SCHEME_ID_ATTR_TAG)) {
+ schemeId = tag.substring(9);
+ attrs.put(EBindingService.SCHEME_ID_ATTR_TAG, schemeId);
+ } else if (tag.startsWith(EBindingService.LOCALE_ATTR_TAG)) {
+ locale = tag.substring(7);
+ attrs.put(EBindingService.LOCALE_ATTR_TAG, locale);
+ } else if (tag
+ .startsWith(EBindingService.PLATFORM_ATTR_TAG)) {
+ platform = tag.substring(9);
+ attrs.put(EBindingService.PLATFORM_ATTR_TAG, platform);
+ } else if (tag.startsWith(EBindingService.TYPE_ATTR_TAG)) {
+ // system bindings won't pass this attr
+ attrs.put(EBindingService.TYPE_ATTR_TAG, "user");
+ }
+ }
+ keyBinding = bindingService.createBinding(sequence, cmd,
+ bindingContext.getId(), attrs);
+ } catch (IllegalArgumentException e) {
+ logger.error("failed to create: " + binding, e); //$NON-NLS-1$
+ return null;
+ }
+
+ }
+ return keyBinding;
+ }
+
+ private void updateBinding(MKeyBinding binding, boolean add, Object eObj) {
+ Object parentObj = ((EObject) binding).eContainer();
+ if (!(parentObj instanceof MBindingTable)) {
+ // the link will already be broken for removes, so we'll try this
+ if (eObj instanceof MBindingTable) {
+ parentObj = eObj;
+ }
+ }
+
+ if (parentObj == null) {
+ return;
+ }
+
+ MBindingTable bt = (MBindingTable) parentObj;
+ final Context bindingContext = contextManager.getContext(bt
+ .getBindingContext().getElementId());
+ BindingTable table = bindingTables.getTable(bindingContext.getId());
+ if (table == null) {
+ logger.error("Trying to create \'" + binding //$NON-NLS-1$
+ + "\' without binding table " + bindingContext.getId());//$NON-NLS-1$
+ return;
+ }
+ Binding keyBinding = createBinding(bindingContext,
+ binding.getCommand(), binding.getParameters(),
+ binding.getKeySequence(), binding);
+ if (keyBinding != null) {
+ if (add) {
+ table.addBinding(keyBinding);
+ } else {
+ table.removeBinding(keyBinding);
+ }
+ }
+ }
+
+ @PreDestroy
+ public void dispose() {
+ unregsiterModelListeners();
+ }
+
+ private void registerModelListeners() {
+ additionHandler = new EventHandler() {
+ public void handleEvent(Event event) {
+ Object elementObj = event
+ .getProperty(UIEvents.EventTags.ELEMENT);
+ if (elementObj instanceof MApplication) {
+ Object newObj = event
+ .getProperty(UIEvents.EventTags.NEW_VALUE);
+ if (UIEvents.EventTypes.ADD.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))
+ && newObj instanceof MBindingTable) {
+ MBindingTable bt = (MBindingTable) newObj;
+ final Context bindingContext = contextManager
+ .getContext(bt.getBindingContext()
+ .getElementId());
+ final BindingTable table = new BindingTable(
+ bindingContext);
+ bindingTables.addTable(table);
+ List<MKeyBinding> bindings = bt.getBindings();
+ for (MKeyBinding binding : bindings) {
+ Binding keyBinding = createBinding(bindingContext,
+ binding.getCommand(),
+ binding.getParameters(),
+ binding.getKeySequence(), binding);
+ if (keyBinding != null) {
+ table.addBinding(keyBinding);
+ }
+ }
+ }
+ } else if (elementObj instanceof MBindingTable) {
+ Object newObj = event
+ .getProperty(UIEvents.EventTags.NEW_VALUE);
+ Object oldObj = event
+ .getProperty(UIEvents.EventTags.OLD_VALUE);
+
+ // adding a binding
+ if (UIEvents.EventTypes.ADD.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))
+ && newObj instanceof MKeyBinding) {
+
+ MKeyBinding binding = (MKeyBinding) newObj;
+ updateBinding(binding, true, elementObj);
+ }
+ // removing a binding
+ else if (UIEvents.EventTypes.REMOVE.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))
+ && oldObj instanceof MKeyBinding) {
+
+ MKeyBinding binding = (MKeyBinding) oldObj;
+ updateBinding(binding, false, elementObj);
+ }
+ } else if (elementObj instanceof MKeyBinding) {
+ MKeyBinding binding = (MKeyBinding) elementObj;
+
+ String attrName = (String) event
+ .getProperty(UIEvents.EventTags.ATTNAME);
+
+ if (UIEvents.EventTypes.SET.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))) {
+ Object oldObj = event
+ .getProperty(UIEvents.EventTags.OLD_VALUE);
+ if (UIEvents.KeyBinding.COMMAND.equals(attrName)) {
+ MKeyBinding oldBinding = (MKeyBinding) EcoreUtil
+ .copy((EObject) binding);
+ oldBinding.setCommand((MCommand) oldObj);
+ updateBinding(oldBinding, false,
+ ((EObject) binding).eContainer());
+ updateBinding(binding, true, null);
+ } else if (UIEvents.KeySequence.KEYSEQUENCE
+ .equals(attrName)) {
+ MKeyBinding oldBinding = (MKeyBinding) EcoreUtil
+ .copy((EObject) binding);
+ oldBinding.setKeySequence((String) oldObj);
+ updateBinding(oldBinding, false,
+ ((EObject) binding).eContainer());
+ updateBinding(binding, true, null);
+ }
+ } else if (UIEvents.KeyBinding.PARAMETERS.equals(attrName)) {
+ if (UIEvents.EventTypes.ADD.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))) {
+ Object newObj = event
+ .getProperty(UIEvents.EventTags.NEW_VALUE);
+ MKeyBinding oldBinding = (MKeyBinding) EcoreUtil
+ .copy((EObject) binding);
+ oldBinding.getParameters().remove(newObj);
+ updateBinding(oldBinding, false,
+ ((EObject) binding).eContainer());
+ updateBinding(binding, true, null);
+ } else if (UIEvents.EventTypes.REMOVE.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))) {
+ Object oldObj = event
+ .getProperty(UIEvents.EventTags.OLD_VALUE);
+ MKeyBinding oldBinding = (MKeyBinding) EcoreUtil
+ .copy((EObject) binding);
+ oldBinding.getParameters().add((MParameter) oldObj);
+ updateBinding(oldBinding, false,
+ ((EObject) binding).eContainer());
+ updateBinding(binding, true, null);
+ }
+ }
+ // if we've updated the tags for an MKeyBinding
+ else if (UIEvents.ApplicationElement.TAGS.equals(attrName)) {
+ List<String> tags = binding.getTags();
+ // if we added a deleted tag to the MKeyBinding, then
+ // remove it from the runtime binding tables
+ if (tags.contains(EBindingService.DELETED_BINDING_TAG)) {
+ updateBinding(binding, false, elementObj);
+ }
+ // else we're adding the binding to the runtime tables
+ else {
+ updateBinding(binding, true, elementObj);
+ }
+ }
+ }
+ }
+ };
+ broker.subscribe(UIEvents.BindingTableContainer.TOPIC_BINDINGTABLES,
+ additionHandler);
+ broker.subscribe(UIEvents.BindingTable.TOPIC_BINDINGS, additionHandler);
+ broker.subscribe(UIEvents.KeyBinding.TOPIC_COMMAND, additionHandler);
+ broker.subscribe(UIEvents.KeyBinding.TOPIC_PARAMETERS, additionHandler);
+ broker.subscribe(UIEvents.KeySequence.TOPIC_KEYSEQUENCE,
+ additionHandler);
+ broker.subscribe(UIEvents.ApplicationElement.TOPIC_TAGS,
+ additionHandler);
+
+ contextHandler = new EventHandler() {
+ public void handleEvent(Event event) {
+ Object elementObj = event
+ .getProperty(UIEvents.EventTags.ELEMENT);
+ Object newObj = event.getProperty(UIEvents.EventTags.NEW_VALUE);
+ if (UIEvents.EventTypes.SET.equals(event
+ .getProperty(UIEvents.EventTags.TYPE))
+ && newObj instanceof IEclipseContext) {
+ activateContexts(elementObj);
+ }
+ }
+ };
+ broker.subscribe(UIEvents.Context.TOPIC_CONTEXT, contextHandler);
+ }
+
+ private void unregsiterModelListeners() {
+ broker.unsubscribe(additionHandler);
+ broker.unsubscribe(additionHandler);
+ broker.unsubscribe(additionHandler);
+ broker.unsubscribe(additionHandler);
+ broker.unsubscribe(additionHandler);
+ broker.unsubscribe(contextHandler);
+ }
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingServiceAddon.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingServiceAddon.java
new file mode 100755
index 000000000..0822ed20f
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/BindingServiceAddon.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.fx.ui.keybindings.e4;
+
+import javax.annotation.PostConstruct;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.fx.ui.keybindings.e4.internal.BindingServiceCreationFunction;
+import org.eclipse.fx.ui.keybindings.e4.internal.BindingTableManager;
+import org.eclipse.fx.ui.keybindings.e4.internal.ContextSet;
+
+
+
+/**
+ * Provide the binding and context id services as an add-on. Must be instantiated against the
+ * application level context.
+ */
+@SuppressWarnings("restriction")
+public class BindingServiceAddon {
+ @PostConstruct
+ public void init(IEclipseContext context) {
+ ContextManager contextManager = context.get(ContextManager.class);
+ ContextSet.setComparator(new ContextSet.CComp(contextManager));
+
+ context.set(BindingTableManager.class,
+ ContextInjectionFactory.make(BindingTableManager.class, context));
+
+ context.set(EBindingService.class.getName(), new BindingServiceCreationFunction());
+ }
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/EBindingService.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/EBindingService.java
new file mode 100755
index 000000000..380ce3f57
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/EBindingService.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.fx.ui.keybindings.e4;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.fx.ui.keybindings.Binding;
+import org.eclipse.fx.ui.keybindings.TriggerSequence;
+
+public interface EBindingService {
+
+ public static final String DIALOG_CONTEXT_ID = "org.eclipse.ui.contexts.dialog"; //$NON-NLS-1$
+ public static final String DEFAULT_SCHEME_ID = "org.eclipse.ui.defaultAcceleratorConfiguration"; //$NON-NLS-1$
+ public static final String MODEL_TO_BINDING_KEY = "binding"; //$NON-NLS-1$
+ public static final String ACTIVE_SCHEME_TAG = "activeSchemeId"; //$NON-NLS-1$
+ public static final String SCHEME_ID_ATTR_TAG = "schemeId"; //$NON-NLS-1$
+ public static final String LOCALE_ATTR_TAG = "locale"; //$NON-NLS-1$
+ public static final String PLATFORM_ATTR_TAG = "platform"; //$NON-NLS-1$
+ public static final String TYPE_ATTR_TAG = "type"; //$NON-NLS-1$
+ public static final String DELETED_BINDING_TAG = "deleted"; //$NON-NLS-1$
+
+ Binding createBinding(TriggerSequence sequence, ParameterizedCommand command, String contextId,
+ Map<String, String> attributes);
+
+ void activateBinding(Binding binding);
+
+ void deactivateBinding(Binding binding);
+
+ TriggerSequence createSequence(String sequence);
+
+ Collection<Binding> getConflictsFor(TriggerSequence sequence);
+
+ Collection<Binding> getAllConflicts();
+
+ Binding getPerfectMatch(TriggerSequence trigger);
+
+ boolean isPartialMatch(TriggerSequence keySequence);
+
+ boolean isPerfectMatch(TriggerSequence sequence);
+
+ TriggerSequence getBestSequenceFor(ParameterizedCommand command);
+
+ Collection<TriggerSequence> getSequencesFor(ParameterizedCommand command);
+
+ Collection<Binding> getPartialMatches(TriggerSequence sequence);
+
+ Collection<Binding> getActiveBindings();
+
+ Collection<Binding> getBindingsFor(ParameterizedCommand cmd);
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceCreationFunction.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceCreationFunction.java
new file mode 100755
index 000000000..4eec74f6b
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceCreationFunction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.fx.ui.keybindings.e4.internal;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+
+/**
+ *
+ */
+@SuppressWarnings("restriction")
+public class BindingServiceCreationFunction extends ContextFunction {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.core.services.context.spi.ContextFunction#compute(org.eclipse.e4.core.services
+ * .context.IEclipseContext, java.lang.Object[])
+ */
+ @Override
+ public Object compute(IEclipseContext context) {
+ return ContextInjectionFactory.make(BindingServiceImpl.class, context);
+ }
+
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceImpl.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceImpl.java
new file mode 100755
index 000000000..7fa82f525
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingServiceImpl.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.fx.ui.keybindings.e4.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.fx.ui.keybindings.Binding;
+import org.eclipse.fx.ui.keybindings.KeyLookup;
+import org.eclipse.fx.ui.keybindings.ParseException;
+import org.eclipse.fx.ui.keybindings.TriggerSequence;
+import org.eclipse.fx.ui.keybindings.e4.EBindingService;
+import org.eclipse.fx.ui.keybindings.service.BindingFactory;
+
+/**
+ *
+ */
+@SuppressWarnings("restriction")
+public class BindingServiceImpl implements EBindingService {
+
+ final static String ACTIVE_CONTEXTS = "activeContexts"; //$NON-NLS-1$
+ final static String USER_TYPE = "user"; //$NON-NLS-1$
+
+ @Inject
+ private IEclipseContext context;
+
+ @Inject
+ private BindingTableManager manager;
+
+ @Inject
+ private ContextManager contextManager;
+
+ @Inject
+ private KeyLookup keylookup;
+
+ @Inject
+ private BindingFactory factory;
+
+ private ContextSet contextSet = ContextSet.EMPTY;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.bindings.EBindingService#createBinding(org.eclipse.
+ * jface.bindings. TriggerSequence,
+ * org.eclipse.core.commands.ParameterizedCommand, java.lang.String,
+ * java.lang.String, java.util.Map)
+ */
+ public Binding createBinding(TriggerSequence sequence,
+ ParameterizedCommand command, String contextId,
+ Map<String, String> attributes) {
+
+ String schemeId = DEFAULT_SCHEME_ID;
+ // String locale = null;
+ // String platform = null;
+ // int bindingType = Binding.SYSTEM;
+
+ if (sequence != null && !sequence.isEmpty() && contextId != null) {
+ if (attributes != null) {
+ String tmp = attributes.get(SCHEME_ID_ATTR_TAG);
+ if (tmp != null && tmp.length() > 0) {
+ schemeId = tmp;
+ }
+ // locale = attributes.get(LOCALE_ATTR_TAG);
+ // platform = attributes.get(PLATFORM_ATTR_TAG);
+ // if (USER_TYPE.equals(attributes.get(TYPE_ATTR_TAG))) {
+ // bindingType = Binding.USER;
+ // }
+ }
+ return factory.createKeyBinding(sequence, command, schemeId,
+ contextId);
+ // return factory.createKeyBinding((EKeySequence) sequence, command,
+ // schemeId, contextId, locale,
+ // platform, null, bindingType);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.bindings.EBindingService#activateBinding(org.eclipse
+ * .jface.bindings.Binding )
+ */
+ public void activateBinding(Binding binding) {
+ String contextId = binding.getContextId();
+ BindingTable table = manager.getTable(contextId);
+ if (table == null) {
+ return;
+ }
+ table.addBinding(binding);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.bindings.EBindingService#deactivateBinding(org.eclipse
+ * .jface.bindings.Binding )
+ */
+ public void deactivateBinding(Binding binding) {
+ String contextId = binding.getContextId();
+ BindingTable table = manager.getTable(contextId);
+ if (table == null) {
+ return;
+ }
+ table.removeBinding(binding);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.bindings.EBindingService#createSequence(java.lang.String
+ * )
+ */
+ public TriggerSequence createSequence(String sequence) {
+ try {
+ return factory.getKeySequenceInstance(keylookup, sequence);
+ } catch (ParseException e) {
+ // should probably log
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#getConflictsFor(org.eclipse
+ * .e4.ui.bindings. TriggerSequence)
+ */
+ public Collection<Binding> getConflictsFor(TriggerSequence sequence) {
+ return manager.getConflictsFor(contextSet, sequence);
+ }
+
+ public Collection<Binding> getAllConflicts() {
+ return manager.getAllConflicts();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#getPerfectMatch(org.eclipse
+ * .e4.ui.bindings. TriggerSequence)
+ */
+ public Binding getPerfectMatch(TriggerSequence trigger) {
+ return manager.getPerfectMatch(contextSet, trigger);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#isPartialMatch(org.eclipse.
+ * e4.ui.bindings. TriggerSequence)
+ */
+ public boolean isPartialMatch(TriggerSequence keySequence) {
+ return manager.isPartialMatch(contextSet, keySequence);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#getBestSequenceFor(org.eclipse
+ * .core.commands. ParameterizedCommand)
+ */
+ public TriggerSequence getBestSequenceFor(ParameterizedCommand command) {
+ Binding binding = manager.getBestSequenceFor(contextSet, command);
+ return binding == null ? null : binding.getTriggerSequence();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#getSequencesFor(org.eclipse
+ * .core.commands. ParameterizedCommand)
+ */
+ public Collection<TriggerSequence> getSequencesFor(
+ ParameterizedCommand command) {
+ Collection<Binding> bindings = manager.getSequencesFor(contextSet,
+ command);
+ ArrayList<TriggerSequence> sequences = new ArrayList<TriggerSequence>(
+ bindings.size());
+ for (Binding binding : bindings) {
+ sequences.add(binding.getTriggerSequence());
+ }
+ return sequences;
+ }
+
+ public Collection<Binding> getBindingsFor(ParameterizedCommand command) {
+ return manager.getBindingsFor(contextSet, command);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#isPerfectMatch(org.eclipse.
+ * e4.ui.bindings. TriggerSequence)
+ */
+ public boolean isPerfectMatch(TriggerSequence sequence) {
+ return getPerfectMatch(sequence) != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.ui.bindings.EBindingService#getPartialMatches(org.eclipse
+ * .e4.ui.bindings. TriggerSequence)
+ */
+ public Collection<Binding> getPartialMatches(TriggerSequence sequence) {
+ return manager.getPartialMatches(contextSet, sequence);
+ }
+
+ /**
+ * @return the context for this service.
+ */
+ public IEclipseContext getContext() {
+ return context;
+ }
+
+ @Inject
+ public void setContextIds(@Named(ACTIVE_CONTEXTS) @Optional Set<String> set) {
+ if (set == null || set.isEmpty() || contextManager == null) {
+ contextSet = ContextSet.EMPTY;
+ if (contextManager != null) {
+ contextManager.setActiveContextIds(Collections.EMPTY_SET);
+ }
+ return;
+ }
+ ArrayList<Context> contexts = new ArrayList<Context>();
+ for (String id : set) {
+ contexts.add(contextManager.getContext(id));
+ }
+ contextSet = manager.createContextSet(contexts);
+ contextManager.setActiveContextIds(set);
+ }
+
+ public Collection<Binding> getActiveBindings() {
+ return manager.getActiveBindings();
+ }
+
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTable.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTable.java
new file mode 100755
index 000000000..35081483b
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTable.java
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.fx.ui.keybindings.e4.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.fx.ui.keybindings.Binding;
+import org.eclipse.fx.ui.keybindings.KeyStroke;
+import org.eclipse.fx.ui.keybindings.Trigger;
+import org.eclipse.fx.ui.keybindings.TriggerSequence;
+
+/**
+ * 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;
+ }
+ }
+ }
+ return 0;
+ }
+
+ public void setActiveSchemes(String[] activeSchemeIds) {
+ this.activeSchemeIds = activeSchemeIds;
+ }
+
+ public int compare(Binding o1, Binding o2) {
+ int rc = compareSchemes(o1.getSchemeId(), o2.getSchemeId());
+ if (rc != 0) {
+ return rc;
+ }
+
+ /*
+ * Check to see which has the least number of triggers in the trigger sequence.
+ */
+ final Trigger[] bestTriggers = o1.getTriggerSequence().getTriggers();
+ final Trigger[] currentTriggers = o2.getTriggerSequence().getTriggers();
+ int compareTo = bestTriggers.length - currentTriggers.length;
+ if (compareTo != 0) {
+ return compareTo;
+ }
+
+ /*
+ * 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) {
+ return compareTo;
+ }
+
+ // If this is still a tie, then just chose the shortest text.
+ return o1.getTriggerSequence().format().length()
+ - o2.getTriggerSequence().format().length();
+ }
+
+ private final int countStrokes(final Trigger[] triggers) {
+ int strokeCount = triggers.length;
+ for (int i = 0; i < triggers.length; i++) {
+ final Trigger trigger = triggers[i];
+ if (trigger instanceof KeyStroke) {
+ final KeyStroke keyStroke = (KeyStroke) trigger;
+ if( keyStroke.hasAltModifier() ) {
+ strokeCount += 8;
+ }
+ if( keyStroke.hasCtrlModifier() ) {
+ strokeCount += 2;
+ }
+ if( keyStroke.hasShiftModifier() ) {
+ strokeCount += 4;
+ }
+ if( keyStroke.hasCommandModifier() ) {
+ strokeCount += 2;
+ }
+
+
+// final int modifierKeys = keyStroke.getModifierKeys();
+// final IKeyLookup lookup = KeyLookupFactory.getDefault();
+// if ((modifierKeys & lookup.getAlt()) != 0) {
+// strokeCount += 8;
+// }
+// if ((modifierKeys & lookup.getCtrl()) != 0) {
+// strokeCount += 2;
+// }
+// if ((modifierKeys & lookup.getShift()) != 0) {
+// strokeCount += 4;
+// }
+// if ((modifierKeys & lookup.getCommand()) != 0) {
+// strokeCount += 2;
+// }
+ } else {
+ strokeCount += 99;
+ }
+ }
+
+ return strokeCount;
+ }
+ }
+
+ public static final BindingComparator BEST_SEQUENCE = new BindingComparator();
+
+ 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>>();
+ private Map<TriggerSequence, ArrayList<Binding>> bindingsByPrefix = new HashMap<TriggerSequence, ArrayList<Binding>>();
+ private Map<TriggerSequence, ArrayList<Binding>> conflicts = new HashMap<TriggerSequence, ArrayList<Binding>>();
+
+ /**
+ * @param context
+ */
+ public BindingTable(Context context) {
+ tableId = context;
+ }
+
+ public Context getTableId() {
+ return tableId;
+ }
+
+ public String getId() {
+ return tableId.getId();
+ }
+
+ public Collection<Binding> getConflicts() {
+ Collection<Binding> conflictsList = new ArrayList<Binding>();
+ for (TriggerSequence key : conflicts.keySet()) {
+ ArrayList<Binding> conflictsForTrigger = conflicts.get(key);
+ if (conflictsForTrigger != null) {
+ conflictsList.addAll(conflictsForTrigger);
+ }
+ }
+ return conflictsList;
+ }
+
+ // checks both the active bindings and conflicts list
+ public Collection<Binding> getConflictsFor(TriggerSequence triggerSequence) {
+ return conflicts.get(triggerSequence);
+ }
+
+ public void addBinding(Binding binding) {
+ if (!getId().equals(binding.getContextId())) {
+ throw new IllegalArgumentException("Binding context " + binding.getContextId() //$NON-NLS-1$
+ + " does not match " + getId()); //$NON-NLS-1$
+ }
+
+ 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;
+ }
+ // 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);
+ }
+ isConflict = true;
+ }
+
+ // if there are no conflicts, then add to the table
+ if (!isConflict) {
+ 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);
+ }
+ 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);
+ }
+ }
+ }
+
+ public void removeBinding(Binding binding) {
+ if (!getId().equals(binding.getContextId())) {
+ 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);
+ }
+
+ } else {
+ bindings.remove(binding);
+ bindingsByTrigger.remove(binding.getTriggerSequence());
+ ArrayList<Binding> sequences = bindingsByCommand.get(binding.getParameterizedCommand());
+
+ 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]);
+ bindings.remove(binding);
+ }
+ }
+ }
+
+ public Binding getPerfectMatch(TriggerSequence trigger) {
+ return bindingsByTrigger.get(trigger);
+ }
+
+ public Binding getBestSequenceFor(ParameterizedCommand command) {
+ ArrayList<Binding> sequences = bindingsByCommand.get(command);
+ if (sequences != null && sequences.size() > 0) {
+ return sequences.get(0);
+ }
+ return null;
+ }
+
+ public Collection<Binding> getSequencesFor(ParameterizedCommand command) {
+ ArrayList<Binding> triggers = bindingsByCommand.get(command);
+ return (Collection<Binding>) (triggers == null ? Collections.EMPTY_LIST : triggers.clone());
+ }
+
+ public Collection<Binding> getPartialMatches(TriggerSequence sequence) {
+ return bindingsByPrefix.get(sequence);
+ }
+
+ public boolean isPartialMatch(TriggerSequence seq) {
+ return bindingsByPrefix.get(seq) != null;
+ }
+
+ public Collection<Binding> getBindings() {
+ return Collections.unmodifiableCollection(bindings);
+ }
+
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTableManager.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTableManager.java
new file mode 100755
index 000000000..809ee61f3
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/BindingTableManager.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.fx.ui.keybindings.e4.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+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.fx.ui.keybindings.Binding;
+import org.eclipse.fx.ui.keybindings.TriggerSequence;
+
+
+/**
+ * manage tables of bindings that can be used to look up commands from keys.
+ */
+@SuppressWarnings("restriction")
+public class BindingTableManager {
+ private static final String BINDING_TABLE_PREFIX = "bindingTable:"; //$NON-NLS-1$
+
+ @Inject
+ private IEclipseContext eclipseContext;
+
+ private ContextSet definedTables = ContextSet.EMPTY;
+
+ private String[] activeSchemeIds;
+
+ public void addTable(BindingTable table) {
+ String contextId = getTableId(table.getId());
+ if (eclipseContext.containsKey(contextId)) {
+ return; // it's already there
+ // throw new IllegalArgumentException("Already contains table " + contextId); //$NON-NLS-1$
+ }
+ eclipseContext.set(contextId, table);
+ final List<Context> contexts = definedTables.getContexts();
+ if (!contexts.contains(table.getTableId())) {
+ // this is only valid because I'm throwing away the old definedTables contextSet
+ contexts.add(table.getTableId());
+ definedTables = createContextSet(contexts);
+ }
+ }
+
+ private String getTableId(String id) {
+ return BINDING_TABLE_PREFIX + id;
+ }
+
+ public void removeTable(BindingTable table) {
+ String contextId = getTableId(table.getId());
+ if (!eclipseContext.containsKey(contextId)) {
+ throw new IllegalArgumentException("Does not contains table " + contextId); //$NON-NLS-1$
+ }
+ eclipseContext.remove(contextId);
+ final List<Context> contexts = definedTables.getContexts();
+ if (contexts.contains(table.getTableId())) {
+ // this is only valid because I'm throwing away the old definedTables contextSet
+ contexts.remove(table.getTableId());
+ definedTables = createContextSet(contexts);
+ }
+ }
+
+ public BindingTable getTable(String id) {
+ return (BindingTable) eclipseContext.get(getTableId(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 (Context ctx : definedTables.getContexts()) {
+ BindingTable table = getTable(ctx.getId());
+ if (table != null) {
+ bindings.addAll(table.getBindings());
+ }
+ }
+ return bindings;
+ }
+
+ public ContextSet createContextSet(Collection<Context> contexts) {
+ return new ContextSet(contexts);
+ }
+
+ public Collection<Binding> getConflictsFor(ContextSet contextSet,
+ TriggerSequence triggerSequence) {
+ Collection<Binding> matches = new ArrayList<Binding>();
+ for (Context ctx : contextSet.getContexts()) {
+ BindingTable table = getTable(ctx.getId());
+ if (table != null) {
+ final Collection<Binding> matchesFor = table.getConflictsFor(triggerSequence);
+ if (matchesFor != null) {
+ matches.addAll(matchesFor);
+ }
+ }
+ }
+ return matches.size() == 0 ? null : matches;
+ }
+
+ public Collection<Binding> getAllConflicts() {
+ Collection<Binding> conflictsList = new ArrayList<Binding>();
+ for (Context ctx : definedTables.getContexts()) {
+ BindingTable table = getTable(ctx.getId());
+ if (table != null) {
+ Collection<Binding> conflictsInTable = table.getConflicts();
+ if (conflictsInTable != null) {
+ conflictsList.addAll(conflictsInTable);
+ }
+ }
+ }
+ return conflictsList;
+ }
+
+ public Binding getPerfectMatch(ContextSet contextSet, TriggerSequence triggerSequence) {
+ Binding result = null;
+ Binding currentResult = null;
+ List<Context> contexts = contextSet.getContexts();
+ ListIterator<Context> it = contexts.listIterator(contexts.size());
+ while (it.hasPrevious()) {
+ Context c = it.previous();
+ BindingTable table = getTable(c.getId());
+ if (table != null) {
+ currentResult = table.getPerfectMatch(triggerSequence);
+ }
+ if (currentResult != null) {
+ if (isMostActiveScheme(currentResult)) {
+ return currentResult;
+ }
+ if (result == null) {
+ result = currentResult;
+ } else {
+ int rc = compareSchemes(result.getSchemeId(), currentResult.getSchemeId());
+ if (rc < 0) {
+ result = currentResult;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param currentResult
+ * @return
+ */
+ private boolean isMostActiveScheme(Binding currentResult) {
+ if (activeSchemeIds == null || activeSchemeIds.length < 2) {
+ return true;
+ }
+ final String mostActive = activeSchemeIds[0];
+ return mostActive == null ? false : mostActive.equals(currentResult.getSchemeId());
+ }
+
+ public Binding getBestSequenceFor(ContextSet contextSet,
+ ParameterizedCommand parameterizedCommand) {
+ ArrayList<Binding> bindings = (ArrayList<Binding>) getSequencesFor(contextSet,
+ parameterizedCommand);
+ if (bindings.size() == 0) {
+ return null;
+ }
+ return bindings.get(0);
+ }
+
+ public Collection<Binding> getSequencesFor(ContextSet contextSet,
+ ParameterizedCommand parameterizedCommand) {
+ ArrayList<Binding> bindings = new ArrayList<Binding>();
+ List<Context> contexts = contextSet.getContexts();
+ ListIterator<Context> it = contexts.listIterator(contexts.size());
+ while (it.hasPrevious()) {
+ Context c = it.previous();
+ BindingTable table = getTable(c.getId());
+ if (table != null) {
+ Collection<Binding> sequences = table.getSequencesFor(parameterizedCommand);
+ if (sequences != null) {
+ bindings.addAll(sequences);
+ }
+ }
+ }
+ Collections.sort(bindings, BindingTable.BEST_SEQUENCE);
+ return bindings;
+ }
+
+ public Collection<Binding> getBindingsFor(ContextSet contextSet, ParameterizedCommand cmd) {
+ Collection<Binding> bindings = new ArrayList<Binding>();
+ for (Context ctx : contextSet.getContexts()) {
+ BindingTable table = getTable(ctx.getId());
+ if (table != null) {
+ Collection<Binding> matches = table.getSequencesFor(cmd);
+ if (matches != null) {
+ bindings.addAll(matches);
+ }
+ }
+ }
+ return bindings;
+ }
+
+ public boolean isPartialMatch(ContextSet contextSet, TriggerSequence sequence) {
+ List<Context> contexts = contextSet.getContexts();
+ ListIterator<Context> it = contexts.listIterator(contexts.size());
+ while (it.hasPrevious()) {
+ Context c = it.previous();
+ BindingTable table = getTable(c.getId());
+ if (table != null) {
+ if (table.isPartialMatch(sequence)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public Collection<Binding> getPartialMatches(ContextSet contextSet, TriggerSequence sequence) {
+ ArrayList<Binding> bindings = new ArrayList<Binding>();
+ List<Context> contexts = contextSet.getContexts();
+ ListIterator<Context> it = contexts.listIterator(contexts.size());
+ while (it.hasPrevious()) {
+ Context c = it.previous();
+ BindingTable table = getTable(c.getId());
+ if (table != null) {
+ Collection<Binding> partialMatches = table.getPartialMatches(sequence);
+ if (partialMatches != null) {
+ bindings.addAll(partialMatches);
+ }
+ }
+ }
+ return bindings;
+ }
+
+ /**
+ * @param activeSchemeIds
+ */
+ public void setActiveSchemes(String[] activeSchemeIds) {
+ this.activeSchemeIds = activeSchemeIds;
+ BindingTable.BEST_SEQUENCE.setActiveSchemes(activeSchemeIds);
+ }
+
+ /*
+ * Copied from org.eclipse.jface.bindings.BindingManager.compareSchemes(String, String)
+ *
+ * Returns an in based on scheme 1 < scheme 2
+ */
+ private final int compareSchemes(final String schemeId1, final String schemeId2) {
+ if (activeSchemeIds == null) {
+ 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;
+ }
+}
diff --git a/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/ContextSet.java b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/ContextSet.java
new file mode 100755
index 000000000..63c2ce316
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.ui.keybindings.e4/src/org/eclipse/fx/ui/keybindings/e4/internal/ContextSet.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.fx.ui.keybindings.e4.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.core.commands.contexts.ContextManager;
+
+public class ContextSet {
+ public static ContextSet EMPTY = new ContextSet(Collections.EMPTY_LIST);
+
+ public static class CComp implements Comparator<Context> {
+ private ContextManager manager;
+
+ public CComp(ContextManager manager) {
+ this.manager = manager;
+ }
+
+ public int compare(Context o1, Context o2) {
+ if (o1.equals(o2)) {
+ return 0;
+ }
+ int l1 = getLevel(o1);
+ int l2 = getLevel(o2);
+ if (l1 != l2) {
+ return l1 - l2;
+ }
+ return o1.getId().compareTo(o2.getId());
+ }
+
+ private int getLevel(Context c) {
+ int l = 0;
+ try {
+ String parentId = c.getParentId();
+ while (parentId != null) {
+ l++;
+ Context context = manager.getContext(parentId);
+ parentId = context.getParentId();
+ }
+ } catch (NotDefinedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return l;
+ }
+ }
+
+ private static Comparator<Context> CONTEXT_COMP = null;
+
+ public static void setComparator(Comparator<Context> comp) {
+ CONTEXT_COMP = comp;
+ }
+
+ public static Comparator<Context> getComparator() {
+ return CONTEXT_COMP;
+ }
+
+ private List<Context> contexts;
+
+ public ContextSet(Collection<Context> c) {
+ contexts = new ArrayList<Context>(c);
+ Collections.sort(contexts, CONTEXT_COMP);
+ }
+
+ public List<Context> getContexts() {
+ return contexts;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof ContextSet)) {
+ return false;
+ }
+ return contexts.equals(((ContextSet) o).contexts);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return contexts.hashCode();
+ }
+}
diff --git a/releng/org.eclipse.fx.releng/pom.xml b/releng/org.eclipse.fx.releng/pom.xml
index 5841b14b0..09ed1b15d 100755
--- a/releng/org.eclipse.fx.releng/pom.xml
+++ b/releng/org.eclipse.fx.releng/pom.xml
@@ -46,6 +46,7 @@
<!-- e4 -->
<module>../../bundles/runtime/org.eclipse.fx.ui.keybindings</module>
<module>../../bundles/runtime/org.eclipse.fx.ui.keybindings.generic</module>
+ <module>../../bundles/runtime/org.eclipse.fx.ui.keybindings.e4</module>
<!-- Format Conversion -->
<module>../../bundles/runtime/org.eclipse.fx.formats.svg</module>

Back to the top