blob: e5a283ec344b1ed532658ad2c7a7cd060678ca6c [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* 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:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.vaaclipse.addons.keybinding;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.core.commands.EHandlerService;
import org.eclipse.e4.core.contexts.Active;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
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.MKeyBinding;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.Selector;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.runtime.common.keystroke.KeyCodeUtil;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeDefinition;
import org.eclipse.osbp.runtime.web.vaadin.common.shortcuts.ShortcutHandler;
import org.eclipse.osbp.runtime.web.vaadin.common.shortcuts.ShortcutManager;
import com.vaadin.ui.Component;
/**
* Is responsible to deal with keybindings for the active MPart.
*/
@SuppressWarnings("restriction")
public class KeyBindingServiceImpl implements IKeyBindingService {
/** The m app. */
@Inject
private MApplication mApp;
/** The command service. */
@Inject
private ECommandService commandService;
/** The handler service. */
@Inject
private EHandlerService handlerService;
/** The model service. */
@Inject
private EModelService modelService;
/** The manager. */
@Inject
private ShortcutManager manager;
/**
* Activates all keybindings for the given mPart.
*
* @param mPart
* the m part
*/
@SuppressWarnings("unchecked")
@Inject
public void activateBindings(@Active @Optional MPart mPart) {
if (mPart == null) {
return;
}
ensureKeybindingData(mPart);
Component component = (Component) mPart.getWidget();
if (!manager.isHandled(component)) {
List<MKeyBinding> partKeyBindings = (List<MKeyBinding>) mPart
.getTransientData().get(LUNIFERA_KEY_BINDINGS);
if (partKeyBindings != null) {
for (MKeyBinding binding : partKeyBindings) {
String sequence = binding.getKeySequence();
ShortcutHandler handler = new ShortcutHandler(
toKeyStrokeDefinition(sequence),
createCallback(binding, mPart), component);
manager.register(component, handler);
}
}
}
// at least, activate all key bindings
manager.activate(component);
}
/**
* Ensure keybinding data.
*
* @param mPart
* the m part
*/
protected void ensureKeybindingData(MPart mPart) {
if (!mPart.getTransientData().containsKey(LUNIFERA_KEY_BINDINGS)) {
internalCollectData(mPart);
}
}
/**
* Creates a callback which executes the bound command.
*
* @param binding
* the binding
* @param mPart
* the m part
* @return the key stroke callback
*/
private KeyStrokeCallback createCallback(MKeyBinding binding, MPart mPart) {
return new CommandKeyStrokeCallback(binding, mPart, commandService,
handlerService);
}
/**
* Parses the given sequence to a valid keystroke definition.
*
* @param sequence
* the sequence
* @return the key stroke definition
*/
private KeyStrokeDefinition toKeyStrokeDefinition(String sequence) {
return KeyCodeUtil.parse(sequence);
}
/**
* Internal collect data.
*
* @param mPart
* the m part
*/
private void internalCollectData(MPart mPart) {
List<MBindingContext> aContexts = mPart.getBindingContexts();
if (aContexts.isEmpty()) {
for (MBindingContext context : mApp.getBindingContexts()) {
aContexts.add(context);
}
}
List<MKeyBinding> partKeyBindings = new ArrayList<MKeyBinding>();
collectKeyBindings(aContexts, partKeyBindings);
// register all keybinding info at the part for later use
mPart.getTransientData().put(LUNIFERA_KEY_BINDINGS, partKeyBindings);
}
/**
* Collects all key bindings for the given part.
*
* @param contexts
* the contexts
* @param partKeyBindings
* the part key bindings
*/
protected void collectKeyBindings(List<MBindingContext> contexts,
List<MKeyBinding> partKeyBindings) {
List<MBindingContext> superContexts = new ArrayList<MBindingContext>();
for (MBindingContext temp : contexts) {
EObject casted = (EObject) temp;
if (casted.eContainer() instanceof MBindingContext) {
superContexts.add((MBindingContext) casted.eContainer());
}
for (MBindingTable tempTable : mApp.getBindingTables()) {
if (tempTable.getBindingContext() == temp) {
partKeyBindings.addAll(tempTable.getBindings());
}
}
}
if (!superContexts.isEmpty()) {
collectKeyBindings(superContexts, partKeyBindings);
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.vaaclipse.addons.keybinding.IKeyBindingService#getKeyBindingString(org.eclipse.e4.ui.model.application.ui.basic.MPart, java.lang.String)
*/
@Override
public String getKeyBindingString(MPart mPart, String commandId) {
MKeyBinding result = findKeyBinding(mPart, commandId);
return result != null ? result.getKeySequence() : "";
}
/**
* Returns the keybinding for the given mPart and the commandId.
*
* @param mPart
* the m part
* @param commandId
* the command id
* @return the m key binding
*/
@SuppressWarnings("unchecked")
protected MKeyBinding findKeyBinding(MPart mPart, String commandId) {
ensureKeybindingData(mPart);
MKeyBinding result = null;
List<MKeyBinding> partKeyBindings = (List<MKeyBinding>) mPart
.getTransientData().get(LUNIFERA_KEY_BINDINGS);
if (partKeyBindings != null) {
for (MKeyBinding binding : partKeyBindings) {
if (binding.getCommand() != null
&& binding.getCommand().getElementId()
.equals(commandId)) {
result = binding;
break;
}
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.vaaclipse.addons.keybinding.IKeyBindingService#getAllKeyBindings()
*/
@Override
public List<MKeyBinding> getAllKeyBindings() {
List<MKeyBinding> result = modelService.findElements(mApp,
MKeyBinding.class, EModelService.ANYWHERE, new Selector() {
@Override
public boolean select(MApplicationElement element) {
return true;
}
});
return result;
}
}