mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GT-2925-2 - Key Bindings - Support Window Menu Provider Key Bindings -
test and review fixes
This commit is contained in:
parent
21db705ecc
commit
dabdc38ea9
11 changed files with 90 additions and 21 deletions
|
@ -43,7 +43,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
|||
private final Icon ICON = ResourceManager.loadImage("images/refresh.png");
|
||||
private static final String PROVIDER_NAME = "Test Action Provider";
|
||||
private static final KeyStroke CONTROL_T =
|
||||
KeyStroke.getKeyStroke(Character.valueOf('t'), DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||
KeyStroke.getKeyStroke(Character.valueOf('T'), DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||
|
||||
private TestEnv env;
|
||||
private PluginTool tool;
|
||||
|
@ -160,6 +160,19 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
|||
assertMenuItemHasKeyStroke(newKs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetKeyBinding_ViaDialog_FromWindowMenu_ThenFireKeyEventToShowProvider() {
|
||||
|
||||
showProvider();
|
||||
|
||||
KeyStroke newKs = CONTROL_T;
|
||||
setKeyBindingViaF4Dialog_FromWindowsMenu(newKs);
|
||||
|
||||
hideProvider();
|
||||
pressKey(CONTROL_T);
|
||||
assertProviderIsActive();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetKeyBinding_ViaDialog_FromWindowMenu_ToAlreadyBoundAction() {
|
||||
|
||||
|
@ -326,6 +339,11 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
|||
waitForSwing();
|
||||
}
|
||||
|
||||
private void hideProvider() {
|
||||
tool.showComponentProvider(provider, false);
|
||||
waitForSwing();
|
||||
}
|
||||
|
||||
private void setDefaultKeyBinding(KeyStroke defaultKs) {
|
||||
runSwing(() -> provider.setKeyBinding(new KeyBindingData(defaultKs)));
|
||||
}
|
||||
|
@ -341,6 +359,14 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
|||
});
|
||||
}
|
||||
|
||||
private void pressKey(KeyStroke ks) {
|
||||
int modifiers = ks.getModifiers();
|
||||
char keyChar = ks.getKeyChar();
|
||||
int keyCode = ks.getKeyCode();
|
||||
JFrame toolFrame = tool.getToolFrame();
|
||||
triggerKey(toolFrame, modifiers, keyCode, keyChar);
|
||||
}
|
||||
|
||||
private DockingActionIf getShowProviderAction() {
|
||||
|
||||
DockingActionIf showProviderAction =
|
||||
|
@ -389,6 +415,11 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
|||
waitForSwing();
|
||||
}
|
||||
|
||||
private void assertProviderIsActive() {
|
||||
assertTrue("The test provider is not showing and focused",
|
||||
runSwing(() -> tool.isActive(provider)));
|
||||
}
|
||||
|
||||
private void assertNoToolbarAction() {
|
||||
assertNull("No toolbar action found for provider", getToolbarShowProviderAction());
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import docking.action.DockingActionIf;
|
|||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.AbstractProgramBasedTest;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
|
||||
public class ProviderNavigationPluginTest extends AbstractProgramBasedTest {
|
||||
|
@ -165,9 +164,6 @@ public class ProviderNavigationPluginTest extends AbstractProgramBasedTest {
|
|||
|
||||
@Override
|
||||
public void accept(ComponentProvider c) {
|
||||
|
||||
Msg.out("Spy - activated: " + c);
|
||||
|
||||
lastActivated = c;
|
||||
forceActivate(c);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public class ActionDialog extends DialogComponentProvider {
|
|||
for (int i = 0; i < list.size(); i++) {
|
||||
ExecutableKeyActionAdapter actionProxy = list.get(i);
|
||||
DockingActionIf action = actionProxy.getAction();
|
||||
listModel.addElement(action.getName());
|
||||
listModel.addElement(action.getName() + " (" + action.getOwnerDescription() + ")");
|
||||
}
|
||||
actionList.setSelectedIndex(0);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ public class ActionDialog extends DialogComponentProvider {
|
|||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
if (e.getModifiers() != InputEvent.BUTTON1_MASK) {
|
||||
if (e.getModifiersEx() != InputEvent.BUTTON1_DOWN_MASK) {
|
||||
return;
|
||||
}
|
||||
int clickCount = e.getClickCount();
|
||||
|
|
|
@ -36,8 +36,6 @@ public class ShowAllComponentsAction extends ShowComponentAction {
|
|||
winMgr.doSetMenuGroup(new String[] { MENU_WINDOW, subMenuName }, "Permanent");
|
||||
|
||||
setHelpLocation(new HelpLocation("DockingWindows", "Windows_Menu"));
|
||||
|
||||
this.winMgr = winMgr;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@ import javax.swing.Icon;
|
|||
import javax.swing.ImageIcon;
|
||||
|
||||
import docking.action.*;
|
||||
import docking.actions.AutoGeneratedDockingAction;
|
||||
import ghidra.util.HelpLocation;
|
||||
import resources.ResourceManager;
|
||||
|
||||
|
@ -26,7 +27,8 @@ import resources.ResourceManager;
|
|||
* Action for showing components. If the component is hidden it will be made visible.
|
||||
* If it is tabbed, it will become the top tab. In all cases it will receive focus.
|
||||
*/
|
||||
class ShowComponentAction extends DockingAction implements Comparable<ShowComponentAction> {
|
||||
class ShowComponentAction extends DockingAction
|
||||
implements AutoGeneratedDockingAction, Comparable<ShowComponentAction> {
|
||||
private static final int MAX_LENGTH = 40;
|
||||
|
||||
protected static final ImageIcon EMPTY_ICON =
|
||||
|
@ -47,6 +49,7 @@ class ShowComponentAction extends DockingAction implements Comparable<ShowCompon
|
|||
|
||||
protected ShowComponentAction(DockingWindowManager winMgr, String name, String subMenuName) {
|
||||
super(truncateTitleAsNeeded(name), DockingWindowManager.DOCKING_WINDOWS_OWNER);
|
||||
this.winMgr = winMgr;
|
||||
}
|
||||
|
||||
ShowComponentAction(DockingWindowManager winMgr, ComponentPlaceholder placeholder,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,15 +15,16 @@
|
|||
*/
|
||||
package docking;
|
||||
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import resources.ResourceManager;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.actions.AutoGeneratedDockingAction;
|
||||
import ghidra.util.HelpLocation;
|
||||
import resources.ResourceManager;
|
||||
|
||||
class ShowWindowAction extends DockingAction implements Comparable<ShowWindowAction> {
|
||||
class ShowWindowAction extends DockingAction
|
||||
implements AutoGeneratedDockingAction, Comparable<ShowWindowAction> {
|
||||
|
||||
private static final Icon ICON = ResourceManager.loadImage("images/application_xp.png");
|
||||
private static final String MENU_WINDOW = "&" + DockingWindowManager.COMPONENT_MENU_NAME;
|
||||
|
|
|
@ -27,10 +27,17 @@ import docking.*;
|
|||
import ghidra.util.ReservedKeyBindings;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
/**
|
||||
* A class that organizes system key bindings by mapping them to assigned {@link DockingActionIf}s.
|
||||
*
|
||||
* <p>This class understands reserved system key bindings. For non-reserved key bindings, this
|
||||
* class knows how to map a single key binding to multiple actions.
|
||||
*/
|
||||
public class KeyBindingsManager implements PropertyChangeListener {
|
||||
|
||||
protected Map<KeyStroke, DockingKeyBindingAction> dockingKeyMap;
|
||||
protected Map<DockingActionIf, ComponentProvider> actionToProviderMap;
|
||||
// this map exists to update the MultiKeyBindingAction when the key binding changes
|
||||
private Map<DockingActionIf, ComponentProvider> actionToProviderMap;
|
||||
private Map<KeyStroke, DockingKeyBindingAction> dockingKeyMap;
|
||||
private DockingTool tool;
|
||||
|
||||
public KeyBindingsManager(DockingTool tool) {
|
||||
|
|
|
@ -277,7 +277,8 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return provider.toString() + " - " + action;
|
||||
String providerString = provider == null ? "" : provider.toString() + " - ";
|
||||
return providerString + action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 docking.actions;
|
||||
|
||||
/**
|
||||
* A marker interface to signal that the implementing action is temporary and gets built
|
||||
* automatically by the tool
|
||||
*/
|
||||
public interface AutoGeneratedDockingAction {
|
||||
// marker interface
|
||||
}
|
|
@ -164,13 +164,18 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener {
|
|||
newStub.addPropertyChangeListener(this);
|
||||
keyBindingOptions.registerOption(newStub.getFullName(), OptionType.KEYSTROKE_TYPE,
|
||||
defaultKeyStroke, null, null);
|
||||
|
||||
keyBindingsManager.addAction(provider, newStub);
|
||||
|
||||
return newStub;
|
||||
});
|
||||
|
||||
stub.addClientAction(action);
|
||||
|
||||
// note: only put the stub in the manager, not the actual action
|
||||
keyBindingsManager.addAction(provider, stub);
|
||||
if (!(action instanceof AutoGeneratedDockingAction)) {
|
||||
// Auto-generated actions are temporary and should not receive key events
|
||||
keyBindingsManager.addAction(provider, action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,7 +55,8 @@ public class TestKeyEventDispatcher {
|
|||
//
|
||||
focusProvider.focusOwner = event.getComponent();
|
||||
try {
|
||||
return systemDispatcher.dispatchKeyEvent(event);
|
||||
boolean success = systemDispatcher.dispatchKeyEvent(event);
|
||||
return success;
|
||||
}
|
||||
finally {
|
||||
focusProvider.focusOwner = null;
|
||||
|
@ -105,6 +106,9 @@ public class TestKeyEventDispatcher {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (focusOwner instanceof Window) {
|
||||
return (Window) focusOwner;
|
||||
}
|
||||
return SwingUtilities.windowForComponent(focusOwner);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue