/* * Copyright 2003-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.editor.runtime.cells; import jetbrains.mps.openapi.editor.cells.KeyMap; import jetbrains.mps.openapi.editor.cells.KeyMapAction; import jetbrains.mps.util.Pair; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; /** * User: shatalin * Date: 2/8/13 */ public class KeyMapImpl implements KeyMap { private boolean myApplicableToEveryModel = false; private List<KeyMap> myChildKeyMaps; private HashMap<ActionKey, KeyMapAction> myActionMap = new HashMap<ActionKey, KeyMapAction>(); private List<Pair<ActionKey, KeyMapAction>> myDuplicatedActionList; @Override public boolean isApplicableToEveryModel() { return myApplicableToEveryModel; } public void setApplicableToEveryModel(boolean isApplicable) { myApplicableToEveryModel = isApplicable; } @Override public void addKeyMap(KeyMap keyMap) { if (myChildKeyMaps == null) { myChildKeyMaps = new LinkedList<KeyMap>(); } myChildKeyMaps.add(keyMap); } @Override public void putAction(String modifiers, String keyCode, KeyMapAction action) { boolean keyTyped = keyCode.length() == 1; ActionKey key = new ActionKey(modifiers, keyCode, keyTyped); if (!myActionMap.containsKey(key)) { myActionMap.put(key, action); } else { if (myDuplicatedActionList == null) { myDuplicatedActionList = new LinkedList<Pair<ActionKey, KeyMapAction>>(); } myDuplicatedActionList.add(new Pair<ActionKey, KeyMapAction>(key, action)); } } @Override public Collection<KeyMapAction> getActions(Collection<ActionKey> keys) { return getActions(keys, new ArrayList<KeyMapAction>()); } private Collection<KeyMapAction> getActions(Collection<KeyMap.ActionKey> keys, Collection<KeyMapAction> result) { for (ActionKey actionKey : keys) { KeyMapAction action = myActionMap.get(actionKey); if (action != null) { result.add(action); if (myDuplicatedActionList != null) { for (Pair<ActionKey, KeyMapAction> pair : myDuplicatedActionList) { if (pair.o1.equals(actionKey)) { result.add(pair.o2); } } } } } if (myChildKeyMaps != null) { for (KeyMap childKeyMap : myChildKeyMaps) { if (childKeyMap instanceof KeyMapImpl) { ((KeyMapImpl) childKeyMap).getActions(keys, result); } else { result.addAll(childKeyMap.getActions(keys)); } } } return result; } @Override public Collection<KeyMapAction> getAllActions() { return getAllActions(new ArrayList<KeyMapAction>()); } private Collection<KeyMapAction> getAllActions(Collection<KeyMapAction> result) { result.addAll(myActionMap.values()); if (myDuplicatedActionList != null) { for (Pair<ActionKey, KeyMapAction> pair : myDuplicatedActionList) { result.add(pair.o2); } } if (myChildKeyMaps != null) { for (KeyMap childKeyMap : myChildKeyMaps) { if (childKeyMap instanceof KeyMapImpl) { ((KeyMapImpl) childKeyMap).getAllActions(result); } else { result.addAll(childKeyMap.getAllActions()); } } } return result; } @Override public Collection<ActionKey> getActionKeys() { return getActionKeys(new HashSet<ActionKey>()); } private Collection<ActionKey> getActionKeys(Set<ActionKey> result) { result.addAll(myActionMap.keySet()); if (myChildKeyMaps != null) { for (KeyMap childKeyMap : myChildKeyMaps) { if (childKeyMap instanceof KeyMapImpl) { ((KeyMapImpl) childKeyMap).getActionKeys(result); } else { result.addAll(childKeyMap.getActionKeys()); } } } return result; } }