/* * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.ins; import static java.awt.event.InputEvent.*; import static java.awt.event.KeyEvent.*; import java.util.*; import javax.swing.*; import com.sun.max.ins.InspectionActions.*; /** * Support for binding {@link KeyStroke}s to {@link InspectionActions}s. */ public class InspectorKeyBindings { /** * The set of InspectorAction types to which a key stroke can be bound. */ @SuppressWarnings("unchecked") public static final Set<Class<? extends InspectorAction>> KEY_BINDABLE_ACTIONS = new HashSet<Class<? extends InspectorAction>>(Arrays.asList( QuitAction.class, ViewClassActorByNameAction.class, ViewMethodActorByNameAction.class, ViewMethodBytecodeByNameAction.class, ViewMethodMachineCodeAction.class, ViewMethodCompilationByNameAction.class, DebugSingleStepAction.class, DebugRunToInstructionAction.class, DebugRunToInstructionWithBreakpointsAction.class, DebugRunToNextCallAction.class, DebugRunToNextCallWithBreakpointsAction.class, DebugReturnFromFrameAction.class, DebugReturnFromFrameWithBreakpointsAction.class, DebugStepOverAction.class, DebugStepOverWithBreakpointsAction.class, DebugResumeAction.class, DebugPauseAction.class, ToggleMachineCodeBreakpointAction.class, SetMachineCodeLabelBreakpointsAction.class, RemoveMachineCodeLabelBreakpointsAction.class, SetBytecodeBreakpointAtMethodEntryByNameAction.class, SetMachineCodeBreakpointAtObjectInitializerAction.class, SetMachineCodeBreakpointAtEntriesByNameAction.class )); /** * A map from {@linkplain InspectorAction actions} to the key strokes to * which they are bound. Each key binding map has a {@linkplain #name() name} which must be unique across all * key binding maps. */ public static class KeyBindingMap extends HashMap<Class<? extends InspectorAction>, KeyStroke> { private static final Map<String, KeyBindingMap> ALL_MODIFIABLE = new HashMap<String, KeyBindingMap>(); /** * A map of all the defined key bindings, indexed by their unique names. */ public static final Map<String, KeyBindingMap> ALL = Collections.unmodifiableMap(ALL_MODIFIABLE); private final String name; /** * Creates a new map of actions to key strokes. * * @param name the name of the key binding map. This name must not correspond with the name of any other key * binding map present in {@link #ALL}. */ KeyBindingMap(String name) { this.name = name; final KeyBindingMap oldValue = ALL_MODIFIABLE.put(name, this); assert oldValue == null : "There's already a set of key binding map named " + name; } public String name() { return name; } @Override public String toString() { return name(); } KeyBindingMap add(Class<? extends InspectorAction> actionClass, int keyCode) { put(actionClass, KeyStroke.getKeyStroke(keyCode, 0)); return this; } KeyBindingMap add(Class<? extends InspectorAction> actionClass, int keyCode, int modifiers) { put(actionClass, KeyStroke.getKeyStroke(keyCode, modifiers)); return this; } private Class<? extends InspectorAction> actionBoundTo(KeyStroke keyStroke) { for (Map.Entry<Class<? extends InspectorAction>, KeyStroke> entry : entrySet()) { if (entry.getValue().equals(keyStroke)) { return entry.getKey(); } } return null; } @Override public KeyStroke put(Class<? extends InspectorAction> actionClass, KeyStroke keyStroke) { assert KEY_BINDABLE_ACTIONS.contains(actionClass) : "Cannot bind a key stroke to " + actionClass; final Class<? extends InspectorAction> existingBoundAction = actionBoundTo(keyStroke); assert existingBoundAction == null : "Cannot bind " + keyStroke + " to " + actionClass.getName() + "; this key stroke is already bound to " + existingBoundAction.getName(); final KeyStroke existingKeyStrokeBinding = super.put(actionClass, keyStroke); assert existingKeyStrokeBinding == null : "Cannot re-bind " + actionClass.getName() + "; it is already bound to " + existingKeyStrokeBinding; return existingKeyStrokeBinding; } } /** * A set of key bindings that matches the default bindings in NetBeans for similar actions. */ public static final KeyBindingMap NETBEANS_KEY_BINDINGS = new KeyBindingMap("NetBeans"). add(QuitAction.class, 'Q', CTRL_DOWN_MASK). add(ViewClassActorByNameAction.class, 'T', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodActorByNameAction.class, 'M', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodBytecodeByNameAction.class, 'J', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodMachineCodeAction.class, 'D', CTRL_DOWN_MASK). add(ViewMethodCompilationByNameAction.class, 'D', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugSingleStepAction.class, VK_F7). add(DebugStepOverWithBreakpointsAction.class, VK_F8). add(DebugStepOverAction.class, VK_F8, CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugReturnFromFrameWithBreakpointsAction.class, VK_F7, CTRL_DOWN_MASK). add(DebugReturnFromFrameAction.class, VK_F7, CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugResumeAction.class, VK_F5). add(DebugPauseAction.class, 'P', CTRL_DOWN_MASK). add(ToggleMachineCodeBreakpointAction.class, VK_F8, CTRL_DOWN_MASK). add(SetMachineCodeBreakpointAtEntriesByNameAction.class, 'E', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetBytecodeBreakpointAtMethodEntryByNameAction.class, 'S', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetMachineCodeBreakpointAtObjectInitializerAction.class, 'I', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetMachineCodeLabelBreakpointsAction.class, 'L', CTRL_DOWN_MASK). add(RemoveMachineCodeLabelBreakpointsAction.class, 'L', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugRunToInstructionWithBreakpointsAction.class, VK_F4). add(DebugRunToInstructionAction.class, VK_F4, CTRL_DOWN_MASK + SHIFT_DOWN_MASK); /** * A default set of key bindings. */ public static final KeyBindingMap DEFAULT_KEY_BINDINGS = new KeyBindingMap("Default"). add(QuitAction.class, 'Q', CTRL_DOWN_MASK). add(ViewClassActorByNameAction.class, 'T', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodActorByNameAction.class, 'M', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodBytecodeByNameAction.class, 'J', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(ViewMethodMachineCodeAction.class, 'D', CTRL_DOWN_MASK). add(ViewMethodCompilationByNameAction.class, 'D', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugSingleStepAction.class, VK_F5). add(DebugStepOverWithBreakpointsAction.class, VK_F6). add(DebugStepOverAction.class, VK_F6, CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugReturnFromFrameWithBreakpointsAction.class, VK_F7). add(DebugReturnFromFrameAction.class, VK_F7, CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugResumeAction.class, VK_F8). add(DebugPauseAction.class, 'P', CTRL_DOWN_MASK). add(ToggleMachineCodeBreakpointAction.class, 'B', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetMachineCodeBreakpointAtEntriesByNameAction.class, 'E', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetBytecodeBreakpointAtMethodEntryByNameAction.class, 'S', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetMachineCodeBreakpointAtObjectInitializerAction.class, 'I', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(SetMachineCodeLabelBreakpointsAction.class, 'L', CTRL_DOWN_MASK). add(RemoveMachineCodeLabelBreakpointsAction.class, 'L', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugRunToInstructionWithBreakpointsAction.class, 'R', CTRL_DOWN_MASK). add(DebugRunToInstructionAction.class, 'R', CTRL_DOWN_MASK + SHIFT_DOWN_MASK). add(DebugRunToNextCallWithBreakpointsAction.class, 'C', CTRL_DOWN_MASK). add(DebugRunToNextCallAction.class, 'C', CTRL_DOWN_MASK + SHIFT_DOWN_MASK); }