mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 11:31:43 +00:00
Merge remote-tracking branch
'origin/GP-759_ghidravore_actions_on_secondary_windows--SQUASHED'
This commit is contained in:
commit
36b32721c6
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.context;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.KeyBindingType;
|
||||
@ -75,15 +73,4 @@ public abstract class ListingContextAction extends DockingAction {
|
||||
protected void actionPerformed(ListingActionContext context) {
|
||||
// clients need to override this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (ListingActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.context;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.KeyBindingType;
|
||||
@ -71,14 +69,4 @@ public abstract class NavigatableContextAction extends DockingAction {
|
||||
}
|
||||
|
||||
protected abstract void actionPerformed(NavigatableActionContext context);
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigatableActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -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,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.context;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
|
||||
@ -51,15 +48,7 @@ public abstract class ProgramContextAction extends DockingAction {
|
||||
}
|
||||
return isValidContext((ProgramActionContext)context);
|
||||
}
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (ProgramActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof ProgramActionContext)) {
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.context;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
|
||||
@ -71,14 +69,4 @@ public abstract class ProgramLocationContextAction extends DockingAction {
|
||||
|
||||
// a version of actionPerformed() that takes a more specific context than our parent
|
||||
protected abstract void actionPerformed(ProgramLocationActionContext context);
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (ProgramLocationActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.nav;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.plugin.core.navigation.NavigationOptions;
|
||||
import ghidra.app.services.GoToService;
|
||||
@ -36,6 +34,7 @@ public abstract class NextRangeAction extends NavigatableContextAction {
|
||||
this.tool = tool;
|
||||
this.navOptions = navOptions;
|
||||
setEnabled(false);
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,14 +98,4 @@ public abstract class NextRangeAction extends NavigatableContextAction {
|
||||
}
|
||||
|
||||
abstract protected ProgramSelection getSelection(ProgramLocationActionContext context);
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigatableRangeActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.nav;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.plugin.core.navigation.NavigationOptions;
|
||||
import ghidra.app.services.GoToService;
|
||||
@ -35,6 +33,7 @@ public abstract class PreviousRangeAction extends NavigatableContextAction {
|
||||
this.tool = tool;
|
||||
this.navOptions = navOptions;
|
||||
setEnabled(false);
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,14 +90,4 @@ public abstract class PreviousRangeAction extends NavigatableContextAction {
|
||||
}
|
||||
|
||||
abstract protected ProgramSelection getSelection(ProgramLocationActionContext context);
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigatableRangeActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import docking.action.MenuData;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.events.ProgramClosedPluginEvent;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
@ -103,14 +103,15 @@ public class FindPossibleReferencesPlugin extends Plugin {
|
||||
.supportsDefaultToolContext(true)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SEARCH, SEARCH_DIRECT_REFS_ACTION_NAME))
|
||||
.description(getPluginDescription().getDescription())
|
||||
.withContext(ListingActionContext.class)
|
||||
.withContext(NavigatableActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(this::findReferences)
|
||||
.enabledWhen(this::hasCorrectAddressSize)
|
||||
.buildAndInstall(tool);
|
||||
|
||||
}
|
||||
|
||||
private boolean hasCorrectAddressSize(ListingActionContext context) {
|
||||
private boolean hasCorrectAddressSize(NavigatableActionContext context) {
|
||||
int size =
|
||||
context.getProgram().getAddressFactory().getDefaultAddressSpace().getSize();
|
||||
if ((size == 64) || (size == 32) || (size == 24) || (size == 16) || (size == 20) ||
|
||||
@ -120,7 +121,7 @@ public class FindPossibleReferencesPlugin extends Plugin {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createLocalActions(ProgramLocationActionContext context, ComponentProvider p,
|
||||
private void createLocalActions(NavigatableActionContext context, ComponentProvider p,
|
||||
FindReferencesTableModel model) {
|
||||
|
||||
addLocalAlignment(p, model, 1);
|
||||
|
@ -15,14 +15,10 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.clear;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.*;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.context.ListingContextAction;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.framework.plugintool.*;
|
||||
@ -46,12 +42,10 @@ import ghidra.program.util.*;
|
||||
)
|
||||
//@formatter:on
|
||||
public class ClearPlugin extends Plugin {
|
||||
private static final String CLEAR_WITH_OPTIONS_NAME = "Clear With Options";
|
||||
private static final String CLEAR_CODE_BYTES_NAME = "Clear Code Bytes";
|
||||
private static final String CLEAR_FLOW_AND_REPAIR = "Clear Flow and Repair";
|
||||
|
||||
private DockingAction clearAllAction;
|
||||
private DockingAction clearAction;
|
||||
private DockingAction clearAndRepairAction;
|
||||
private ClearDialog clearDialog;
|
||||
private ClearFlowDialog clearFlowDialog;
|
||||
|
||||
@ -215,123 +209,71 @@ public class ClearPlugin extends Plugin {
|
||||
* Create the actions.
|
||||
*/
|
||||
private void createActions() {
|
||||
new ActionBuilder(CLEAR_CODE_BYTES_NAME, getName())
|
||||
.menuPath(ToolConstants.MENU_EDIT, CLEAR_CODE_BYTES_NAME)
|
||||
.menuGroup(CLEAR_CODE_BYTES_NAME, "1")
|
||||
.popupMenuPath(CLEAR_CODE_BYTES_NAME)
|
||||
.popupMenuGroup(CLEAR_CODE_BYTES_NAME, "1")
|
||||
.keyBinding("C")
|
||||
.withContext(ListingActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.enabledWhen(this::isClearCodeBytesEnabled)
|
||||
.onAction(this::clearCodeBytes)
|
||||
.buildAndInstall(tool);
|
||||
|
||||
// new context aware version
|
||||
clearAction = new ListingContextAction(CLEAR_CODE_BYTES_NAME, getName()) {
|
||||
new ActionBuilder(CLEAR_WITH_OPTIONS_NAME, getName())
|
||||
.menuPath(ToolConstants.MENU_EDIT, CLEAR_WITH_OPTIONS_NAME + "...")
|
||||
.menuGroup(CLEAR_CODE_BYTES_NAME, "2")
|
||||
.popupMenuPath(CLEAR_WITH_OPTIONS_NAME)
|
||||
.popupMenuGroup(CLEAR_CODE_BYTES_NAME, "2")
|
||||
.withContext(ListingActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(this::showClearAllDialog)
|
||||
.buildAndInstall(tool);
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ListingActionContext context) {
|
||||
ClearOptions opts = new ClearOptions();
|
||||
|
||||
opts.setClearCode(true);
|
||||
opts.setClearSymbols(false);
|
||||
opts.setClearComments(false);
|
||||
opts.setClearProperties(false);
|
||||
opts.setClearFunctions(false);
|
||||
opts.setClearRegisters(false);
|
||||
opts.setClearEquates(false);
|
||||
opts.setClearUserReferences(true);
|
||||
opts.setClearAnalysisReferences(true);
|
||||
opts.setClearImportReferences(true);
|
||||
opts.setClearDefaultReferences(false);
|
||||
opts.setClearBookmarks(false);
|
||||
|
||||
if (clearWithContext(context, opts)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean clearWithContext(ListingActionContext context, ClearOptions opts) {
|
||||
clear(opts, context);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ListingActionContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ListingActionContext context) {
|
||||
ProgramLocation loc = context.getLocation();
|
||||
ProgramSelection currentSelection = context.getSelection();
|
||||
if (currentSelection != null && !currentSelection.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
else if ((loc != null) && (loc.getAddress() != null) &&
|
||||
(loc instanceof CodeUnitLocation)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
int menuOrdinal = 1;
|
||||
MenuData menuData =
|
||||
new MenuData(new String[] { ToolConstants.MENU_EDIT, CLEAR_CODE_BYTES_NAME }, null,
|
||||
"Clear Code Bytes");
|
||||
|
||||
menuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAction.setMenuBarData(menuData);
|
||||
MenuData popupMenuData =
|
||||
new MenuData(new String[] { CLEAR_CODE_BYTES_NAME }, null, "Clear Code Bytes");
|
||||
popupMenuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAction.setPopupMenuData(popupMenuData);
|
||||
clearAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_C, 0));
|
||||
|
||||
String clearWithOptionsName = "Clear With Options";
|
||||
clearAllAction = new DockingAction(clearWithOptionsName, getName()) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
showClearAllDialog((ListingActionContext) context.getContextObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return context.getContextObject() instanceof ListingActionContext;
|
||||
}
|
||||
};
|
||||
|
||||
menuOrdinal++;
|
||||
menuData =
|
||||
new MenuData(new String[] { ToolConstants.MENU_EDIT, clearWithOptionsName + "..." },
|
||||
null, "Clear Code Bytes");
|
||||
menuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAllAction.setMenuBarData(menuData);
|
||||
popupMenuData =
|
||||
new MenuData(new String[] { clearWithOptionsName + "..." }, null, "Clear Code Bytes");
|
||||
popupMenuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAllAction.setPopupMenuData(popupMenuData);
|
||||
|
||||
clearAndRepairAction = new DockingAction(CLEAR_FLOW_AND_REPAIR, getName()) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
showClearFlowDialog((ListingActionContext) context.getContextObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return context.getContextObject() instanceof ListingActionContext;
|
||||
}
|
||||
};
|
||||
|
||||
menuOrdinal++;
|
||||
menuData = new MenuData(new String[] { ToolConstants.MENU_EDIT, CLEAR_FLOW_AND_REPAIR },
|
||||
null, "Clear Code Bytes");
|
||||
menuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAndRepairAction.setMenuBarData(menuData);
|
||||
popupMenuData =
|
||||
new MenuData(new String[] { CLEAR_FLOW_AND_REPAIR + "..." }, null, "Clear Code Bytes");
|
||||
popupMenuData.setMenuSubGroup(Integer.toString(menuOrdinal));
|
||||
clearAndRepairAction.setPopupMenuData(popupMenuData);
|
||||
|
||||
//clearAndRepairAction.setAcceleratorKey(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0));
|
||||
|
||||
tool.addAction(clearAction);
|
||||
tool.addAction(clearAllAction);
|
||||
tool.addAction(clearAndRepairAction);
|
||||
new ActionBuilder(CLEAR_FLOW_AND_REPAIR, getName())
|
||||
.menuPath(ToolConstants.MENU_EDIT, CLEAR_FLOW_AND_REPAIR + "...")
|
||||
.menuGroup(CLEAR_CODE_BYTES_NAME, "3")
|
||||
.popupMenuPath(CLEAR_FLOW_AND_REPAIR)
|
||||
.popupMenuGroup(CLEAR_CODE_BYTES_NAME, "3")
|
||||
.withContext(ListingActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(this::showClearFlowDialog)
|
||||
.buildAndInstall(tool);
|
||||
}
|
||||
|
||||
private boolean isClearCodeBytesEnabled(ListingActionContext context) {
|
||||
ProgramLocation loc = context.getLocation();
|
||||
ProgramSelection currentSelection = context.getSelection();
|
||||
if (currentSelection != null && !currentSelection.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
else if ((loc != null) && (loc.getAddress() != null) && (loc instanceof CodeUnitLocation)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private void clearCodeBytes(ListingActionContext context) {
|
||||
ClearOptions opts = new ClearOptions();
|
||||
|
||||
opts.setClearCode(true);
|
||||
opts.setClearSymbols(false);
|
||||
opts.setClearComments(false);
|
||||
opts.setClearProperties(false);
|
||||
opts.setClearFunctions(false);
|
||||
opts.setClearRegisters(false);
|
||||
opts.setClearEquates(false);
|
||||
opts.setClearUserReferences(true);
|
||||
opts.setClearAnalysisReferences(true);
|
||||
opts.setClearImportReferences(true);
|
||||
opts.setClearDefaultReferences(false);
|
||||
opts.setClearBookmarks(false);
|
||||
|
||||
clear(opts, context);
|
||||
|
||||
}
|
||||
/**
|
||||
* Pop up the clear with options dialog.
|
||||
*/
|
||||
|
@ -43,7 +43,6 @@ import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.events.*;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.core.codebrowser.actions.*;
|
||||
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
|
||||
import ghidra.app.plugin.core.table.TableComponentProvider;
|
||||
import ghidra.app.services.*;
|
||||
@ -169,17 +168,38 @@ public class CodeBrowserPlugin extends Plugin
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
DockingAction selectAllAction = new SelectAllAction(getName());
|
||||
selectAllAction.getMenuBarData().setMenuSubGroup("a");
|
||||
tool.addAction(selectAllAction);
|
||||
new ActionBuilder("Select All", getName())
|
||||
.menuPath(ToolConstants.MENU_SELECTION, "&All in View")
|
||||
.menuGroup("Select Group", "a")
|
||||
.keyBinding("ctrl A")
|
||||
.supportsDefaultToolContext(true)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SELECTION, getName()))
|
||||
.withContext(CodeViewerActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> ((CodeViewerProvider) c.getComponentProvider()).selectAll())
|
||||
.buildAndInstall(tool);
|
||||
|
||||
DockingAction selectNoneAction = new ClearSelectionAction(getName());
|
||||
selectNoneAction.getMenuBarData().setMenuSubGroup("a");
|
||||
tool.addAction(selectNoneAction);
|
||||
new ActionBuilder("Clear Selection", getName())
|
||||
.menuPath(ToolConstants.MENU_SELECTION, "&Clear Selection")
|
||||
.menuGroup("Select Group", "b")
|
||||
.supportsDefaultToolContext(true)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SELECTION, getName()))
|
||||
.withContext(CodeViewerActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> ((CodeViewerProvider) c.getComponentProvider())
|
||||
.setSelection(new ProgramSelection()))
|
||||
.buildAndInstall(tool);
|
||||
|
||||
new ActionBuilder("Select Complement", getName())
|
||||
.menuPath(ToolConstants.MENU_SELECTION, "&Complement")
|
||||
.menuGroup("Select Group", "c")
|
||||
.supportsDefaultToolContext(true)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SELECTION, getName()))
|
||||
.withContext(CodeViewerActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> ((CodeViewerProvider) c.getComponentProvider()).selectComplement())
|
||||
.buildAndInstall(tool);
|
||||
|
||||
DockingAction selectComplementAction = new SelectComplementAction(getName());
|
||||
selectComplementAction.getMenuBarData().setMenuSubGroup("b");
|
||||
tool.addAction(selectComplementAction);
|
||||
}
|
||||
|
||||
protected void viewChanged(AddressSetView addrSet) {
|
||||
|
@ -1,45 +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.app.plugin.core.codebrowser.actions;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Action for clearing the current selection
|
||||
*/
|
||||
public class ClearSelectionAction extends CodeViewerContextAction {
|
||||
|
||||
public ClearSelectionAction(String owner) {
|
||||
super("Clear Selection", owner);
|
||||
setSupportsDefaultToolContext(true);
|
||||
setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "&Clear Selection" }, null, "Select"));
|
||||
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
CodeViewerProvider provider = (CodeViewerProvider) context.getComponentProvider();
|
||||
provider.setSelection(new ProgramSelection());
|
||||
}
|
||||
}
|
@ -1,85 +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.app.plugin.core.codebrowser.actions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerActionContext;
|
||||
|
||||
public abstract class CodeViewerContextAction extends DockingAction {
|
||||
|
||||
public CodeViewerContextAction(String name, String owner) {
|
||||
super(name, owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (!(context instanceof CodeViewerActionContext)) {
|
||||
return false;
|
||||
}
|
||||
return isEnabledForContext((CodeViewerActionContext) context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidContext(ActionContext context) {
|
||||
if (!(context instanceof CodeViewerActionContext)) {
|
||||
return false;
|
||||
}
|
||||
return isValidContext((CodeViewerActionContext) context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof CodeViewerActionContext)) {
|
||||
return false;
|
||||
}
|
||||
return isAddToPopup((CodeViewerActionContext) context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
actionPerformed((CodeViewerActionContext) context);
|
||||
}
|
||||
|
||||
protected boolean isAddToPopup(CodeViewerActionContext context) {
|
||||
return isEnabledForContext(context);
|
||||
}
|
||||
|
||||
protected boolean isValidContext(CodeViewerActionContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isEnabledForContext(CodeViewerActionContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void actionPerformed(CodeViewerActionContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (CodeViewerActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -45,6 +45,9 @@ public class ExpandAllDataAction extends ProgramLocationContextAction {
|
||||
setHelpLocation(new HelpLocation("CodeBrowserPlugin", "ExpandCollapseActions"));
|
||||
|
||||
setEnabled(true);
|
||||
|
||||
// make sure the action is in all windows that can provide the needed context
|
||||
addToWindowWhen(ProgramLocationActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,6 +50,7 @@ public class GotoNextFunctionAction extends NavigatableContextAction {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK);
|
||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, "Next_Previous_Function"));
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
private Function getNextFunction(Program program, Address address) {
|
||||
|
@ -50,6 +50,7 @@ public class GotoPreviousFunctionAction extends NavigatableContextAction {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK);
|
||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, "Next_Previous_Function"));
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
private Function getPreviousFunction(Program program, Address address) {
|
||||
|
@ -1,53 +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.app.plugin.core.codebrowser.actions;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Action for adding all fields to the current format.
|
||||
*/
|
||||
public class SelectAllAction extends CodeViewerContextAction {
|
||||
|
||||
public SelectAllAction(String owner) {
|
||||
super("Select All", owner);
|
||||
// this is in the main tool menu, so make it a tool action
|
||||
setSupportsDefaultToolContext(true);
|
||||
setMenuBarData(
|
||||
new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "&All in View" }, null, "Select"));
|
||||
|
||||
setKeyBindingData(new KeyBindingData(
|
||||
KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
|
||||
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
CodeViewerProvider provider = (CodeViewerProvider) context.getComponentProvider();
|
||||
provider.selectAll();
|
||||
}
|
||||
}
|
@ -1,62 +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.app.plugin.core.codebrowser.actions;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerActionContext;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Action for changing the selection to the complement of all the currently
|
||||
* selected addresses and restricting this new selection to the current view.
|
||||
*/
|
||||
public class SelectComplementAction extends CodeViewerContextAction {
|
||||
|
||||
public SelectComplementAction(String owner) {
|
||||
super("Select Complement", owner);
|
||||
|
||||
// this is in the main tool menu, so make it a tool action
|
||||
setSupportsDefaultToolContext(true);
|
||||
|
||||
setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "&Complement" },
|
||||
null,
|
||||
"Select"));
|
||||
|
||||
setEnabled(false);
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
CodeViewerProvider provider = (CodeViewerProvider) context.getComponentProvider();
|
||||
provider.selectComplement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(CodeViewerActionContext context) {
|
||||
ProgramSelection selection = context.getSelection();
|
||||
if (selection != null && selection.getInteriorSelection() != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import docking.widgets.table.GTable;
|
||||
import docking.widgets.table.threaded.ThreadedTableModelListener;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.app.services.GoToService;
|
||||
@ -151,7 +152,7 @@ public class AutoTableDisassemblerPlugin extends ProgramPlugin implements Domain
|
||||
findTableAction.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SEARCH, "For Address Tables" }, null, "search for"));
|
||||
findTableAction.setDescription(getPluginDescription().getDescription());
|
||||
|
||||
findTableAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(findTableAction);
|
||||
|
||||
} // end of createActions()
|
||||
|
@ -115,6 +115,7 @@ public class AboutProgramPlugin extends Plugin implements FrontEndable {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
aboutAction.addToWindowWhen(ProgramActionContext.class);
|
||||
aboutAction.setSupportsDefaultToolContext(true);
|
||||
|
||||
aboutAction.setMenuBarData(
|
||||
|
@ -101,6 +101,8 @@ public class SetHighlightPlugin extends Plugin {
|
||||
HIGHLIGHT_GROUP));
|
||||
setHighlightFromSelectionAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_H,
|
||||
InputEvent.CTRL_DOWN_MASK));
|
||||
setHighlightFromSelectionAction
|
||||
.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(setHighlightFromSelectionAction);
|
||||
|
||||
clearHighlightAction = new NavigatableContextAction("Remove Highlight", getName()) {
|
||||
@ -121,6 +123,7 @@ public class SetHighlightPlugin extends Plugin {
|
||||
clearHighlightAction.setMenuBarData(menuData);
|
||||
clearHighlightAction.setPopupMenuData(new MenuData(CLEAR_HIGHLIGHT_POPUPPATH,
|
||||
HIGHLIGHT_GROUP));
|
||||
clearHighlightAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(clearHighlightAction);
|
||||
|
||||
addSelectionAction = new NavigatableContextAction("Add Selection To Highlight", getName()) {
|
||||
@ -142,7 +145,7 @@ public class SetHighlightPlugin extends Plugin {
|
||||
menuData.setMenuSubGroup(Integer.toString(programHighlightSubMenuPosition++));
|
||||
addSelectionAction.setMenuBarData(menuData);
|
||||
addSelectionAction.setPopupMenuData(new MenuData(ADD_SELECTION_POPUPPATH, HIGHLIGHT_GROUP));
|
||||
|
||||
addSelectionAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(addSelectionAction);
|
||||
|
||||
subtractSelectionAction =
|
||||
@ -163,6 +166,7 @@ public class SetHighlightPlugin extends Plugin {
|
||||
new MenuData(new String[] { ToolConstants.MENU_SELECTION, MENU_HIGHLIGHT,
|
||||
"Subtract Selection" }, HIGHLIGHT_GROUP);
|
||||
menuData.setMenuSubGroup(Integer.toString(programHighlightSubMenuPosition++));
|
||||
subtractSelectionAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
subtractSelectionAction.setMenuBarData(menuData);
|
||||
subtractSelectionAction.setPopupMenuData(new MenuData(SUBTRACT_SELECTION_POPUPPATH,
|
||||
HIGHLIGHT_GROUP));
|
||||
@ -185,11 +189,11 @@ public class SetHighlightPlugin extends Plugin {
|
||||
ToolConstants.MENU_SELECTION, "From Highlight" }, HIGHLIGHT_GROUP));
|
||||
setSelectionFromHighlightAction.setPopupMenuData(new MenuData(SET_SELECTION_POPUPPATH,
|
||||
HIGHLIGHT_GROUP));
|
||||
|
||||
setSelectionFromHighlightAction
|
||||
.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(setSelectionFromHighlightAction);
|
||||
|
||||
tool.setMenuGroup(new String[] { MENU_HIGHLIGHT }, HIGHLIGHT_GROUP);
|
||||
tool.setMenuGroup(new String[] { MENU_SELECTION }, HIGHLIGHT_GROUP);
|
||||
tool.setMenuGroup(new String[] { MENU_SELECTION, MENU_HIGHLIGHT }, HIGHLIGHT_GROUP);
|
||||
}
|
||||
|
||||
protected void setHighlight(Navigatable navigatable, ProgramSelection highlight) {
|
||||
|
@ -250,6 +250,7 @@ public class InstructionSearchPlugin extends ProgramPlugin {
|
||||
}
|
||||
|
||||
};
|
||||
searchAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
searchAction.setHelpLocation(new HelpLocation("Search", "Instruction_Pattern_Search"));
|
||||
searchAction.setMenuBarData(
|
||||
new MenuData(new String[] { ToolConstants.MENU_SEARCH, "For Instruction Patterns" },
|
||||
|
@ -15,15 +15,14 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.label;
|
||||
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.context.ListingContextAction;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.context.ListingContextAction;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
public class AllHistoryAction extends ListingContextAction {
|
||||
|
||||
@ -36,7 +35,7 @@ public class AllHistoryAction extends ListingContextAction {
|
||||
null, "Search"));
|
||||
|
||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_H, 0));
|
||||
|
||||
addToWindowWhen(ListingActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,6 +50,7 @@ public abstract class AbstractNextPreviousAction extends NavigatableContextActio
|
||||
setKeyBindingData(new KeyBindingData(getKeyStroke()));
|
||||
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, name));
|
||||
setDescription(getDescriptionString());
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
protected abstract Icon getIcon();
|
||||
|
@ -103,6 +103,7 @@ public class GoToAddressLabelPlugin extends Plugin implements OptionsChangeListe
|
||||
return true;
|
||||
}
|
||||
};
|
||||
action.addToWindowWhen(NavigatableActionContext.class);
|
||||
action.setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, action.getName()));
|
||||
action.setMenuBarData(
|
||||
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, "Go To..." }, null, "GoTo",
|
||||
|
@ -17,7 +17,8 @@ package ghidra.app.plugin.core.navigation;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
@ -27,7 +28,8 @@ import docking.action.*;
|
||||
import docking.menu.MultiActionDockingAction;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.context.ProgramActionContext;
|
||||
import ghidra.app.nav.LocationMemento;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
@ -182,16 +184,6 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
historyService.clear(getNavigatable(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigationActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (!(context instanceof ProgramActionContext)) {
|
||||
@ -204,6 +196,7 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
return hasNext || hasPrevious;
|
||||
}
|
||||
};
|
||||
clearAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
clearAction.setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, clearAction.getName()));
|
||||
MenuData menuData = new MenuData(CLEAR_MENUPATH, HISTORY_MENU_GROUP);
|
||||
menuData.setMenuSubGroup("1"); // first in menu!
|
||||
@ -314,6 +307,7 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
int keycode = isNext ? KeyEvent.VK_RIGHT : KeyEvent.VK_LEFT;
|
||||
setKeyBindingData(new KeyBindingData(keycode, InputEvent.ALT_DOWN_MASK));
|
||||
setDescription(isNext ? "Go to next location" : "Go to previous location");
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -339,16 +333,6 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigationActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DockingActionIf> getActionList(ActionContext context) {
|
||||
Navigatable navigatable = getNavigatable(context);
|
||||
@ -414,6 +398,7 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
new MenuData(new String[] { "Navigation", menuItemName }, HISTORY_MENU_GROUP);
|
||||
menuData.setMenuSubGroup("2"); // after clear
|
||||
setMenuBarData(menuData);
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -438,16 +423,6 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||
historyService.previousFunction(navigatable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (NavigationActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ public class NextPrevCodeUnitPlugin extends Plugin {
|
||||
setHelpLocation(
|
||||
new HelpLocation(HelpTopics.NAVIGATION, longName));
|
||||
setDescription(longName);
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ package ghidra.app.plugin.core.navigation;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@ -64,6 +63,7 @@ public class NextPreviousBookmarkAction extends MultiStateDockingAction<String>
|
||||
toolBarData.setToolBarSubGroup(subGroup);
|
||||
setToolBarData(toolBarData);
|
||||
|
||||
addToWindowWhen(CodeViewerActionContext.class);
|
||||
setKeyBindingData(new KeyBindingData(getKeyStroke()));
|
||||
|
||||
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, getName()));
|
||||
@ -258,14 +258,4 @@ public class NextPreviousBookmarkAction extends MultiStateDockingAction<String>
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return context instanceof ListingActionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (CodeViewerActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package ghidra.app.plugin.core.navigation;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.KeyStroke;
|
||||
@ -83,9 +82,11 @@ public class NextPreviousMarkerAction extends MultiStateDockingAction<String> {
|
||||
setMenuBarData(menuData);
|
||||
|
||||
setKeyBindingData(new KeyBindingData(getKeyStroke()));
|
||||
addToWindowWhen(CodeViewerActionContext.class);
|
||||
|
||||
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, getName()));
|
||||
setDescription("Set marker options");
|
||||
addToWindowWhen(CodeViewerActionContext.class);
|
||||
|
||||
ActionState<String> allMarkers =
|
||||
new ActionState<String>("All Types", markerIcon, "All Types");
|
||||
@ -310,13 +311,4 @@ public class NextPreviousMarkerAction extends MultiStateDockingAction<String> {
|
||||
return isEnabledForContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (CodeViewerActionContext.class.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -523,10 +523,12 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
int subMenuGroupOrder = 1;
|
||||
|
||||
openAction = new ActionBuilder("Open File", getName())
|
||||
.onAction(c -> open())
|
||||
.menuPath(ToolConstants.MENU_FILE, "&Open...")
|
||||
.menuGroup(OPEN_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.keyBinding("ctrl O")
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> open())
|
||||
.buildAndInstall(tool);
|
||||
|
||||
closeAction = new ActionBuilder("Close File", getName())
|
||||
@ -534,6 +536,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.menuGroup(OPEN_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.withContext(ProgramActionContext.class)
|
||||
.supportsDefaultToolContext(true)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> closeProgram(c.getProgram(), false))
|
||||
.keyBinding("ctrl W")
|
||||
.buildAndInstall(tool);
|
||||
@ -542,12 +545,16 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.menuPath(ToolConstants.MENU_FILE, "Close &Others")
|
||||
.menuGroup(OPEN_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.enabled(false)
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> closeOtherPrograms(false))
|
||||
.buildAndInstall(tool);
|
||||
|
||||
closeAllAction = new ActionBuilder("Close All", getName())
|
||||
.menuPath(ToolConstants.MENU_FILE, "Close &All")
|
||||
.menuGroup(OPEN_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> closeAllPrograms(false))
|
||||
.enabled(false)
|
||||
.buildAndInstall(tool);
|
||||
@ -561,6 +568,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.toolBarGroup(ToolConstants.TOOLBAR_GROUP_ONE)
|
||||
.keyBinding("ctrl S")
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.supportsDefaultToolContext(true)
|
||||
.enabledWhen(c -> c.getProgram() != null && c.getProgram().isChanged())
|
||||
.onAction(c -> programSaveMgr.saveProgram(c.getProgram()))
|
||||
@ -570,6 +578,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.menuPath(ToolConstants.MENU_FILE, "Save &As...")
|
||||
.menuGroup(SAVE_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.supportsDefaultToolContext(true)
|
||||
.onAction(c -> programSaveMgr.saveAs(c.getProgram()))
|
||||
.buildAndInstall(tool);
|
||||
@ -578,6 +587,8 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.menuPath(ToolConstants.MENU_FILE, "Save All")
|
||||
.description("Save All Programs")
|
||||
.menuGroup(SAVE_GROUP, Integer.toString(subMenuGroupOrder++))
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.onAction(c -> programSaveMgr.saveChangedPrograms())
|
||||
.buildAndInstall(tool);
|
||||
|
||||
@ -587,6 +598,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
||||
.menuGroup(ToolConstants.TOOL_OPTIONS_MENU_GROUP,
|
||||
ToolConstants.TOOL_OPTIONS_MENU_GROUP + "b")
|
||||
.withContext(ProgramActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.supportsDefaultToolContext(true)
|
||||
.onAction(c -> showProgramOptions(c.getProgram()))
|
||||
.buildAndInstall(tool);
|
||||
|
@ -47,6 +47,9 @@ public class RedoAction extends ProgramContextAction {
|
||||
setKeyBindingData(new KeyBindingData("ctrl shift Z"));
|
||||
setDescription("Redo");
|
||||
setSupportsDefaultToolContext(true);
|
||||
|
||||
// we want this action to appear in all windows that can produce a program context
|
||||
addToWindowWhen(ProgramActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,6 +46,9 @@ public class UndoAction extends ProgramContextAction {
|
||||
setDescription("Undo");
|
||||
setKeyBindingData(new KeyBindingData("ctrl Z"));
|
||||
setSupportsDefaultToolContext(true);
|
||||
|
||||
// we want this action to appear in all windows that can produce a program context
|
||||
addToWindowWhen(ProgramActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,6 +154,7 @@ public class ScalarSearchPlugin extends ProgramPlugin implements DomainObjectLis
|
||||
searchAction.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SEARCH, "For Scalars..." }, null, "search for"));
|
||||
searchAction.setDescription("Search program for scalars");
|
||||
searchAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(searchAction);
|
||||
|
||||
//
|
||||
|
@ -263,31 +263,11 @@ class GhidraScriptActionManager {
|
||||
.onAction(context -> showGhidraScriptJavadoc())
|
||||
.buildAndInstallLocal(provider);
|
||||
|
||||
// XXX In order to override a method of the new DockingAction and use the builder, we
|
||||
// need to override the build method of the ActionBuilder. When the ActionBuilder is
|
||||
// updated, this code can be cleaned up.
|
||||
new ActionBuilder("Ghidra API Help", plugin.getName()) {
|
||||
@Override
|
||||
public DockingAction build() {
|
||||
validate();
|
||||
DockingAction action = new DockingAction(name, owner, keyBindingType) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
actionCallback.accept(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow,
|
||||
Set<Class<?>> contextTypes) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
decorateAction(action);
|
||||
return action;
|
||||
}
|
||||
}.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
|
||||
new ActionBuilder("Ghidra API Help", plugin.getName())
|
||||
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
|
||||
.menuPath(ToolConstants.MENU_HELP, "Ghidra API Help")
|
||||
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
|
||||
.inWindow(ActionBuilder.When.ALWAYS)
|
||||
.onAction(context -> showGhidraScriptJavadoc())
|
||||
.buildAndInstall(plugin.getTool());
|
||||
}
|
||||
|
@ -359,6 +359,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
|
||||
searchAction.setMenuBarData(new MenuData(menuPath, "search"));
|
||||
searchAction.setKeyBindingData(new KeyBindingData('S', 0));
|
||||
searchAction.setDescription("Search Memory for byte sequence");
|
||||
searchAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(searchAction);
|
||||
|
||||
searchAgainAction = new NavigatableContextAction("Repeat Memory Search", getName()) {
|
||||
@ -379,6 +380,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
|
||||
searchAgainAction.setMenuBarData(new MenuData(menuPath, "search"));
|
||||
searchAgainAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_F3, 0));
|
||||
searchAgainAction.setDescription("Search Memory for byte sequence");
|
||||
searchAgainAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(searchAgainAction);
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,8 @@ public class MnemonicSearchPlugin extends Plugin {
|
||||
MENU_PULLRIGHT, "Include Operands (except constants)" }, null, group,
|
||||
MenuData.NO_MNEMONIC, "3"));
|
||||
setSearchMnemonicOpsNoConstAction.setHelpLocation(helpLocation);
|
||||
setSearchMnemonicOpsNoConstAction
|
||||
.addToWindowWhen(NavigatableActionContext.class);
|
||||
|
||||
//
|
||||
// ACTION 2: Search for instructions, including operands.
|
||||
@ -174,6 +176,8 @@ public class MnemonicSearchPlugin extends Plugin {
|
||||
setSearchMnemonicOpsConstAction.setMenuBarData(new MenuData(new String[] { "&Search",
|
||||
MENU_PULLRIGHT, "Include Operands" }, null, group, MenuData.NO_MNEMONIC, "2"));
|
||||
setSearchMnemonicOpsConstAction.setHelpLocation(helpLocation);
|
||||
setSearchMnemonicOpsConstAction
|
||||
.addToWindowWhen(NavigatableActionContext.class);
|
||||
|
||||
//
|
||||
// ACTION 3: Search for instructions, excluding constants.
|
||||
@ -195,6 +199,8 @@ public class MnemonicSearchPlugin extends Plugin {
|
||||
setSearchMnemonicNoOpsNoConstAction.setMenuBarData(new MenuData(new String[] { "&Search",
|
||||
MENU_PULLRIGHT, "Exclude Operands" }, null, group, MenuData.NO_MNEMONIC, "1"));
|
||||
setSearchMnemonicNoOpsNoConstAction.setHelpLocation(helpLocation);
|
||||
setSearchMnemonicNoOpsNoConstAction
|
||||
.addToWindowWhen(NavigatableActionContext.class);
|
||||
|
||||
// Add the actions to the tool...
|
||||
tool.addAction(setSearchMnemonicOpsNoConstAction);
|
||||
|
@ -383,6 +383,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||
.description(DESCRIPTION)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SEARCH, "Search Text"))
|
||||
.withContext(NavigatableActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.supportsDefaultToolContext(true)
|
||||
.onAction(c -> {
|
||||
setNavigatable(c.getNavigatable());
|
||||
@ -398,6 +399,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||
.supportsDefaultToolContext(true)
|
||||
.helpLocation(new HelpLocation(HelpTopics.SEARCH, "Repeat Text Search"))
|
||||
.withContext(NavigatableActionContext.class)
|
||||
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
|
||||
.enabledWhen(c -> searchedOnce)
|
||||
.onAction(c -> {
|
||||
setNavigatable(c.getNavigatable());
|
||||
|
@ -15,19 +15,19 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.select;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.context.NavigatableContextAction;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.util.HelpLocation;
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
|
||||
/**
|
||||
* This plugin class contains the structure needed for the user to
|
||||
@ -72,9 +72,11 @@ public class SelectBlockPlugin extends Plugin {
|
||||
}
|
||||
};
|
||||
MenuData menuData =
|
||||
new MenuData(new String[] { ToolConstants.MENU_SELECTION, "Bytes..." }, null, "Select");
|
||||
new MenuData(new String[] { ToolConstants.MENU_SELECTION, "Bytes..." }, null,
|
||||
"Select Group 2");
|
||||
menuData.setMenuSubGroup("1");
|
||||
toolBarAction.setMenuBarData(menuData);
|
||||
toolBarAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
|
||||
toolBarAction.setEnabled(false);
|
||||
toolBarAction.setDescription("Allows user to select blocks of data.");
|
||||
|
@ -15,10 +15,14 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.select.flow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.context.NavigatableContextAction;
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
import ghidra.app.nav.NavigationUtils;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
@ -38,12 +42,6 @@ import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
|
||||
/**
|
||||
* The SelectByFlowPlugin adds selection of code based on program flow to a
|
||||
* tool. Selection is based on the initial selection or if there is no selection
|
||||
@ -484,9 +482,9 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
|
||||
selectProgramChangesAction.setHelpLocation(new HelpLocation(HelpTopics.SELECTION,
|
||||
selectProgramChangesAction.getName()));
|
||||
|
||||
selectProgramChangesAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectProgramChangesAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(selectProgramChangesAction);
|
||||
|
||||
/**
|
||||
@ -496,6 +494,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select All Flows From", this, SELECT_ALL_FLOWS_FROM);
|
||||
selectAllFlowsFromAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectAllFlowsFromAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectAllFlowsFromAction);
|
||||
|
||||
/**
|
||||
@ -505,6 +504,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select All Flows To", this, SELECT_ALL_FLOWS_TO);
|
||||
selectAllFlowsToAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectAllFlowsToAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectAllFlowsToAction);
|
||||
|
||||
/**
|
||||
@ -514,6 +514,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select Limited Flows From", this, SELECT_LIMITED_FLOWS_FROM);
|
||||
selectLimitedFlowsFromAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectLimitedFlowsFromAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectLimitedFlowsFromAction);
|
||||
|
||||
/**
|
||||
@ -523,6 +524,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select Limited Flows To", this, SELECT_LIMITED_FLOWS_TO);
|
||||
selectLimitedFlowsToAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectLimitedFlowsToAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectLimitedFlowsToAction);
|
||||
|
||||
/**
|
||||
@ -532,6 +534,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select Subroutine", this, SELECT_SUBROUTINES);
|
||||
selectSubroutineAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectSubroutineAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectSubroutineAction);
|
||||
|
||||
/**
|
||||
@ -541,6 +544,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
new SelectByFlowAction("Select Dead Subroutine", this, SELECT_DEAD_SUBROUTINES);
|
||||
selectDeadSubroutineAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectDeadSubroutineAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectDeadSubroutineAction);
|
||||
|
||||
/**
|
||||
@ -549,6 +553,7 @@ public class SelectByFlowPlugin extends Plugin implements OptionsChangeListener
|
||||
selectFunctionAction = new SelectByFlowAction("Select Function", this, SELECT_FUNCTIONS);
|
||||
selectFunctionAction.getMenuBarData().setMenuSubGroup(
|
||||
Integer.toString(subMenuGroupPosition++));
|
||||
selectFunctionAction.addToWindowWhen(ListingActionContext.class);
|
||||
tool.addAction(selectFunctionAction);
|
||||
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class SelectByScopedFlowPlugin extends ProgramPlugin {
|
||||
action.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "Scoped Flow", "Forward Scoped Flow" },
|
||||
null, "Select"));
|
||||
|
||||
action.addToWindowWhen(NavigatableActionContext.class);
|
||||
action.setDescription("Allows user to select scoped flow from current location.");
|
||||
action.setHelpLocation(new HelpLocation("FlowSelection", "Scoped_Flow"));
|
||||
tool.addAction(action);
|
||||
@ -131,7 +131,7 @@ public class SelectByScopedFlowPlugin extends ProgramPlugin {
|
||||
action.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "Scoped Flow", "Reverse Scoped Flow" },
|
||||
null, "Select"));
|
||||
|
||||
action.addToWindowWhen(NavigatableActionContext.class);
|
||||
action.setDescription("Allows user to select scoped flow to the current location.");
|
||||
action.setHelpLocation(new HelpLocation("FlowSelection", "Scoped_Flow"));
|
||||
tool.addAction(action);
|
||||
|
@ -25,7 +25,7 @@ import ghidra.app.nav.NavigationUtils;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
@ -301,8 +301,8 @@ public class QualifiedSelectionPlugin extends Plugin {
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, name));
|
||||
setEnabled(false);
|
||||
setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_SELECTION, name }, null,
|
||||
"Select"));
|
||||
|
||||
"Select Group 2"));
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,24 +15,23 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.select.reference;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.context.NavigatableContextAction;
|
||||
import ghidra.app.nav.NavigationUtils;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.action.MenuData;
|
||||
|
||||
public class SelectBackRefsAction extends NavigatableContextAction {
|
||||
|
||||
private final PluginTool tool;
|
||||
@ -47,6 +45,7 @@ public class SelectBackRefsAction extends NavigatableContextAction {
|
||||
|
||||
setKeyBindingData( new KeyBindingData(KeyEvent.VK_SEMICOLON, InputEvent.CTRL_MASK ) );
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, "Backward"));
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,6 +46,7 @@ public class SelectForwardRefsAction extends NavigatableContextAction {
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, "Forward"));
|
||||
// setKeyBindingData( new KeyBindingData(KeyEvent.VK_SEMICOLON, InputEvent.CTRL_MASK ) );
|
||||
// setHelpLocation(new HelpLocation(HelpTopics.SELECTION, "Backward"));
|
||||
addToWindowWhen(NavigatableActionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,7 +80,7 @@ public class StringTablePlugin extends ProgramPlugin {
|
||||
new String[] { ToolConstants.MENU_SEARCH, "For &Strings..." }, null, "search for"));
|
||||
|
||||
stringSearchAction.setDescription(getPluginDescription().getDescription());
|
||||
|
||||
stringSearchAction.addToWindowWhen(NavigatableActionContext.class);
|
||||
tool.addAction(stringSearchAction);
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,7 @@ import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.conditiontestpanel.ConditionTester;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.ProgramActionContext;
|
||||
import ghidra.app.context.ProgramContextAction;
|
||||
import ghidra.app.context.*;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.core.analysis.validator.PostAnalysisValidator;
|
||||
import ghidra.framework.plugintool.*;
|
||||
@ -95,7 +94,7 @@ public class ValidateProgramPlugin extends Plugin {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
validateAction.addToWindowWhen(ListingActionContext.class);
|
||||
validateAction.setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_ANALYSIS,
|
||||
ACTION_NAME }, null, "ZZZ"));
|
||||
|
||||
|
@ -15,19 +15,11 @@
|
||||
*/
|
||||
package ghidra.app.plugin.prototype.debug;
|
||||
|
||||
import ghidra.app.DeveloperPluginPackage;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.framework.plugintool.PluginInfo;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
@ -36,6 +28,12 @@ import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.tool.ToolConstants;
|
||||
import ghidra.app.DeveloperPluginPackage;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.framework.plugintool.PluginInfo;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
||||
//@formatter:off
|
||||
@PluginInfo(
|
||||
@ -93,13 +91,8 @@ public class ScreenshotPlugin extends ProgramPlugin {
|
||||
writeFile(image, file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;// this is a global-level action
|
||||
}
|
||||
};
|
||||
|
||||
captureActiveWindowAction.setAddToAllWindows(true);
|
||||
captureActiveWindowAction.setDescription("Takes a screenshot of the active component provider and exports it to PNG format.");
|
||||
captureActiveWindowAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_F11,
|
||||
InputEvent.ALT_DOWN_MASK));
|
||||
@ -123,13 +116,8 @@ public class ScreenshotPlugin extends ProgramPlugin {
|
||||
writeFile(image, file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;// this is a global-level action
|
||||
}
|
||||
};
|
||||
|
||||
captureToolFrameAction.setAddToAllWindows(true);
|
||||
captureToolFrameAction.setDescription("Takes a screenshot of the active tool and exports it to PNG format.");
|
||||
captureToolFrameAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_F12,
|
||||
InputEvent.ALT_DOWN_MASK));
|
||||
|
@ -21,6 +21,7 @@ import java.awt.Window;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.ToggleDockingAction;
|
||||
import docking.util.image.ToolIconURL;
|
||||
@ -175,7 +176,8 @@ public class DiffSaveSettingsTest extends DiffApplyTestAdapter {
|
||||
ProgramManagerPlugin pm = getPlugin(tool, ProgramManagerPlugin.class);
|
||||
DockingActionIf closeAllProgramAction = getAction(pm, "Close All");
|
||||
assertNotNull(closeAllProgramAction);
|
||||
performAction(closeAllProgramAction, true);
|
||||
ActionContext defaultContext = tool.getDefaultToolContext();
|
||||
performAction(closeAllProgramAction, defaultContext, true);
|
||||
|
||||
openProgram(p3);
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class WindowActionManager {
|
||||
public void setActions(List<DockingActionIf> actionList) {
|
||||
menuBarMgr.clearActions();
|
||||
toolBarMgr.clearActions();
|
||||
actionToProxyMap.clear();
|
||||
for (DockingActionIf action : actionList) {
|
||||
addAction(action);
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package docking.action;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import docking.ActionContext;
|
||||
|
||||
/**
|
||||
@ -68,16 +66,6 @@ public abstract class ContextSpecificAction<T> extends DockingAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (contextClass.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext actionContext) {
|
||||
actionPerformed(contextClass.cast(actionContext));
|
||||
|
@ -83,6 +83,8 @@ public abstract class DockingAction implements DockingActionIf {
|
||||
private Predicate<ActionContext> enabledPredicate;
|
||||
private Predicate<ActionContext> popupPredicate;
|
||||
private Predicate<ActionContext> validContextPredicate;
|
||||
private boolean shouldAddToAllWindows = false;
|
||||
private Class<? extends ActionContext> addToWindowWhenContextClass = null;
|
||||
|
||||
private boolean supportsDefaultToolContext;
|
||||
|
||||
@ -193,15 +195,42 @@ public abstract class DockingAction implements DockingActionIf {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behavior is to add to main window;
|
||||
* Determines if this action should be added to a window.
|
||||
* <P>
|
||||
* If the client wants the action on all windows, then they can call {@link #shouldAddToAllWindows}
|
||||
* <P>
|
||||
* If the client wants the action to be on a window only when the window can produce
|
||||
* a certain context type, the the client should call
|
||||
* {@link #addToWindowWhen(Class)}
|
||||
* <P>
|
||||
* Otherwise, by default, the action will only be on the main window.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
if (isMainWindow) {
|
||||
// only return true if it is a tool menu or toolbar action
|
||||
return menuBarData != null || toolBarData != null;
|
||||
public final boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
// this method only applies to actions with top level menus or tool bars.
|
||||
if (menuBarData == null && toolBarData == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
// clients can specify that the action should be on all windows.
|
||||
if (shouldAddToAllWindows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clients can specify a context class that determines if an action should
|
||||
// be added to a window.
|
||||
if (addToWindowWhenContextClass != null) {
|
||||
for (Class<?> class1 : contextTypes) {
|
||||
if (addToWindowWhenContextClass.isAssignableFrom(class1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// default to only appearing in main window
|
||||
return isMainWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -584,6 +613,30 @@ public abstract class DockingAction implements DockingActionIf {
|
||||
validContextPredicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ActionContext class for when this action should be added to a window
|
||||
* <P>
|
||||
* If this is set, the the action will only be added to windows that have providers
|
||||
* that can produce an ActionContext that is appropriate for this action.
|
||||
* <P>
|
||||
* @param contextClass the ActionContext class required to be producible by a
|
||||
* provider that is hosted in that window before this action is added to that
|
||||
* window.
|
||||
*
|
||||
*/
|
||||
public void addToWindowWhen(Class<? extends ActionContext> contextClass) {
|
||||
addToWindowWhenContextClass = contextClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells this action to add itself to all windows
|
||||
* <P>
|
||||
* @param b to add to all windows or not
|
||||
*/
|
||||
public void setAddToAllWindows(boolean b) {
|
||||
shouldAddToAllWindows = b;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Non-public methods
|
||||
//==================================================================================================
|
||||
@ -611,4 +664,5 @@ public abstract class DockingAction implements DockingActionIf {
|
||||
String classInfo = trace[0].toString();
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -284,10 +284,9 @@ public interface DockingActionIf extends HelpDescriptor {
|
||||
/**
|
||||
* Determines whether this action should be added to a window (either the main window or a
|
||||
* secondary detached window). By default, this method will return true for the main window
|
||||
* and false otherwise. Actions that want to also appear in other windows should override this
|
||||
* method to return true when appropriate for the context types
|
||||
* @param isMainWindow true if the window in question is the main window. Otherwise, the window
|
||||
* is a secondary window.
|
||||
* and false otherwise.
|
||||
*
|
||||
* @param isMainWindow true if the window in question is the main window
|
||||
* @param contextTypes a list of contextTypes (Classes) based on the providers that are currently
|
||||
* in the window.
|
||||
* @return true if this action should be added to the window, false otherwise.
|
||||
|
@ -176,7 +176,23 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
|
||||
* Set to true if the action supports using the default tool context if the local context is invalid
|
||||
*/
|
||||
private boolean supportsDefaultToolContext;
|
||||
|
||||
/**
|
||||
* Specifies when the action should appear in a window.
|
||||
*/
|
||||
private When windowWhen;
|
||||
|
||||
/**
|
||||
* For use with the {@link AbstractActionBuilder#inWindow(When)} method to specify which windows (main window
|
||||
* or secondary windows) a global tool bar or menu action will appear in.
|
||||
*
|
||||
*/
|
||||
public enum When {
|
||||
MAIN_WINDOW, // action should only appear in the main window
|
||||
ALWAYS, // action should appear in all windows
|
||||
CONTEXT_MATCHES // action should appear if and only if the window has
|
||||
} // has a provider that generates the appropriate context.
|
||||
|
||||
/**
|
||||
* Builder constructor
|
||||
* @param name the name of the action to be built
|
||||
@ -197,7 +213,7 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
|
||||
/**
|
||||
* Builds the action. To build and install the action in one step, use
|
||||
* {@link #buildAndInstall(Tool)} or {@link #buildAndInstallLocal(ComponentProvider)}.
|
||||
*
|
||||
* {@link #inWindow(When)}
|
||||
* @return the newly build action
|
||||
*/
|
||||
public abstract T build();
|
||||
@ -592,6 +608,29 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
|
||||
supportsDefaultToolContext = b;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies when a global action should appear in a window (main or secondary).
|
||||
* <P>
|
||||
* Global menu or toolbar actions can be configured to appear in 1) only the main
|
||||
* window, or 2) all windows, or 3) any window that has a provider that
|
||||
* generates an action context that matches the context that this action
|
||||
* consumes. If the "context matches" options is chosen, then the
|
||||
* {@link #withContext(Class)} method must also be called to specify the matching
|
||||
* context; otherwise an exception will be thrown when the action is built.
|
||||
* <P>
|
||||
*
|
||||
* The default is that the action will only appear in the main window.
|
||||
*
|
||||
* @param when use the {@link When} enum to specify the windowing behavior
|
||||
* of the action.
|
||||
*
|
||||
* @return this builder (for chaining)
|
||||
*/
|
||||
public B inWindow(When when) {
|
||||
this.windowWhen = when;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specific ActionContext type to use for the various predicate calls
|
||||
@ -669,6 +708,11 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
|
||||
throw new IllegalStateException(
|
||||
"Can't build a DockingAction without an action callback");
|
||||
}
|
||||
if (windowWhen == When.CONTEXT_MATCHES && actionContextClass == null) {
|
||||
throw new IllegalStateException("The InWindow state was set to "
|
||||
+ "\"CONTEXT_MATCHES\", but no context class was set. Use"
|
||||
+ " the \"withContext\" method");
|
||||
}
|
||||
}
|
||||
|
||||
protected void decorateAction(DockingAction action) {
|
||||
@ -691,6 +735,14 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
|
||||
|
||||
action.validContextWhen(adaptPredicate(validContextPredicate));
|
||||
action.popupWhen(adaptPredicate(popupPredicate));
|
||||
|
||||
if (windowWhen == When.ALWAYS) {
|
||||
action.setAddToAllWindows(true);
|
||||
}
|
||||
else if (windowWhen == When.CONTEXT_MATCHES) {
|
||||
action.addToWindowWhen(actionContextClass);
|
||||
}
|
||||
// else action defaults to main window only
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@ import org.jdom.Element;
|
||||
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.actions.ToolActions;
|
||||
import docking.framework.AboutDialog;
|
||||
@ -921,11 +922,8 @@ public abstract class PluginTool extends AbstractDockingTool {
|
||||
optionsMgr.editOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return isMainWindow || !contextTypes.isEmpty();
|
||||
}
|
||||
};
|
||||
optionsAction.setAddToAllWindows(true);
|
||||
optionsAction.setHelpLocation(
|
||||
new HelpLocation(ToolConstants.FRONT_END_HELP_TOPIC, "Tool Options"));
|
||||
MenuData menuData =
|
||||
@ -1016,90 +1014,43 @@ public abstract class PluginTool extends AbstractDockingTool {
|
||||
}
|
||||
|
||||
protected void addHelpActions() {
|
||||
new ActionBuilder("About Ghidra", ToolConstants.TOOL_OWNER)
|
||||
.menuPath(ToolConstants.MENU_HELP, "&About Ghidra")
|
||||
.menuGroup("ZZA")
|
||||
.helpLocation(new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "About_Ghidra"))
|
||||
.inWindow(ActionBuilder.When.ALWAYS)
|
||||
.onAction(c -> DockingWindowManager.showDialog(new AboutDialog()))
|
||||
.buildAndInstall(this);
|
||||
|
||||
DockingAction action = new DockingAction("About Ghidra", ToolConstants.TOOL_OWNER) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
DockingWindowManager.showDialog(new AboutDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
action.setMenuBarData(
|
||||
new MenuData(new String[] { ToolConstants.MENU_HELP, "&About Ghidra" }, null, "ZZA"));
|
||||
|
||||
action.setHelpLocation(new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "About_Ghidra"));
|
||||
action.setEnabled(true);
|
||||
addAction(action);
|
||||
|
||||
DockingAction userAgreementAction = new DockingAction("User Agreement",
|
||||
ToolConstants.TOOL_OWNER, KeyBindingType.UNSUPPORTED) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
DockingWindowManager.showDialog(new UserAgreementDialog(false, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
userAgreementAction.setMenuBarData(
|
||||
new MenuData(new String[] { ToolConstants.MENU_HELP, "&User Agreement" }, null,
|
||||
ToolConstants.HELP_CONTENTS_MENU_GROUP));
|
||||
userAgreementAction.setHelpLocation(
|
||||
new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "User_Agreement"));
|
||||
|
||||
userAgreementAction.setEnabled(true);
|
||||
addAction(userAgreementAction);
|
||||
new ActionBuilder("User Agreement", ToolConstants.TOOL_OWNER)
|
||||
.menuPath(ToolConstants.MENU_HELP, "&User Agreement")
|
||||
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
|
||||
.helpLocation(new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "User_Agreement"))
|
||||
.inWindow(ActionBuilder.When.ALWAYS)
|
||||
.onAction(
|
||||
c -> DockingWindowManager.showDialog(new UserAgreementDialog(false, false)))
|
||||
.buildAndInstall(this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
action.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_HELP, "&Report Bug..." }, null, "BBB"));
|
||||
|
||||
action.setHelpLocation(new HelpLocation("ErrorReporting", "Report_Bug"));
|
||||
action.setEnabled(true);
|
||||
addAction(action);
|
||||
new ActionBuilder("Report Bug", ToolConstants.TOOL_OWNER)
|
||||
.menuPath(ToolConstants.MENU_HELP, "&Report Bug...")
|
||||
.menuGroup("BBB")
|
||||
.helpLocation(new HelpLocation("ErrorReporting", "Report_Bug"))
|
||||
.inWindow(ActionBuilder.When.ALWAYS)
|
||||
.onAction(c -> reporter.report(getToolFrame(), "User Bug Report", null))
|
||||
.buildAndInstall(this);
|
||||
}
|
||||
|
||||
HelpService help = Help.getHelpService();
|
||||
action = new DockingAction("Contents", ToolConstants.TOOL_OWNER) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
help.showHelp(null, false, getToolFrame());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
action.setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_HELP, "&Contents" },
|
||||
null, ToolConstants.HELP_CONTENTS_MENU_GROUP));
|
||||
|
||||
action.setEnabled(true);
|
||||
action.setHelpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"));
|
||||
|
||||
addAction(action);
|
||||
new ActionBuilder("Contents", ToolConstants.TOOL_OWNER)
|
||||
.menuPath(ToolConstants.MENU_HELP, "&Contents")
|
||||
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
|
||||
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
|
||||
.inWindow(ActionBuilder.When.ALWAYS)
|
||||
.onAction(c -> help.showHelp(null, false, getToolFrame()))
|
||||
.buildAndInstall(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user