GT-2925 - Key Bindings - Support Window Menu Provider Key Bindings -

Step  - Added 'snapshot' concept to base Component Provider to fix how
actions are added to the toolbar and menu; fixed bugs and tests
This commit is contained in:
dragonmacher
2019-06-28 18:03:19 -04:00
parent 3946a05ded
commit 10621008e0
18 changed files with 291 additions and 84 deletions

View File

@@ -70,9 +70,13 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
public ProgramByteViewerComponentProvider(PluginTool tool, ByteViewerPlugin plugin,
boolean isConnected) {
super(tool, plugin, "Bytes", ByteViewerActionContext.class);
this.isConnected = isConnected;
setIcon(ResourceManager.loadImage("images/binaryData.gif"), true);
this.isConnected = isConnected;
if (!isConnected) {
setTransient();
}
setIcon(ResourceManager.loadImage("images/binaryData.gif"), isConnected);
decorationComponent = new DecoratorPanel(panel, isConnected);
clipboardProvider = new ByteViewerClipboardProvider(this, tool);
@@ -88,6 +92,12 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
tool.addLocalAction(this, cloneByteViewerAction);
}
@Override
public boolean isSnapshot() {
// we are a snapshot when we are 'disconnected'
return !isConnected();
}
@Override
public JComponent getComponent() {
return decorationComponent;
@@ -132,11 +142,6 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
plugin.closeProvider(this);
}
@Override
public boolean isTransient() {
return false;
}
@Override
public void setSelection(ProgramSelection selection) {
setSelection(selection, true);

View File

@@ -28,8 +28,10 @@ import javax.swing.event.TableColumnModelEvent;
import org.junit.*;
import docking.ActionContext;
import docking.*;
import docking.action.DockingActionIf;
import docking.menu.ToolBarItemManager;
import docking.menu.ToolBarManager;
import docking.widgets.EventTrigger;
import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.field.Field;
@@ -168,7 +170,7 @@ public class ByteViewerPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
DataModelInfo info = panel.getDataModelInfo();
String[] names = info.getNames();
assertEquals(3, names.length);
Set<String> viewNames = new HashSet<String>(Arrays.asList(names));
Set<String> viewNames = new HashSet<>(Arrays.asList(names));
assertTrue(viewNames.contains("Hex"));
assertTrue(viewNames.contains("Octal"));
assertTrue(viewNames.contains("Ascii"));
@@ -668,6 +670,64 @@ public class ByteViewerPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
}
}
@Test
public void testShowingSnapshotDoesNotAddMultipleToolbarActions() {
DockingActionIf cloneAction = getAction(plugin, "ByteViewer Clone");
performAction(cloneAction);
waitForSwing();
assertOnlyOneProviderToolbarAction();
performAction(cloneAction);
waitForSwing();
assertOnlyOneProviderToolbarAction();
}
//==================================================================================================
// Private Methods
//==================================================================================================
@SuppressWarnings("unchecked")
private void assertOnlyOneProviderToolbarAction() {
DockingWindowManager dwm = tool.getWindowManager();
ActionToGuiMapper guiActions =
(ActionToGuiMapper) getInstanceField("actionToGuiMapper", dwm);
GlobalMenuAndToolBarManager menuManager =
(GlobalMenuAndToolBarManager) getInstanceField("menuAndToolBarManager", guiActions);
Map<WindowNode, WindowActionManager> windowToActionManagerMap =
(Map<WindowNode, WindowActionManager>) getInstanceField("windowToActionManagerMap",
menuManager);
ProgramByteViewerComponentProvider provider = plugin.getProvider();
DockingActionIf showAction =
(DockingActionIf) getInstanceField("showProviderAction", provider);
String actionName = showAction.getName();
List<DockingActionIf> matches = new ArrayList<>();
for (WindowActionManager actionManager : windowToActionManagerMap.values()) {
ToolBarManager toolbarManager =
(ToolBarManager) getInstanceField("toolBarMgr", actionManager);
Map<String, List<ToolBarItemManager>> groupToItems =
(Map<String, List<ToolBarItemManager>>) getInstanceField("groupToItemsMap",
toolbarManager);
Collection<List<ToolBarItemManager>> values = groupToItems.values();
for (List<ToolBarItemManager> list : values) {
for (ToolBarItemManager manager : list) {
DockingActionIf action = manager.getAction();
if (actionName.equals(action.getName())) {
matches.add(action);
}
}
}
}
assertEquals("Should only have 1 action on toolbar to show the provider", 1,
matches.size());
}
private void goToOperand(String addr) {
goTo(addr(addr), OperandFieldFactory.FIELD_NAME);
}
@@ -731,11 +791,6 @@ public class ByteViewerPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
assertEquals(expectedColumn, location.getCol());
}
private void goTo(String addr) {
GoToService goToService = tool.getService(GoToService.class);
goToService.goTo(addr(addr));
}
private void goToByte(String addr) {
goToByte(addr(addr));
}