diff --git a/Ghidra/Features/Base/certification.manifest b/Ghidra/Features/Base/certification.manifest index 5d8a8163a5..f801e96de0 100644 --- a/Ghidra/Features/Base/certification.manifest +++ b/Ghidra/Features/Base/certification.manifest @@ -377,7 +377,6 @@ src/main/help/help/topics/FunctionComparison/images/ListingCodeComparisonOptions src/main/help/help/topics/FunctionComparison/images/MultiFunctionComparisonWindow.png||GHIDRA||||END| src/main/help/help/topics/FunctionComparison/images/NavNextIcon.png||GHIDRA||||END| src/main/help/help/topics/FunctionComparison/images/NavPreviousIcon.png||GHIDRA||||END| -src/main/help/help/topics/FunctionComparison/images/NavSelectedIcon.png||GHIDRA||||END| src/main/help/help/topics/FunctionComparison/images/RemoveFromComparisonIcon.png||GHIDRA||||END| src/main/help/help/topics/FunctionComparison/images/binaryData.gif||GHIDRA||||END| src/main/help/help/topics/FunctionComparison/images/class.png||GHIDRA||||END| @@ -725,7 +724,7 @@ src/main/help/help/topics/ShowInstructionInfoPlugin/images/ProcessorManualOption src/main/help/help/topics/ShowInstructionInfoPlugin/images/RawInstructionDisplay.png||GHIDRA||||END| src/main/help/help/topics/ShowInstructionInfoPlugin/images/ShowInstructionInfo.png||GHIDRA||||END| src/main/help/help/topics/ShowInstructionInfoPlugin/images/UnableToLaunch.png||GHIDRA||||END| -src/main/help/help/topics/Snapshots/Snapshots.html||GHIDRA||reviewed||END| +src/main/help/help/topics/Snapshots/Snapshots.html||GHIDRA||||END| src/main/help/help/topics/Snapshots/images/camera-photo.png||Tango Icons - Public Domain|||tango|END| src/main/help/help/topics/StackEditor/StackEditor.html||GHIDRA||||END| src/main/help/help/topics/StackEditor/images/Array.png||GHIDRA||||END| diff --git a/Ghidra/Features/Base/ghidra_scripts/CallAnotherScriptForAllPrograms.java b/Ghidra/Features/Base/ghidra_scripts/CallAnotherScriptForAllPrograms.java index 850175d5da..4832a4be91 100644 --- a/Ghidra/Features/Base/ghidra_scripts/CallAnotherScriptForAllPrograms.java +++ b/Ghidra/Features/Base/ghidra_scripts/CallAnotherScriptForAllPrograms.java @@ -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. diff --git a/Ghidra/Features/Base/ghidra_scripts/IterateFunctionsByAddressScript.java b/Ghidra/Features/Base/ghidra_scripts/IterateFunctionsByAddressScript.java index 3b187e54a2..164997fb4c 100644 --- a/Ghidra/Features/Base/ghidra_scripts/IterateFunctionsByAddressScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/IterateFunctionsByAddressScript.java @@ -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. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java index 8008fce753..9ba95e5641 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java @@ -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. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java index 1334810ad1..7106e32182 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/context/NavigatableContextAction.java @@ -17,9 +17,11 @@ package ghidra.app.context; import java.util.Set; -import docking.ActionContext; +import docking.*; import docking.action.DockingAction; import docking.action.KeyBindingType; +import ghidra.app.nav.Navigatable; +import ghidra.app.services.GoToService; public abstract class NavigatableContextAction extends DockingAction { @@ -33,23 +35,61 @@ public abstract class NavigatableContextAction extends DockingAction { @Override public boolean isEnabledForContext(ActionContext context) { - if (!(context instanceof NavigatableActionContext)) { + NavigatableActionContext appropriateContext = getAppropriateContext(context); + if (appropriateContext == null) { return false; } - return isEnabledForContext((NavigatableActionContext) context); + return isEnabledForContext(appropriateContext); } @Override public void actionPerformed(ActionContext context) { - actionPerformed((NavigatableActionContext) context); + actionPerformed(getAppropriateContext(context)); + } + + private NavigatableActionContext getAppropriateContext(ActionContext context) { + if (context instanceof NavigatableActionContext && + isValidNavigationContext((NavigatableActionContext) context)) { + return (NavigatableActionContext) context; + } + return getGlobalNavigationContext(context); } @Override - public boolean isValidContext(ActionContext context) { - if (!(context instanceof NavigatableActionContext)) { - return false; + public final boolean isValidContext(ActionContext context) { + return true; + } + + protected boolean isValidNavigationContext(NavigatableActionContext context) { + return true; + } + + private NavigatableActionContext getGlobalNavigationContext(ActionContext context) { + Tool tool = getTool(context.getComponentProvider()); + + if (tool == null) { + return null; } - return isValidContext((NavigatableActionContext) context); + GoToService service = tool.getService(GoToService.class); + if (service == null) { + return null; + } + Navigatable defaultNavigatable = service.getDefaultNavigatable(); + if (defaultNavigatable.getProgram() == null) { + return null; + } + return new NavigatableActionContext(null, defaultNavigatable); + } + + private Tool getTool(ComponentProvider provider) { + if (provider != null) { + return provider.getTool(); + } + DockingWindowManager manager = DockingWindowManager.getActiveInstance(); + if (manager != null) { + return manager.getTool(); + } + return null; } @Override @@ -60,10 +100,6 @@ public abstract class NavigatableContextAction extends DockingAction { return isAddToPopup((NavigatableActionContext) context); } - protected boolean isValidContext(NavigatableActionContext context) { - return true; - } - protected boolean isEnabledForContext(NavigatableActionContext context) { return true; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/tool/ListingMergePanelProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/tool/ListingMergePanelProvider.java index ecdc282480..7a72818051 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/tool/ListingMergePanelProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/tool/ListingMergePanelProvider.java @@ -55,7 +55,7 @@ public class ListingMergePanelProvider extends ComponentProviderAdapter } @Override - public List getPopupActions(DockingTool dt, ActionContext context) { + public List getPopupActions(Tool dt, ActionContext context) { ListingPanel resultPanel = mergePanel.getResultPanel(); if (resultPanel != null) { return resultPanel.getHeaderActions(getName()); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NavigatableRegistry.java b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NavigatableRegistry.java index fffcf623f3..55bfaa1e59 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NavigatableRegistry.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NavigatableRegistry.java @@ -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,16 +15,16 @@ */ package ghidra.app.nav; -import ghidra.framework.model.Tool; - import java.util.*; +import ghidra.framework.plugintool.PluginTool; + public class NavigatableRegistry { private static Map navigatableMap = new HashMap(); - private static Map> toolMap = new HashMap>(); + private static Map> toolMap = + new HashMap>(); - - public static void registerNavigatable(Tool tool, Navigatable navigatable) { + public static void registerNavigatable(PluginTool tool, Navigatable navigatable) { navigatableMap.put(navigatable.getInstanceID(), navigatable); List list = toolMap.get(tool); if (list == null) { @@ -35,7 +34,7 @@ public class NavigatableRegistry { list.add(navigatable); } - public static void unregisterNavigatable(Tool tool, Navigatable navigatable) { + public static void unregisterNavigatable(PluginTool tool, Navigatable navigatable) { navigatableMap.remove(navigatable.getInstanceID()); List list = toolMap.get(tool); if (list == null) { @@ -46,13 +45,15 @@ public class NavigatableRegistry { toolMap.remove(tool); } } - public static List getRegisteredNavigatables(Tool tool) { + + public static List getRegisteredNavigatables(PluginTool tool) { List list = toolMap.get(tool); if (list == null) { list = new ArrayList(navigatableMap.values()); } return list; } + public static Navigatable getNavigatable(long navigationID) { return navigatableMap.get(navigationID); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NextRangeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NextRangeAction.java index 1badc379bd..5297cd23c4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NextRangeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/NextRangeAction.java @@ -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,6 +15,8 @@ */ package ghidra.app.nav; +import java.util.Set; + import ghidra.app.context.*; import ghidra.app.plugin.core.navigation.NavigationOptions; import ghidra.app.services.GoToService; @@ -24,8 +25,6 @@ import ghidra.program.model.address.*; import ghidra.program.model.listing.CodeUnit; import ghidra.program.util.ProgramSelection; -import java.util.Set; - public abstract class NextRangeAction extends NavigatableContextAction { private PluginTool tool; @@ -39,7 +38,7 @@ public abstract class NextRangeAction extends NavigatableContextAction { } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { // // We want the nav actions to work in the current view that supports this, which right // now is the ListingActionContext. If the current context does not support that, then @@ -51,13 +50,12 @@ public abstract class NextRangeAction extends NavigatableContextAction { @Override public boolean isEnabledForContext(NavigatableActionContext context) { Address currentAddress = context.getAddress(); - ListingActionContext listingContext = (ListingActionContext) context; - ProgramSelection selection = getSelection(listingContext); + ProgramSelection selection = getSelection(context); if (selection == null || selection.isEmpty() || currentAddress == null) { return false; } - CodeUnit cu = listingContext.getProgram().getListing().getCodeUnitAt(currentAddress); + CodeUnit cu = context.getProgram().getListing().getCodeUnitAt(currentAddress); if (cu != null) { currentAddress = cu.getMaxAddress(); } @@ -71,13 +69,10 @@ public abstract class NextRangeAction extends NavigatableContextAction { @Override public void actionPerformed(NavigatableActionContext context) { - // Note: we verified above that the context we are grabbing here is the correct type - ListingActionContext listingContext = (ListingActionContext) context; - - Address goToAddress = getGoToAddress(listingContext); + Address goToAddress = getGoToAddress(context); GoToService service = tool.getService(GoToService.class); if (service != null) { - service.goTo(listingContext.getNavigatable(), goToAddress); + service.goTo(context.getNavigatable(), goToAddress); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/PreviousRangeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/PreviousRangeAction.java index d0295ae817..e5b04096d2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/nav/PreviousRangeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/nav/PreviousRangeAction.java @@ -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,6 +15,8 @@ */ package ghidra.app.nav; +import java.util.Set; + import ghidra.app.context.*; import ghidra.app.plugin.core.navigation.NavigationOptions; import ghidra.app.services.GoToService; @@ -23,8 +24,6 @@ import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.program.util.ProgramSelection; -import java.util.Set; - public abstract class PreviousRangeAction extends NavigatableContextAction { private PluginTool tool; @@ -39,7 +38,7 @@ public abstract class PreviousRangeAction extends NavigatableContextAction { } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { // // We want the nav actions to work in the current view that supports this, which right // now is the ListingActionContext. If the current context does not support that, then @@ -58,9 +57,8 @@ public abstract class PreviousRangeAction extends NavigatableContextAction { } private Address getGoToAddress(NavigatableActionContext context) { - ListingActionContext listingContext = (ListingActionContext) context; - ProgramSelection selection = getSelection(listingContext); - Address currentAddress = listingContext.getAddress(); + ProgramSelection selection = getSelection(context); + Address currentAddress = context.getAddress(); AddressRangeIterator it = selection.getAddressRanges(currentAddress, false); if (!it.hasNext()) { @@ -94,8 +92,7 @@ public abstract class PreviousRangeAction extends NavigatableContextAction { @Override public boolean isEnabledForContext(NavigatableActionContext context) { Address currentAddress = context.getAddress(); - ListingActionContext listingContext = (ListingActionContext) context; - ProgramSelection selection = getSelection(listingContext); + ProgramSelection selection = getSelection(context); if (selection == null || selection.isEmpty() || currentAddress == null) { return false; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkPlugin.java index 68d4485a12..332096c47f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkPlugin.java @@ -22,7 +22,7 @@ import javax.swing.Icon; import javax.swing.SwingUtilities; import docking.ActionContext; -import docking.DockingTool; +import docking.Tool; import docking.action.*; import docking.actions.PopupActionProvider; import docking.widgets.table.GTable; @@ -362,10 +362,6 @@ public class BookmarkPlugin extends ProgramPlugin getBookmarkNavigator(bookmarkMgr.getBookmarkType(type)); } - /** - * Bookmark has been changed. - * @param bookmark - */ private void bookmarkChanged(Bookmark bookmark) { if (bookmark == null) { scheduleUpdate(null); @@ -378,10 +374,6 @@ public class BookmarkPlugin extends ProgramPlugin provider.bookmarkChanged(bookmark); } - /** - * Bookmark has been added. - * @param bookmark - */ private void bookmarkAdded(Bookmark bookmark) { if (bookmark == null) { scheduleUpdate(null); @@ -496,7 +488,7 @@ public class BookmarkPlugin extends ProgramPlugin } @Override - public List getPopupActions(DockingTool tool, ActionContext context) { + public List getPopupActions(Tool activeTool, ActionContext context) { Object contextObject = context.getContextObject(); if (!(contextObject instanceof MarkerLocation)) { return null; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearPlugin.java index 81235b8507..c9e3371ee0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearPlugin.java @@ -26,7 +26,7 @@ import ghidra.app.context.ListingContextAction; import ghidra.app.plugin.PluginCategoryNames; import ghidra.framework.cmd.Command; import ghidra.framework.plugintool.*; -import ghidra.framework.plugintool.util.*; +import ghidra.framework.plugintool.util.PluginStatus; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; import ghidra.program.model.data.*; @@ -264,12 +264,6 @@ public class ClearPlugin extends Plugin { } return false; } - - @Override - public boolean isValidGlobalContext(ActionContext context) { - // it's too dangerous to let the clear action work globally - return false; - } }; int menuOrdinal = 1; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java index ff7d25c0fe..68326d01cc 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java @@ -952,7 +952,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter } @Override - public List getPopupActions(DockingTool dt, ActionContext context) { + public List getPopupActions(Tool dt, ActionContext context) { if (context.getComponentProvider() == this) { return listingPanel.getHeaderActions(getName()); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/comments/CommentsPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/comments/CommentsPlugin.java index 447a7ac2d6..0aa565b108 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/comments/CommentsPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/comments/CommentsPlugin.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.comments; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.*; import ghidra.app.CorePluginPackage; import ghidra.app.cmd.comments.SetCommentCmd; @@ -187,11 +186,6 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener { getPopupMenuData().setMenuPath(new String[] { "Comments", "Delete" }); return false; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } }; deleteAction.setPopupMenuData(new MenuData(DELETE_MENUPATH, null, "comments")); deleteAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeManagerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeManagerPlugin.java index 9acef2cdaa..b3cf35615d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeManagerPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeManagerPlugin.java @@ -27,7 +27,7 @@ import javax.swing.SwingUtilities; import javax.swing.tree.TreePath; import docking.ActionContext; -import docking.DockingTool; +import docking.Tool; import docking.action.*; import docking.actions.PopupActionProvider; import docking.widgets.tree.GTreeNode; @@ -678,7 +678,7 @@ public class DataTypeManagerPlugin extends ProgramPlugin } @Override - public List getPopupActions(DockingTool dockingTool, ActionContext context) { + public List getPopupActions(Tool dockingTool, ActionContext context) { if (!(context instanceof DataTypesActionContext)) { return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/editor/DataTypeEditorManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/editor/DataTypeEditorManager.java index 72de637ed7..26f28bf7d0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/editor/DataTypeEditorManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/editor/DataTypeEditorManager.java @@ -22,8 +22,8 @@ import javax.swing.ComboBoxModel; import javax.swing.JPanel; import docking.ComponentProvider; +import docking.actions.DockingToolActions; import docking.actions.SharedDockingActionPlaceholder; -import docking.actions.ToolActions; import docking.widgets.checkbox.GCheckBox; import docking.widgets.combobox.GhidraComboBox; import docking.widgets.label.GLabel; @@ -163,7 +163,7 @@ public class DataTypeEditorManager } private void registerAction(String name) { - ToolActions toolActions = plugin.getTool().getToolActions(); + DockingToolActions toolActions = plugin.getTool().getToolActions(); toolActions.registerSharedActionPlaceholder(new DtSharedActionPlaceholder(name)); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java index b861620245..3787fa1ec1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java @@ -19,7 +19,6 @@ import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; -import docking.ActionContext; import docking.action.*; import docking.widgets.OptionDialog; import ghidra.app.CorePluginPackage; @@ -374,8 +373,8 @@ public class EquatePlugin extends Plugin { Program program = context.getProgram(); List opIndices = getInstructionMatches(program, inst, equate); Address addr = inst.getAddress(); - for (int i = 0; i < opIndices.size(); i++) { - bgCmd.add(createRenameCmd(oldName, newName, addr, opIndices.get(i))); + for (Integer opIndice : opIndices) { + bgCmd.add(createRenameCmd(oldName, newName, addr, opIndice)); } } else if (cu instanceof Data) { @@ -429,9 +428,9 @@ public class EquatePlugin extends Plugin { Program program = context.getProgram(); List opIndexes = getInstructionMatches(program, instr, equate); - for (int i = 0; i < opIndexes.size(); i++) { + for (Integer opIndexe : opIndexes) { bckCmd.add( - new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexes.get(i))); + new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexe)); } } else if (cu instanceof Data) { @@ -728,12 +727,6 @@ public class EquatePlugin extends Plugin { protected boolean isEnabledForContext(ListingActionContext context) { return getEquate(context) != null; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } - }; removeAction.setPopupMenuData(new MenuData(REMOVE_MENUPATH, null, GROUP_NAME)); removeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/DeleteFunctionAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/DeleteFunctionAction.java index 3ff943b536..af7baf7401 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/DeleteFunctionAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/DeleteFunctionAction.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.KeyBindingData; import docking.action.MenuData; import ghidra.app.cmd.function.DeleteFunctionCmd; @@ -71,9 +70,4 @@ class DeleteFunctionAction extends ListingContextAction { return false; } - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } - } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java index eae8ea827f..8fa5c54353 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.KeyBindingData; import docking.action.MenuData; import ghidra.app.cmd.function.CallDepthChangeInfo; @@ -73,9 +72,4 @@ class RemoveStackDepthChangeAction extends ListingContextAction { context.getAddress()) != null; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableCommentDeleteAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableCommentDeleteAction.java index 0d554828df..14df6a6a28 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableCommentDeleteAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableCommentDeleteAction.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.KeyBindingData; import docking.action.KeyBindingType; import ghidra.app.cmd.function.SetVariableCommentCmd; @@ -89,8 +88,4 @@ class VariableCommentDeleteAction extends ListingContextAction { return (loc instanceof VariableCommentFieldLocation); } - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableDeleteAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableDeleteAction.java index 71d90f9396..fe71f670c9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableDeleteAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/VariableDeleteAction.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.function; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.KeyBindingData; import docking.action.MenuData; import ghidra.app.cmd.function.DeleteVariableCmd; @@ -105,9 +104,4 @@ class VariableDeleteAction extends ListingContextAction { } return null; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functioncompare/FunctionComparisonProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functioncompare/FunctionComparisonProvider.java index e10203f827..4305e52542 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functioncompare/FunctionComparisonProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functioncompare/FunctionComparisonProvider.java @@ -19,7 +19,7 @@ import java.awt.event.MouseEvent; import java.util.*; import docking.ActionContext; -import docking.DockingTool; +import docking.Tool; import docking.action.DockingAction; import docking.action.DockingActionIf; import docking.actions.PopupActionProvider; @@ -130,7 +130,7 @@ public class FunctionComparisonProvider extends ComponentProviderAdapter } @Override - public List getPopupActions(DockingTool tool, ActionContext context) { + public List getPopupActions(Tool tool, ActionContext context) { if (context.getComponentProvider() == this) { ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/gotoquery/GoToServicePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/gotoquery/GoToServicePlugin.java index 82ab820d43..691f890f36 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/gotoquery/GoToServicePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/gotoquery/GoToServicePlugin.java @@ -60,7 +60,7 @@ public final class GoToServicePlugin extends ProgramPlugin { * Creates a new instance of the GoToServicePlugin */ public GoToServicePlugin(PluginTool plugintool) { - super(plugintool, true, false); + super(plugintool, true, true); gotoService = new GoToServiceImpl(this, new DefaultNavigatable()); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java index 073ae5fea6..7557b2636e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/instructionsearch/InstructionSearchPlugin.java @@ -245,7 +245,7 @@ public class InstructionSearchPlugin extends ProgramPlugin { } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { return !(context instanceof RestrictedAddressSetContext); } }; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/RemoveLabelAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/RemoveLabelAction.java index 7ff668024f..c4ac18f512 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/RemoveLabelAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/RemoveLabelAction.java @@ -19,7 +19,6 @@ import java.awt.event.KeyEvent; import javax.swing.KeyStroke; -import docking.ActionContext; import docking.action.*; import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingContextAction; @@ -66,11 +65,6 @@ class RemoveLabelAction extends ListingContextAction { return !plugin.isOnExternalReference(context) && isOnSymbol(context); } - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } - boolean isOnSymbol(ListingActionContext context) { Symbol s = plugin.getSymbol(context); return ((s instanceof CodeSymbol) && !s.isDynamic()) || diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/NextPrevAddressPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/NextPrevAddressPlugin.java index 01980005d5..6fef5ce938 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/NextPrevAddressPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/NextPrevAddressPlugin.java @@ -316,16 +316,6 @@ public class NextPrevAddressPlugin extends Plugin { setDescription(isNext ? "Go to next location" : "Go to previous location"); } - @Override - public boolean isValidContext(ActionContext context) { - return false; - } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return (globalContext instanceof NavigatableActionContext); - } - @Override public boolean isEnabledForContext(ActionContext context) { Navigatable navigatable = getNavigatable(context); @@ -426,16 +416,6 @@ public class NextPrevAddressPlugin extends Plugin { setMenuBarData(menuData); } - @Override - public boolean isValidContext(ActionContext context) { - return false; - } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return (globalContext instanceof NavigatableActionContext); - } - @Override public boolean isEnabledForContext(ActionContext context) { Navigatable navigatable = getNavigatable(context); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/processors/LanguageProviderPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/processors/LanguageProviderPlugin.java index b85a2880a7..44b9fc6091 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/processors/LanguageProviderPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/processors/LanguageProviderPlugin.java @@ -326,7 +326,7 @@ public final class LanguageProviderPlugin extends Plugin implements FrontEndable SwingUtilities.invokeAndWait(() -> { ToolServices toolServices = tool.getToolServices(); String defaultToolName = toolServices.getDefaultToolTemplate(file).getName(); - for (Tool t : toolServices.getRunningTools()) { + for (PluginTool t : toolServices.getRunningTools()) { if (t.getName().equals(defaultToolName)) { openTool = (PluginTool) t; break; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/DeleteReferencesAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/DeleteReferencesAction.java index 3cfc5913bc..226bd34d00 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/DeleteReferencesAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/DeleteReferencesAction.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.references; import java.awt.event.KeyEvent; -import docking.ActionContext; import docking.action.KeyBindingData; import docking.action.MenuData; import ghidra.app.cmd.refs.RemoveAllReferencesCmd; @@ -116,10 +115,4 @@ public class DeleteReferencesAction extends ListingContextAction { } return actionOK; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } - } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/register/RegisterPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/register/RegisterPlugin.java index 495d71ccaf..5a3385776d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/register/RegisterPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/register/RegisterPlugin.java @@ -167,11 +167,6 @@ public class RegisterPlugin extends ProgramPlugin { } return false; } - - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - return false; // only work on active provider context. - } }; deleteRegisterRangeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0)); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java index 31c0f86fae..5927f65187 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/scalartable/ScalarSearchPlugin.java @@ -145,7 +145,7 @@ public class ScalarSearchPlugin extends ProgramPlugin implements DomainObjectLis } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { return !(context instanceof RestrictedAddressSetContext); } }; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java index 9af5bdc03a..0edd603493 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/searchmem/MemSearchPlugin.java @@ -350,7 +350,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener, } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { return !(context instanceof RestrictedAddressSetContext); } }; @@ -374,7 +374,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener, } @Override - protected boolean isValidContext(NavigatableActionContext context) { + protected boolean isValidNavigationContext(NavigatableActionContext context) { return !(context instanceof RestrictedAddressSetContext); } }; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/ProgramDropProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/ProgramDropProvider.java index cd1dd7daaa..4c4e240289 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/ProgramDropProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/ProgramDropProvider.java @@ -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. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java index e749a3b43f..8a109cb156 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java @@ -95,6 +95,7 @@ public class BinaryLoader extends AbstractProgramLoader { long length = 0; long fileOffset = 0; long origFileLength; + boolean isOverlay = false; try { origFileLength = provider.length(); } @@ -174,6 +175,7 @@ public class BinaryLoader extends AbstractProgramLoader { if (!Boolean.class.isAssignableFrom(option.getValueClass())) { return OPTION_NAME_IS_OVERLAY + " must be a boolean"; } + isOverlay = (boolean) option.getValue(); } } catch (Exception e) { @@ -194,7 +196,7 @@ public class BinaryLoader extends AbstractProgramLoader { return "Invalid length specified"; } if (program != null) { - if (program.getMemory().intersects(baseAddr, baseAddr.add(length - 1))) { + if (program.getMemory().intersects(baseAddr, baseAddr.add(length - 1)) && !isOverlay) { return "Memory Conflict: Use to change the base address!"; } } @@ -340,7 +342,7 @@ public class BinaryLoader extends AbstractProgramLoader { FileBytes fileBytes, long length, MessageLog log) throws AddressOverflowException, IOException { - if (prog.getMemory().intersects(baseAddr, baseAddr.add(length - 1))) { + if (prog.getMemory().intersects(baseAddr, baseAddr.add(length - 1)) && !isOverlay) { throw new IOException("Can't load " + length + " bytes at address " + baseAddr + " since it conflicts with existing memory blocks!"); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/FunctionsXmlMgr.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/FunctionsXmlMgr.java index 628bfa2892..d5887d3869 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/FunctionsXmlMgr.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/FunctionsXmlMgr.java @@ -166,7 +166,8 @@ class FunctionsXmlMgr { String regularComment = getElementText(parser, "REGULAR_CMT"); func.setComment(regularComment); - getElementText(parser, "REPEATABLE_CMT"); + String repeatableComment = getElementText(parser, "REPEATABLE_CMT"); + func.setRepeatableComment(repeatableComment); String typeInfoComment = getElementText(parser, "TYPEINFO_CMT"); List stackParams = new ArrayList<>(); List stackVariables = new ArrayList<>(); @@ -533,6 +534,7 @@ class FunctionsXmlMgr { writeReturnType(writer, func); writeAddressRange(writer, func); writeRegularComment(writer, func.getComment()); + writeRepeatableComment(writer, func.getRepeatableComment()); if (func.getSignatureSource() != SourceType.DEFAULT) { writeTypeInfoComment(writer, func); } @@ -602,6 +604,12 @@ class FunctionsXmlMgr { } } + private void writeRepeatableComment(XmlWriter writer, String comment) { + if (comment != null && comment.length() > 0) { + writer.writeElement("REPEATABLE_CMT", null, comment); + } + } + private void writeStackFrame(XmlWriter writer, Function func) { StackFrame frame = func.getStackFrame(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugins/fsbrowser/FSBUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/plugins/fsbrowser/FSBUtils.java index ac18d30e66..775a85d83d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/plugins/fsbrowser/FSBUtils.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/plugins/fsbrowser/FSBUtils.java @@ -22,7 +22,6 @@ import docking.ActionContext; import docking.widgets.tree.GTreeNode; import ghidra.app.services.ProgramManager; import ghidra.formats.gfilesystem.*; -import ghidra.framework.model.Tool; import ghidra.framework.plugintool.PluginTool; import ghidra.util.Msg; @@ -60,7 +59,7 @@ public class FSBUtils { } public static FSBRootNode getNodesRoot(FSBNode node) { - GTreeNode tmp = (GTreeNode) node; + GTreeNode tmp = node; while (tmp != null && !(tmp instanceof FSBRootNode)) { tmp = tmp.getParent(); } @@ -102,13 +101,11 @@ public class FSBUtils { public static List getRunningProgramManagerTools(PluginTool tool) { List pluginTools = new ArrayList<>(); - for (Tool runningTool : tool.getToolServices().getRunningTools()) { - if (runningTool instanceof PluginTool) { - PluginTool pt = (PluginTool) runningTool; - ProgramManager pmService = pt.getService(ProgramManager.class); - if (pmService != null) { - pluginTools.add(pt); - } + for (PluginTool runningTool : tool.getToolServices().getRunningTools()) { + PluginTool pt = runningTool; + ProgramManager pmService = pt.getService(ProgramManager.class); + if (pmService != null) { + pluginTools.add(pt); } } return pluginTools; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/test/ProjectTestUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/test/ProjectTestUtils.java index 927da808a3..6c359364e0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/test/ProjectTestUtils.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/test/ProjectTestUtils.java @@ -22,6 +22,7 @@ import java.util.*; import generic.test.AbstractGenericTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.framework.store.LockException; import ghidra.program.database.ProgramDB; import ghidra.program.model.lang.*; @@ -155,18 +156,18 @@ public class ProjectTestUtils { return dir.delete(); } - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { + for (File file : files) { + if (file.isDirectory()) { // use a dummy monitor as not to ruin our progress - if (!deleteDir(files[i])) { - Msg.debug(ProjectTestUtils.class, "Unable to delete directory: " + files[i]); + if (!deleteDir(file)) { + Msg.debug(ProjectTestUtils.class, "Unable to delete directory: " + file); return false; } } else { - if (!files[i].delete()) { - if (!ignoredDeleteNames.contains(files[i].getName())) { - Msg.debug(ProjectTestUtils.class, "Unable to delete file: " + files[i]); + if (!file.delete()) { + if (!ignoredDeleteNames.contains(file.getName())) { + Msg.debug(ProjectTestUtils.class, "Unable to delete file: " + file); return false; } @@ -186,6 +187,10 @@ public class ProjectTestUtils { * @param folder domain folder within the specified project which the * user has permission to write. If null, the root data folder will be used. * @return new domain file. + * @throws InvalidNameException if the filename is invalid + * @throws CancelledException if the opening is cancelled + * @throws LanguageNotFoundException if the language cannot be found + * @throws IOException if there is an exception creating the program or domain file */ public static DomainFile createProgramFile(Project proj, String progName, Language language, CompilerSpec compilerSpec, DomainFolder folder) throws InvalidNameException, @@ -210,8 +215,9 @@ public class ProjectTestUtils { * @param project the project to which the tool belongs * @param toolName name of the tool to get from the active workspace. * If null, launch a new empty tool in the active workspace. + * @return the tool */ - public static Tool getTool(Project project, String toolName) { + public static PluginTool getTool(Project project, String toolName) { ToolManager tm = project.getToolManager(); @@ -222,7 +228,7 @@ public class ProjectTestUtils { // use the first one for the testing Workspace activeWorkspace = workspaces[0]; - Tool tool = null; + PluginTool tool = null; if (toolName == null) { // create a new empty tool tool = activeWorkspace.createTool(); @@ -244,7 +250,7 @@ public class ProjectTestUtils { * @param tool The tool to be saved * @return The tool template for the given tool. */ - public static ToolTemplate saveTool(Project project, Tool tool) { + public static ToolTemplate saveTool(Project project, PluginTool tool) { // save the tool to the project tool chest ToolChest toolChest = project.getLocalToolChest(); ToolTemplate toolTemplate = tool.saveToolToToolTemplate(); @@ -254,8 +260,8 @@ public class ProjectTestUtils { /** * Remove the specified tool if it exists. - * @param project - * @param toolName + * @param project the project + * @param toolName the tool name * @return true if it existed and was removed from the local tool chest. */ public static boolean deleteTool(Project project, String toolName) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/test/TestEnv.java b/Ghidra/Features/Base/src/main/java/ghidra/test/TestEnv.java index e9c458225d..b6876c9834 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/test/TestEnv.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/test/TestEnv.java @@ -640,7 +640,7 @@ public class TestEnv { * NOTE: This array will not contain any of the TestTools! * @return an array of tools spawned by the Ghidra environment */ - public Tool[] getGhidraCreatedTools() { + public PluginTool[] getGhidraCreatedTools() { return gp.getProject().getToolManager().getRunningTools(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/util/data/DataTypeParser.java b/Ghidra/Features/Base/src/main/java/ghidra/util/data/DataTypeParser.java index 840c786a35..3505971ed9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/util/data/DataTypeParser.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/util/data/DataTypeParser.java @@ -20,7 +20,6 @@ import java.util.List; import ghidra.app.plugin.core.datamgr.util.DataTypeUtils; import ghidra.app.services.DataTypeQueryService; -import ghidra.app.services.DataTypeManagerService; import ghidra.program.database.data.DataTypeUtilities; import ghidra.program.database.data.ProgramDataTypeManager; import ghidra.program.model.data.*; @@ -440,8 +439,21 @@ public class DataTypeParser { private static String getBaseString(String dataTypeString) { int nextIndex = 0; + int templateCount = 0; while (nextIndex < dataTypeString.length()) { char c = dataTypeString.charAt(nextIndex); + if (c == '<') { + templateCount++; + } + else if (c == '>') { + templateCount--; + } + + if (templateCount != 0) { + ++nextIndex; + continue; + } + if (c == '*' || c == '[' || c == ':' || c == '{') { return dataTypeString.substring(0, nextIndex).trim(); } diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java index e2816e4c3e..8fe1c5042a 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java @@ -610,7 +610,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio } private void performLaunchKeyStrokeDialogAction() { - ToolActions toolActions = ((AbstractDockingTool) tool).getToolActions(); + ToolActions toolActions = (ToolActions) ((AbstractDockingTool) tool).getToolActions(); Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4")); assertNotNull(action); runSwing(() -> action.actionPerformed(new ActionEvent(this, 0, "")), false); @@ -624,7 +624,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio private JComponent component = new JTextField("Hey!"); - TestActionsComponentProvider(DockingTool tool) { + TestActionsComponentProvider(Tool tool) { super(tool, PROVIDER_NAME, "Fooberry Plugin"); } @@ -637,7 +637,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio private class HasDefaultKeyBindingComponentProvider extends ComponentProvider { private JComponent component = new JTextField("Hey!"); - HasDefaultKeyBindingComponentProvider(DockingTool tool) { + HasDefaultKeyBindingComponentProvider(Tool tool) { super(tool, HasDefaultKeyBindingComponentProvider.class.getSimpleName(), "Fooberry Plugin"); diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/DockingWindowManagerTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/DockingWindowManagerTest.java index d6899593ef..8c352f182b 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/DockingWindowManagerTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/DockingWindowManagerTest.java @@ -36,7 +36,7 @@ import ghidra.test.DummyTool; public class DockingWindowManagerTest extends AbstractDockingTest { - private DockingTool tool = new DummyTool(); + private Tool tool = new DummyTool(); @Test public void testDefaultGroupWindowPosition() { diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java index f8eaebce66..960756be3f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/action/KeyEntryDialogTest.java @@ -25,8 +25,8 @@ import javax.swing.*; import org.junit.*; import docking.*; +import docking.actions.DockingToolActions; import docking.actions.KeyEntryDialog; -import docking.actions.ToolActions; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin; import ghidra.framework.plugintool.PluginTool; @@ -197,7 +197,7 @@ public class KeyEntryDialogTest extends AbstractGhidraHeadedIntegrationTest { public DockingAction getKeyBindingAction() { - ToolActions toolActions = tool.getToolActions(); + DockingToolActions toolActions = tool.getToolActions(); KeyBindingsManager kbm = (KeyBindingsManager) getInstanceField("keyBindingsManager", toolActions); @SuppressWarnings("unchecked") diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/GhidraScriptMgrPlugin1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/GhidraScriptMgrPlugin1Test.java index 860fb93427..f8786c5b93 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/GhidraScriptMgrPlugin1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/script/GhidraScriptMgrPlugin1Test.java @@ -28,8 +28,7 @@ import org.junit.Test; import docking.DockingUtils; import docking.action.DockingActionIf; -import docking.actions.KeyBindingUtils; -import docking.actions.ToolActions; +import docking.actions.*; public class GhidraScriptMgrPlugin1Test extends AbstractGhidraScriptMgrPluginTest { @@ -147,7 +146,7 @@ public class GhidraScriptMgrPlugin1Test extends AbstractGhidraScriptMgrPluginTes KeyStroke actionKs = toolAction.getKeyBinding(); assertEquals(newKs, actionKs); - ToolActions toolActions = plugin.getTool().getToolActions(); + ToolActions toolActions = (ToolActions) plugin.getTool().getToolActions(); Action toolActionByKeyStroke = toolActions.getAction(newKs); assertNotNull(toolActionByKeyStroke); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/CreateDomainObjectTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/CreateDomainObjectTest.java index 523861f4c6..8cf67aa389 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/CreateDomainObjectTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/CreateDomainObjectTest.java @@ -15,11 +15,12 @@ */ package ghidra.framework.project; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import org.junit.*; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.framework.protocol.ghidra.GhidraURL; import ghidra.program.database.ProgramBuilder; import ghidra.program.model.listing.Program; @@ -73,7 +74,7 @@ public class CreateDomainObjectTest extends AbstractGhidraHeadedIntegrationTest // test 1 create a program and add it to a project Program program1 = createProgram(project, "Prog1", this); - Tool consumer2 = new DummyTool(); + PluginTool consumer2 = new DummyTool(); Program program2 = null; try { // test 2 - get the object from the project and make sure it is the @@ -213,7 +214,7 @@ public class CreateDomainObjectTest extends AbstractGhidraHeadedIntegrationTest private static void createProgramReadOnly(Project proj, String progName) throws Exception { - Tool t = new DummyTool(); + PluginTool t = new DummyTool(); Program p = createDefaultProgram(progName, ProgramBuilder._TOY, t); try { @@ -295,7 +296,7 @@ public class CreateDomainObjectTest extends AbstractGhidraHeadedIntegrationTest DomainFolder f3 = f.createFolder("Y"); DomainFolder f4 = f.createFolder("Z"); - Tool t = new DummyTool("Tool1"); + PluginTool t = new DummyTool("Tool1"); Program p1 = null; Program p2 = null; @@ -344,7 +345,7 @@ public class CreateDomainObjectTest extends AbstractGhidraHeadedIntegrationTest DomainFolder f3 = f.getFolder("Y"); DomainFolder f4 = f.getFolder("Z"); - Tool t = new DummyTool("Tool1"); + PluginTool t = new DummyTool("Tool1"); if ((f.getFile("AAA") == null) || (f.getFile("BBB") == null) || (f2.getFile("CCC") == null) || (f3.getFile("DDD") == null) || diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/AbstractToolSavingTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/AbstractToolSavingTest.java index 7501a98df1..db9cae750b 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/AbstractToolSavingTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/AbstractToolSavingTest.java @@ -200,9 +200,9 @@ public abstract class AbstractToolSavingTest extends AbstractGhidraHeadedIntegra protected List findOpenTools() { ToolManager tm = testEnv.getProject().getToolManager(); Workspace activeWorkspace = tm.getActiveWorkspace(); - Tool[] tools = activeWorkspace.getTools(); + PluginTool[] tools = activeWorkspace.getTools(); List pluginToolList = new ArrayList<>(tools.length); - for (Tool tool : tools) { + for (PluginTool tool : tools) { pluginToolList.add((PluginTool) tool); } return pluginToolList; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ChangeToolDataTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ChangeToolDataTest.java index 6bb17eef30..6fcead101e 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ChangeToolDataTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ChangeToolDataTest.java @@ -17,8 +17,10 @@ package ghidra.framework.project.tool; import org.junit.*; -import generic.test.AbstractGenericTest; -import ghidra.framework.model.*; +import generic.test.AbstractGTest; +import ghidra.framework.model.DomainFile; +import ghidra.framework.model.Project; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.database.ProgramBuilder; import ghidra.test.*; @@ -30,20 +32,12 @@ import ghidra.test.*; */ public class ChangeToolDataTest extends AbstractGhidraHeadedIntegrationTest { - private final static String DIRECTORY_NAME = AbstractGenericTest.getTestDirectoryPath(); + private final static String DIRECTORY_NAME = AbstractGTest.getTestDirectoryPath(); private final static String DATA_NAME_1 = "TestData1"; private final static String DATA_NAME_2 = "TestData2"; private Project project; - /** - * Constructor - * @param arg0 - */ - public ChangeToolDataTest() { - super(); - } - @Before public void setUp() throws Exception { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); @@ -56,8 +50,8 @@ public class ChangeToolDataTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); } - /** - * This doTest() routine tests the following requirements: + /* + * Tests the following requirements: * (1) connect two running tools by one or more specified events * (2) disconnect one or more specified events between two connected tools * @param args same as args to main() @@ -72,7 +66,7 @@ public class ChangeToolDataTest extends AbstractGhidraHeadedIntegrationTest { // // setup the running tool // - Tool runningTool = new DummyTool(); + PluginTool runningTool = new DummyTool(); // // TEST 1: set the data for a tool running without data diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java index f278ebe5cd..1df954ad6a 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java @@ -53,10 +53,8 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest { @After public void tearDown() throws Exception { - executeOnSwingWithoutBlocking(() -> env.dispose()); - + env.dispose(); closeAllWindows(); - } @Test diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ConnectToolsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ConnectToolsTest.java index a09412e697..78c8422614 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ConnectToolsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/ConnectToolsTest.java @@ -17,8 +17,9 @@ package ghidra.framework.project.tool; import org.junit.*; -import generic.test.AbstractGenericTest; +import generic.test.AbstractGTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.test.*; /** @@ -30,18 +31,10 @@ import ghidra.test.*; public class ConnectToolsTest extends AbstractGhidraHeadedIntegrationTest { private final static String BAD_EVENT_NAME = "TEST_CONNECT_FOR_BAD_EVENT"; - private final static String DIRECTORY_NAME = AbstractGenericTest.getTestDirectoryPath(); + private final static String DIRECTORY_NAME = AbstractGTest.getTestDirectoryPath(); private Project project; - /** - * Constructor - * @param arg0 - */ - public ConnectToolsTest() { - super(); - } - @Before public void setUp() throws Exception { @@ -56,16 +49,16 @@ public class ConnectToolsTest extends AbstractGhidraHeadedIntegrationTest { } - /** - * This doTest() routine tests the following requirements: + /* + * Tests the following requirements: * (1) connect two running tools by one or more specified events * (2) disconnect one or more specified events between two connected tools */ @Test public void testConnectTools() throws Exception { - Tool producer = new DummyTool("ProducerTool"); - Tool consumer = new DummyTool("ConsumerTool"); + PluginTool producer = new DummyTool("ProducerTool"); + PluginTool consumer = new DummyTool("ConsumerTool"); ToolConnection tc; String eventName = null; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateToolTest.java index 7bd1e0c48d..1f5428e6eb 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateToolTest.java @@ -17,8 +17,10 @@ package ghidra.framework.project.tool; import org.junit.*; -import generic.test.AbstractGenericTest; -import ghidra.framework.model.*; +import generic.test.AbstractGTest; +import ghidra.framework.model.Project; +import ghidra.framework.model.ToolManager; +import ghidra.framework.plugintool.PluginTool; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.ProjectTestUtils; @@ -29,20 +31,10 @@ import ghidra.test.ProjectTestUtils; */ public class CreateToolTest extends AbstractGhidraHeadedIntegrationTest { - private final static String DIRECTORY_NAME = AbstractGenericTest.getTestDirectoryPath(); + private final static String DIRECTORY_NAME = AbstractGTest.getTestDirectoryPath(); private Project project; -// private Workspace activeWorkspace; - - private Tool tool; - - /** - * Constructor - * @param arg0 - */ - public CreateToolTest() { - super(); - } + private PluginTool tool; @Before public void setUp() throws Exception { @@ -56,7 +48,7 @@ public class CreateToolTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); } - private void closeTool(final Tool theTool) { + private void closeTool(final PluginTool theTool) { executeOnSwingWithoutBlocking(new Runnable() { @Override public void run() { @@ -65,10 +57,10 @@ public class CreateToolTest extends AbstractGhidraHeadedIntegrationTest { }); // this handles the save changes dialog and potential analysis dialogs - closeAllWindowsAndFrames(); + closeAllWindows(); } - /** + /* * Do the test. * This doTest() routine tests the following requirements: * (1) create (launch) an empty tool in the active workspace @@ -92,7 +84,7 @@ public class CreateToolTest extends AbstractGhidraHeadedIntegrationTest { try { // verify the tool is actually running before declaring success ToolManager tm = project.getToolManager(); - Tool[] runningTools = tm.getRunningTools(); + PluginTool[] runningTools = tm.getRunningTools(); for (int t = 0; !verified && t < runningTools.length; t++) { if (runningTools[t].equals(tool)) { verified = true; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateWorkspaceTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateWorkspaceTest.java index 8a96d21557..f787f4e994 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateWorkspaceTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CreateWorkspaceTest.java @@ -15,7 +15,7 @@ */ package ghidra.framework.project.tool; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import java.io.IOException; @@ -23,6 +23,7 @@ import org.junit.*; import generic.test.AbstractGenericTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.framework.store.LockException; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.ProjectTestUtils; @@ -138,7 +139,7 @@ public class CreateWorkspaceTest extends AbstractGhidraHeadedIntegrationTest { } }); - Tool[] runningTools = wspaces[0].getTools(); + PluginTool[] runningTools = wspaces[0].getTools(); assertEquals(1, runningTools.length); setWorkspaceActive(wspaces[1]); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/DeleteToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/DeleteToolTest.java index cb38951d51..4a8b822012 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/DeleteToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/DeleteToolTest.java @@ -17,8 +17,9 @@ package ghidra.framework.project.tool; import org.junit.*; -import generic.test.AbstractGenericTest; +import generic.test.AbstractGTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.ProjectTestUtils; @@ -30,20 +31,12 @@ import ghidra.test.ProjectTestUtils; */ public class DeleteToolTest extends AbstractGhidraHeadedIntegrationTest { - private final static String PROJECT_DIRECTORY = AbstractGenericTest.getTestDirectoryPath(); + private final static String PROJECT_DIRECTORY = AbstractGTest.getTestDirectoryPath(); private final static String TOOL_NAME = "TestTool"; - private Tool runningTool; + private PluginTool runningTool; private Project project; - /** - * Constructor - * @param arg0 - */ - public DeleteToolTest() { - super(); - } - @Before public void setUp() throws Exception { ProjectTestUtils.deleteProject(PROJECT_DIRECTORY, PROJECT_NAME); @@ -56,8 +49,8 @@ public class DeleteToolTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteProject(PROJECT_DIRECTORY, PROJECT_NAME); } - /** - * This doTest() routine tests the following requirements: + /* + * Tsts the following requirements: * (1) delete a non-running tool from the user's project space * (2) delete a running tool from the user's project space * diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/RunToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/RunToolTest.java index 10c36aeb33..508d8cb2c4 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/RunToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/RunToolTest.java @@ -15,16 +15,13 @@ */ package ghidra.framework.project.tool; -import static org.junit.Assert.assertNotNull; - -import java.beans.PropertyVetoException; - -import javax.swing.SwingUtilities; +import static org.junit.Assert.*; import org.junit.*; -import generic.test.AbstractGenericTest; +import generic.test.AbstractGTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.ProjectTestUtils; @@ -36,20 +33,12 @@ import ghidra.test.ProjectTestUtils; */ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { - private final static String DIRECTORY_NAME = AbstractGenericTest.getTestDirectoryPath(); + private final static String DIRECTORY_NAME = AbstractGTest.getTestDirectoryPath(); private final static String TOOL_NAME = "TestTool"; private Project project; - private Tool runningTool; - private Tool tool; - - /** - * Constructor - * @param arg0 - */ - public RunToolTest() { - super(); - } + private PluginTool runningTool; + private PluginTool tool; @Before public void setUp() throws Exception { @@ -59,7 +48,7 @@ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { @After public void tearDown() throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { project.save(); @@ -69,7 +58,7 @@ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); } - /** + /* * Do the test. * This doTest() routine tests the following requirements: * (1) Run Project Tool Without Data @@ -84,22 +73,18 @@ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteTool(project, TOOL_NAME); // Create tool and save tool config - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { tool = ProjectTestUtils.getTool(project, null); - try { - tool.setToolName(TOOL_NAME); - } - catch (PropertyVetoException e) { - } + tool.setToolName(TOOL_NAME); } }); try { final ToolTemplate toolConfig = ProjectTestUtils.saveTool(project, tool); - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { tool.close(); @@ -118,14 +103,14 @@ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { // use the first one for the test final Workspace activeWorkspace = workspaces[0]; - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { runningTool = activeWorkspace.runTool(toolConfig); } }); assertNotNull(runningTool); - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { runningTool.close(); @@ -135,7 +120,7 @@ public class RunToolTest extends AbstractGhidraHeadedIntegrationTest { } finally { // Don't leave the tool in the tool chest - SwingUtilities.invokeAndWait(new Runnable() { + runSwing(new Runnable() { @Override public void run() { ProjectTestUtils.deleteTool(project, TOOL_NAME); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/SaveToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/SaveToolTest.java index dc0d8228a2..9b4d22355b 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/SaveToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/SaveToolTest.java @@ -15,12 +15,13 @@ */ package ghidra.framework.project.tool; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.*; -import generic.test.AbstractGenericTest; +import generic.test.AbstractGTest; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.ProjectTestUtils; @@ -29,20 +30,12 @@ import ghidra.test.ProjectTestUtils; */ public class SaveToolTest extends AbstractGhidraHeadedIntegrationTest { - private final static String DIRECTORY_NAME = AbstractGenericTest.getTestDirectoryPath(); + private final static String DIRECTORY_NAME = AbstractGTest.getTestDirectoryPath(); private final static String TOOL_NAME = "TestTool"; - private Tool runningTool; + private PluginTool runningTool; private Project project; - /** - * Constructor - * @param name The name of the test to run. - */ - public SaveToolTest() { - super(); - } - @Before public void setUp() throws Exception { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); @@ -55,7 +48,7 @@ public class SaveToolTest extends AbstractGhidraHeadedIntegrationTest { ProjectTestUtils.deleteProject(DIRECTORY_NAME, PROJECT_NAME); } - /** + /* * This tests the following requirements: * (1) create an empty tool in the active workspace, and * (2) that duplicate project names do not throw exceptions. diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/data/DataTypeParserTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/data/DataTypeParserTest.java index 66d187c540..baa1c1446e 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/data/DataTypeParserTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/data/DataTypeParserTest.java @@ -69,6 +69,45 @@ public class DataTypeParserTest extends AbstractEditorTest { super.tearDown(); } + @Test + public void testParse_NameWithTemplate() throws Exception { + + String typeName = "templated_name"; + StructureDataType structure = new StructureDataType(typeName, 0); + + tx(program, () -> { + programDTM.resolve(structure, null); + }); + + DataTypeParser parser = new DataTypeParser(dtmService, AllowedDataTypes.ALL); + DataType dt = parser.parse(typeName); + assertNotNull(dt); + assertTrue(dt.isEquivalent(structure)); + } + + @Test + public void testParse_PointerToNameWithTemplate() throws Exception { + + // + // Attempt to resolve a pointer to an existing type when that pointer does not already + // exist. + // + + String typeName = "templated_name"; + StructureDataType structure = new StructureDataType(typeName, 0); + PointerDataType pointer = new PointerDataType(structure); + String pointerName = pointer.getName(); + + tx(program, () -> { + programDTM.resolve(structure, null); + }); + + DataTypeParser parser = new DataTypeParser(dtmService, AllowedDataTypes.ALL); + DataType dt = parser.parse(pointerName); + assertNotNull(dt); + assertTrue(dt.isEquivalent(pointer)); + } + @Test public void testValidDataTypeSyntax() { checkValidDt("byte"); diff --git a/Ghidra/Features/GraphFunctionCalls/src/main/java/functioncalls/plugin/FcgProvider.java b/Ghidra/Features/GraphFunctionCalls/src/main/java/functioncalls/plugin/FcgProvider.java index 3e289e9a78..95dd6487b5 100644 --- a/Ghidra/Features/GraphFunctionCalls/src/main/java/functioncalls/plugin/FcgProvider.java +++ b/Ghidra/Features/GraphFunctionCalls/src/main/java/functioncalls/plugin/FcgProvider.java @@ -97,7 +97,7 @@ public class FcgProvider private ToggleDockingAction navigateIncomingToggleAction; - public FcgProvider(DockingTool tool, FunctionCallGraphPlugin plugin) { + public FcgProvider(Tool tool, FunctionCallGraphPlugin plugin) { super(tool, NAME, plugin.getName()); this.plugin = plugin; diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTSubToolManager.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTSubToolManager.java index 7db615c5a5..e7e4b1dd14 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTSubToolManager.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTSubToolManager.java @@ -174,7 +174,7 @@ public class VTSubToolManager implements VTControllerListener, OptionsChangeList return newTool; } - private DockingActionIf getToolAction(Tool tool, String actionName) { + private DockingActionIf getToolAction(PluginTool tool, String actionName) { Set actions = tool.getDockingActionsByOwnerName(ToolConstants.TOOL_OWNER); for (DockingActionIf action : actions) { if (action.getName().equals(actionName)) { diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/functionassociation/VTFunctionAssociationProvider.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/functionassociation/VTFunctionAssociationProvider.java index 773316a659..4f144d81e0 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/functionassociation/VTFunctionAssociationProvider.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/functionassociation/VTFunctionAssociationProvider.java @@ -219,7 +219,7 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter } @Override - public List getPopupActions(DockingTool tool, ActionContext context) { + public List getPopupActions(Tool tool, ActionContext context) { if (context.getComponentProvider() == this) { ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel(); diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableProvider.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableProvider.java index 69ce829e07..1f8abd13b7 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableProvider.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableProvider.java @@ -452,7 +452,7 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter } @Override - public List getPopupActions(DockingTool tool, ActionContext context) { + public List getPopupActions(Tool tool, ActionContext context) { ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel(); if (context.getComponentProvider() == this && dualListingPanel != null) { ListingPanel sourcePanel = dualListingPanel.getLeftPanel(); diff --git a/Ghidra/Framework/DB/src/main/java/db/NodeMgr.java b/Ghidra/Framework/DB/src/main/java/db/NodeMgr.java index 0f79c7e3bc..84cbe772b2 100644 --- a/Ghidra/Framework/DB/src/main/java/db/NodeMgr.java +++ b/Ghidra/Framework/DB/src/main/java/db/NodeMgr.java @@ -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. diff --git a/Ghidra/Framework/DB/src/main/java/db/buffers/ChangeMapFile.java b/Ghidra/Framework/DB/src/main/java/db/buffers/ChangeMapFile.java index 0f7626af54..0d72982afa 100644 --- a/Ghidra/Framework/DB/src/main/java/db/buffers/ChangeMapFile.java +++ b/Ghidra/Framework/DB/src/main/java/db/buffers/ChangeMapFile.java @@ -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. diff --git a/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java b/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java index d9c2be767e..fcb5e09fd4 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/AbstractDockingTool.java @@ -21,16 +21,15 @@ import java.util.*; import javax.swing.JFrame; import docking.action.DockingActionIf; -import docking.actions.PopupActionProvider; -import docking.actions.ToolActions; +import docking.actions.*; import ghidra.framework.options.ToolOptions; import ghidra.util.Swing; /** - * A partial implementation of {@link DockingTool} that serves as a place to share common + * A partial implementation of {@link Tool} that serves as a place to share common * functionality */ -public abstract class AbstractDockingTool implements DockingTool { +public abstract class AbstractDockingTool implements Tool { protected DockingWindowManager winMgr; protected ToolActions toolActions; @@ -209,11 +208,6 @@ public abstract class AbstractDockingTool implements DockingTool { winMgr.contextChanged(provider); } - @Override - public ActionContext getGlobalContext() { - return winMgr.getGlobalContext(); - } - @Override public void addContextListener(DockingContextListener listener) { winMgr.addContextListener(listener); @@ -240,7 +234,7 @@ public abstract class AbstractDockingTool implements DockingTool { } @Override - public ToolActions getToolActions() { + public DockingToolActions getToolActions() { return toolActions; } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java b/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java index c6c7c38d6a..ad26604735 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java @@ -85,7 +85,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext // maps for mapping old provider names and owner to new names and/or owner private static Map oldOwnerMap = new HashMap<>(); private static Map oldNameMap = new HashMap<>(); - protected DockingTool dockingTool; + protected Tool dockingTool; private String name; private final String owner; private String title; @@ -121,7 +121,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext * the same window. * @param owner The owner of this provider, usually a plugin name. */ - public ComponentProvider(DockingTool tool, String name, String owner) { + public ComponentProvider(Tool tool, String name, String owner) { this(tool, name, owner, null); } @@ -134,7 +134,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext * @param contextType the type of context supported by this provider; may be null (see * {@link #getContextType()} */ - public ComponentProvider(DockingTool tool, String name, String owner, Class contextType) { + public ComponentProvider(Tool tool, String name, String owner, Class contextType) { this.dockingTool = tool; this.name = name; this.owner = owner; @@ -744,7 +744,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext return this; } - public DockingTool getTool() { + public Tool getTool() { return dockingTool; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java b/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java index 595d162ea9..ed28d9a3fb 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockableToolBarManager.java @@ -74,7 +74,7 @@ class DockableToolBarManager { String owner = provider.getOwner(); ToolBarCloseAction closeAction = new ToolBarCloseAction(owner); closeButtonManager = new ToolBarItemManager(closeAction, winMgr); - DockingTool tool = winMgr.getTool(); + Tool tool = winMgr.getTool(); // we need to add this action to the tool in order to use key bindings tool.addLocalAction(provider, closeAction); @@ -166,7 +166,7 @@ class DockableToolBarManager { // this will be null for non-standard use cases if (dockableComponent != null) { DockingWindowManager dwm = dockableComponent.getDockingWindowManager(); - DockingTool tool = dwm.getTool(); + Tool tool = dwm.getTool(); ComponentProvider provider = dockableComponent.getComponentProvider(); tool.removeLocalAction(provider, closeButtonManager.getAction()); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingActionProxy.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingActionProxy.java index 8ff8c19c58..fb12bfc3cf 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingActionProxy.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingActionProxy.java @@ -117,11 +117,6 @@ public class DockingActionProxy return dockingAction.isValidContext(context); } - @Override - public boolean isValidGlobalContext(ActionContext context) { - return dockingAction.isValidGlobalContext(context); - } - @Override public void removePropertyChangeListener(PropertyChangeListener listener) { propertyListeners.remove(listener); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingKeyBindingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingKeyBindingAction.java index 42e9e20b03..22218ba3b7 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingKeyBindingAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingKeyBindingAction.java @@ -32,9 +32,9 @@ public abstract class DockingKeyBindingAction extends AbstractAction { private DockingActionIf docakbleAction; protected final KeyStroke keyStroke; - protected final DockingTool tool; + protected final Tool tool; - public DockingKeyBindingAction(DockingTool tool, DockingActionIf action, KeyStroke keyStroke) { + public DockingKeyBindingAction(Tool tool, DockingActionIf action, KeyStroke keyStroke) { super(KeyBindingUtils.parseKeyStroke(keyStroke)); this.tool = tool; this.docakbleAction = action; diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java index b4c9aca2f6..f83f1812f2 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java @@ -79,7 +79,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder // we use a list to maintain order private static List instances = new ArrayList<>(); - private DockingTool tool; + private Tool tool; private RootNode root; private PlaceholderManager placeholderManager; @@ -116,7 +116,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder * @param tool the tool * @param images the images to use for windows in this window manager */ - public DockingWindowManager(DockingTool tool, List images) { + public DockingWindowManager(Tool tool, List images) { this(tool, images, false, true, true, null); } @@ -131,7 +131,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder * @param hasStatusBar if true a status bar will be created for the main window * @param factory the drop target factory */ - public DockingWindowManager(DockingTool tool, List images, boolean modal, + public DockingWindowManager(Tool tool, List images, boolean modal, boolean isDocking, boolean hasStatusBar, DropTargetFactory factory) { KeyBindingOverrideKeyEventDispatcher.install(); @@ -330,7 +330,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder * Returns the tool that owns this manager * @return the tool */ - public DockingTool getTool() { + public Tool getTool() { return tool; } @@ -353,23 +353,6 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder defaultProvider = provider; } - /** - * Returns this tool's notion of the current action context, which is based upon the active - * {@link ComponentProvider}. If there is not active provider, then a generic context will - * be returned. - * - * @return the context - */ - public ActionContext getGlobalContext() { - if (defaultProvider != null) { - ActionContext actionContext = defaultProvider.getActionContext(null); - if (actionContext != null) { - return actionContext; - } - } - return new ActionContext(); - } - /** * Get the window which contains the specified Provider's component. * @param provider component provider diff --git a/Ghidra/Framework/Docking/src/main/java/docking/MenuBarMenuHandler.java b/Ghidra/Framework/Docking/src/main/java/docking/MenuBarMenuHandler.java index 8366eb08bd..ec01f01d32 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/MenuBarMenuHandler.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/MenuBarMenuHandler.java @@ -47,36 +47,20 @@ public class MenuBarMenuHandler extends MenuHandler { DockingWindowManager.clearMouseOverHelp(); ComponentProvider provider = windowManager.getActiveComponentProvider(); - ActionContext context = provider == null ? null : provider.getActionContext(null); - ActionContext localContext = context == null ? new ActionContext() : context; - ActionContext globalContext = windowManager.getGlobalContext(); + ActionContext providerContext = provider == null ? null : provider.getActionContext(null); + ActionContext context = providerContext == null ? new ActionContext() : providerContext; - ActionContext tempContext = null; - if (action.isValidContext(localContext)) { - tempContext = localContext; // we prefer the local over the global context if valid - } - else if (action.isValidGlobalContext(globalContext)) { - tempContext = globalContext; - } - else { - return; // context is not valid, nothing to do - } - - tempContext.setSourceObject(event.getSource()); - final ActionContext finalContext = tempContext; + context.setSourceObject(event.getSource()); // this gives the UI some time to repaint before executing the action - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - windowManager.setStatusText(""); - if (action.isEnabledForContext(finalContext)) { - if (action instanceof ToggleDockingActionIf) { - ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action); - toggleAction.setSelected(!toggleAction.isSelected()); - } - action.actionPerformed(finalContext); + SwingUtilities.invokeLater(() -> { + windowManager.setStatusText(""); + if (action.isValidContext(context) && action.isEnabledForContext(context)) { + if (action instanceof ToggleDockingActionIf) { + ToggleDockingActionIf toggleAction = ((ToggleDockingActionIf) action); + toggleAction.setSelected(!toggleAction.isSelected()); } + action.actionPerformed(context); } }); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingTool.java b/Ghidra/Framework/Docking/src/main/java/docking/Tool.java similarity index 96% rename from Ghidra/Framework/Docking/src/main/java/docking/DockingTool.java rename to Ghidra/Framework/Docking/src/main/java/docking/Tool.java index eb79345a45..b0a6d08277 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingTool.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/Tool.java @@ -24,12 +24,13 @@ import docking.action.DockingActionIf; import docking.actions.DockingToolActions; import docking.actions.PopupActionProvider; import ghidra.framework.options.ToolOptions; +import ghidra.framework.plugintool.ServiceProvider; /** * Generic tool interface for managing {@link ComponentProvider}s and * {@link DockingActionIf actions} */ -public interface DockingTool { +public interface Tool extends ServiceProvider { /** * Returns a combination of the tool name and the instance name of the form @@ -247,15 +248,6 @@ public interface DockingTool { */ public void contextChanged(ComponentProvider provider); - /** - * Returns this tool's notion of the current action context, which is based upon the active - * {@link ComponentProvider}. If there is not active provider, then a generic context will - * be returned. - * - * @return the context - */ - public ActionContext getGlobalContext(); - /** * Adds the given context listener to this tool * @param listener the listener to add diff --git a/Ghidra/Framework/Docking/src/main/java/docking/WindowActionManager.java b/Ghidra/Framework/Docking/src/main/java/docking/WindowActionManager.java index d7fa7a408b..9a86143e81 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/WindowActionManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/WindowActionManager.java @@ -121,7 +121,6 @@ public class WindowActionManager { ComponentProvider provider = placeHolderForScheduledActionUpdate == null ? null : placeHolderForScheduledActionUpdate.getProvider(); ActionContext localContext = provider == null ? null : provider.getActionContext(null); - ActionContext globalContext = winMgr.getGlobalContext(); if (localContext == null) { localContext = new ActionContext(); } @@ -132,9 +131,6 @@ public class WindowActionManager { if (action.isValidContext(localContext)) { action.setEnabled(action.isEnabledForContext(localContext)); } - else if (action.isValidGlobalContext(globalContext)) { - action.setEnabled(action.isEnabledForContext(globalContext)); - } else { action.setEnabled(false); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingAction.java index 0ae34ddc1b..5b112ebc3f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingAction.java @@ -76,7 +76,6 @@ public abstract class DockingAction implements DockingActionIf { private Predicate enabledPredicate; private Predicate popupPredicate; private Predicate validContextPredicate; - private Predicate validGlobalContextPredicate; public DockingAction(String name, String owner) { this.name = name; @@ -184,14 +183,6 @@ public abstract class DockingAction implements DockingActionIf { return true; } - @Override - public boolean isValidGlobalContext(ActionContext globalContext) { - if (validGlobalContextPredicate != null) { - return validGlobalContextPredicate.test(globalContext); - } - return isValidContext(globalContext); - } - /** * Default behavior is to add to main window; */ @@ -572,17 +563,6 @@ public abstract class DockingAction implements DockingActionIf { validContextPredicate = predicate; } - /** - * Sets a predicate for dynamically determining if this action is valid for the current global - * {@link ActionContext}. See {@link DockingActionIf#isValidGlobalContext(ActionContext)} - * - * @param predicate the predicate that will be used to dynamically determine an action's - * validity for a given global {@link ActionContext} - */ - public void validGlobalContextWhen(Predicate predicate) { - validGlobalContextPredicate = predicate; - } - //================================================================================================== // Non-public methods //================================================================================================== diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionIf.java b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionIf.java index bc86fcdf8a..80d92e768c 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionIf.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionIf.java @@ -193,19 +193,6 @@ public interface DockingActionIf extends HelpDescriptor { */ public boolean isValidContext(ActionContext context); - /** - * Method that actions implement to indicate if this action is valid (knows how to work with, is - * appropriate for) for the given global context. This method is just like the isValidContext - * and in fact calls that method by default. Many actions will work with either the active - * provider context or the global (the main listing) context if the local context is not valid. - * If you want a global action to only work on the global context, then override this method - * and return false. - * - * @param globalContext the global {@link ActionContext} from the active provider. - * @return true if this action is appropriate for the given context. - */ - public boolean isValidGlobalContext(ActionContext globalContext); - /** * Method used to determine if this action should be enabled for the given context. *

diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionProviderIf.java b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionProviderIf.java index 2aff5ffbcc..5819cd9e6c 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionProviderIf.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/DockingActionProviderIf.java @@ -17,7 +17,7 @@ package docking.action; import java.util.List; -import docking.DockingTool; +import docking.Tool; /** * An interface for objects (really Components) to implement that signals they provide actions @@ -29,7 +29,7 @@ import docking.DockingTool; * actions. Further, in this example, the actions given will be inserted into the popup menu * that is shown. * - * @deprecated use {@link DockingTool} + * @deprecated use {@link Tool} */ // Note: this API is not likely used by forward-facing clients and can be removed in the next release @Deprecated(since = "9.1", forRemoval = true) diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/KeyBindingsManager.java b/Ghidra/Framework/Docking/src/main/java/docking/action/KeyBindingsManager.java index 780d2f5527..f29071f815 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/KeyBindingsManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/KeyBindingsManager.java @@ -38,9 +38,9 @@ public class KeyBindingsManager implements PropertyChangeListener { // this map exists to update the MultiKeyBindingAction when the key binding changes private Map actionToProviderMap; private Map dockingKeyMap; - private DockingTool tool; + private Tool tool; - public KeyBindingsManager(DockingTool tool) { + public KeyBindingsManager(Tool tool) { this.tool = tool; dockingKeyMap = new HashMap<>(); actionToProviderMap = new HashMap<>(); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java index 4541fb7044..9417957562 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java @@ -40,7 +40,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { * @param action action that will be added to the list of actions bound to a keystroke * @param keyStroke the keystroke, if any, associated with the action */ - public MultipleKeyAction(DockingTool tool, ComponentProvider provider, DockingActionIf action, + public MultipleKeyAction(Tool tool, ComponentProvider provider, DockingActionIf action, KeyStroke keyStroke) { super(tool, action, keyStroke); addAction(provider, action); @@ -121,8 +121,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { ActionContext localContext = getLocalContext(localProvider); localContext.setSourceObject(event.getSource()); - ActionContext globalContext = tool.getGlobalContext(); - List list = getValidContextActions(localContext, globalContext); + List list = getValidContextActions(localContext); // If menu active, disable all key bindings if (ignoreActionWhileMenuShowing()) { @@ -164,8 +163,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { return menuManager.getSelectedPath().length != 0; } - private List getValidContextActions(ActionContext localContext, - ActionContext globalContext) { + private List getValidContextActions(ActionContext localContext) { List list = new ArrayList<>(); boolean hasLocalActionsForKeyBinding = false; @@ -222,9 +220,6 @@ public class MultipleKeyAction extends DockingKeyBindingAction { if (isValidAndEnabled(actionData, localContext)) { list.add(new ExecutableKeyActionAdapter(actionData.action, localContext)); } - else if (isValidAndEnabledGlobally(actionData, globalContext)) { - list.add(new ExecutableKeyActionAdapter(actionData.action, globalContext)); - } } } return list; @@ -235,11 +230,6 @@ public class MultipleKeyAction extends DockingKeyBindingAction { return a.isValidContext(localContext) && a.isEnabledForContext(localContext); } - private boolean isValidAndEnabledGlobally(ActionData actionData, ActionContext globalContext) { - DockingActionIf a = actionData.action; - return a.isValidGlobalContext(globalContext) && a.isEnabledForContext(globalContext); - } - @Override public boolean isReservedKeybindingPrecedence() { return false; // MultipleKeyActions can never be reserved @@ -249,9 +239,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { public KeyBindingPrecedence getKeyBindingPrecedence() { ComponentProvider localProvider = tool.getActiveComponentProvider(); ActionContext localContext = getLocalContext(localProvider); - ActionContext globalContext = tool.getGlobalContext(); - List validActions = - getValidContextActions(localContext, globalContext); + List validActions = getValidContextActions(localContext); if (validActions.isEmpty()) { return null; // a signal that no actions are valid for the current context diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/ReservedKeyBindingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/ReservedKeyBindingAction.java index 2d69b23cd0..5128599358 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/ReservedKeyBindingAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/ReservedKeyBindingAction.java @@ -21,7 +21,7 @@ import docking.*; class ReservedKeyBindingAction extends DockingKeyBindingAction { - ReservedKeyBindingAction(DockingTool tool, DockingActionIf action, KeyStroke keyStroke) { + ReservedKeyBindingAction(Tool tool, DockingActionIf action, KeyStroke keyStroke) { super(tool, action, keyStroke); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java index 88b620f723..222d8b87ee 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/AbstractActionBuilder.java @@ -19,10 +19,12 @@ import java.util.function.Consumer; import java.util.function.Predicate; import javax.swing.Icon; +import javax.swing.KeyStroke; import docking.*; import docking.action.*; import ghidra.util.HelpLocation; +import ghidra.util.Msg; import resources.ResourceManager; /** @@ -137,6 +139,11 @@ public abstract class AbstractActionBuilder validContextPredicate; - /** - * Predicate for determining if an action is applicable for a given global context - */ - private Predicate validGlobalContextPredicate; - /** * Builder constructor * @param name the name of the action to be built @@ -175,7 +177,7 @@ public abstract class AbstractActionBuilderNote: most actions will not use this method, but rely instead on - * {@link #enabledWhen(Predicate)}. - * - * @param predicate the predicate that will be used to dynamically determine an action's - * validity for a given global {@link ActionContext} - * @return this builder (for chaining) - */ - public B validGlobalContextWhen(Predicate predicate) { - validGlobalContextPredicate = predicate; - return self(); - } - protected void validate() { if (actionCallback == null) { throw new IllegalStateException( @@ -547,6 +559,7 @@ public abstract class AbstractActionBuilder getAllActions(); + + /** + * Allows clients to register an action by using a placeholder. This is useful when + * an API wishes to have a central object (like a plugin) register actions for transient + * providers, that may not be loaded until needed. + * + *

This method may be called multiple times with the same conceptual placeholder--the + * placeholder will only be added once. + * + * @param placeholder the placeholder containing information related to the action it represents + */ + public void registerSharedActionPlaceholder(SharedDockingActionPlaceholder placeholder); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyBindingUtils.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyBindingUtils.java index e095aa8165..bd5c4e5efa 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyBindingUtils.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/KeyBindingUtils.java @@ -33,7 +33,7 @@ import org.jdom.*; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; -import docking.DockingTool; +import docking.Tool; import docking.DockingUtils; import docking.action.*; import docking.widgets.filechooser.GhidraFileChooser; @@ -465,7 +465,7 @@ public class KeyBindingUtils { * @param tool the tool containing the actions * @return the actions mapped by their full name (e.g., 'Name (OwnerName)') */ - public static Map> getAllActionsByFullName(DockingTool tool) { + public static Map> getAllActionsByFullName(Tool tool) { Map> result = LazyMap.lazyMap(new HashMap<>(), s -> new LinkedList<>()); @@ -493,7 +493,7 @@ public class KeyBindingUtils { * @param owner the action owner name * @return the actions */ - public static Set getKeyBindingActionsForOwner(DockingTool tool, + public static Set getKeyBindingActionsForOwner(Tool tool, String owner) { Map deduper = new HashMap<>(); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/PopupActionProvider.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/PopupActionProvider.java index 7268e2f335..380bff8eb7 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/PopupActionProvider.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/PopupActionProvider.java @@ -18,13 +18,13 @@ package docking.actions; import java.util.List; import docking.ActionContext; -import docking.DockingTool; +import docking.Tool; import docking.action.DockingActionIf; /** * Provides notification when the popup action menu is displayed. This interface allows * temporary/transient actions (those not registered with the tool via - * {@link DockingTool#addAction(DockingActionIf)}) to be used in the popup context menu. + * {@link Tool#addAction(DockingActionIf)}) to be used in the popup context menu. * *

* Most clients will register actions directly with the tool. However, clients that have numerous @@ -32,7 +32,7 @@ import docking.action.DockingActionIf; * on demand as the popup is about to be shown, and only if their context is active. This * mechanism can reduce the tool's action management overhead. Once you have created an * implementation of this class, you must register it with - * {@link DockingTool#addPopupActionProvider(PopupActionProvider)}. + * {@link Tool#addPopupActionProvider(PopupActionProvider)}. */ public interface PopupActionProvider { @@ -46,5 +46,5 @@ public interface PopupActionProvider { * @param context the ActionContext * @return list of temporary popup actions; return null if there are no popup actions */ - public List getPopupActions(DockingTool tool, ActionContext context); + public List getPopupActions(Tool tool, ActionContext context); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedActionRegistry.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedActionRegistry.java index 1d8670a44a..755bebc3f7 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedActionRegistry.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/SharedActionRegistry.java @@ -15,7 +15,7 @@ */ package docking.actions; -import docking.DockingTool; +import docking.Tool; import docking.action.DockingActionIf; import docking.tool.ToolConstants; import docking.widgets.table.GTable; @@ -33,7 +33,7 @@ public class SharedActionRegistry { * @param tool the tool * @param toolActions the tool action manager */ - public static void installSharedActions(DockingTool tool, ToolActions toolActions) { + public static void installSharedActions(Tool tool, ToolActions toolActions) { GTable.createSharedActions(tool, toolActions, ToolConstants.SHARED_OWNER); } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java b/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java index adac9e97be..6fd42d9a8f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/actions/ToolActions.java @@ -55,7 +55,7 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { private Map sharedActionMap = new HashMap<>(); private ToolOptions keyBindingOptions; - private DockingTool dockingTool; + private Tool dockingTool; private KeyBindingsManager keyBindingsManager; /** @@ -64,7 +64,7 @@ public class ToolActions implements DockingToolActions, PropertyChangeListener { * @param tool tool using this ActionManager * @param actionToGuiHelper the class that takes actions and maps them to GUI widgets */ - public ToolActions(DockingTool tool, ActionToGuiHelper actionToGuiHelper) { + public ToolActions(Tool tool, ActionToGuiHelper actionToGuiHelper) { this.dockingTool = tool; this.actionGuiHelper = actionToGuiHelper; this.keyBindingsManager = new KeyBindingsManager(tool); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java index dc411e78ea..5b034086bb 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java @@ -150,8 +150,7 @@ public abstract class MultiStateDockingAction extends DockingAction { DockingWindowManager manager = DockingWindowManager.getActiveInstance(); ComponentProvider provider = manager.getActiveComponentProvider(); ActionContext localContext = provider == null ? null : provider.getActionContext(null); - final ActionContext actionContext = - localContext == null ? manager.getGlobalContext() : localContext; + ActionContext actionContext = localContext == null ? new ActionContext() : localContext; return actionContext; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/ToolBarItemManager.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/ToolBarItemManager.java index 7085f6632e..b05db19667 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/menu/ToolBarItemManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/ToolBarItemManager.java @@ -189,33 +189,23 @@ public class ToolBarItemManager implements PropertyChangeListener, ActionListene @Override public void actionPerformed(ActionEvent event) { DockingWindowManager.clearMouseOverHelp(); - ActionContext localContext = getActionContext(); - ActionContext globalContext = null; - if (windowManager != null) { - globalContext = windowManager.getGlobalContext(); + ActionContext context = getActionContext(); + + if (!toolBarAction.isValidContext(context)) { + return; } - ActionContext tempContext = null; - if (toolBarAction.isValidContext(localContext)) { - tempContext = localContext; // we prefer the local over the global context if valid - } - else if (toolBarAction.isValidGlobalContext(globalContext)) { - tempContext = globalContext; - } - else { - return; // context is not valid, nothing to do - } - tempContext.setSourceObject(event.getSource()); - final ActionContext finalContext = tempContext; + context.setSourceObject(event.getSource()); // this gives the UI some time to repaint before executing the action SwingUtilities.invokeLater(() -> { - if (toolBarAction.isEnabledForContext(finalContext)) { + if (toolBarAction.isValidContext(context) && + toolBarAction.isEnabledForContext(context)) { if (toolBarAction instanceof ToggleDockingActionIf) { ToggleDockingActionIf toggleAction = (ToggleDockingActionIf) toolBarAction; toggleAction.setSelected(!toggleAction.isSelected()); } - toolBarAction.actionPerformed(finalContext); + toolBarAction.actionPerformed(context); } }); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java b/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java index ade9a16fbc..49983ddc2b 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/test/AbstractDockingTest.java @@ -1098,7 +1098,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the name to match * @return the matching actions; empty list if no matches */ - public static Set getActionsByName(DockingTool tool, String name) { + public static Set getActionsByName(Tool tool, String name) { Set result = new HashSet<>(); @@ -1119,7 +1119,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the owner's name to match * @return the matching actions; empty list if no matches */ - public static Set getActionsByOwner(DockingTool tool, String name) { + public static Set getActionsByOwner(Tool tool, String name) { return tool.getDockingActionsByOwnerName(name); } @@ -1132,7 +1132,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the owner's name to match * @return the matching actions; empty list if no matches */ - public static Set getActionsByOwnerAndName(DockingTool tool, String owner, + public static Set getActionsByOwnerAndName(Tool tool, String owner, String name) { Set ownerActions = tool.getDockingActionsByOwnerName(owner); return ownerActions.stream() @@ -1143,7 +1143,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { /** * Finds the singular tool action by the given name. If more than one action exists with * that name, then an exception is thrown. If you want more than one matching action, - * the call {@link #getActionsByName(DockingTool, String)} instead. + * the call {@link #getActionsByName(Tool, String)} instead. * *

Note: more specific test case subclasses provide other methods for finding actions * when you have an owner name (which is usually the plugin name). @@ -1152,7 +1152,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the name to match * @return the matching action; null if no matching action can be found */ - public static DockingActionIf getAction(DockingTool tool, String name) { + public static DockingActionIf getAction(Tool tool, String name) { Set actions = getActionsByName(tool, name); if (actions.isEmpty()) { @@ -1169,7 +1169,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { /** * Finds the action by the given owner name and action name. * If you do not know the owner name, then use - * the call {@link #getActionsByName(DockingTool, String)} instead (this will not include + * the call {@link #getActionsByName(Tool, String)} instead (this will not include * reserved system actions). * *

Note: more specific test case subclasses provide other methods for finding actions @@ -1180,7 +1180,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the name to match * @return the matching action; null if no matching action can be found */ - public static DockingActionIf getAction(DockingTool tool, String owner, String name) { + public static DockingActionIf getAction(Tool tool, String owner, String name) { Set actions = getActionsByOwnerAndName(tool, owner, name); if (actions.isEmpty()) { return null; @@ -1203,7 +1203,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @return the action */ public static DockingActionIf getLocalAction(ComponentProvider provider, String actionName) { - DockingTool tool = provider.getTool(); + Tool tool = provider.getTool(); DockingToolActions toolActions = tool.getToolActions(); DockingActionIf action = toolActions.getLocalAction(provider, actionName); return action; @@ -1862,7 +1862,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { * @param name the name of the provider to show * @return the newly shown provider */ - public ComponentProvider showProvider(DockingTool tool, String name) { + public ComponentProvider showProvider(Tool tool, String name) { ComponentProvider provider = tool.getComponentProvider(name); tool.showComponentProvider(provider, true); return provider; @@ -1870,7 +1870,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest { /** * Closes the given provider. You could just call - * {@link DockingTool#removeComponentProvider(ComponentProvider)}, but some providers have extra + * {@link Tool#removeComponentProvider(ComponentProvider)}, but some providers have extra * logic that happens when {@link ComponentProvider#closeComponent()} is called. This will * likely change in the future. * diff --git a/Ghidra/Framework/Docking/src/main/java/docking/tool/util/DockingToolConstants.java b/Ghidra/Framework/Docking/src/main/java/docking/tool/util/DockingToolConstants.java index 5f05b96ec5..69fd48f6d5 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/tool/util/DockingToolConstants.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/tool/util/DockingToolConstants.java @@ -15,10 +15,10 @@ */ package docking.tool.util; -import docking.DockingTool; +import docking.Tool; /** - * An interface to house constants used by the {@link DockingTool} + * An interface to house constants used by the {@link Tool} */ public interface DockingToolConstants { diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTable.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTable.java index 6c4147be1b..025b7b86fd 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTable.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTable.java @@ -1203,7 +1203,7 @@ public class GTable extends JTable { GTableToCSV.writeCSVUsingColunns(file, GTable.this, columnList); } - public static void createSharedActions(DockingTool tool, ToolActions toolActions, + public static void createSharedActions(Tool tool, ToolActions toolActions, String owner) { String actionMenuGroup = "zzzTableGroup"; diff --git a/Ghidra/Framework/Docking/src/test.slow/java/docking/actions/SharedKeyBindingDockingActionTest.java b/Ghidra/Framework/Docking/src/test.slow/java/docking/actions/SharedKeyBindingDockingActionTest.java index 851ec56f9f..e3cb5222dd 100644 --- a/Ghidra/Framework/Docking/src/test.slow/java/docking/actions/SharedKeyBindingDockingActionTest.java +++ b/Ghidra/Framework/Docking/src/test.slow/java/docking/actions/SharedKeyBindingDockingActionTest.java @@ -54,7 +54,7 @@ public class SharedKeyBindingDockingActionTest extends AbstractDockingTest { private SpyErrorLogger spyLogger = new SpyErrorLogger(); - private DockingTool tool; + private Tool tool; @Before public void setUp() { diff --git a/Ghidra/Framework/Docking/src/test/java/docking/FakeDockingTool.java b/Ghidra/Framework/Docking/src/test/java/docking/FakeDockingTool.java index 2696dbccaa..e62cbb8b2a 100644 --- a/Ghidra/Framework/Docking/src/test/java/docking/FakeDockingTool.java +++ b/Ghidra/Framework/Docking/src/test/java/docking/FakeDockingTool.java @@ -23,9 +23,10 @@ import javax.swing.ImageIcon; import docking.actions.ToolActions; import docking.framework.ApplicationInformationDisplayFactory; import ghidra.framework.options.ToolOptions; +import ghidra.framework.plugintool.util.ServiceListener; /** - * A Test Double of the {@link DockingTool} that provides minimal tool functionality, such + * A Test Double of the {@link Tool} that provides minimal tool functionality, such * as the {@link DockingWindowManager} */ public class FakeDockingTool extends AbstractDockingTool { @@ -62,4 +63,19 @@ public class FakeDockingTool extends AbstractDockingTool { public void close() { // stub } + + @Override + public T getService(Class serviceClass) { + return null; + } + + @Override + public void addServiceListener(ServiceListener listener) { + // stub + } + + @Override + public void removeServiceListener(ServiceListener listener) { + // stub + } } diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/IntIntHashtable.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/IntIntHashtable.java index b7390643b0..4fbb0c84a6 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/IntIntHashtable.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/IntIntHashtable.java @@ -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. diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/LongDoubleHashtable.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/LongDoubleHashtable.java index 62cdc1eb81..24a687fe91 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/LongDoubleHashtable.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/LongDoubleHashtable.java @@ -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. diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/ObjectKeyIndexer.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/ObjectKeyIndexer.java index cc85911c3c..07e1d55545 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/ObjectKeyIndexer.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/ObjectKeyIndexer.java @@ -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. diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/StringKeyIndexer.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/StringKeyIndexer.java index 173ea4b955..471737ca05 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/StringKeyIndexer.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/datastruct/StringKeyIndexer.java @@ -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. diff --git a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/VisualGraphComponentProvider.java b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/VisualGraphComponentProvider.java index 2c5dd05592..fe1afc08d0 100644 --- a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/VisualGraphComponentProvider.java +++ b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/VisualGraphComponentProvider.java @@ -59,11 +59,11 @@ public abstract class VisualGraphComponentProvider> subFeatures = new ArrayList<>(); - protected VisualGraphComponentProvider(DockingTool tool, String name, String owner) { + protected VisualGraphComponentProvider(Tool tool, String name, String owner) { super(tool, name, owner); } - protected VisualGraphComponentProvider(DockingTool tool, String name, String owner, + protected VisualGraphComponentProvider(Tool tool, String name, String owner, Class contextType) { super(tool, name, owner, contextType); } diff --git a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/featurette/VgSatelliteFeaturette.java b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/featurette/VgSatelliteFeaturette.java index bef3c7ac4d..8b404bb0f9 100644 --- a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/featurette/VgSatelliteFeaturette.java +++ b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/featurette/VgSatelliteFeaturette.java @@ -60,7 +60,7 @@ public class VgSatelliteFeaturette view; private String owner; private String providerName; @@ -229,7 +229,7 @@ public class VgSatelliteFeaturetteconfirmClose is called. * - * @param confirmClose true if the confirmation dialog should be - * displayed * @param isExiting true if we are closing the project because * Ghidra is exiting * @return false if user cancels the close operation @@ -428,9 +431,9 @@ class FileActionManager { } // check for any changes since last saved - Tool[] runningTools = activeProject.getToolManager().getRunningTools(); - for (int i = 0; i < runningTools.length; i++) { - if (!runningTools[i].canClose(isExiting)) { + PluginTool[] runningTools = activeProject.getToolManager().getRunningTools(); + for (PluginTool runningTool : runningTools) { + if (!runningTool.canClose(isExiting)) { return false; } } @@ -655,7 +658,7 @@ class FileActionManager { /** * Checks the list for read-only files; if any are found, pops up * a dialog for whether to save now or lose changes. - * @param files list of files which correspond to modified + * @param objs list of files which correspond to modified * domain objects. * @return true if there are no read only files OR if the user * wants to lose his changes; false if the user wants to save the diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java index bac8087625..08600d5354 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java @@ -660,9 +660,9 @@ public class FrontEndPlugin extends Plugin private ToolTemplate getUpToDateTemplate(ToolTemplate template) { ToolManager toolManager = activeProject.getToolManager(); - Tool[] runningTools = toolManager.getRunningTools(); + PluginTool[] runningTools = toolManager.getRunningTools(); String templateName = template.getName(); - for (Tool runningTool : runningTools) { + for (PluginTool runningTool : runningTools) { if (runningTool.getName().equals(templateName)) { return runningTool.getToolTemplate(true); } @@ -960,8 +960,8 @@ public class FrontEndPlugin extends Plugin private boolean isToolRunning(ToolTemplate template) { ToolManager toolManager = activeProject.getToolManager(); - Tool[] runningTools = toolManager.getRunningTools(); - for (Tool runningTool : runningTools) { + PluginTool[] runningTools = toolManager.getRunningTools(); + for (PluginTool runningTool : runningTools) { if (runningTool.getToolName().equals(template.getName())) { return true; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java index 53e87c9aee..d44c07123d 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java @@ -745,8 +745,8 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener { @Override public boolean canCloseDomainFile(DomainFile df) { - Tool[] tools = getProject().getToolManager().getRunningTools(); - for (Tool tool : tools) { + PluginTool[] tools = getProject().getToolManager().getRunningTools(); + for (PluginTool tool : tools) { DomainFile[] files = tool.getDomainFiles(); for (DomainFile domainFile : files) { if (df == domainFile) { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectInfoDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectInfoDialog.java index eac6e066da..071e86f6ab 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectInfoDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectInfoDialog.java @@ -34,6 +34,7 @@ import ghidra.app.util.GenericHelpTopics; import ghidra.framework.client.*; import ghidra.framework.data.ConvertFileSystem; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.framework.remote.User; import ghidra.framework.store.local.*; import ghidra.util.*; @@ -456,10 +457,10 @@ public class ProjectInfoDialog extends DialogComponentProvider { } private boolean filesAreOpen() { - Tool[] tools = project.getToolManager().getRunningTools(); + PluginTool[] tools = project.getToolManager().getRunningTools(); if (tools.length > 0) { - for (Tool tool : tools) { + for (PluginTool tool : tools) { if (tool.getDomainFiles().length > 0) { return true; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/RunningToolsPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/RunningToolsPanel.java index 8f7a8427d3..8408441e14 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/RunningToolsPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/RunningToolsPanel.java @@ -23,12 +23,14 @@ import java.util.Map; import javax.swing.*; import docking.DockingUtils; -import ghidra.framework.model.*; +import ghidra.framework.model.ToolTemplate; +import ghidra.framework.model.Workspace; +import ghidra.framework.plugintool.PluginTool; class RunningToolsPanel extends JPanel { private JToolBar runningToolbar; private FrontEndPlugin plugin; - private Map runningTools; + private Map runningTools; RunningToolsPanel(FrontEndPlugin plugin, Workspace ws) { super(new BorderLayout(0, 0)); @@ -55,12 +57,13 @@ class RunningToolsPanel extends JPanel { // remove the default etched border add(runningToolbar, BorderLayout.CENTER); - runningTools = new HashMap(WorkspacePanel.TYPICAL_NUM_RUNNING_TOOLS); + runningTools = + new HashMap(WorkspacePanel.TYPICAL_NUM_RUNNING_TOOLS); // populate the toolbar if the workspace has running tools if (ws != null) { - Tool[] tools = ws.getTools(); - for (Tool element : tools) { + PluginTool[] tools = ws.getTools(); + for (PluginTool element : tools) { addTool(element); } } @@ -73,7 +76,7 @@ class RunningToolsPanel extends JPanel { return runningToolbar.getPreferredSize(); } - void addTool(Tool runningTool) { + void addTool(PluginTool runningTool) { ToolButton toolButton = new ToolButton(plugin, runningTool, runningTool.getToolTemplate(true)); runningToolbar.add(toolButton); @@ -83,7 +86,7 @@ class RunningToolsPanel extends JPanel { repaint(); } - void removeTool(Tool tool) { + void removeTool(PluginTool tool) { ToolButton button = runningTools.get(tool); if (button == null) { return; @@ -97,13 +100,13 @@ class RunningToolsPanel extends JPanel { } // parameter not used - void toolNameChanged(Tool changedTool) { + void toolNameChanged(PluginTool changedTool) { } /** * Update the tool template for the tool button. */ - void updateToolButton(Tool tool, ToolTemplate template, Icon icon) { + void updateToolButton(PluginTool tool, ToolTemplate template, Icon icon) { ToolButton button = runningTools.get(tool); if (button != null) { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolActionManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolActionManager.java index 90d9398a5c..d7d66ceeab 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolActionManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolActionManager.java @@ -307,7 +307,7 @@ class ToolActionManager implements ToolChestChangeListener { } // only enable if project has more than 1 running tool ToolManager tm = project.getToolManager(); - Tool[] runningTools = tm.getRunningTools(); + PluginTool[] runningTools = tm.getRunningTools(); connectToolsAction.setEnabled(runningTools.length > 1); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java index 5fbae30216..1fb96282cc 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java @@ -65,7 +65,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { private FrontEndPlugin plugin; private ToolTemplate template; - private Tool associatedRunningTool; + private PluginTool associatedRunningTool; private DefaultToolChangeListener toolChangeListener; private ToolServices toolServices; @@ -83,7 +83,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { * Construct a tool label that represents a running tool, using the * default RUNNING_TOOL icon. */ - ToolButton(FrontEndPlugin plugin, Tool tool, ToolTemplate template) { + ToolButton(FrontEndPlugin plugin, PluginTool tool, ToolTemplate template) { this(plugin, tool, template, tool.getIconURL()); setHelpLocation("Run_Tool"); } @@ -91,7 +91,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { /** * Construct a tool label that represents a running tool. */ - private ToolButton(FrontEndPlugin plugin, Tool tool, ToolTemplate template, + private ToolButton(FrontEndPlugin plugin, PluginTool tool, ToolTemplate template, ToolIconURL iconURL) { super(iconURL.getIcon()); this.plugin = plugin; @@ -298,9 +298,9 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { private void addFromToolButton(ToolButton toolButton) { plugin.setToolButtonTransferable(null); - Tool tool = null; + PluginTool tool = null; if (associatedRunningTool != null && toolButton.associatedRunningTool != null) { - final Tool t2 = toolButton.associatedRunningTool; + final PluginTool t2 = toolButton.associatedRunningTool; SwingUtilities.invokeLater(() -> connectTools(associatedRunningTool, t2)); return; } @@ -309,14 +309,14 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { if (toolButton.associatedRunningTool == null) { tool = plugin.getActiveWorkspace().runTool(toolButton.template); accepted = tool.acceptDomainFiles(associatedRunningTool.getDomainFiles()); - final Tool t = tool; + final PluginTool t = tool; SwingUtilities.invokeLater(() -> connectTools(t, associatedRunningTool)); } else { tool = plugin.getActiveWorkspace().runTool(template); accepted = tool.acceptDomainFiles(toolButton.associatedRunningTool.getDomainFiles()); - final Tool t = tool; - final Tool t2 = toolButton.associatedRunningTool; + final PluginTool t = tool; + final PluginTool t2 = toolButton.associatedRunningTool; SwingUtilities.invokeLater(() -> connectTools(t, t2)); } @@ -328,7 +328,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { /** * Connect the tools in both directions. */ - private void connectTools(Tool t1, Tool t2) { + private void connectTools(PluginTool t1, PluginTool t2) { ToolManager tm = plugin.getActiveProject().getToolManager(); ToolConnection tc = tm.getConnection(t1, t2); connectAll(tc); @@ -514,7 +514,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { associatedRunningTool.close(); } - Tool getRunningTool() { + PluginTool getRunningTool() { return associatedRunningTool; } @@ -570,7 +570,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { Msg.debug(this, "Found root frame without a GhidraGlassPane registered!"); // try to recover without animation - Tool newTool = plugin.getActiveWorkspace().runTool(template); + PluginTool newTool = plugin.getActiveWorkspace().runTool(template); openDomainFiles(newTool, domainFiles); finishedCallback.run(); return; @@ -621,7 +621,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { try { // cleanup any residual painting effects toolGlassPane.paintImmediately(toolGlassPane.getBounds()); - Tool newTool = plugin.getActiveWorkspace().runTool(template); + PluginTool newTool = plugin.getActiveWorkspace().runTool(template); openDomainFiles(newTool, domainFiles); } finally { @@ -640,7 +640,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { zoomRunner.run(); } - private void openDomainFiles(Tool tool, DomainFile[] domainFiles) { + private void openDomainFiles(PluginTool tool, DomainFile[] domainFiles) { if (domainFiles == null) { return; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionDialog.java index 29f5670ee8..202e6f0c7e 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionDialog.java @@ -23,6 +23,7 @@ import javax.swing.JPanel; import docking.DialogComponentProvider; import ghidra.app.util.GenericHelpTopics; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.HelpLocation; /** @@ -39,9 +40,6 @@ class ToolConnectionDialog extends DialogComponentProvider implements WorkspaceC private JButton connectAllButton; private JButton disconnectAllButton; - /** - * Constructor - */ ToolConnectionDialog(FrontEndTool tool, ToolManager toolManager) { super("Connect Tools", false); this.frontEndTool = tool; @@ -59,9 +57,6 @@ class ToolConnectionDialog extends DialogComponentProvider implements WorkspaceC toolManager.addWorkspaceChangeListener(this); } - /** - * Set the dialog to be visible according to the v param. - */ void setVisible(boolean v) { if (v) { @@ -79,27 +74,16 @@ class ToolConnectionDialog extends DialogComponentProvider implements WorkspaceC } } - // WorkspaceChangedListener - /** - * Tool was added to the given workspace. - */ @Override - public void toolAdded(Workspace ws, Tool tool) { + public void toolAdded(Workspace ws, PluginTool tool) { panel.toolAdded(tool); } - /** - * Tool was removed from the given workspace. - */ @Override - public void toolRemoved(Workspace ws, Tool tool) { + public void toolRemoved(Workspace ws, PluginTool tool) { panel.toolRemoved(tool); } - /* - * (non-Javadoc) - * @see ghidra.util.bean.GhidraDialog#okCallback() - */ @Override protected void okCallback() { setVisible(false); @@ -117,23 +101,15 @@ class ToolConnectionDialog extends DialogComponentProvider implements WorkspaceC public void workspaceSetActive(Workspace ws) { } - /** - * Property change on the workspace. - */ @Override public void propertyChange(PropertyChangeEvent event) { Object eventSource = event.getSource(); - if (eventSource instanceof Tool) { + if (eventSource instanceof PluginTool) { // tool name might have changed updateDisplay(); } } - /////////////////////////////////////////////////////////////////// - - /** - * Update the tool manager object. - */ void setToolManager(ToolManager tm) { toolManager.removeWorkspaceChangeListener(this); toolManager = tm; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionPanel.java index 196e65a807..c117ee3a81 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolConnectionPanel.java @@ -27,7 +27,9 @@ import javax.swing.event.ListSelectionListener; import docking.widgets.checkbox.GCheckBox; import docking.widgets.label.GDLabel; import docking.widgets.list.GListCellRenderer; -import ghidra.framework.model.*; +import ghidra.framework.model.ToolConnection; +import ghidra.framework.model.ToolManager; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.Msg; /** @@ -41,20 +43,16 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { private ToolConnectionDialog toolDialog; private ToolManager toolManager; - private JList consumerList; // list of receiver tools - private JList producerList; // list of source (of events) + private JList consumerList; // list of receiver tools + private JList producerList; // list of source (of events) private JList eventList; // names of events generated by source - private DefaultListModel producerModel; - private DefaultListModel consumerModel; + private DefaultListModel producerModel; + private DefaultListModel consumerModel; private GCheckBox[] checkboxes; private String[] eventNames; private final static String msgSource = "Tool Connection"; - /** - * Constructor - * @param myTool plugin tool associated with this connect panel - */ ToolConnectionPanel(ToolConnectionDialog toolDialog, ToolManager toolManager) { super(); this.toolDialog = toolDialog; @@ -62,9 +60,6 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { initialize(); } - /** - * ListSelectionListener method to process selection events. - */ @Override public void valueChanged(ListSelectionEvent e) { toolDialog.setStatusText(""); @@ -77,9 +72,6 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { processSelection(); } - /** - * Set the tool manager; need to do this if another project is opened. - */ void setToolManager(ToolManager toolManager) { this.toolManager = toolManager; updateDisplay(); @@ -91,8 +83,8 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { * added or removed. */ void updateDisplay() { - Tool producer = producerList.getSelectedValue(); - Tool consumer = consumerList.getSelectedValue(); + PluginTool producer = producerList.getSelectedValue(); + PluginTool consumer = consumerList.getSelectedValue(); showData(); @@ -138,7 +130,7 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { * Tool was added to the workspace; update the display. * @param tool tool added */ - void toolAdded(Tool tool) { + void toolAdded(PluginTool tool) { String[] consumedEvents = tool.getConsumedToolEventNames(); String[] producedEvents = tool.getToolEventNames(); if (consumedEvents.length > 0) { @@ -154,7 +146,7 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { * Tool was removed from a workspace; update the display. * @param tool tool removed */ - void toolRemoved(Tool tool) { + void toolRemoved(PluginTool tool) { int index = producerModel.indexOf(tool); if (index >= 0) { producerModel.remove(index); @@ -167,13 +159,10 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { validate(); } - /** - * Interconnect two producers and consumers - */ void connectAll(boolean connect) { - Tool producer = producerList.getSelectedValue(); - Tool consumer = consumerList.getSelectedValue(); + PluginTool producer = producerList.getSelectedValue(); + PluginTool consumer = consumerList.getSelectedValue(); // clear the event list eventList.setModel(new DefaultListModel<>()); @@ -237,8 +226,8 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { GListCellRenderer.createDefaultCellTextRenderer(tool -> tool.getName())); consumerList.setCellRenderer( GListCellRenderer.createDefaultCellTextRenderer(tool -> tool.getName())); - producerModel = (DefaultListModel) producerList.getModel(); - consumerModel = (DefaultListModel) consumerList.getModel(); + producerModel = (DefaultListModel) producerList.getModel(); + consumerModel = (DefaultListModel) consumerList.getModel(); } private void processMouseClicked(MouseEvent e) { @@ -256,8 +245,8 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { checkboxes[index].setSelected(!selected); refreshList(checkboxes); - Tool producer = producerList.getSelectedValue(); - Tool consumer = consumerList.getSelectedValue(); + PluginTool producer = producerList.getSelectedValue(); + PluginTool consumer = consumerList.getSelectedValue(); doConnect(producer, consumer, eventNames[index], !selected); int connectedCount = 0; @@ -270,7 +259,8 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { } } - private void doConnect(Tool producer, Tool consumer, String eventName, boolean connect) { + private void doConnect(PluginTool producer, PluginTool consumer, String eventName, + boolean connect) { ToolConnection tc = toolManager.getConnection(producer, consumer); if (tc.isConnected(eventName) == connect) { // if already connected @@ -292,13 +282,13 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { private void populateConsumerList() { consumerModel.removeAllElements(); - Tool[] tools = toolManager.getConsumerTools(); + PluginTool[] tools = toolManager.getConsumerTools(); Arrays.sort(tools, (t1, t2) -> { return t1.getName().compareTo(t2.getName()); }); - for (Tool tool : tools) { + for (PluginTool tool : tools) { consumerModel.addElement(tool); } if (tools.length == 0) { @@ -309,13 +299,13 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { private void populateProducerList() { producerModel.removeAllElements(); - Tool[] tools = toolManager.getProducerTools(); + PluginTool[] tools = toolManager.getProducerTools(); Arrays.sort(tools, (t1, t2) -> { return t1.getName().compareTo(t2.getName()); }); - for (Tool tool : tools) { + for (PluginTool tool : tools) { producerModel.addElement(tool); } if (tools.length == 0) { @@ -327,13 +317,13 @@ class ToolConnectionPanel extends JPanel implements ListSelectionListener { // clear the event list eventList.setModel(new DefaultListModel<>()); - Tool producer = producerList.getSelectedValue(); + PluginTool producer = producerList.getSelectedValue(); if (producer == null) { toolDialog.setStatusText("Please select an Event Producer"); return; } - Tool consumer = consumerList.getSelectedValue(); + PluginTool consumer = consumerList.getSelectedValue(); if (consumer == null) { toolDialog.setStatusText("Please select an Event Consumer"); return; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/WorkspacePanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/WorkspacePanel.java index 3506532f4d..71ad2a40ab 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/WorkspacePanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/WorkspacePanel.java @@ -28,6 +28,7 @@ import docking.help.HelpService; import docking.widgets.combobox.GComboBox; import docking.widgets.dialogs.InputDialog; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.HelpLocation; import ghidra.util.Msg; import ghidra.util.exception.DuplicateNameException; @@ -87,7 +88,7 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { * Tool was removed from the given workspace. */ @Override - public void toolRemoved(Workspace ws, Tool tool) { + public void toolRemoved(Workspace ws, PluginTool tool) { removeTool(ws.getName(), tool); plugin.getToolActionManager().enableConnectTools(); } @@ -96,7 +97,7 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { * Tool was added to the given workspace. */ @Override - public void toolAdded(Workspace ws, Tool tool) { + public void toolAdded(Workspace ws, PluginTool tool) { addTool(ws.getName(), tool); plugin.getToolActionManager().enableConnectTools(); } @@ -192,13 +193,13 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { // if this is a change in a tool, update the running tools panel // containing the tool Object eventSource = event.getSource(); - if (eventSource instanceof Tool) { - Tool tool = (Tool) eventSource; + if (eventSource instanceof PluginTool) { + PluginTool tool = (PluginTool) eventSource; ToolTemplate template = tool.getToolTemplate(true); Icon icon = tool.getIconURL().getIcon(); String workspaceName = activeWorkspace.getName(); RunningToolsPanel rtp = runningToolsMap.get(workspaceName); - if (eventPropertyName.equals(Tool.TOOL_NAME_PROPERTY)) { + if (eventPropertyName.equals(PluginTool.TOOL_NAME_PROPERTY)) { rtp.toolNameChanged(tool); } else { @@ -210,6 +211,7 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { /** * called whenever the active project changes or is being set for * the first time + * @param project the project */ void setActiveProject(Project project) { // clear state from previous project @@ -233,8 +235,8 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { ToolManager toolManager = project.getToolManager(); toolManager.addWorkspaceChangeListener(this); - Tool[] tools = toolManager.getRunningTools(); - for (Tool tool : tools) { + PluginTool[] tools = toolManager.getRunningTools(); + for (PluginTool tool : tools) { tool.addPropertyChangeListener(this); } @@ -247,10 +249,7 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { initProjectState(activeProject); } - /** - * add a running tool to the panel - */ - void addTool(String workspaceName, Tool runningTool) { + void addTool(String workspaceName, PluginTool runningTool) { RunningToolsPanel rtp = runningToolsMap.get(workspaceName); if (rtp != null) { rtp.addTool(runningTool); @@ -418,8 +417,9 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { } /** - * cause the specified workspace to be the active one + * Cause the specified workspace to be the active one * NOTE: this workspace must already be known to the ToolManager + * @param ws the workspace */ void setActiveWorkspace(Workspace ws) { chooseWorkspace(ws.getName()); @@ -452,7 +452,7 @@ class WorkspacePanel extends JPanel implements WorkspaceChangeListener { setBorder(INACTIVE_BORDER); } - private void removeTool(String workspaceName, Tool tool) { + private void removeTool(String workspaceName, PluginTool tool) { RunningToolsPanel rtp = runningToolsMap.get(workspaceName); if (rtp != null) { rtp.removeTool(tool); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataOpenToolAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataOpenToolAction.java index 606315b08e..c0752298ed 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataOpenToolAction.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataOpenToolAction.java @@ -24,6 +24,7 @@ import ghidra.framework.main.AppInfo; import ghidra.framework.main.datatable.ProjectDataActionContext; import ghidra.framework.main.datatable.ProjectDataContextAction; import ghidra.framework.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.HTMLUtilities; import ghidra.util.HelpLocation; @@ -58,7 +59,7 @@ public class ProjectDataOpenToolAction extends ProjectDataContextAction { Workspace activeWorkspace = toolManager.getActiveWorkspace(); ToolTemplate template = toolChest.getToolTemplate(toolName); - Tool newTool = activeWorkspace.runTool(template); + PluginTool newTool = activeWorkspace.runTool(template); DomainFile[] files = fileList.toArray(new DomainFile[fileList.size()]); newTool.acceptDomainFiles(files); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/VersionControlAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/VersionControlAction.java index 8c2b3997a9..38e51ffa24 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/VersionControlAction.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/VersionControlAction.java @@ -122,8 +122,8 @@ public abstract class VersionControlAction extends DomainFileProviderContextActi */ boolean canCloseDomainFile(DomainFile df) { Project project = tool.getProject(); - Tool[] tools = project.getToolManager().getRunningTools(); - for (Tool t : tools) { + PluginTool[] tools = project.getToolManager().getRunningTools(); + for (PluginTool t : tools) { DomainFile[] files = t.getDomainFiles(); for (DomainFile domainFile : files) { if (df == domainFile) { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Tool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Tool.java deleted file mode 100644 index c1e5b7dade..0000000000 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Tool.java +++ /dev/null @@ -1,221 +0,0 @@ -/* ### - * 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 ghidra.framework.model; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyVetoException; - -import org.jdom.Element; - -import docking.DockingTool; -import docking.util.image.ToolIconURL; -import ghidra.framework.plugintool.PluginEvent; - -/** - * - * A Tool represents a collection of Plugins that are the basic building - * blocks. The plugins cooperate with one another to achieve certain - * functionality. The tool interface defines methods called by the - * Project that manages the tools. - */ -public interface Tool extends DockingTool, ToolListener { - - /** - * Name of the property for the tool name. - */ - public final static String TOOL_NAME_PROPERTY = "ToolName"; - /** - * Name of the property for the tool icon. - */ - public final static String ICON_PROPERTY_NAME = "Icon"; - /** - * Name of the property for the description of the tool. - */ - public final static String DESCRIPTION_PROPERTY_NAME = "Description"; - /** - * Name of the property for the number of plugins the tool has. - */ - public final static String PLUGIN_COUNT_PROPERTY_NAME = "PluginCount"; - - /** - * Tells the tool to stop functioning and release its resources. - * The tool should dispose of all its windows and other resources. - */ - public void exit(); - - /** - * Can this tool be closed? - * @param isExiting true if all of Ghidra is closing, false if just this tool is closing. - * @return true if the tool is in a state that it can be closed. - */ - public boolean canClose(boolean isExiting); - - /** - * Can the domain File be closed? - *
Note: This forces plugins to terminate any tasks they have running for the - * indicated domain object and apply any unsaved data to the domain object. If they can't do - * this or the user cancels then this returns false. - * @return false any of the plugins reports that the domain object - * should not be closed - */ - public boolean canCloseDomainFile(DomainFile domainFile); - - /** - * Fire the plugin event by notifying the event manager which - * calls the listeners. - * @param event plugin event - */ - public void firePluginEvent(PluginEvent event); - - /** - * Returns the name associated with the tool - */ - public String getToolName(); - - /** - * Sets the type name of the tool. - * @param toolName the basename to use when setting the tool's name - * @exception PropertyVetoException thrown if a VetoableChangeListener - * rejects the change - */ - public void setToolName(String toolName) throws PropertyVetoException; - - /** - * Associates a unique(within the active project) name to a tool instance. - * @param instanceName unique tool instance name - */ - public void putInstanceName(String instanceName); - - /** - * Returns the tool's unique name. - */ - public String getInstanceName(); - - /** - * Returns the names of all the possible ToolEvents that this - * tool might generate. Used by the ConnectionManager to connect - * tools together. - */ - public String[] getToolEventNames(); - - /** - * Returns a list of eventNames that this Tool is interested in. - */ - public String[] getConsumedToolEventNames(); - - /** - * When the user drags a data file onto a tool, an event will be fired - * that the tool will respond to by accepting the data. - * - * @param data the data to be used by the running tool - */ - public boolean acceptDomainFiles(DomainFile[] data); - - /** - * Get the domain files that this tool currently has open. - */ - public DomainFile[] getDomainFiles(); - - /** - * Adds a ToolListener to be notified for any of a Tool's ToolEvents. - * The listener will be notified of any events that this tool generates. - * - * @param listener ToolListener to be added to receive all events - */ - public void addToolListener(ToolListener listener); - - /** - * Removes a ToolListener from receiving any event generated by this Tool. - * The tool will still receive specific events that it has registered for. - * - * @param listener The ToolListener to be removed from receiving all events. - */ - public void removeToolListener(ToolListener listener); - - /** - * Add property change listener. - */ - public void addPropertyChangeListener(PropertyChangeListener l); - - /** - * Remove property change listener. - */ - public void removePropertyChangeListener(PropertyChangeListener l); - - /** - * Get the classes of the data types that this tool supports, - * i.e., what data types can be dropped onto this tool. - */ - public Class[] getSupportedDataTypes(); - - /** - * Tells tool to write its data state from the given output stream. - * @param isTransactionState true if saving the toolstate is for a potential undo/redo - * (database transaction) - */ - public Element saveDataStateToXml(boolean isTransactionState); - - /** - * Tells tool to read its data state from the given input stream. - * @param element XML data state - */ - public void restoreDataStateFromXml(Element element); - - /** - * Set the icon for this tool. - * @param iconURL icon location - */ - public void setIconURL(ToolIconURL iconURL); - - /** - * Get the url for the icon that this tool is using. - */ - public ToolIconURL getIconURL(); - - /** - * Returns a ToolTemplate for this Tool that describes the state of the tool. - * @return a ToolTemplate for this Tool that describes the state of the tool. - */ - public ToolTemplate getToolTemplate(boolean includeConfigState); - - /** - * Save the tool and return its state as a ToolTemplate. Forces a complete - * regeneration of the tool template. - * @return a toolTemplate for this tool. - */ - public ToolTemplate saveToolToToolTemplate(); - - /** - * Saves the tool's Docking Window layout and positioning information to an XML element. - * @return the element containing the DockingWindow's layout information. - */ - public Element saveWindowingDataToXml(); - - /** - * Restores the tool's Docking Window layout and positioning information from an XML element. - * @param windowData the element containing the information. - */ - public void restoreWindowingDataFromXml(Element windowData); - - /** - * Returns true if this tool should save its data, based upon its changed state and the state - * of Ghidra's saving method. - * @return true if this tool should save its data - */ - public boolean shouldSave(); - - public Element saveToXml(boolean includeConfigState); -} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolConnection.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolConnection.java index c32243b82e..a55ddec9de 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolConnection.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolConnection.java @@ -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,60 +15,63 @@ */ package ghidra.framework.model; +import ghidra.framework.plugintool.PluginTool; + /** * Represents a connection between a producer tool and a * consumer tool. */ public interface ToolConnection { - /** - * Get the tool that produces an event. - */ - public Tool getProducer(); - - /** - * Get the tool that consumes an event. - */ - public Tool getConsumer(); + /** + * Get the tool that produces an event + * @return the tool + */ + public PluginTool getProducer(); /** - * Get the list of event names that is an intersection - * between what the producer produces and what the - * consumers consumes. - * - * @return an array of event names - */ - public String[] getEvents(); + * Get the tool that consumes an event + * @return the tool + */ + public PluginTool getConsumer(); - /** - * Connect the tools for the given event name. - * - * @param eventName name of event to connect - * - * @throws IllegalArgumentException if eventName is not valid for this + /** + * Get the list of event names that is an intersection + * between what the producer produces and what the + * consumers consumes. + * + * @return an array of event names + */ + public String[] getEvents(); + + /** + * Connect the tools for the given event name. + * + * @param eventName name of event to connect + * + * @throws IllegalArgumentException if eventName is not valid for this * producer/consumer pair. - */ - public void connect(String eventName); + */ + public void connect(String eventName); /** - * Break the connection between the tools for the - * given event name. - * - * @param eventName name of event to disconnect - * - * @throws IllegalArgumentException if eventName is not valid for this - * producer/consumer pair. - */ - public void disconnect(String eventName); + * Break the connection between the tools for the + * given event name. + * + * @param eventName name of event to disconnect + * + * @throws IllegalArgumentException if eventName is not valid for this + * producer/consumer pair. + */ + public void disconnect(String eventName); - /** - * Return whether the tools are connected for the - * given event name. - * + /** + * Return whether the tools are connected for the + * given event name. + * * @param eventName name of event to check * @return true if the tools are connected by eventName. */ - public boolean isConnected(String eventName); - + public boolean isConnected(String eventName); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolManager.java index 78250d3ac2..71d8157b62 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolManager.java @@ -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,6 +15,7 @@ */ package ghidra.framework.model; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.exception.DuplicateNameException; /** @@ -29,106 +29,103 @@ import ghidra.util.exception.DuplicateNameException; */ public interface ToolManager { - /** - * The name to use for a new unnamed workspace; used by the Ghidra - * Project Window when the user creates a new workspace. - */ - public final static String DEFAULT_WORKSPACE_NAME = "Workspace"; - - /** - * Property used when sending the change event when a workspace name is - * changed. - */ - public final static String WORKSPACE_NAME_PROPERTY = "WorkspaceName"; - - /** - * Get the connection object for the producer and consumer - * tools. - * - * @param producer tool that is producing the tool event - * @param consumer tool that is consuming the tool event - */ - public ToolConnection getConnection(Tool producer, Tool consumer); - - /** - * Get a list of tools that produce at least one tool event. - * - * @return zero-length array if no tool produces any events - */ - public Tool[] getProducerTools(); - - /** - * Get a list of tools that consume at least one tool event. - * - * @return zero-length array if no tool consumes any events - */ - public Tool[] getConsumerTools(); - - - /** - * Get a list running tools across all workspaces. - * - * @return zero-length array if there are no running tools. - */ - public Tool[] getRunningTools(); - - /** - * Create a workspace with the given name. - * - * @param name name of workspace - * - * @throws DuplicateNameException if a workspace with this - * name already exists. - */ - public Workspace createWorkspace(String name) throws DuplicateNameException; - - /** - * Remove the workspace. - * - * @param ws workspace to remove - */ - public void removeWorkspace(Workspace ws); - - /** - * Get list of known workspaces. - * - * @return an array of known workspaces - */ - public Workspace[] getWorkspaces(); - - /** - * Get the active workspace - * - * @return the active workspace - */ - public Workspace getActiveWorkspace(); + /** + * The name to use for a new unnamed workspace; used by the Ghidra + * Project Window when the user creates a new workspace. + */ + public final static String DEFAULT_WORKSPACE_NAME = "Workspace"; /** - * Add the listener that will be notified when a tool is added - * or removed. - * - * @param listener workspace listener to add - */ - public void addWorkspaceChangeListener(WorkspaceChangeListener listener); - - /** - * Remove the workspace listener. - * - * @param l workspace listener to remove - */ - public void removeWorkspaceChangeListener(WorkspaceChangeListener l); + * Property used when sending the change event when a workspace name is + * changed. + */ + public final static String WORKSPACE_NAME_PROPERTY = "WorkspaceName"; + + /** + * Get the connection object for the producer and consumer tools + * + * @param producer tool that is producing the tool event + * @param consumer tool that is consuming the tool event + * @return the connection + */ + public ToolConnection getConnection(PluginTool producer, PluginTool consumer); + + /** + * Get a list of tools that produce at least one tool event. + * + * @return zero-length array if no tool produces any events + */ + public PluginTool[] getProducerTools(); + + /** + * Get a list of tools that consume at least one tool event. + * + * @return zero-length array if no tool consumes any events + */ + public PluginTool[] getConsumerTools(); + + /** + * Get a list running tools across all workspaces. + * + * @return zero-length array if there are no running tools. + */ + public PluginTool[] getRunningTools(); + + /** + * Create a workspace with the given name. + * + * @param name name of workspace + * @return the workspace + * @throws DuplicateNameException if a workspace with this name already exists + */ + public Workspace createWorkspace(String name) throws DuplicateNameException; + + /** + * Remove the workspace. + * + * @param ws workspace to remove + */ + public void removeWorkspace(Workspace ws); + + /** + * Get list of known workspaces. + * + * @return an array of known workspaces + */ + public Workspace[] getWorkspaces(); + + /** + * Get the active workspace + * + * @return the active workspace + */ + public Workspace getActiveWorkspace(); + + /** + * Add the listener that will be notified when a tool is added + * or removed. + * + * @param listener workspace listener to add + */ + public void addWorkspaceChangeListener(WorkspaceChangeListener listener); + + /** + * Remove the workspace listener. + * + * @param l workspace listener to remove + */ + public void removeWorkspaceChangeListener(WorkspaceChangeListener l); /** * Removes all connections involving tool * @param tool tool for which to remove all connections */ - public void disconnectTool(Tool tool); - + public void disconnectTool(PluginTool tool); + /** * A configuration change was made to the tool; a plugin was added * or removed. * @param tool tool that changed */ - public void toolChanged(Tool tool); + public void toolChanged(PluginTool tool); } - diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolServices.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolServices.java index bed0424e18..c4b07d6fe5 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolServices.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolServices.java @@ -19,6 +19,7 @@ import java.io.*; import java.util.Set; import ghidra.framework.plugintool.PluginEvent; +import ghidra.framework.plugintool.PluginTool; /** * Services that the Tool uses. @@ -33,7 +34,7 @@ public interface ToolServices { * * @param tool tool that is closing */ - public void closeTool(Tool tool); + public void closeTool(PluginTool tool); /** * Saves the tool's configuration in the standard @@ -41,7 +42,7 @@ public interface ToolServices { * * @param tool tool to save. */ - public void saveTool(Tool tool); + public void saveTool(PluginTool tool); /** * Save the tool to the given location on the local file system. @@ -54,7 +55,8 @@ public interface ToolServices { public File exportTool(ToolTemplate tool) throws FileNotFoundException, IOException; /** - * Get the tool chest for the project. + * Get the tool chest for the project + * @return the tool chest */ public ToolChest getToolChest(); @@ -68,7 +70,7 @@ public interface ToolServices { * @param domainFile open this file in the found/created tool. * @param event invoke this event on the found/created tool */ - public void displaySimilarTool(Tool tool, DomainFile domainFile, PluginEvent event); + public void displaySimilarTool(PluginTool tool, DomainFile domainFile, PluginEvent event); /** * Returns the default tool template used to open the tool. Here default means the @@ -83,6 +85,7 @@ public interface ToolServices { /** * Returns a set of tools that can open the given domain file class. * @param domainClass The domain file class type for which to get tools + * @return the tools */ public Set getCompatibleTools(Class domainClass); @@ -90,6 +93,7 @@ public interface ToolServices { * Returns the {@link ToolAssociationInfo associations}, which describe content * types and the tools used to open them, for all content types known to the system. * + * @return the associations * @see #setContentTypeToolAssociations(Set) */ public Set getContentTypeToolAssociations(); @@ -107,24 +111,27 @@ public interface ToolServices { * Launch the default tool; if domainFile is not null, this file will * be opened in the tool. * @param domainFile the file to open; may be null + * @return the tool */ - public Tool launchDefaultTool(DomainFile domainFile); + public PluginTool launchDefaultTool(DomainFile domainFile); /** * Launch the tool with the given name * @param toolName name of the tool to launch * @param domainFile the file to open; may be null + * @return the tool */ - public Tool launchTool(String toolName, DomainFile domainFile); + public PluginTool launchTool(String toolName, DomainFile domainFile); /** - * Add a listener that will be notified when the default tool - * specification changes. + * Add a listener that will be notified when the default tool specification changes + * @param listener the listener */ public void addDefaultToolChangeListener(DefaultToolChangeListener listener); /** - * Remove the listener. + * Remove the listener + * @param listener the listener */ public void removeDefaultToolChangeListener(DefaultToolChangeListener listener); @@ -132,13 +139,13 @@ public interface ToolServices { * Return array of running tools * @return array of Tools */ - public Tool[] getRunningTools(); + public PluginTool[] getRunningTools(); /** - * Returns true if this tool should be saved base on the state of other runnings instances of + * Returns true if this tool should be saved base on the state of other running instances of * the same tool * @param tool the tool to check for saving * @return true if the tool should be saved */ - public boolean canAutoSave(Tool tool); + public boolean canAutoSave(PluginTool tool); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolTemplate.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolTemplate.java index 5ec55f1eca..2f204427b0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolTemplate.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/ToolTemplate.java @@ -20,6 +20,7 @@ import javax.swing.ImageIcon; import org.jdom.Element; import docking.util.image.ToolIconURL; +import ghidra.framework.plugintool.PluginTool; /** * Configuration of a tool that knows how to create tools. @@ -51,7 +52,8 @@ public interface ToolTemplate { void setName(String name); /** - * Get the iconURL for this tool template. + * Get the iconURL for this tool template + * @return the iconURL for this tool template */ ToolIconURL getIconURL(); @@ -88,7 +90,7 @@ public interface ToolTemplate { * @param project the project in which the tool will be living. * @return a new tool for this template implementation. */ - public Tool createTool(Project project); + public PluginTool createTool(Project project); /** * This returns the XML element that represents the tool part of the overall XML hierarchy. diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Workspace.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Workspace.java index 3b47b39409..30adaf8fb2 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Workspace.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Workspace.java @@ -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,6 +15,7 @@ */ package ghidra.framework.model; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.exception.DuplicateNameException; /** @@ -24,47 +24,49 @@ import ghidra.util.exception.DuplicateNameException; */ public interface Workspace { - /** - * Get the workspace name. - */ - public String getName(); + /** + * Get the workspace name + * @return the name + */ + public String getName(); - /** - * Get the running tools in the workspace. - * - * @return list of running tools or zero-length array if there are no tools in the workspace - */ - public Tool[] getTools(); + /** + * Get the running tools in the workspace. + * + * @return list of running tools or zero-length array if there are no tools in the workspace + */ + public PluginTool[] getTools(); - /** - * Launch an empty tool. - * @return name of empty tool that is launched. - */ - public Tool createTool(); + /** + * Launch an empty tool. + * @return name of empty tool that is launched. + */ + public PluginTool createTool(); - /** - * Run the tool specified by the tool template object. - * @return launched tool that is now running. - */ - public Tool runTool(ToolTemplate template); + /** + * Run the tool specified by the tool template object. + * @param template the template + * @return launched tool that is now running. + */ + public PluginTool runTool(ToolTemplate template); - /** - * Rename this workspace. - * - * @param newName new workspace name - * - * @throws DuplicateNameException if newName is already the - * name of a workspace. - */ - public void setName(String newName) - throws DuplicateNameException; + /** + * Rename this workspace. + * + * @param newName new workspace name + * + * @throws DuplicateNameException if newName is already the + * name of a workspace. + */ + public void setName(String newName) + throws DuplicateNameException; - /** - * Set this workspace to be the active workspace, i.e., - * all tools become visible. - * The currently active workspace becomes inactive, and - * this workspace becomes active. - */ - public void setActive(); + /** + * Set this workspace to be the active workspace, i.e., + * all tools become visible. + * The currently active workspace becomes inactive, and + * this workspace becomes active. + */ + public void setActive(); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/WorkspaceChangeListener.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/WorkspaceChangeListener.java index 33bbca3241..725d865c16 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/WorkspaceChangeListener.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/WorkspaceChangeListener.java @@ -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. @@ -18,41 +17,43 @@ package ghidra.framework.model; import java.beans.PropertyChangeListener; +import ghidra.framework.plugintool.PluginTool; + /** * Listener that is notified when a tool is added or removed from a * workspace, or when workspace properties change. */ public interface WorkspaceChangeListener extends PropertyChangeListener { - /** - * Notification that a tool was added to the given workspace. - * @param ws workspace the affected workspace - * @param tool tool that was added - */ - public void toolAdded(Workspace ws, Tool tool); + /** + * Notification that a tool was added to the given workspace. + * @param ws workspace the affected workspace + * @param tool tool that was added + */ + public void toolAdded(Workspace ws, PluginTool tool); - /** - * Notification that a tool was removed from the given workspace. - * @param ws workspace the affected workspace - * @param tool tool that was removed from the workspace - */ - public void toolRemoved(Workspace ws, Tool tool); + /** + * Notification that a tool was removed from the given workspace. + * @param ws workspace the affected workspace + * @param tool tool that was removed from the workspace + */ + public void toolRemoved(Workspace ws, PluginTool tool); - /** - * Notification that the given workspace was added by the ToolManager. - * @param ws workspace the affected workspace - */ - public void workspaceAdded(Workspace ws); + /** + * Notification that the given workspace was added by the ToolManager. + * @param ws workspace the affected workspace + */ + public void workspaceAdded(Workspace ws); - /** - * Notification that the given workspace was removed by the ToolManager. - * @param ws workspace the affected workspace - */ - public void workspaceRemoved(Workspace ws); + /** + * Notification that the given workspace was removed by the ToolManager. + * @param ws workspace the affected workspace + */ + public void workspaceRemoved(Workspace ws); - /** - * Notification that the given workspace is the current one. - * @param ws workspace the affected workspace - */ - public void workspaceSetActive(Workspace ws); + /** + * Notification that the given workspace is the current one. + * @param ws workspace the affected workspace + */ + public void workspaceSetActive(Workspace ws); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ComponentProviderAdapter.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ComponentProviderAdapter.java index e376d2fbb2..b6926c453e 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ComponentProviderAdapter.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ComponentProviderAdapter.java @@ -16,11 +16,11 @@ package ghidra.framework.plugintool; import docking.ComponentProvider; -import docking.DockingTool; +import docking.Tool; /** * Extends the {@link ComponentProvider} to fit into the Plugin architecture by taking in a - * {@link PluginTool} which extends {@link DockingTool}. Most implementers will want to extend + * {@link PluginTool} which extends {@link Tool}. Most implementers will want to extend * this class instead of the ComponentProvider class because they will want to access the extra * methods provided by PluginTool over DockingTool without having to cast the dockingTool variable. */ diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java index 30c755c46d..f4576ad477 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java @@ -73,7 +73,24 @@ import ghidra.util.task.*; *

The PluginTool also manages tasks that run in the background, and options used by the plugins. * */ -public abstract class PluginTool extends AbstractDockingTool implements Tool, ServiceProvider { +public abstract class PluginTool extends AbstractDockingTool { + + /** + * Name of the property for the tool name. + */ + public final static String TOOL_NAME_PROPERTY = "ToolName"; + /** + * Name of the property for the tool icon. + */ + public final static String ICON_PROPERTY_NAME = "Icon"; + /** + * Name of the property for the description of the tool. + */ + public final static String DESCRIPTION_PROPERTY_NAME = "Description"; + /** + * Name of the property for the number of plugins the tool has. + */ + public final static String PLUGIN_COUNT_PROPERTY_NAME = "PluginCount"; private static final String DOCKING_WINDOWS_ON_TOP = "Docking Windows On Top"; @@ -170,6 +187,10 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se installHomeButton(); } + protected PluginTool() { + // non-public constructor for stub subclasses + } + public abstract PluginClassManager getPluginClassManager(); /** @@ -368,43 +389,36 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se winMgr.setDefaultComponent(provider); } - @Override public ToolTemplate getToolTemplate(boolean includeConfigState) { throw new UnsupportedOperationException( "You cannot create templates for generic tools: " + getClass().getName()); } - @Override public ToolTemplate saveToolToToolTemplate() { setConfigChanged(false); optionsMgr.removeUnusedOptions(); return getToolTemplate(true); } - @Override public Element saveWindowingDataToXml() { throw new UnsupportedOperationException( "You cannot persist generic tools: " + getClass().getName()); } - @Override public void restoreWindowingDataFromXml(Element windowData) { throw new UnsupportedOperationException( "You cannot persist generic tools: " + getClass().getName()); } - @Override public boolean acceptDomainFiles(DomainFile[] data) { return pluginMgr.acceptData(data); } - @Override public void addPropertyChangeListener(PropertyChangeListener l) { propertyChangeMgr.addPropertyChangeListener(l); } - @Override public void addToolListener(ToolListener listener) { eventMgr.addToolListener(listener); } @@ -417,7 +431,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se return eventMgr.hasToolListeners(); } - @Override public void exit() { dispose(); } @@ -458,17 +471,14 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se executingTaskListeners.clear(); } - @Override public void firePluginEvent(PluginEvent event) { eventMgr.fireEvent(event); } - @Override public String[] getConsumedToolEventNames() { return eventMgr.getEventsConsumed(); } - @Override public DomainFile[] getDomainFiles() { return pluginMgr.getData(); } @@ -478,12 +488,10 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se return iconURL.getIcon(); } - @Override public ToolIconURL getIconURL() { return iconURL; } - @Override public String getInstanceName() { return instanceName; } @@ -493,22 +501,18 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se return fullName; } - @Override public Class[] getSupportedDataTypes() { return pluginMgr.getSupportedDataTypes(); } - @Override public String[] getToolEventNames() { return eventMgr.getEventsProduced(); } - @Override public String getToolName() { return toolName; } - @Override public void putInstanceName(String newInstanceName) { this.instanceName = newInstanceName; if (instanceName.length() == 0) { @@ -520,24 +524,20 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se updateTitle(); } - @Override public void removePropertyChangeListener(PropertyChangeListener l) { propertyChangeMgr.removePropertyChangeListener(l); } - @Override public void removeToolListener(ToolListener listener) { eventMgr.removeToolListener(listener); } - @Override public void restoreDataStateFromXml(Element root) { pluginMgr.restoreDataStateFromXml(root); setConfigChanged(false); } - @Override public Element saveDataStateToXml(boolean savingProject) { return pluginMgr.saveDataStateToXml(savingProject); } @@ -570,7 +570,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se return hasErrors; } - @Override public Element saveToXml(boolean includeConfigState) { Element root = new Element("TOOL"); @@ -591,7 +590,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se } } - @Override public void setIconURL(ToolIconURL newIconURL) { if (newIconURL == null) { throw new NullPointerException("iconURL cannot be null."); @@ -609,7 +607,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se winMgr.setIcon(newValue); } - @Override public void setToolName(String name) { String oldName = toolName; toolName = name; @@ -623,7 +620,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se propertyChangeMgr.firePropertyChange(TOOL_NAME_PROPERTY, oldName, toolName); } - @Override public void processToolEvent(PluginEvent toolEvent) { eventMgr.processToolEvent(toolEvent); } @@ -718,6 +714,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se * Get the options for the given category name; if no options exist with * the given name, then one is created. */ + @Override public ToolOptions getOptions(String categoryName) { return optionsMgr.getOptions(categoryName); @@ -894,6 +891,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se protected void addExitAction() { DockingAction exitAction = new DockingAction("Exit Ghidra", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { AppInfo.exitGhidra(); @@ -918,6 +916,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se protected void addOptionsAction() { DockingAction optionsAction = new DockingAction("Edit Options", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { optionsMgr.editOptions(); @@ -943,6 +942,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se protected void addSaveToolAction() { DockingAction saveAction = new DockingAction("Save Tool", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { saveTool(); @@ -956,6 +956,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se saveAction.setHelpLocation(new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Save Tool")); DockingAction saveAsAction = new DockingAction("Save Tool As", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { saveToolAs(); @@ -983,6 +984,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se int subGroup = 1; DockingAction exportToolAction = new DockingAction("Export Tool", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { dialogMgr.exportTool(); @@ -998,6 +1000,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se DockingAction exportDefautToolAction = new DockingAction("Export Default Tool", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext e) { dialogMgr.exportDefaultTool(); @@ -1016,6 +1019,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se protected void addHelpActions() { DockingAction action = new DockingAction("About Ghidra", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { DockingWindowManager.showDialog(new AboutDialog()); @@ -1035,6 +1039,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se DockingAction userAgreementAction = new DockingAction("User Agreement", ToolConstants.TOOL_OWNER, KeyBindingType.UNSUPPORTED) { + @Override public void actionPerformed(ActionContext context) { DockingWindowManager.showDialog(new UserAgreementDialog(false, false)); @@ -1057,6 +1062,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se final ErrorReporter reporter = ErrLogDialog.getErrorReporter(); if (reporter != null) { action = new DockingAction("Report Bug", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { reporter.report(getToolFrame(), "User Bug Report", null); @@ -1077,6 +1083,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se HelpService help = Help.getHelpService(); action = new DockingAction("Contents", ToolConstants.TOOL_OWNER) { + @Override public void actionPerformed(ActionContext context) { help.showHelp(null, false, getToolFrame()); @@ -1115,6 +1122,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se *

  • notify the project tool services that this tool is going away. * */ + @Override public void close() { if (canClose(false) && pluginMgr.saveData()) { @@ -1141,7 +1149,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se toolServices.closeTool(this); } - @Override public boolean shouldSave() { return configChangedFlag; // ignore the window layout changes } @@ -1185,10 +1192,11 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se *
    Note: This forces plugins to terminate any tasks they have running and * apply any unsaved data to domain objects or files. If they can't do * this or the user cancels then this returns false. + * + * @param isExiting whether the tool is exiting * @return false if this tool has tasks in progress or can't be closed * since the user has unfinished/unsaved changes. */ - @Override public boolean canClose(boolean isExiting) { if (taskMgr.isBusy()) { if (isExiting) { @@ -1236,7 +1244,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se return pluginMgr.canCloseDomainObject(domainObject); } - @Override public boolean canCloseDomainFile(DomainFile domainFile) { Object consumer = new Object(); DomainObject domainObject = domainFile.getOpenedDomainObject(consumer); @@ -1469,6 +1476,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se //================================================================================================== private class ToolOptionsListener implements OptionsChangeListener { + @Override public void optionsChanged(ToolOptions options, String name, Object oldValue, Object newValue) { @@ -1483,7 +1491,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se private void checkedRunSwingNow(CheckedRunnable r, Class exceptionClass) throws T { AtomicReference caughtException = new AtomicReference<>(); - SystemUtilities.runSwingNow(() -> { + Swing.runNow(() -> { try { r.run(); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java index 76e165929a..1d5e24c673 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java @@ -29,7 +29,6 @@ import org.jdom.output.XMLOutputter; import docking.framework.*; import ghidra.framework.*; -import ghidra.framework.model.Tool; import ghidra.framework.model.ToolServices; import ghidra.util.Msg; import ghidra.util.SystemUtilities; @@ -249,12 +248,12 @@ public abstract class StandAloneApplication implements GenericStandAloneApplicat return new ToolServicesAdapter() { @Override - public void closeTool(Tool t) { + public void closeTool(PluginTool t) { System.exit(0); } @Override - public void saveTool(Tool saveTool) { + public void saveTool(PluginTool saveTool) { Element toolElement = saveTool.saveToXml(true); Element dataStateElement = saveTool.saveDataStateToXml(false); Element rootElement = new Element("Root"); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ToolServicesAdapter.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ToolServicesAdapter.java index 144a4b8005..b865f615e0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ToolServicesAdapter.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/ToolServicesAdapter.java @@ -27,17 +27,17 @@ public class ToolServicesAdapter implements ToolServices { } @Override - public boolean canAutoSave(Tool tool) { + public boolean canAutoSave(PluginTool tool) { return true; } @Override - public void closeTool(Tool tool) { + public void closeTool(PluginTool tool) { // override } @Override - public void displaySimilarTool(Tool tool, DomainFile domainFile, PluginEvent event) { + public void displaySimilarTool(PluginTool tool, DomainFile domainFile, PluginEvent event) { // override } @@ -62,7 +62,7 @@ public class ToolServicesAdapter implements ToolServices { } @Override - public Tool[] getRunningTools() { + public PluginTool[] getRunningTools() { return null; } @@ -72,12 +72,12 @@ public class ToolServicesAdapter implements ToolServices { } @Override - public Tool launchDefaultTool(DomainFile domainFile) { + public PluginTool launchDefaultTool(DomainFile domainFile) { return null; } @Override - public Tool launchTool(String toolName, DomainFile domainFile) { + public PluginTool launchTool(String toolName, DomainFile domainFile) { return null; } @@ -87,7 +87,7 @@ public class ToolServicesAdapter implements ToolServices { } @Override - public void saveTool(Tool tool) { + public void saveTool(PluginTool tool) { // override } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/GhidraToolTemplate.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/GhidraToolTemplate.java index 49beb9b2b1..397680a173 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/GhidraToolTemplate.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/GhidraToolTemplate.java @@ -22,7 +22,9 @@ import javax.swing.ImageIcon; import org.jdom.Element; import docking.util.image.ToolIconURL; -import ghidra.framework.model.*; +import ghidra.framework.model.Project; +import ghidra.framework.model.ToolTemplate; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.Msg; import ghidra.util.NumericUtilities; @@ -46,6 +48,7 @@ public class GhidraToolTemplate implements ToolTemplate { /** * Constructor. * @param root XML element that contains the tool template data + * @param path the path of the template */ public GhidraToolTemplate(Element root, String path) { this.path = path; @@ -208,7 +211,7 @@ public class GhidraToolTemplate implements ToolTemplate { } @Override - public Tool createTool(Project project) { + public PluginTool createTool(Project project) { return new GhidraTool(project, this); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/SelectChangedToolDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/SelectChangedToolDialog.java index f6161c8048..5a4187a4c5 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/SelectChangedToolDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/SelectChangedToolDialog.java @@ -27,18 +27,18 @@ import docking.DialogComponentProvider; import docking.widgets.OptionDialog; import docking.widgets.button.GRadioButton; import docking.widgets.label.GHtmlLabel; -import ghidra.framework.model.Tool; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.HTMLUtilities; import ghidra.util.layout.VerticalLayout; public class SelectChangedToolDialog extends DialogComponentProvider { - private final List toolList; + private final List toolList; private boolean wasCancelled; - private Tool selectedTool; + private PluginTool selectedTool; - public SelectChangedToolDialog(List toolList) { + public SelectChangedToolDialog(List toolList) { super("Save Tool Changes?", true, false, true, false); this.toolList = toolList; @@ -87,7 +87,7 @@ public class SelectChangedToolDialog extends DialogComponentProvider { buttonGroup.add(noneButton); panel.add(noneButton); - for (final Tool tool : toolList) { + for (final PluginTool tool : toolList) { GRadioButton radioButton = new GRadioButton(tool.getName()); radioButton.addItemListener(new ItemListener() { @Override @@ -119,7 +119,7 @@ public class SelectChangedToolDialog extends DialogComponentProvider { return wasCancelled; } - Tool getSelectedTool() { + PluginTool getSelectedTool() { return selectedTool; } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolConnectionImpl.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolConnectionImpl.java index 60ed11f656..3107e22d58 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolConnectionImpl.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolConnectionImpl.java @@ -19,8 +19,10 @@ import java.util.*; import org.jdom.Element; -import ghidra.framework.model.*; +import ghidra.framework.model.ToolConnection; +import ghidra.framework.model.ToolListener; import ghidra.framework.plugintool.PluginEvent; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.Msg; import ghidra.util.datastruct.StringIntHashtable; import ghidra.util.exception.NoValueException; @@ -32,146 +34,149 @@ import ghidra.util.exception.NoValueException; */ class ToolConnectionImpl implements ToolConnection, ToolListener { - private Tool producerTool; - private Tool consumerTool; - private StringIntHashtable connectHt; // maps event -> int value 1 if - // tools are connected, int value 0 if tools are not connected + private PluginTool producerTool; + private PluginTool consumerTool; + private StringIntHashtable connectHt; // maps event -> int value 1 if + // tools are connected, int value 0 if tools are not connected - private final static int CONNECTED = 1; - private final static int DISCONNECTED = 0; + private final static int CONNECTED = 1; + private final static int DISCONNECTED = 0; - private boolean listenerAdded; // set to true the first time a - // connection is made for any event - private boolean changed; // flag for whether the connection was changed + private boolean listenerAdded; // set to true the first time a + // connection is made for any event + private boolean changed; // flag for whether the connection was changed - /** - * Constructor - */ - ToolConnectionImpl(Tool producerTool, Tool consumerTool) { - this.producerTool = producerTool; - this.consumerTool = consumerTool; + /** + * Constructor + */ + ToolConnectionImpl(PluginTool producerTool, PluginTool consumerTool) { + this.producerTool = producerTool; + this.consumerTool = consumerTool; - connectHt = new StringIntHashtable(); - updateEventList(); - } + connectHt = new StringIntHashtable(); + updateEventList(); + } - /** - * Default constructor used when there is a problem restoring state - * on the workspace; want the restore() method to still work. - */ - ToolConnectionImpl() { - } - - /* + /** + * Default constructor used when there is a problem restoring state + * on the workspace; want the restore() method to still work. + */ + ToolConnectionImpl() { + } + + /* * @see ghidra.framework.model.ToolConnection#connect(java.lang.String) */ - @Override + @Override public void connect(String eventName) { - validateEventName(eventName); - connectHt.put(eventName, CONNECTED); - if (!listenerAdded) { - producerTool.addToolListener(this); - listenerAdded = true; - } - changed = true; - } - - /* + validateEventName(eventName); + connectHt.put(eventName, CONNECTED); + if (!listenerAdded) { + producerTool.addToolListener(this); + listenerAdded = true; + } + changed = true; + } + + /* * @see ghidra.framework.model.ToolConnection#isConnected(java.lang.String) */ - @Override + @Override public boolean isConnected(String eventName) { - if (!connectHt.contains(eventName)) { - return false; - } - try { - int value = connectHt.get(eventName); - return (value == CONNECTED); + if (!connectHt.contains(eventName)) { + return false; + } + try { + int value = connectHt.get(eventName); + return (value == CONNECTED); - } catch (NoValueException e) { - return false; - } + } + catch (NoValueException e) { + return false; + } - } - - /* + } + + /* * @see ghidra.framework.model.ToolConnection#getEvents() */ - @Override + @Override public String[] getEvents() { - String []keys = connectHt.getKeys(); - Arrays.sort(keys); + String[] keys = connectHt.getKeys(); + Arrays.sort(keys); - return keys; - } - - /* + return keys; + } + + /* * @see ghidra.framework.model.ToolConnection#disconnect(java.lang.String) */ - @Override + @Override public void disconnect(String eventName) { - validateEventName(eventName); - connectHt.put(eventName, DISCONNECTED); - checkConnections(); - changed = true; - } + validateEventName(eventName); + connectHt.put(eventName, DISCONNECTED); + checkConnections(); + changed = true; + } - /* + /* * @see ghidra.framework.model.ToolConnection#getProducer() */ - @Override - public Tool getProducer() { - return producerTool; - } - /* + @Override + public PluginTool getProducer() { + return producerTool; + } + + /* * @see ghidra.framework.model.ToolConnection#getConsumer() */ - @Override - public Tool getConsumer() { - return consumerTool; - } + @Override + public PluginTool getConsumer() { + return consumerTool; + } - /* + /* * @see ghidra.framework.model.ToolListener#processToolEvent(ghidra.framework.model.ToolEvent) */ @Override public void processToolEvent(PluginEvent toolEvent) { - if (isConnected(toolEvent.getToolEventName())) { - consumerTool.processToolEvent(toolEvent); - } - } + if (isConnected(toolEvent.getToolEventName())) { + consumerTool.processToolEvent(toolEvent); + } + } - /** - * Saves the Tool Connection into an XML element. - */ - public Element saveToXml() { + /** + * Saves the Tool Connection into an XML element. + */ + public Element saveToXml() { Element root = new Element("CONNECTION"); - root.setAttribute("PRODUCER",producerTool.getName()); - root.setAttribute("CONSUMER",consumerTool.getName()); - root.setAttribute("LISTENER_ADDED",""+listenerAdded); - String [] keys = connectHt.getKeys(); - for (int i = 0 ; i < keys.length ; ++i) { + root.setAttribute("PRODUCER", producerTool.getName()); + root.setAttribute("CONSUMER", consumerTool.getName()); + root.setAttribute("LISTENER_ADDED", "" + listenerAdded); + String[] keys = connectHt.getKeys(); + for (String key : keys) { Element elem = new Element("EVENT"); - elem.setAttribute("NAME", keys[i]); + elem.setAttribute("NAME", key); int val = DISCONNECTED; try { - val = connectHt.get(keys[i]); + val = connectHt.get(key); + } + catch (NoValueException nve) { } - catch (NoValueException nve) {} elem.setAttribute("CONNECTED", (val == CONNECTED ? "true" : "false")); root.addContent(elem); } - changed = false; - return root; - } - - /** - * restores the ToolConnection from an XML element - * - * @param root XML element to restore ToolConnection from. - */ - public void restoreFromXml(Element root) { + changed = false; + return root; + } + + /** + * restores the ToolConnection from an XML element + * + * @param root XML element to restore ToolConnection from. + */ + public void restoreFromXml(Element root) { listenerAdded = false; Iterator iter = root.getChildren("EVENT").iterator(); @@ -181,144 +186,144 @@ class ToolConnectionImpl implements ToolConnection, ToolListener { String state = elem.getAttributeValue("CONNECTED"); boolean connected = (state != null && state.equalsIgnoreCase("true")); connectHt.put(name, (connected ? CONNECTED : DISCONNECTED)); - if (connected && !listenerAdded) { - producerTool.addToolListener(this); - listenerAdded = true; - } + if (connected && !listenerAdded) { + producerTool.addToolListener(this); + listenerAdded = true; + } } - } + } - /** - * Returns a hash code value for the object. This method is - * supported for the benefit of hashtables such as those provided by - * java.util.Hashtable. - */ - @Override - public int hashCode() { - return producerTool.getName().hashCode() + - consumerTool.getName().hashCode(); - } + /** + * Returns a hash code value for the object. This method is + * supported for the benefit of hashtables such as those provided by + * java.util.Hashtable. + */ + @Override + public int hashCode() { + return producerTool.getName().hashCode() + + consumerTool.getName().hashCode(); + } - /** - * Indicates whether some other object is "equal to" this one. - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj == this) { - return true; - } + /** + * Indicates whether some other object is "equal to" this one. + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } - if (getClass() != obj.getClass()) { - return false; - } + if (getClass() != obj.getClass()) { + return false; + } - ToolConnectionImpl tc = (ToolConnectionImpl)obj; + ToolConnectionImpl tc = (ToolConnectionImpl) obj; - return producerTool.getName().equals(tc.producerTool.getName()) && - consumerTool.getName().equals(tc.consumerTool.getName()); - } - - /** - * Returns a string representation of the object. In general, the - * toString method returns a string that - * "textually represents" this object. The result should - * be a concise but informative representation that is easy for a - * person to read. - */ - @Override - public String toString() { - return "Producer=" + producerTool.getName() + - ", Consumer=" + consumerTool.getName(); - } + return producerTool.getName().equals(tc.producerTool.getName()) && + consumerTool.getName().equals(tc.consumerTool.getName()); + } - //////////////////////////////////////////////////////////////// - // ** package methods - /////////////////////////////////////////////////////////////// - /** - * Return true if the connection changed. - */ - boolean hasChanged() { - return changed; - } + /** + * Returns a string representation of the object. In general, the + * toString method returns a string that + * "textually represents" this object. The result should + * be a concise but informative representation that is easy for a + * person to read. + */ + @Override + public String toString() { + return "Producer=" + producerTool.getName() + + ", Consumer=" + consumerTool.getName(); + } - /** - * Update the events that are consumed and produced, as the tool - * may have added or removed plugins. - */ - void updateEventList() { + //////////////////////////////////////////////////////////////// + // ** package methods + /////////////////////////////////////////////////////////////// + /** + * Return true if the connection changed. + */ + boolean hasChanged() { + return changed; + } - String[] producerEvents = producerTool.getToolEventNames(); - String[] consumedEvents = consumerTool.getConsumedToolEventNames(); - List pList = Arrays.asList(producerEvents); - List cList = Arrays.asList(consumedEvents); - ArrayList producerList = new ArrayList<>(pList); - ArrayList consumerList = new ArrayList<>(cList); + /** + * Update the events that are consumed and produced, as the tool + * may have added or removed plugins. + */ + void updateEventList() { - // get the intersection of the lists - producerList.retainAll(consumerList); - consumerList.retainAll(producerList); + String[] producerEvents = producerTool.getToolEventNames(); + String[] consumedEvents = consumerTool.getConsumedToolEventNames(); + List pList = Arrays.asList(producerEvents); + List cList = Arrays.asList(consumedEvents); + ArrayList producerList = new ArrayList<>(pList); + ArrayList consumerList = new ArrayList<>(cList); - for (int i=0; i connectMap; // map generic tool names to list of tools - private Map> namesMap; + private Map> namesMap; /** * keep a handle to the active workspace to make inactive when another @@ -90,8 +92,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * @param toolName the name of the tool being registers * @param tool the tool being registered */ - private void registerTool(String toolName, Tool tool) { - List list = namesMap.get(toolName); + private void registerTool(String toolName, PluginTool tool) { + List list = namesMap.get(toolName); if (list == null) { list = new ArrayList<>(5); namesMap.put(toolName, list); @@ -109,8 +111,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { tool.addPropertyChangeListener(this); } - private void deregisterTool(String toolName, Tool tool) { - List list = namesMap.get(toolName); + private void deregisterTool(String toolName, PluginTool tool) { + List list = namesMap.get(toolName); SystemUtilities.assertTrue(list != null, "Attempted to remove tool that's not there"); list.remove(tool); if (list.size() == 0) { @@ -126,45 +128,45 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } @Override - public Tool[] getConsumerTools() { - ArrayList consumers = new ArrayList<>(TYPICAL_NUM_TOOLS); - Tool[] runningTools = getRunningTools(); - for (Tool tool : runningTools) { + public PluginTool[] getConsumerTools() { + ArrayList consumers = new ArrayList<>(TYPICAL_NUM_TOOLS); + PluginTool[] runningTools = getRunningTools(); + for (PluginTool tool : runningTools) { if (tool.getConsumedToolEventNames().length > 0) { consumers.add(tool); } } - Tool[] tools = new Tool[consumers.size()]; + PluginTool[] tools = new PluginTool[consumers.size()]; consumers.toArray(tools); return tools; } @Override - public Tool[] getProducerTools() { - ArrayList producers = new ArrayList<>(TYPICAL_NUM_TOOLS); - Tool[] runningTools = getRunningTools(); - for (Tool tool : runningTools) { + public PluginTool[] getProducerTools() { + ArrayList producers = new ArrayList<>(TYPICAL_NUM_TOOLS); + PluginTool[] runningTools = getRunningTools(); + for (PluginTool tool : runningTools) { if (tool.getToolEventNames().length > 0) { producers.add(tool); } } - Tool[] tools = new Tool[producers.size()]; + PluginTool[] tools = new PluginTool[producers.size()]; return producers.toArray(tools); } @Override - public Tool[] getRunningTools() { + public PluginTool[] getRunningTools() { Workspace[] wsList = new Workspace[workspaces.size()]; workspaces.toArray(wsList); - ArrayList runningTools = new ArrayList<>(TYPICAL_NUM_TOOLS); + ArrayList runningTools = new ArrayList<>(TYPICAL_NUM_TOOLS); for (Workspace element : wsList) { - Tool[] tools = element.getTools(); - for (Tool tool : tools) { + PluginTool[] tools = element.getTools(); + for (PluginTool tool : tools) { runningTools.add(tool); } } - Tool[] tools = new Tool[runningTools.size()]; + PluginTool[] tools = new PluginTool[runningTools.size()]; runningTools.toArray(tools); return tools; @@ -174,7 +176,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * @see ghidra.framework.model.ToolManager#getConnection(ghidra.framework.model.Tool, ghidra.framework.model.Tool) */ @Override - public ToolConnection getConnection(Tool producer, Tool consumer) { + public ToolConnection getConnection(PluginTool producer, PluginTool consumer) { String key = getKey(producer, consumer); ToolConnectionImpl tc = connectMap.get(key); if (tc == null) { @@ -229,8 +231,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { // first close all the tools running in the workspace // and if any of the tools don't close, don't remove the workspace - Tool[] runningTools = ws.getTools(); - for (Tool runningTool : runningTools) { + PluginTool[] runningTools = ws.getTools(); + for (PluginTool runningTool : runningTools) { // if data has changed in the tool, the frontEnd will take care // of asking/confirming saving tool runningTool.close(); @@ -310,7 +312,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { public void restoreFromXml(Element root) { inRestoreMode = true; try { - HashMap toolMap = new HashMap<>(); + HashMap toolMap = new HashMap<>(); String activeWSName = root.getAttributeValue("ACTIVE_WORKSPACE"); Workspace makeMeActive = null; @@ -325,8 +327,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { if (ws.getName().equals(activeWSName)) { makeMeActive = ws; } - Tool[] tools = ws.getTools(); - for (Tool tool : tools) { + PluginTool[] tools = ws.getTools(); + for (PluginTool tool : tools) { toolMap.put(tool.getName(), tool); } } @@ -340,8 +342,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { String producerName = elem.getAttributeValue("PRODUCER"); String consumerName = elem.getAttributeValue("CONSUMER"); // get the tools - Tool producer = toolMap.get(producerName); - Tool consumer = toolMap.get(consumerName); + PluginTool producer = toolMap.get(producerName); + PluginTool consumer = toolMap.get(consumerName); if (producer != null && consumer != null) { ToolConnectionImpl tc = new ToolConnectionImpl(producer, consumer); tc.restoreFromXml(elem); @@ -393,9 +395,9 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { public boolean saveSessionTools() { Set keySet = namesMap.keySet(); for (String toolName : keySet) { - List tools = namesMap.get(toolName); + List tools = namesMap.get(toolName); if (tools.size() == 1) { - Tool tool = tools.get(0); + PluginTool tool = tools.get(0); if (tool.shouldSave()) { toolServices.saveTool(tool); } @@ -410,9 +412,9 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { return true; } - private boolean saveToolSet(List tools) { - List changedTools = new ArrayList<>(); - for (Tool tool : tools) { + private boolean saveToolSet(List tools) { + List changedTools = new ArrayList<>(); + for (PluginTool tool : tools) { if (tool.hasConfigChanged()) { changedTools.add(tool); } @@ -422,7 +424,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } if (changedTools.size() == 1) { - Tool changedTool = changedTools.get(0); + PluginTool changedTool = changedTools.get(0); if (changedTool.shouldSave()) { toolServices.saveTool(changedTool); } @@ -436,7 +438,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { return false; } - Tool tool = dialog.getSelectedTool(); + PluginTool tool = dialog.getSelectedTool(); if (tool != null) { toolServices.saveTool(tool); } @@ -467,15 +469,15 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { - Tool tool = (Tool) evt.getSource(); + PluginTool tool = (PluginTool) evt.getSource(); String propertyName = evt.getPropertyName(); - if (propertyName.equals(Tool.PLUGIN_COUNT_PROPERTY_NAME)) { + if (propertyName.equals(PluginTool.PLUGIN_COUNT_PROPERTY_NAME)) { updateConnections(evt); } - if (!propertyName.equals(Tool.TOOL_NAME_PROPERTY)) { + if (!propertyName.equals(PluginTool.TOOL_NAME_PROPERTY)) { return; } @@ -524,7 +526,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } @Override - public void toolChanged(Tool tool) { + public void toolChanged(PluginTool tool) { updateConnectMap(tool); } @@ -536,13 +538,13 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * @param toolName the name of the tool * @return the tool */ - public Tool getTool(String toolName) { + public PluginTool getTool(String toolName) { ToolTemplate template = toolServices.getToolChest().getToolTemplate(toolName); if (template == null) { return null; } - Tool tool = template.createTool(project); + PluginTool tool = template.createTool(project); if (tool != null) { registerTool(toolName, tool); } @@ -558,13 +560,13 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * * @param tool tool to be closed. */ - void closeTool(Tool tool) { + void closeTool(PluginTool tool) { // find the workspace running the tool for (int i = 0; i < workspaces.size(); i++) { WorkspaceImpl ws = (WorkspaceImpl) workspaces.get(i); - Tool[] tools = ws.getTools(); - for (Tool tool2 : tools) { + PluginTool[] tools = ws.getTools(); + for (PluginTool tool2 : tools) { if (tool == tool2) { ws.closeRunningTool(tool); return; @@ -655,8 +657,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { /* * Get a tool from the template; set the instance name. */ - Tool getTool(Workspace ws, ToolTemplate template) { - Tool tool = template.createTool(project); + PluginTool getTool(Workspace ws, ToolTemplate template) { + PluginTool tool = template.createTool(project); if (tool != null) { registerTool(tool.getToolName(), tool); } @@ -666,7 +668,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { /* * Called by the workspace when a tool is removed. */ - void toolRemoved(Workspace ws, Tool tool) { + void toolRemoved(Workspace ws, PluginTool tool) { deregisterTool(tool.getToolName(), tool); disconnectTool(tool); @@ -680,13 +682,13 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * Generate an instance name in the form * of a one-up number. */ - private String generateInstanceName(String toolName, Tool tool) { - List list = namesMap.get(toolName); + private String generateInstanceName(String toolName, PluginTool tool) { + List list = namesMap.get(toolName); if (list.size() <= 1) { return ""; } - Tool lastTool = list.get(list.size() - 2); // the last one is the one we just added above + PluginTool lastTool = list.get(list.size() - 2); // the last one is the one we just added above String instanceName = lastTool.getInstanceName(); if (instanceName.length() == 0) { return "2"; @@ -696,8 +698,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { return "" + (n + 1); } - Tool createEmptyTool() { - Tool tool = new GhidraTool(project, "Untitled"); + PluginTool createEmptyTool() { + PluginTool tool = new GhidraTool(project, "Untitled"); addNewTool(tool, "Untitled"); return tool; } @@ -706,18 +708,12 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * Add the tool to the table, add us as a listener for property * changes on the tool. */ - private void addNewTool(Tool tool, String toolName) { - try { - tool.setToolName(toolName); - registerTool(toolName, tool); - } - catch (PropertyVetoException e) { - // shouldn't happen - Msg.showError(this, null, "Error Setting Tool Name", "Set tool name was vetoed", e); - } + private void addNewTool(PluginTool tool, String toolName) { + tool.setToolName(toolName); + registerTool(toolName, tool); } - void fireToolAddedEvent(Workspace ws, Tool tool) { + void fireToolAddedEvent(Workspace ws, PluginTool tool) { for (int i = 0; i < changeListeners.size(); i++) { WorkspaceChangeListener l = changeListeners.get(i); l.toolAdded(ws, tool); @@ -725,13 +721,13 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } @Override - public void disconnectTool(Tool tool) { + public void disconnectTool(PluginTool tool) { Iterator keys = connectMap.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); ToolConnection tc = connectMap.get(key); - Tool producer = tc.getProducer(); - Tool consumer = tc.getConsumer(); + PluginTool producer = tc.getProducer(); + PluginTool consumer = tc.getConsumer(); if (producer == tool || consumer == tool) { keys.remove(); producer.removeToolListener((ToolConnectionImpl) tc); @@ -739,15 +735,15 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } } - private void updateConnectMap(Tool tool) { + private void updateConnectMap(PluginTool tool) { Iterator keys = connectMap.keySet().iterator(); Map map = new HashMap<>(); while (keys.hasNext()) { String key = keys.next(); ToolConnectionImpl tc = connectMap.get(key); - Tool producer = tc.getProducer(); - Tool consumer = tc.getConsumer(); + PluginTool producer = tc.getProducer(); + PluginTool consumer = tc.getConsumer(); if (producer == tool || consumer == tool) { String newkey = getKey(producer, consumer); tc.updateEventList(); @@ -767,13 +763,13 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { * @param consumer tool consuming an event * */ - private String getKey(Tool producer, Tool consumer) { + private String getKey(PluginTool producer, PluginTool consumer) { return producer.getName() + "+" + consumer.getName(); } private void updateConnections(PropertyChangeEvent ev) { - Tool tool = (Tool) ev.getSource(); + PluginTool tool = (PluginTool) ev.getSource(); updateConnectMap(tool); // notify listeners of tool change @@ -809,7 +805,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { return name; } - public boolean canAutoSave(Tool tool) { + public boolean canAutoSave(PluginTool tool) { ToolSaveStatus status = toolStatusMap.get(tool.getToolName()); if (status == ToolSaveStatus.ASK_SAVE_MODE) { return false; @@ -829,7 +825,7 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { return (status == ToolSaveStatus.AUTO_SAVE_MODE); } - public void toolSaved(Tool tool, boolean toolChanged) { + public void toolSaved(PluginTool tool, boolean toolChanged) { String toolName = tool.getToolName(); if (getToolInstanceCount(tool) == 1) { // saving with only one instance open resets the status @@ -841,8 +837,8 @@ public class ToolManagerImpl implements ToolManager, PropertyChangeListener { } } - private int getToolInstanceCount(Tool tool) { - List list = namesMap.get(tool.getToolName()); + private int getToolInstanceCount(PluginTool tool) { + List list = namesMap.get(tool.getToolName()); if (list == null) { return 0; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolServicesImpl.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolServicesImpl.java index bbbca24aef..a78fa72238 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolServicesImpl.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/ToolServicesImpl.java @@ -60,7 +60,7 @@ class ToolServicesImpl implements ToolServices { } @Override - public void closeTool(Tool tool) { + public void closeTool(PluginTool tool) { toolManager.closeTool(tool); } @@ -150,7 +150,7 @@ class ToolServicesImpl implements ToolServices { } @Override - public void saveTool(Tool tool) { + public void saveTool(PluginTool tool) { boolean toolChanged = tool.hasConfigChanged(); ToolTemplate template = tool.saveToolToToolTemplate(); toolManager.toolSaved(tool, toolChanged); @@ -164,10 +164,10 @@ class ToolServicesImpl implements ToolServices { } @Override - public void displaySimilarTool(Tool tool, DomainFile domainFile, PluginEvent event) { + public void displaySimilarTool(PluginTool tool, DomainFile domainFile, PluginEvent event) { - Tool[] similarTools = getSameNamedRunningTools(tool); - Tool matchingTool = findToolUsingFile(similarTools, domainFile); + PluginTool[] similarTools = getSameNamedRunningTools(tool); + PluginTool matchingTool = findToolUsingFile(similarTools, domainFile); if (matchingTool != null) { // Bring the matching tool forward. matchingTool.toFront(); @@ -185,11 +185,11 @@ class ToolServicesImpl implements ToolServices { } @Override - public Tool launchDefaultTool(DomainFile domainFile) { + public PluginTool launchDefaultTool(DomainFile domainFile) { ToolTemplate template = getDefaultToolTemplate(domainFile); if (template != null) { Workspace workspace = toolManager.getActiveWorkspace(); - Tool tool = workspace.runTool(template); + PluginTool tool = workspace.runTool(template); tool.setVisible(true); if (domainFile != null) { tool.acceptDomainFiles(new DomainFile[] { domainFile }); @@ -200,11 +200,11 @@ class ToolServicesImpl implements ToolServices { } @Override - public Tool launchTool(String toolName, DomainFile domainFile) { + public PluginTool launchTool(String toolName, DomainFile domainFile) { ToolTemplate template = findToolChestToolTemplate(toolName); if (template != null) { Workspace workspace = toolManager.getActiveWorkspace(); - Tool tool = workspace.runTool(template); + PluginTool tool = workspace.runTool(template); tool.setVisible(true); if (domainFile != null) { tool.acceptDomainFiles(new DomainFile[] { domainFile }); @@ -451,20 +451,20 @@ class ToolServicesImpl implements ToolServices { * * @return array of tools that are running and named the same as this one. */ - private Tool[] getSameNamedRunningTools(Tool tool) { + private PluginTool[] getSameNamedRunningTools(PluginTool tool) { String toolName = tool.getToolName(); - Tool[] tools = toolManager.getRunningTools(); - List toolList = new ArrayList<>(tools.length); - for (Tool element : tools) { + PluginTool[] tools = toolManager.getRunningTools(); + List toolList = new ArrayList<>(tools.length); + for (PluginTool element : tools) { if (toolName.equals(element.getToolName())) { toolList.add(element); } } - return toolList.toArray(new Tool[toolList.size()]); + return toolList.toArray(new PluginTool[toolList.size()]); } @Override - public Tool[] getRunningTools() { + public PluginTool[] getRunningTools() { return toolManager.getRunningTools(); } @@ -476,8 +476,8 @@ class ToolServicesImpl implements ToolServices { * * @return first tool found to be using the domainFile */ - private Tool findToolUsingFile(Tool[] tools, DomainFile domainFile) { - Tool matchingTool = null; + private PluginTool findToolUsingFile(PluginTool[] tools, DomainFile domainFile) { + PluginTool matchingTool = null; for (int toolNum = 0; (toolNum < tools.length) && (matchingTool == null); toolNum++) { PluginTool pTool = (PluginTool) tools[toolNum]; // Is this tool the same as the type we are in. @@ -493,7 +493,7 @@ class ToolServicesImpl implements ToolServices { } @Override - public boolean canAutoSave(Tool tool) { + public boolean canAutoSave(PluginTool tool) { return toolManager.canAutoSave(tool); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/WorkspaceImpl.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/WorkspaceImpl.java index bd939f7108..f94a200368 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/WorkspaceImpl.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/tool/WorkspaceImpl.java @@ -19,7 +19,9 @@ import java.util.*; import org.jdom.Element; -import ghidra.framework.model.*; +import ghidra.framework.model.ToolTemplate; +import ghidra.framework.model.Workspace; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.exception.DuplicateNameException; /** @@ -33,7 +35,7 @@ class WorkspaceImpl implements Workspace { private String name; private ToolManagerImpl toolManager; - private Set runningTools = new HashSet(TYPICAL_NUM_RUNNING_TOOLS); + private Set runningTools = new HashSet(TYPICAL_NUM_RUNNING_TOOLS); private boolean isActive; WorkspaceImpl(String name, ToolManagerImpl toolManager) { @@ -47,16 +49,16 @@ class WorkspaceImpl implements Workspace { } @Override - public Tool[] getTools() { - Tool[] tools = new Tool[runningTools.size()]; + public PluginTool[] getTools() { + PluginTool[] tools = new PluginTool[runningTools.size()]; runningTools.toArray(tools); return tools; } @Override - public Tool createTool() { + public PluginTool createTool() { // launch the empty tool - Tool emptyTool = toolManager.createEmptyTool(); + PluginTool emptyTool = toolManager.createEmptyTool(); // add the new tool to our list of running tools runningTools.add(emptyTool); @@ -70,9 +72,9 @@ class WorkspaceImpl implements Workspace { } @Override - public Tool runTool(ToolTemplate template) { + public PluginTool runTool(ToolTemplate template) { - Tool tool = toolManager.getTool(this, template); + PluginTool tool = toolManager.getTool(this, template); if (tool != null) { tool.setVisible(true); @@ -129,7 +131,7 @@ class WorkspaceImpl implements Workspace { root.setAttribute("NAME", name); root.setAttribute("ACTIVE", "" + isActive); - for (Tool tool : runningTools) { + for (PluginTool tool : runningTools) { Element elem = new Element("RUNNING_TOOL"); elem.setAttribute("TOOL_NAME", tool.getToolName()); elem.addContent(tool.saveWindowingDataToXml()); @@ -156,12 +158,12 @@ class WorkspaceImpl implements Workspace { String defaultTool = System.getProperty("ghidra.defaulttool"); if (defaultTool != null && !defaultTool.equals("")) { - Tool tool = toolManager.getTool(defaultTool); + PluginTool tool = toolManager.getTool(defaultTool); runningTools.add(tool); toolManager.fireToolAddedEvent(this, tool); return; } - + Iterator iter = root.getChildren("RUNNING_TOOL").iterator(); while (iter.hasNext()) { Element elememnt = (Element) iter.next(); @@ -170,7 +172,7 @@ class WorkspaceImpl implements Workspace { continue; } - Tool tool = toolManager.getTool(toolName); + PluginTool tool = toolManager.getTool(toolName); if (tool != null) { tool.setVisible(isActive); @@ -198,26 +200,19 @@ class WorkspaceImpl implements Workspace { } } - /********************************************************************* - * package level methods - ********************************************************************/ +//================================================================================================== +// Package Methods +//================================================================================================== - /** - * sets the workspace inactive so it can hide its tools - */ void setVisible(boolean state) { isActive = state; - Tool[] tools = getTools(); - for (int t = 0; t < tools.length; t++) { - tools[t].setVisible(state); + PluginTool[] tools = getTools(); + for (PluginTool tool : tools) { + tool.setVisible(state); } } - /** - * Called by the ToolManagerImpl when ToolServices calls - * the closeTool() method. - */ - void closeRunningTool(Tool tool) { + void closeRunningTool(PluginTool tool) { // tool is already closed via the call that got us here, so just clean up runningTools.remove(tool); @@ -232,7 +227,7 @@ class WorkspaceImpl implements Workspace { * ToolManagerImpl which is called from the Project's close() */ void close() { - for (Tool tool : runningTools) { + for (PluginTool tool : runningTools) { try { tool.exit(); } diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/plugintool/DummyPluginTool.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/plugintool/DummyPluginTool.java index 01db7ae1ed..a6bfca21f4 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/plugintool/DummyPluginTool.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/plugintool/DummyPluginTool.java @@ -15,7 +15,6 @@ */ package ghidra.framework.plugintool; -import ghidra.framework.model.Tool; import ghidra.framework.plugintool.util.PluginClassManager; /** @@ -37,7 +36,7 @@ public class DummyPluginTool extends PluginTool { private static class DummyToolServices extends ToolServicesAdapter { @Override - public void closeTool(Tool t) { + public void closeTool(PluginTool t) { // If we call this, then the entire test VM will exit, which is bad // System.exit(0); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/pcoderaw/VarnodeData.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/pcoderaw/VarnodeData.java index ddf98ad482..4b328f7b05 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/pcoderaw/VarnodeData.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/pcoderaw/VarnodeData.java @@ -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. diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/CodeBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/CodeBlock.java index 49e1eeefe6..734b5f48b9 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/CodeBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/CodeBlock.java @@ -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. diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyTool.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyTool.java index 32c00a05ca..4e70428db7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyTool.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyTool.java @@ -17,7 +17,6 @@ package ghidra.test; import java.awt.Window; import java.beans.PropertyChangeListener; -import java.beans.PropertyVetoException; import java.util.Collections; import java.util.Set; @@ -34,17 +33,20 @@ import docking.util.image.ToolIconURL; import ghidra.framework.model.*; import ghidra.framework.options.ToolOptions; import ghidra.framework.plugintool.PluginEvent; +import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.util.PluginClassManager; +import ghidra.framework.plugintool.util.ServiceListener; import ghidra.program.model.listing.Program; -public class DummyTool implements Tool { +public class DummyTool extends PluginTool { private final static String DEFAULT_NAME = "untitled"; private String name = DEFAULT_NAME; private String instanceName; private String description; - private ToolIconURL iconURL; + private ToolIconURL dummyIconUrl; private Project project; - private DockingToolActions toolActions = new DummyToolActions(); + private DockingToolActions dummyToolActions = new DummyToolActions(); public DummyTool() { this(DEFAULT_NAME); @@ -60,7 +62,7 @@ public class DummyTool implements Tool { } @Override - public void setToolName(String typeName) throws PropertyVetoException { + public void setToolName(String typeName) { name = typeName; } @@ -193,10 +195,6 @@ public class DummyTool implements Tool { return null; } - public void restoreFromXml(Element root) { - //do nothing - } - @Override public void restoreDataStateFromXml(Element root) { //do nothing @@ -226,18 +224,18 @@ public class DummyTool implements Tool { } @Override - public void setIconURL(ToolIconURL iconURL) { - this.iconURL = iconURL; + public void setIconURL(ToolIconURL iconUrl) { + this.dummyIconUrl = iconUrl; } @Override public ToolIconURL getIconURL() { - return iconURL; + return dummyIconUrl; } @Override public ImageIcon getIcon() { - return iconURL.getIcon(); + return dummyIconUrl.getIcon(); } @Override @@ -369,11 +367,6 @@ public class DummyTool implements Tool { //do nothing } - @Override - public ActionContext getGlobalContext() { - return null; - } - @Override public void setStatusInfo(String text) { //do nothing @@ -421,6 +414,26 @@ public class DummyTool implements Tool { @Override public DockingToolActions getToolActions() { - return toolActions; + return dummyToolActions; + } + + @Override + public T getService(Class serviceClass) { + return null; + } + + @Override + public void addServiceListener(ServiceListener listener) { + //do nothing + } + + @Override + public void removeServiceListener(ServiceListener listener) { + //do nothing + } + + @Override + public PluginClassManager getPluginClassManager() { + return null; } } diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolActions.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolActions.java index 3b4b216106..c9337b44b1 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolActions.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolActions.java @@ -20,6 +20,7 @@ import java.util.Set; import docking.ComponentProvider; import docking.action.DockingActionIf; import docking.actions.DockingToolActions; +import docking.actions.SharedDockingActionPlaceholder; public class DummyToolActions implements DockingToolActions { @@ -67,4 +68,9 @@ public class DummyToolActions implements DockingToolActions { public void removeActions(ComponentProvider provider) { // stub } + + @Override + public void registerSharedActionPlaceholder(SharedDockingActionPlaceholder placeholder) { + // stub + } } diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolTemplate.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolTemplate.java index 75612afaea..bc285175b4 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolTemplate.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/test/DummyToolTemplate.java @@ -20,13 +20,15 @@ import javax.swing.ImageIcon; import org.jdom.Element; import docking.util.image.ToolIconURL; -import ghidra.framework.model.*; +import ghidra.framework.model.Project; +import ghidra.framework.model.ToolTemplate; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; public class DummyToolTemplate implements ToolTemplate { @Override - public Tool createTool(Project project) { + public PluginTool createTool(Project project) { return new DummyTool(project); } diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc index a1703b1845..097fe7286b 100644 --- a/Ghidra/Processors/68000/data/languages/68000.sinc +++ b/Ghidra/Processors/68000/data/languages/68000.sinc @@ -1076,9 +1076,9 @@ macro shiftCXFlags(cntreg) { :lsr.l cntreg,regdn is op=14 & cntreg & op8=0 & op67=2 & op34=1 & regdn { getbit(CF,regdn,cntreg-1); shiftCXFlags(cntreg); regdn=regdn >>cntreg; resflags(regdn); } :lsr eaw is (opbig=0xe2 & op67=3 & $(MEM_ALTER_ADDR_MODES))... & eaw { getbit(CF,eaw,0); shiftCXFlags(eaw); eaw=eaw >>1; resflags(eaw); } -:move.b eab,e2b is (op=1 & $(DAT_ALTER_ADDR_MODES2))... & eab ; e2b { build eab; build e2b; e2b = eab; resflags(eab); logflags(); } -:move.w eaw,e2w is (op=3 & $(DAT_ALTER_ADDR_MODES2))... & eaw ; e2w { build eaw; build e2w; e2w = eaw; resflags(eaw); logflags(); } -:move.l eal,e2l is (op=2 & $(DAT_ALTER_ADDR_MODES2))... & eal ; e2l { build eal; build e2l; e2l = eal; resflags(eal); logflags(); } +:move.b eab,e2b is (op=1 & $(DAT_ALTER_ADDR_MODES2))... & eab ; e2b { build eab; local tmp = eab; build e2b; e2b = tmp; resflags(tmp); logflags(); } +:move.w eaw,e2w is (op=3 & $(DAT_ALTER_ADDR_MODES2))... & eaw ; e2w { build eaw; local tmp = eaw; build e2w; e2w = tmp; resflags(tmp); logflags(); } +:move.l eal,e2l is (op=2 & $(DAT_ALTER_ADDR_MODES2))... & eal ; e2l { build eal; local tmp = eal; build e2l; e2l = tmp; resflags(tmp); logflags(); } :move "CCR",eaw is (opbig=0x42 & op67=3 & $(DAT_ALTER_ADDR_MODES))... & eaw { packflags(SR); eaw = SR; } :move eaw,"CCR" is (opbig=0x44 & op67=3 & $(DAT_ALTER_ADDR_MODES))... & eaw { unpackflags(eaw); } diff --git a/Ghidra/Processors/6805/data/languages/6809.slaspec b/Ghidra/Processors/6805/data/languages/6809.slaspec index ddd1a870af..d1ddee1009 100644 --- a/Ghidra/Processors/6805/data/languages/6809.slaspec +++ b/Ghidra/Processors/6805/data/languages/6809.slaspec @@ -1,6 +1,6 @@ # sleigh specification file for Motorola 6809 -@define M6809 +@define M6809 "" @include "6x09.sinc" @include "6x09_push.sinc" diff --git a/Ghidra/Processors/6805/data/languages/6x09.sinc b/Ghidra/Processors/6805/data/languages/6x09.sinc index 568505ac16..17bc8551fd 100644 --- a/Ghidra/Processors/6805/data/languages/6x09.sinc +++ b/Ghidra/Processors/6805/data/languages/6x09.sinc @@ -87,8 +87,8 @@ attach variables [ idxReg ] [ X Y U S ]; EA: simm5,idxReg is simm5 & idxReg & noOffset5=0 { - local offset:1 = simm5; - local addr:2 = idxReg + sext(offset); + local offs:1 = simm5; + local addr:2 = idxReg + sext(offs); export addr; } EA: ","idxReg is idxReg & noOffset5=1 & idxMode=4 # no offset @@ -160,8 +160,8 @@ EA: "[,"idxReg"]" is idxReg & noOffset5=1 & idxMode=20 } EA: "["simm8,idxReg"]" is idxReg & noOffset5=1 & idxMode=24; simm8 { - local offset:1 = simm8; - local addr:2 = idxReg + sext(offset); + local offs:1 = simm8; + local addr:2 = idxReg + sext(offs); addr = *:2 addr; export addr; } diff --git a/Ghidra/Processors/ARM/data/languages/ARM.sinc b/Ghidra/Processors/ARM/data/languages/ARM.sinc index dd2b35dede..e017abf5d0 100644 --- a/Ghidra/Processors/ARM/data/languages/ARM.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARM.sinc @@ -248,22 +248,22 @@ CheckInIT_ZN: is TMode=1 { ZR = tmpZR; NG = tmpNG; } # in old @if defined(VERSION_6T2) || defined(VERSION_7) # conditionals for instruction following IT Block -thfcc: "eq" is cond_full=0 { local tmp = (ZR!=0); export tmp; } -thfcc: "ne" is cond_full=1 { local tmp = (ZR==0); export tmp; } -thfcc: "cs" is cond_full=2 { local tmp = (CY!=0); export tmp; } -thfcc: "cc" is cond_full=3 { local tmp = (CY==0); export tmp; } -thfcc: "mi" is cond_full=4 { local tmp = (NG!=0); export tmp; } -thfcc: "pl" is cond_full=5 { local tmp = (NG==0); export tmp; } -thfcc: "vs" is cond_full=6 { local tmp = (OV!=0); export tmp; } -thfcc: "vc" is cond_full=7 { local tmp = (OV==0); export tmp; } -thfcc: "hi" is cond_full=8 { local tmp = CY && !ZR; export tmp; } -thfcc: "ls" is cond_full=9 { local tmp = !CY || ZR; export tmp; } -thfcc: "ge" is cond_full=10 { local tmp = (NG == OV); export tmp; } -thfcc: "lt" is cond_full=11 { local tmp = (NG != OV); export tmp; } -thfcc: "gt" is cond_full=12 { local tmp = !ZR && (NG == OV); export tmp; } -thfcc: "le" is cond_full=13 { local tmp = ZR || (NG != OV); export tmp; } -# thfcc: "AL" is cond_full=14 { local tmp = 1; export tmp; } -# thfcc: "NV" is cond_full=15 { local tmp = 0; export tmp; } +thfcc: "eq" is cond_full=0 { local tmp:1 = (ZR!=0); export tmp; } +thfcc: "ne" is cond_full=1 { local tmp:1 = (ZR==0); export tmp; } +thfcc: "cs" is cond_full=2 { local tmp:1 = (CY!=0); export tmp; } +thfcc: "cc" is cond_full=3 { local tmp:1 = (CY==0); export tmp; } +thfcc: "mi" is cond_full=4 { local tmp:1 = (NG!=0); export tmp; } +thfcc: "pl" is cond_full=5 { local tmp:1 = (NG==0); export tmp; } +thfcc: "vs" is cond_full=6 { local tmp:1 = (OV!=0); export tmp; } +thfcc: "vc" is cond_full=7 { local tmp:1 = (OV==0); export tmp; } +thfcc: "hi" is cond_full=8 { local tmp:1 = CY && !ZR; export tmp; } +thfcc: "ls" is cond_full=9 { local tmp:1 = !CY || ZR; export tmp; } +thfcc: "ge" is cond_full=10 { local tmp:1 = (NG == OV); export tmp; } +thfcc: "lt" is cond_full=11 { local tmp:1 = (NG != OV); export tmp; } +thfcc: "gt" is cond_full=12 { local tmp:1 = !ZR && (NG == OV); export tmp; } +thfcc: "le" is cond_full=13 { local tmp:1 = ZR || (NG != OV); export tmp; } +thfcc: "al" is cond_full=14 { local tmp:1 = 1; export tmp; } #can happen +#thfcc: "nv" is cond_full=15 { local tmp:1 = 0; export tmp; } #unpredictable, shouldn't happen # no ITcondition diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc index 31a363f889..970152c32f 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc @@ -306,6 +306,7 @@ it_thfcc: "ge" is fcond=10 { tmp:1 = (NG == OV); export tmp; } it_thfcc: "lt" is fcond=11 { tmp:1 = (NG == OV); export tmp; } it_thfcc: "gt" is fcond=12 { tmp:1 = !ZR && (NG == OV); export tmp; } it_thfcc: "le" is fcond=13 { tmp:1 = !ZR && (NG == OV); export tmp; } +it_thfcc: "al" is fcond=14 { tmp:1 = 1; export tmp; } @define IT_THFCC "it_thfcc & (thc0707=0 | thc0606=0 | thc0505=0)" @@ -1829,14 +1830,14 @@ th2_SetMode: "#"^31 is thc0004=0x1f { setSystemMode(); } @endif # VERSION_8 @if defined(VERSION_6T2) || defined(VERSION_7) -X: "T" is TMode=1 & ((thc0404=1 & thc0303=1) | (thc0404=0 & thc0303=0)) & (thc0202=1 | thc0101=1 | thc0000=1) { } -X: "E" is TMode=1 & ((thc0404=1 & thc0303=0) | (thc0404=0 & thc0303=1)) & (thc0202=1 | thc0101=1 | thc0000=1) { } +X: "t" is TMode=1 & ((thc0404=1 & thc0303=1) | (thc0404=0 & thc0303=0)) & (thc0202=1 | thc0101=1 | thc0000=1) { } +X: "e" is TMode=1 & ((thc0404=1 & thc0303=0) | (thc0404=0 & thc0303=1)) & (thc0202=1 | thc0101=1 | thc0000=1) { } X: "" is TMode=1 & thc0404 & thc0303 & (thc0202=0 & thc0101=0 & thc0000=0) { } -Y: "T" is TMode=1 & ((thc0404=1 & thc0202=1) | (thc0404=0 & thc0202=0)) & (thc0101=1 | thc0000=1) { } -Y: "E" is TMode=1 & ((thc0404=1 & thc0202=0) | (thc0404=0 & thc0202=1)) & (thc0101=1 | thc0000=1) { } +Y: "t" is TMode=1 & ((thc0404=1 & thc0202=1) | (thc0404=0 & thc0202=0)) & (thc0101=1 | thc0000=1) { } +Y: "e" is TMode=1 & ((thc0404=1 & thc0202=0) | (thc0404=0 & thc0202=1)) & (thc0101=1 | thc0000=1) { } Y: "" is TMode=1 & thc0404 & thc0202 & (thc0101=0 & thc0000=0) { } -Z: "T" is TMode=1 & ((thc0404=1 & thc0101=1) | (thc0404=0 & thc0101=0)) & (thc0000=1) { } -Z: "E" is TMode=1 & ((thc0404=1 & thc0101=0) | (thc0404=0 & thc0101=1)) & (thc0000=1) { } +Z: "t" is TMode=1 & ((thc0404=1 & thc0101=1) | (thc0404=0 & thc0101=0)) & (thc0000=1) { } +Z: "e" is TMode=1 & ((thc0404=1 & thc0101=0) | (thc0404=0 & thc0101=1)) & (thc0000=1) { } Z: "" is TMode=1 & thc0404 & thc0101 & (thc0000=0) { } XYZ: is TMode=1 & sop0003=8 { } @@ -1846,7 +1847,7 @@ XYZ: X^Y^Z is TMode=1 & X & Y & Z { } :it^XYZ it_thfcc is TMode=1 & op8=0xbf & XYZ & $(IT_THFCC) & thc0507 & thc0004 [ itmode=0; cond_base = thc0507; cond_shft=thc0004; globalset(inst_next,condit); ] { - # just sets up the condtion and IF Then/Else mask + # just sets up the condition and If Then/Else mask } :ldc^ItCond thcpn,thCRd,taddrmode5 is (TMode=1 & ItCond & op9=0x76 & thN6=0 & thL4=1; thCRd & thcpn) & taddrmode5 @@ -3515,7 +3516,7 @@ macro BitReverse(val) { @endif # defined(VERSION_6T2) || defined(VERSION_7) -:rsb^thSBIT_CZNO^ItCond Rd0811,Rn0003,ThumbExpandImm12 is TMode=1 & ItCond & (op11=0x1e & thc0909=0 & sop0508=14 & thSBIT_CZNO & Rn0003; thc1515=0 & Rd0811) & ThumbExpandImm12 +:rsb^thSBIT_CZNO^ItCond^".w" Rd0811,Rn0003,ThumbExpandImm12 is TMode=1 & ItCond & (op11=0x1e & thc0909=0 & sop0508=14 & thSBIT_CZNO & Rn0003; thc1515=0 & Rd0811) & ThumbExpandImm12 { build ItCond; th_subflags(ThumbExpandImm12,Rn0003); @@ -3524,7 +3525,7 @@ macro BitReverse(val) { build thSBIT_CZNO; } -:rsb^thSBIT_CZNO^ItCond^".w" Rd0811,Rn0003,thshift2 is TMode=1 & ItCond & op11=0x1d & thc0910=1 & sop0508=14 & thSBIT_CZNO & Rn0003; thc1515=0 & Rd0811 & thshift2 +:rsb^thSBIT_CZNO^ItCond Rd0811,Rn0003,thshift2 is TMode=1 & ItCond & op11=0x1d & thc0910=1 & sop0508=14 & thSBIT_CZNO & Rn0003; thc1515=0 & Rd0811 & thshift2 { build ItCond; th_subflags(thshift2,Rn0003); diff --git a/Ghidra/Processors/tricore/data/languages/tricore.sinc b/Ghidra/Processors/tricore/data/languages/tricore.sinc index b52934e77e..ef92070238 100644 --- a/Ghidra/Processors/tricore/data/languages/tricore.sinc +++ b/Ghidra/Processors/tricore/data/languages/tricore.sinc @@ -7972,9 +7972,9 @@ macro multiply_u_u(mres0, rega, regb, n) { # ST.T off18, bpos3, b (ABSB) :st.t off18,const0810Z,const1111Z is PCPMode=0 & ( const0810Z & const1111Z & op0007=0xd5 ; op2627=0x0 ) & off18 { - local tmp:4 = 1 << const0810Z; - tmp = tmp | (const1111Z << const0810Z); - *[ram]:1 off18 = *[ram]:1 off18 & ~tmp[0,8]; + local tmp:4 = *[ram]:1 off18; + tmp = (tmp & ~(1 << const0810Z)) | (const1111Z << const0810Z); + *[ram]:1 off18 = tmp; } @if defined(TRICORE_RIDER_B) || defined(TRICORE_RIDER_D) || defined(TRICORE_V2) diff --git a/Ghidra/Processors/x86/data/languages/rdrand.sinc b/Ghidra/Processors/x86/data/languages/rdrand.sinc index 8432b8f0fa..5b68faa7a5 100644 --- a/Ghidra/Processors/x86/data/languages/rdrand.sinc +++ b/Ghidra/Processors/x86/data/languages/rdrand.sinc @@ -2,5 +2,6 @@ define pcodeop rdrand; define pcodeop rdrandIsValid; :RDRAND rm16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; (rm16 & reg_opcode=6 ...) { rm16 = rdrand(); CF=rdrandIsValid(); } :RDRAND rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; (rm32 & reg_opcode=6 ...) { rm32 = rdrand(); CF=rdrandIsValid(); } +@ifdef IA64 :RDRAND rm64 is vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; (rm64 & reg_opcode=6 ...) { rm64 = rdrand(); CF=rdrandIsValid(); } - +@endif diff --git a/Ghidra/Processors/x86/data/languages/rdseed.sinc b/Ghidra/Processors/x86/data/languages/rdseed.sinc index ba93179e0a..144e56ae19 100644 --- a/Ghidra/Processors/x86/data/languages/rdseed.sinc +++ b/Ghidra/Processors/x86/data/languages/rdseed.sinc @@ -2,5 +2,6 @@ define pcodeop rdseed; define pcodeop rdseedIsValid; :RDSEED r16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; r16 & reg_opcode=7 { r16 = rdseed(); CF=rdseedIsValid(); } :RDSEED r32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; r32 & reg_opcode=7 { r32 = rdseed(); CF=rdseedIsValid(); } +@ifdef IA64 :RDSEED r64 is vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; r64 & reg_opcode=7 { r64 = rdseed(); CF=rdseedIsValid(); } - +@endif diff --git a/Ghidra/Processors/x86/data/languages/x86.slaspec b/Ghidra/Processors/x86/data/languages/x86.slaspec index af5cfda753..49194af394 100644 --- a/Ghidra/Processors/x86/data/languages/x86.slaspec +++ b/Ghidra/Processors/x86/data/languages/x86.slaspec @@ -13,3 +13,5 @@ @include "sha.sinc" @include "smx.sinc" @include "cet.sinc" +@include "rdrand.sinc" +@include "rdseed.sinc" \ No newline at end of file diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ByteViewerToolConnectionTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ByteViewerToolConnectionTest.java index ab707f0049..cd9aa687c0 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ByteViewerToolConnectionTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ByteViewerToolConnectionTest.java @@ -30,7 +30,6 @@ import docking.action.DockingActionIf; import docking.test.AbstractDockingTest; import ghidra.app.plugin.core.byteviewer.ByteViewerPlugin; import ghidra.app.services.ProgramManager; -import ghidra.framework.model.Tool; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.util.PluginException; @@ -62,7 +61,7 @@ public class ByteViewerToolConnectionTest extends AbstractGhidraHeadedIntegratio pressButtonByText(dialog, "OK"); } - closeAllWindowsAndFrames(); + closeAllWindows(); env.dispose(); } @@ -265,8 +264,8 @@ public class ByteViewerToolConnectionTest extends AbstractGhidraHeadedIntegratio DockingActionIf runAction = getAction(toolName, "Run Tool"); assertNotNull(runAction);// if action is null, the name of the tool changed performAction(runAction, toolName, true); - Tool[] tools = frontEndTool.getToolServices().getRunningTools(); - return (PluginTool) tools[tools.length - 1]; + PluginTool[] tools = frontEndTool.getToolServices().getRunningTools(); + return tools[tools.length - 1]; } private void performAction(final DockingActionIf action, String name, boolean doWait) diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolActionManagerTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolActionManagerTest.java index fd2a898f75..de972cac90 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolActionManagerTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolActionManagerTest.java @@ -125,7 +125,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { DockingActionIf closeAction = getAction("Close Tool"); performToolButtonAction(closeAction, "Untitled", true, true); - Tool[] tools = frontEndTool.getProject().getToolServices().getRunningTools(); + PluginTool[] tools = frontEndTool.getProject().getToolServices().getRunningTools(); assertEquals(0, tools.length); } @@ -136,7 +136,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { DockingActionIf runAction = getAction("Untitled", "Run Tool"); performAction(runAction, "Untitled", true); - Tool[] tools = frontEndTool.getProject().getToolServices().getRunningTools(); + PluginTool[] tools = frontEndTool.getProject().getToolServices().getRunningTools(); assertEquals(2, tools.length); } @@ -160,7 +160,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { assertNotNull(window); waitForCondition(() -> { - Tool[] tools = frontEndTool.getToolServices().getRunningTools(); + PluginTool[] tools = frontEndTool.getToolServices().getRunningTools(); return tools.length == 2; }); @@ -238,7 +238,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { clickMouse(jTree, MouseEvent.BUTTON1, bounds.x + 5, bounds.y + 5, 2, 0); waitForSwing(); - Tool tool = waitForTool("CodeBrowser", project); + PluginTool tool = waitForTool("CodeBrowser", project); // close the CodeBrowser tool close(tool); @@ -609,7 +609,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { return builder.getProgram(); } - private void close(final Tool tool) { + private void close(final PluginTool tool) { runSwing(() -> tool.close()); } @@ -617,15 +617,15 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { Preferences.clear(); } - private Tool waitForTool(String toolName, Project project) { - Tool tool = null; + private PluginTool waitForTool(String toolName, Project project) { + PluginTool tool = null; int sleepTime = 100; int waitCount = 0; while (tool == null && waitCount < 300) { waitForSwing(); sleep(sleepTime); ToolManager toolManager = project.getToolManager(); - Tool[] runningTools = toolManager.getRunningTools(); + PluginTool[] runningTools = toolManager.getRunningTools(); if (runningTools != null && runningTools.length > 0) { tool = runningTools[0]; } @@ -689,7 +689,7 @@ public class ToolActionManagerTest extends AbstractGhidraHeadedIntegrationTest { private PluginTool createTool() throws Exception { DockingActionIf createAction = getAction("Create Tool"); performAction(createAction, true); - Tool[] tools = frontEndTool.getProject().getToolManager().getRunningTools(); + PluginTool[] tools = frontEndTool.getProject().getToolManager().getRunningTools(); final PluginTool tool = (PluginTool) tools[0]; runSwing(() -> { try { diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolConnectionTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolConnectionTest.java index 04a5eaf6fe..d10764fc9a 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolConnectionTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/ToolConnectionTest.java @@ -29,7 +29,6 @@ import docking.ActionContext; import docking.action.DockingActionIf; import ghidra.app.plugin.core.byteviewer.ByteViewerPlugin; import ghidra.app.services.ProgramManager; -import ghidra.framework.model.Tool; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.util.PluginException; @@ -232,8 +231,8 @@ public class ToolConnectionTest extends AbstractGhidraHeadedIntegrationTest { DockingActionIf runAction = getAction(toolName, "Run Tool"); assertNotNull(runAction);// if action is null, the name of the tool changed performAction(runAction, toolName, true); - Tool[] tools = frontEndTool.getToolServices().getRunningTools(); - return (PluginTool) tools[tools.length - 1]; + PluginTool[] tools = frontEndTool.getToolServices().getRunningTools(); + return tools[tools.length - 1]; } private void performAction(final DockingActionIf action, String name, boolean doWait) diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction1Test.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction1Test.java index bb753c6c4a..8ab9ead6d4 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction1Test.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction1Test.java @@ -32,7 +32,9 @@ import docking.DialogComponentProvider; import docking.action.DockingActionIf; import docking.widgets.table.*; import docking.widgets.tree.GTreeNode; -import ghidra.framework.model.*; +import ghidra.framework.model.DomainFile; +import ghidra.framework.model.DomainFolder; +import ghidra.framework.plugintool.PluginTool; import ghidra.framework.store.ItemCheckoutStatus; import ghidra.framework.store.Version; import ghidra.program.model.listing.Program; @@ -213,16 +215,18 @@ public class VersionControlAction1Test extends AbstractVersionControlActionTest waitForTasks(); // make some changes to check in - Program program = (Program) ((DomainFileNode) node).getDomainFile().getDomainObject(this, - true, false, TaskMonitor.DUMMY); + Program program = (Program) ((DomainFileNode) node).getDomainFile() + .getDomainObject(this, + true, false, TaskMonitor.DUMMY); editProgram(program, (p) -> { SymbolTable symTable = p.getSymbolTable(); symTable.createLabel(p.getMinAddress().getNewAddress(0x010001000), "fred", SourceType.USER_DEFINED); }); - program = (Program) ((DomainFileNode) xnode).getDomainFile().getDomainObject(this, true, - false, TaskMonitor.DUMMY); + program = (Program) ((DomainFileNode) xnode).getDomainFile() + .getDomainObject(this, true, + false, TaskMonitor.DUMMY); editProgram(program, (p) -> { SymbolTable symTable = p.getSymbolTable(); symTable.createLabel(p.getMinAddress(), "bob", SourceType.USER_DEFINED); @@ -251,8 +255,9 @@ public class VersionControlAction1Test extends AbstractVersionControlActionTest checkout(programNode); Program program = - (Program) ((DomainFileNode) programNode).getDomainFile().getDomainObject(this, true, - false, TaskMonitor.DUMMY); + (Program) ((DomainFileNode) programNode).getDomainFile() + .getDomainObject(this, true, + false, TaskMonitor.DUMMY); createHistoryEntry(program, "Symbol1"); frontEnd.checkIn(programNode, "This is checkin 1"); @@ -334,7 +339,7 @@ public class VersionControlAction1Test extends AbstractVersionControlActionTest waitForSwing(); - List tools = frontEnd.getTools(); + List tools = frontEnd.getTools(); assertEquals(1, tools.size()); DomainFile[] dfs = tools.get(0).getDomainFiles(); @@ -405,7 +410,7 @@ public class VersionControlAction1Test extends AbstractVersionControlActionTest waitForSwing(); - List tools = frontEnd.getTools(); + List tools = frontEnd.getTools(); assertEquals(1, tools.size()); DomainFile[] dfs = tools.get(0).getDomainFiles(); @@ -482,7 +487,7 @@ public class VersionControlAction1Test extends AbstractVersionControlActionTest waitForSwing(); - List tools = frontEnd.getTools(); + List tools = frontEnd.getTools(); assertEquals(1, tools.size()); DomainFile[] dfs = tools.get(0).getDomainFiles(); diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/test/FrontEndTestEnv.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/test/FrontEndTestEnv.java index b24fecb10b..c6cbd51ede 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/test/FrontEndTestEnv.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/test/FrontEndTestEnv.java @@ -335,8 +335,8 @@ public class FrontEndTestEnv { return env.showTool(); } - public List getTools() { - Tool[] tools = frontEndTool.getProject().getToolManager().getActiveWorkspace().getTools(); + public List getTools() { + PluginTool[] tools = frontEndTool.getProject().getToolManager().getActiveWorkspace().getTools(); return new ArrayList<>(Arrays.asList(tools)); }