mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-25 17:25:17 +02:00
Fixed docking action key bindings in dialogs
This commit is contained in:
@@ -538,20 +538,26 @@ public abstract class AbstractGhidraHeadedDebuggerTest
|
||||
}
|
||||
|
||||
protected static void assertDisabled(ActionContextProvider provider, DockingActionIf action) {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
ActionContext context = createActionContext(provider);
|
||||
assertFalse(action.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
protected static void assertEnabled(ActionContextProvider provider, DockingActionIf action) {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
ActionContext context = createActionContext(provider);
|
||||
assertTrue(action.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
protected static void performEnabledAction(ActionContextProvider provider,
|
||||
DockingActionIf action, boolean wait) {
|
||||
ActionContext context = waitForValue(() -> {
|
||||
ActionContext ctx =
|
||||
provider == null ? new DefaultActionContext() : provider.getActionContext(null);
|
||||
|
||||
ActionContext ctx = null;
|
||||
if (provider == null) {
|
||||
ctx = new DefaultActionContext();
|
||||
}
|
||||
|
||||
ctx.setContextProvider(provider);
|
||||
|
||||
if (!action.isEnabledForContext(ctx)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -25,6 +25,7 @@ import javax.swing.JTextField;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.ToggleDockingAction;
|
||||
import docking.menu.ActionState;
|
||||
@@ -118,7 +119,8 @@ public class SampleGraphPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
ToggleDockingAction showFilterAction =
|
||||
(ToggleDockingAction) getAction(plugin, SampleGraphProvider.SHOW_FILTER_ACTION_NAME);
|
||||
setToggleActionSelected(showFilterAction, provider.getActionContext(null), true);
|
||||
ActionContext context = createActionContext(provider);
|
||||
setToggleActionSelected(showFilterAction, context, true);
|
||||
|
||||
Component filterPanel =
|
||||
findComponentByName(provider.getComponent(), "sample.graph.filter.panel");
|
||||
|
||||
@@ -43,6 +43,7 @@ public class ProgramActionContext extends DefaultActionContext {
|
||||
if (sourceComponent == null) {
|
||||
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
setSourceObject(kfm.getFocusOwner());
|
||||
setContextProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -21,8 +21,7 @@ import java.awt.event.MouseEvent;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.WindowPosition;
|
||||
import docking.*;
|
||||
import docking.util.image.ToolIconURL;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.label.*;
|
||||
@@ -86,30 +85,24 @@ class MergeManagerProvider extends ComponentProviderAdapter {
|
||||
MergeManager mergeManager = plugin.getMergeManager();
|
||||
if (event != null && event.getSource() instanceof FieldHeaderComp) {
|
||||
FieldHeaderComp comp = (FieldHeaderComp) event.getSource();
|
||||
FieldHeaderLocation fieldHeaderLocation = comp.getFieldHeaderLocation(event.getPoint());
|
||||
return createContext(fieldHeaderLocation);
|
||||
|
||||
FieldHeaderLocation fhLoc = comp.getFieldHeaderLocation(event.getPoint());
|
||||
return new DefaultActionContext(this).setContextObject(fhLoc);
|
||||
}
|
||||
if (mergeManager instanceof ProgramMultiUserMergeManager) {
|
||||
ProgramMultiUserMergeManager programMergeManager =
|
||||
(ProgramMultiUserMergeManager) mergeManager;
|
||||
Navigatable navigatable = programMergeManager.navigatable;
|
||||
if (currentComponent instanceof ListingMergePanel) {
|
||||
|
||||
if (mergeManager instanceof ProgramMultiUserMergeManager programMerger) {
|
||||
Navigatable navigatable = programMerger.navigatable;
|
||||
if (currentComponent instanceof ListingMergePanel listingMergePanel) {
|
||||
// Set the program location within the context so it is from the listing panel
|
||||
// that is being clicked. Actions should use the location to know which of the
|
||||
// 4 programs or listings is in the current context.
|
||||
ListingMergePanel listingMergePanel = (ListingMergePanel) currentComponent;
|
||||
Object actionContext = listingMergePanel.getActionContext(event);
|
||||
if (actionContext instanceof ProgramLocation) {
|
||||
ListingActionContext listingActionContext = new ListingActionContext(this,
|
||||
navigatable, (ProgramLocation) actionContext);
|
||||
return listingActionContext;
|
||||
if (actionContext instanceof ProgramLocation loc) {
|
||||
return new ListingActionContext(this, navigatable, loc);
|
||||
}
|
||||
}
|
||||
ProgramLocation programLocation = navigatable.getLocation();
|
||||
ListingActionContext listingActionContext =
|
||||
new ListingActionContext(this, navigatable, programLocation);
|
||||
return listingActionContext;
|
||||
|
||||
ProgramLocation location = navigatable.getLocation();
|
||||
return new ListingActionContext(this, navigatable, location);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ListingMergePanelProvider extends ComponentProviderAdapter
|
||||
@Override
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
Object obj = mergePanel.getActionContext(event);
|
||||
return createContext(obj);
|
||||
return new DefaultActionContext(this).setContextObject(obj);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
|
||||
@@ -312,13 +312,13 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
FieldHeader headerPanel = listingPanel.getFieldHeader();
|
||||
if (headerPanel != null && source instanceof FieldHeaderComp) {
|
||||
FieldHeaderLocation fhLoc = headerPanel.getFieldHeaderLocation(event.getPoint());
|
||||
return createContext(fhLoc);
|
||||
return new DefaultActionContext(this).setContextObject(fhLoc);
|
||||
}
|
||||
|
||||
if (otherPanel != null && otherPanel.isAncestorOf((Component) source)) {
|
||||
Object obj = getContextForMarginPanels(otherPanel, event);
|
||||
if (obj != null) {
|
||||
return createContext(obj);
|
||||
return new DefaultActionContext(this).setContextObject(obj);
|
||||
}
|
||||
return new OtherPanelContext(this, program);
|
||||
}
|
||||
@@ -333,7 +333,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
|
||||
return createContext(getContextForMarginPanels(listingPanel, event));
|
||||
Object marginContextObject = getContextForMarginPanels(listingPanel, event);
|
||||
return new DefaultActionContext(this).setContextObject(marginContextObject);
|
||||
}
|
||||
|
||||
private Object getContextForMarginPanels(ListingPanel lp, MouseEvent event) {
|
||||
|
||||
@@ -18,7 +18,6 @@ package ghidra.app.plugin.core.script;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.*;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -632,11 +631,6 @@ public class GhidraScriptEditorComponentProvider extends ComponentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
return createContext(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return scrollPane;
|
||||
@@ -645,6 +639,7 @@ public class GhidraScriptEditorComponentProvider extends ComponentProvider {
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
||||
/**
|
||||
* Special JTextArea that knows how to properly handle it's key events.
|
||||
* See {@link #processKeyBinding(KeyStroke, KeyEvent, int, boolean)}
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.event.TableModelListener;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DefaultActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import generic.theme.GIcon;
|
||||
@@ -217,7 +218,7 @@ public class PropertyManagerProvider extends ComponentProviderAdapter {
|
||||
Rectangle rowBounds =
|
||||
table.getCellRect(row, PropertyManagerTableModel.PROPERTY_NAME_COLUMN, true);
|
||||
if (rowBounds.contains(event.getPoint())) {
|
||||
return createContext(rowBounds);
|
||||
return new DefaultActionContext(this).setContextObject(rowBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,24 +15,14 @@
|
||||
*/
|
||||
package ghidra.features.base.memsearch.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingContextListener;
|
||||
@@ -46,9 +36,7 @@ import docking.widgets.OptionDialogBuilder;
|
||||
import docking.widgets.table.actions.DeleteTableRowAction;
|
||||
import generic.theme.GIcon;
|
||||
import ghidra.app.context.NavigatableActionContext;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.nav.NavigatableRegistry;
|
||||
import ghidra.app.nav.NavigatableRemovalListener;
|
||||
import ghidra.app.nav.*;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.script.AskDialog;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
@@ -58,10 +46,7 @@ import ghidra.features.base.memsearch.combiner.Combiner;
|
||||
import ghidra.features.base.memsearch.matcher.SearchData;
|
||||
import ghidra.features.base.memsearch.matcher.UserInputByteMatcher;
|
||||
import ghidra.features.base.memsearch.scan.Scanner;
|
||||
import ghidra.features.base.memsearch.searcher.AlignmentFilter;
|
||||
import ghidra.features.base.memsearch.searcher.CodeUnitFilter;
|
||||
import ghidra.features.base.memsearch.searcher.MemoryMatch;
|
||||
import ghidra.features.base.memsearch.searcher.MemorySearcher;
|
||||
import ghidra.features.base.memsearch.searcher.*;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.model.DomainObjectClosedListener;
|
||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||
@@ -69,9 +54,7 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.BytesFieldLocation;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
@@ -127,7 +110,7 @@ public class MemorySearchProvider extends ComponentProviderAdapter
|
||||
|
||||
// used to show a temporary message over the table
|
||||
private GGlassPaneMessage glassPaneMessage;
|
||||
|
||||
|
||||
public MemorySearchProvider(MemorySearchPlugin plugin, Navigatable navigatable,
|
||||
SearchSettings settings, MemorySearchOptions options, SearchHistory history) {
|
||||
super(plugin.getTool(), "Memory Search", plugin.getName());
|
||||
@@ -721,13 +704,8 @@ public class MemorySearchProvider extends ComponentProviderAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionContext createContext(Component focusedComponent, Object contextObject) {
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
ActionContext context = new NavigatableActionContext(this, navigatable);
|
||||
context.setContextObject(contextObject);
|
||||
|
||||
// the 'sourceComponent' will be the focused item if the focus owner is in our provider,
|
||||
// otherwise it will be the main component
|
||||
context.setSourceObject(focusedComponent);
|
||||
|
||||
// we make the source component be the table so that the 'activate filter' action works
|
||||
// from anywhere in this provider
|
||||
@@ -761,28 +739,31 @@ public class MemorySearchProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
ArrayList<String> choices = new ArrayList<String>(programMap.keySet());
|
||||
AskDialog<String> dialog = new AskDialog<String>(null, "Compare to...", "Program", AskDialog.STRING, choices, null);
|
||||
AskDialog<String> dialog = new AskDialog<String>(null, "Compare to...", "Program",
|
||||
AskDialog.STRING, choices, null);
|
||||
if (dialog.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigatable next = programMap.get(dialog.getChoiceValue());
|
||||
MemorySearchProvider nextProvider = new MemorySearchProvider(plugin, next, model.getSettings(), options, new SearchHistory(searchHistory));
|
||||
MemorySearchProvider nextProvider = new MemorySearchProvider(plugin, next,
|
||||
model.getSettings(), options, new SearchHistory(searchHistory));
|
||||
AddressableByteSource nextByteSource = nextProvider.byteSource;
|
||||
nextProvider.setSearchInput(this.getSearchInput());
|
||||
nextProvider.showScanPanel(true);
|
||||
|
||||
|
||||
List<MemoryMatch<SearchData>> searchResults = getSearchResults();
|
||||
List<MemoryMatch<SearchData>> rebasedResults = new ArrayList<>();
|
||||
for (MemoryMatch<SearchData> match : searchResults) {
|
||||
ProgramLocation canonicalLocation = byteSource.getCanonicalLocation(match.getAddress());
|
||||
Address rebase = nextByteSource.rebaseFromCanonical(canonicalLocation);
|
||||
if (rebase != null) {
|
||||
MemoryMatch<SearchData> nextMatch = new MemoryMatch<>(rebase, match.getBytes(), match.getPattern());
|
||||
MemoryMatch<SearchData> nextMatch =
|
||||
new MemoryMatch<>(rebase, match.getBytes(), match.getPattern());
|
||||
rebasedResults.add(nextMatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemorySearchResultsPanel nextResultsPanel = nextProvider.getResultsPanel();
|
||||
nextProvider.setBusy(true);
|
||||
nextResultsPanel.refreshAndMaybeScanForChanges(nextByteSource, scanner, rebasedResults);
|
||||
|
||||
@@ -166,11 +166,7 @@ public abstract class AbstractDataTreeDialog extends DialogComponentProvider
|
||||
return super.getActionContext(event);
|
||||
}
|
||||
|
||||
ActionContext actionContext = treePanel.getActionContext(null, event);
|
||||
if (actionContext instanceof DialogActionContext dac) {
|
||||
dac.setDialogComponentProvider(this);
|
||||
}
|
||||
return actionContext;
|
||||
return treePanel.getActionContext(null, event);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
||||
@@ -352,7 +352,7 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
|
||||
PlaceholderManager pm = dwm.getPlaceholderManager();
|
||||
Set<ComponentProvider> allProviders = pm.getActiveProviders();
|
||||
for (ComponentProvider cp : allProviders) {
|
||||
ActionContext context = cp.getActionContext(null);
|
||||
ActionContext context = createActionContext(cp);
|
||||
if (context == null) {
|
||||
continue; // a null context is allowed
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.DockingActionIf;
|
||||
@@ -831,7 +832,8 @@ public class CopyPasteCommentsTest extends AbstractProgramBasedTest {
|
||||
|
||||
private void assertEnabled(DockingActionIf action, ComponentProvider provider) {
|
||||
boolean isEnabled = runSwing(() -> {
|
||||
return action.isEnabledForContext(provider.getActionContext(null));
|
||||
ActionContext context = createActionContext(provider);
|
||||
return action.isEnabledForContext(context);
|
||||
});
|
||||
assertTrue("Action was not enabled when it should be", isEnabled);
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
JButton parseToFileButton = findButtonByText(dialog, "Parse to File...");
|
||||
assertNotNull(parseToFileButton);
|
||||
|
||||
ActionContext context = dialog.getActionContext(null);
|
||||
ActionContext context = createActionContext(dialog);
|
||||
DockingActionIf saveAsAction = getAction(dialog, "Save Profile As");
|
||||
assertTrue(saveAsAction.isEnabledForContext(context));
|
||||
|
||||
@@ -139,10 +139,12 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
addSourceFile("c:\\temp\\fred.h");
|
||||
|
||||
DockingActionIf saveAction = getAction(dialog, "Save Profile");
|
||||
assertFalse(saveAction.isEnabledForContext(dialog.getActionContext(null)));
|
||||
ActionContext context = createActionContext(dialog);
|
||||
assertFalse(saveAction.isEnabledForContext(context));
|
||||
|
||||
DockingActionIf saveAsAction = getAction(dialog, "Save Profile As");
|
||||
assertTrue(saveAsAction.isEnabledForContext(dialog.getActionContext(null)));
|
||||
context = createActionContext(dialog);
|
||||
assertTrue(saveAsAction.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -75,8 +75,8 @@ public class LocationReferencesPlugin2Test extends AbstractLocationReferencesTes
|
||||
Address address = addr(0x01004350);
|
||||
goTo(address, "Mnemonic", 1);
|
||||
|
||||
assertTrue(!showReferencesAction.isEnabledForContext(
|
||||
getCodeViewerProvider().getActionContext(null)));
|
||||
ActionContext context = createActionContext(getCodeViewerProvider());
|
||||
assertTrue(!showReferencesAction.isEnabledForContext(context));
|
||||
|
||||
LocationReferencesProvider provider = getResultsProvider();
|
||||
assertNull("Found a provider for showing references to an undefined mnemonic field.",
|
||||
@@ -128,8 +128,8 @@ public class LocationReferencesPlugin2Test extends AbstractLocationReferencesTes
|
||||
|
||||
// test that the current provider contains the correct location descriptor for a
|
||||
// given location
|
||||
assertTrue(!showReferencesAction.isEnabledForContext(
|
||||
getCodeViewerProvider().getActionContext(null)));
|
||||
ActionContext context = createActionContext(getCodeViewerProvider());
|
||||
assertTrue(!showReferencesAction.isEnabledForContext(context));
|
||||
|
||||
assertNoResults("Found a provider for showing references to an undefined mnemonic field.");
|
||||
}
|
||||
@@ -214,7 +214,7 @@ public class LocationReferencesPlugin2Test extends AbstractLocationReferencesTes
|
||||
int parameterColumn = 5;
|
||||
goTo(address, "Variable XRef Header", parameterColumn);
|
||||
|
||||
ActionContext context = getCodeViewerProvider().getActionContext(null);
|
||||
ActionContext context = createActionContext(getCodeViewerProvider());
|
||||
assertFalse(showReferencesAction.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.swing.undo.UndoableEdit;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DefaultActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.widgets.OptionDialog;
|
||||
@@ -1086,7 +1087,8 @@ public abstract class AbstractGhidraScriptMgrPluginTest
|
||||
waitForSwing();
|
||||
DockingActionIf saveAction = getAction(plugin, "Save Script");
|
||||
|
||||
boolean isEnabled = saveAction.isEnabledForContext(editor.getActionContext(null));
|
||||
ActionContext context = createActionContext(editor);
|
||||
boolean isEnabled = saveAction.isEnabledForContext(context);
|
||||
if (!isEnabled) {
|
||||
// the action is enabled when the provider detects changes; it is disabled for read-only
|
||||
|
||||
@@ -1135,7 +1137,8 @@ public abstract class AbstractGhidraScriptMgrPluginTest
|
||||
protected void assertSaveButtonDisabled() {
|
||||
waitForSwing();
|
||||
DockingActionIf saveAction = getAction(plugin, "Save Script");
|
||||
assertFalse(saveAction.isEnabledForContext(editor.getActionContext(null)));
|
||||
ActionContext context = createActionContext(editor);
|
||||
assertFalse(saveAction.isEnabledForContext(context));
|
||||
|
||||
assertEditorHasNoChanges();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.swing.table.TableModel;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.tool.ToolConstants;
|
||||
@@ -98,10 +99,12 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
public void testActionEnablement() {
|
||||
DockingAction saveAction = managePluginsDialog.getSaveAction();
|
||||
performAction(saveAction, true);
|
||||
assertFalse(saveAction.isEnabledForContext(managePluginsDialog.getActionContext(null)));
|
||||
ActionContext context = createActionContext(managePluginsDialog);
|
||||
assertFalse(saveAction.isEnabledForContext(context));
|
||||
|
||||
DockingAction saveAsAction = managePluginsDialog.getSaveAsAction();
|
||||
assertTrue(saveAsAction.isEnabledForContext(managePluginsDialog.getActionContext(null)));
|
||||
context = createActionContext(managePluginsDialog);
|
||||
assertTrue(saveAsAction.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,7 +151,8 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
assertTrue(tool.hasConfigChanged());
|
||||
DockingAction action = managePluginsDialog.getSaveAction();
|
||||
assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null)));
|
||||
ActionContext context = createActionContext(managePluginsDialog);
|
||||
assertTrue(action.isEnabledForContext(context));
|
||||
assertTrue(
|
||||
pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class)));
|
||||
}
|
||||
@@ -160,7 +164,8 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
pluginModel.removePlugin(PluginDescription.getPluginDescription(EquateTablePlugin.class));
|
||||
assertTrue(tool.hasConfigChanged());
|
||||
DockingAction action = managePluginsDialog.getSaveAction();
|
||||
assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null)));
|
||||
ActionContext context = createActionContext(managePluginsDialog);
|
||||
assertTrue(action.isEnabledForContext(context));
|
||||
assertFalse(
|
||||
pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class)));
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.DockingActionIf;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.features.base.quickfix.*;
|
||||
@@ -55,8 +56,9 @@ public class SearchAndReplaceDialogTest extends AbstractGhidraHeadedIntegrationT
|
||||
env.open(program);
|
||||
env.showTool();
|
||||
searchAndReplaceAction = getAction(plugin, "Search And Replace");
|
||||
ActionContext actionContext = tool.getActiveComponentProvider().getActionContext(null);
|
||||
performAction(searchAndReplaceAction, actionContext, false);
|
||||
ComponentProvider provider = tool.getActiveComponentProvider();
|
||||
ActionContext context = createActionContext(provider);
|
||||
performAction(searchAndReplaceAction, context, false);
|
||||
dialog = waitForDialogComponent(SearchAndReplaceDialog.class);
|
||||
assertNotNull(dialog);
|
||||
}
|
||||
|
||||
@@ -426,7 +426,8 @@ public class FunctionGraphPlugin1Test extends AbstractFunctionGraphTest {
|
||||
//
|
||||
DockingAction copyAction = getCopyAction();
|
||||
ComponentProvider provider = getProvider();
|
||||
assertTrue(copyAction.isEnabledForContext(provider.getActionContext(null)));
|
||||
ActionContext context = createActionContext(provider);
|
||||
assertTrue(copyAction.isEnabledForContext(context));
|
||||
|
||||
performAction(copyAction, provider, false);
|
||||
|
||||
@@ -478,11 +479,11 @@ public class FunctionGraphPlugin1Test extends AbstractFunctionGraphTest {
|
||||
// Validate and execute the action
|
||||
//
|
||||
ComponentProvider provider = getProvider();
|
||||
ActionContext actionContext = provider.getActionContext(null);
|
||||
boolean isEnabled = copyAction.isEnabledForContext(actionContext);
|
||||
debugAction(copyAction, actionContext);
|
||||
ActionContext context = createActionContext(provider);
|
||||
boolean isEnabled = copyAction.isEnabledForContext(context);
|
||||
debugAction(copyAction, context);
|
||||
assertTrue(isEnabled);
|
||||
performAction(copyAction, actionContext, true);
|
||||
performAction(copyAction, context, true);
|
||||
|
||||
Transferable contents = systemClipboard.getContents(systemClipboard);
|
||||
assertNotNull(contents);
|
||||
|
||||
@@ -109,7 +109,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
* Whether to ensure the focused vertex is visible, scrolling if necessary the visualization in
|
||||
* order to center the selected vertex or the center of the set of selected vertices
|
||||
*/
|
||||
private boolean ensureVertexIsVisible = false;
|
||||
private boolean ensureVertexIsVisible = true;
|
||||
|
||||
/**
|
||||
* Allows selection of various {@link LayoutAlgorithm} ('arrangements')
|
||||
@@ -314,21 +314,17 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
new ToggleActionBuilder("Scroll To Selection", ACTION_OWNER)
|
||||
.toolBarIcon(Icons.NAVIGATE_ON_INCOMING_EVENT_ICON)
|
||||
.description("Ensure that the 'focused' vertex is visible")
|
||||
.selected(true)
|
||||
.onAction(context -> ensureVertexIsVisible =
|
||||
((AbstractButton) context.getSourceObject()).isSelected())
|
||||
.selected(ensureVertexIsVisible)
|
||||
.onAction(context -> ensureVertexIsVisible = !ensureVertexIsVisible)
|
||||
.buildAndInstallLocal(componentProvider);
|
||||
|
||||
this.ensureVertexIsVisible = true; // since we initialized action to selected
|
||||
|
||||
// create a toggle for enabling 'free-form' selection: selection is inside of a traced
|
||||
// shape instead of a rectangle
|
||||
new ToggleActionBuilder("Free-Form Selection", ACTION_OWNER)
|
||||
.toolBarIcon(DefaultDisplayGraphIcons.LASSO_ICON)
|
||||
.description("Trace Free-Form Shape to select multiple vertices (CTRL-click-drag)")
|
||||
.selected(false)
|
||||
.onAction(context -> freeFormSelection =
|
||||
((AbstractButton) context.getSourceObject()).isSelected())
|
||||
.selected(freeFormSelection)
|
||||
.onAction(context -> freeFormSelection = !freeFormSelection)
|
||||
.buildAndInstallLocal(componentProvider);
|
||||
|
||||
// create an icon button to display the satellite view
|
||||
@@ -349,8 +345,10 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
ToggleDockingAction lensToggle = new ToggleActionBuilder("View Magnifier", ACTION_OWNER)
|
||||
.description("Show View Magnifier")
|
||||
.toolBarIcon(DefaultDisplayGraphIcons.VIEW_MAGNIFIER_ICON)
|
||||
.onAction(context -> magnifyViewSupport
|
||||
.activate(((AbstractButton) context.getSourceObject()).isSelected()))
|
||||
.onAction(context -> {
|
||||
boolean isActive = magnifyViewSupport.isActive();
|
||||
magnifyViewSupport.activate(!isActive);
|
||||
})
|
||||
.build();
|
||||
magnifyViewSupport.addItemListener(
|
||||
itemEvent -> lensToggle.setSelected(itemEvent.getStateChange() == ItemEvent.SELECTED));
|
||||
@@ -749,9 +747,12 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||
}
|
||||
|
||||
private void toggleSatellite(ActionContext context) {
|
||||
boolean selected = ((AbstractButton) context.getSourceObject()).isSelected();
|
||||
graphDisplayProvider.setDefaultSatelliteState(selected);
|
||||
if (selected) {
|
||||
|
||||
boolean wasSelected = graphDisplayProvider.getDefaultSatelliteState();
|
||||
boolean isSelected = !wasSelected;
|
||||
|
||||
graphDisplayProvider.setDefaultSatelliteState(isSelected);
|
||||
if (isSelected) {
|
||||
viewer.getComponent().add(satelliteViewer.getComponent());
|
||||
satelliteViewer.scaleToLayout();
|
||||
}
|
||||
|
||||
@@ -468,11 +468,13 @@ public class DiffTest extends DiffTestAdapter {
|
||||
JTree tree = getProgramTree();
|
||||
selectTreeNodeByText(tree, ".data");
|
||||
|
||||
runSwing(() -> setView.actionPerformed(programTreeProvider.getActionContext(null)));
|
||||
ActionContext context1 = createActionContext(programTreeProvider);
|
||||
runSwing(() -> setView.actionPerformed(context1));
|
||||
|
||||
selectTreeNodeByText(tree, ".rsrc");
|
||||
|
||||
runSwing(() -> goToView.actionPerformed(programTreeProvider.getActionContext(null)));
|
||||
ActionContext context2 = createActionContext(programTreeProvider);
|
||||
runSwing(() -> goToView.actionPerformed(context2));
|
||||
|
||||
topOfFile(fp1);
|
||||
assertEquals(addr("1008000"), cb.getCurrentAddress());
|
||||
@@ -536,7 +538,7 @@ public class DiffTest extends DiffTestAdapter {
|
||||
openDiff(diffTestP1, diffTestP2);
|
||||
JTree tree = getProgramTree();
|
||||
selectTreeNodeByText(tree, "DiffTestPgm1");
|
||||
ActionContext context = runSwing(() -> programTreeProvider.getActionContext(null));
|
||||
ActionContext context = runSwing(() -> createActionContext(programTreeProvider));
|
||||
performAction(removeView, context, true);
|
||||
AddressSet viewSet = new AddressSet();
|
||||
assertEquals(viewSet, cb.getView());
|
||||
|
||||
@@ -511,7 +511,7 @@ public class DiffTestAdapter extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
protected void setView() {
|
||||
ActionContext context = runSwing(() -> programTreeProvider.getActionContext(null));
|
||||
ActionContext context = createActionContext(programTreeProvider);
|
||||
performAction(setView, context, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -399,7 +399,7 @@ public class DualProgramTest extends DiffTestAdapter {
|
||||
setView();
|
||||
selectTreeNodeByText(tree, ".rsrc");
|
||||
|
||||
ActionContext context = runSwing(() -> programTreeProvider.getActionContext(null));
|
||||
ActionContext context = runSwing(() -> createActionContext(programTreeProvider));
|
||||
performAction(goToView, context, true);
|
||||
|
||||
topOfFile(fp1);
|
||||
@@ -413,7 +413,7 @@ public class DualProgramTest extends DiffTestAdapter {
|
||||
openSecondProgram(diffTestP1, diffTestP2);
|
||||
JTree tree = findComponent(tool.getToolFrame(), JTree.class);
|
||||
selectTreeNodeByText(tree, "DiffTestPgm1");
|
||||
ActionContext context = runSwing(() -> programTreeProvider.getActionContext(null));
|
||||
ActionContext context = runSwing(() -> createActionContext(programTreeProvider));
|
||||
performAction(removeView, context, true);
|
||||
topOfFile(fp1);
|
||||
assertNull(cb.getCurrentAddress());
|
||||
|
||||
@@ -279,6 +279,7 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
||||
vtListingContext.setCodeComparisonPanel(dualListingProvider);
|
||||
vtListingContext.setContextObject(dualListingProvider);
|
||||
vtListingContext.setSourceObject(source);
|
||||
vtListingContext.setContextProvider(this);
|
||||
return vtListingContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -512,6 +512,7 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
||||
vtListingContext.setCodeComparisonPanel(listingView);
|
||||
vtListingContext.setContextObject(listingView);
|
||||
vtListingContext.setSourceObject(source);
|
||||
vtListingContext.setContextProvider(this);
|
||||
return vtListingContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package docking;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
|
||||
import docking.action.ActionContextProvider;
|
||||
import docking.action.DockingActionIf;
|
||||
|
||||
/**
|
||||
@@ -49,9 +50,9 @@ import docking.action.DockingActionIf;
|
||||
* {@link DockingActionIf}, again using a possible default context if the active context isn't valid
|
||||
* for that action. Ultimately, context serves to manage actions and to
|
||||
* allow plugins to share state with actions without them being directly coupled together.
|
||||
|
||||
*
|
||||
* <P>
|
||||
* {@link ComponentProvider}s are required to return ActionContext objects in their
|
||||
* {@link ComponentProvider}s can choose to return ActionContext objects in their
|
||||
* {@link ComponentProvider#getActionContext(MouseEvent)} methods. Generally, ComponentProviders
|
||||
* have two ways to use this class. They can either create an {@link DefaultActionContext} instance
|
||||
* and pass in a contextObject that will be useful to its actions or, subclass the ActionContext
|
||||
@@ -64,7 +65,8 @@ import docking.action.DockingActionIf;
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>provider</b> - the component provider to which this context belongs; the provider that
|
||||
* contains the component that is the source of the user action
|
||||
* contains the component that is the source of the user action. This value
|
||||
* is client-defined, typically at construction time.
|
||||
* </li>
|
||||
* <li><b>contextObject</b> - client-defined data object. This allows clients to save any
|
||||
* information desired to be used when the action is performed.
|
||||
@@ -82,7 +84,14 @@ import docking.action.DockingActionIf;
|
||||
* will not change between
|
||||
* {@link DockingActionIf#isEnabledForContext(ActionContext) enablement}
|
||||
* and {@link DockingActionIf#actionPerformed(ActionContext) execution}.
|
||||
* This value is set by the framework.
|
||||
* </li>
|
||||
* <li><b>contextProvider</b> - the {@link ActionContextProvider} that created the context. This
|
||||
* will be null in the case that a default context was created. When
|
||||
* not null this will typically be a {@link ComponentProvider} or a
|
||||
* {@link DialogComponentProvider}. This value is set by the
|
||||
* framework.
|
||||
* </li>
|
||||
* <li><b>mouseEvent</b> - the mouse event that triggered the action; null if the action was
|
||||
* triggered by a key binding.
|
||||
* </li>
|
||||
@@ -110,12 +119,6 @@ public interface ActionContext {
|
||||
*/
|
||||
public ActionContext setContextObject(Object contextObject);
|
||||
|
||||
/**
|
||||
* Returns the sourceObject from the actionEvent that triggered this context to be generated.
|
||||
* @return the sourceObject from the actionEvent that triggered this context to be generated.
|
||||
*/
|
||||
public Object getSourceObject();
|
||||
|
||||
/**
|
||||
* Sets the modifiers for this event that were present when the item was clicked on.
|
||||
*
|
||||
@@ -145,14 +148,35 @@ public interface ActionContext {
|
||||
|
||||
/**
|
||||
* Sets the sourceObject for this ActionContext. This method is used internally by the
|
||||
* DockingWindowManager. ComponentProvider and action developers should only use this
|
||||
* method for testing.
|
||||
* framework. ComponentProvider and action developers should only use this method for testing.
|
||||
*
|
||||
* @param sourceObject the source object
|
||||
* @return this context
|
||||
*/
|
||||
public ActionContext setSourceObject(Object sourceObject);
|
||||
|
||||
/**
|
||||
* Returns the sourceObject from the actionEvent that triggered this context to be generated.
|
||||
* The value returned will typically be the clicked component for mouse events and the focused
|
||||
* component for key binding events.
|
||||
* @return the sourceObject; may be null.
|
||||
*/
|
||||
public Object getSourceObject();
|
||||
|
||||
/**
|
||||
* Sets the context provider for this ActionContext. This method is used internally by the
|
||||
* framework.
|
||||
* @param provider the context provider
|
||||
* @return this context
|
||||
*/
|
||||
public ActionContext setContextProvider(ActionContextProvider provider);
|
||||
|
||||
/**
|
||||
* Returns the context provider used to create this context. May be null.
|
||||
* @return the context provider
|
||||
*/
|
||||
public ActionContextProvider getContextProvider();
|
||||
|
||||
/**
|
||||
* Updates the context's mouse event. Contexts that are based upon key events will have no
|
||||
* mouse event. This method is really for the framework to use. Client calls to this
|
||||
|
||||
@@ -544,13 +544,16 @@ public class ComponentPlaceholder {
|
||||
return; // disposed
|
||||
}
|
||||
|
||||
ActionContext actionContext = componentProvider.getActionContext(null);
|
||||
if (actionContext == null) {
|
||||
actionContext = new DefaultActionContext(componentProvider, null);
|
||||
ActionContext context = componentProvider.getActionContext(null);
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext(componentProvider, null);
|
||||
}
|
||||
for (DockingActionIf action : actions) {
|
||||
action.setEnabled(
|
||||
action.isValidContext(actionContext) && action.isEnabledForContext(actionContext));
|
||||
|
||||
context.setContextProvider(componentProvider);
|
||||
|
||||
for (DockingActionIf a : actions) {
|
||||
boolean enabled = a.isValidContext(context) && a.isEnabledForContext(context);
|
||||
a.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -487,42 +487,68 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context object which corresponds to the
|
||||
* area of focus within this provider's component. Null
|
||||
* is returned when there is no context.
|
||||
* @param event popup event which corresponds to this request.
|
||||
* May be null for key-stroke or other non-mouse event.
|
||||
* Returns the context object which corresponds to the area of focus within this provider's
|
||||
* component. Null is returned when there is no context.
|
||||
* <p>
|
||||
* Subclasses should override this method to provider more specific context objects or
|
||||
* information.
|
||||
*
|
||||
* @param event popup event which corresponds to this request. Will be null for key-stroke or
|
||||
* other non-mouse uses.
|
||||
*/
|
||||
@Override
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
Component c = getContextSourceComponent();
|
||||
|
||||
// Note: this call is deprecated. It shall remain here to handle cases where the subclasses
|
||||
// have overridden createContext(). Eventually we will remove this call and create the
|
||||
// default context directly.
|
||||
return createContext(c, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a component to use as the {@code sourceComponent} when creating an action context.
|
||||
* The focused component is preferred when it is inside of this provider's
|
||||
* {@link #getComponent() component}. Otherwise, this provider's component is returned.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
protected Component getContextSourceComponent() {
|
||||
Component c = getComponent();
|
||||
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
Component focusedComponent = kfm.getFocusOwner();
|
||||
if (focusedComponent != null && SwingUtilities.isDescendingFrom(focusedComponent, c)) {
|
||||
c = focusedComponent;
|
||||
}
|
||||
return createContext(c, null);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* A default method for creating an action context for this provider, using the given
|
||||
* {@link ActionContext#getContextObject() context object}. If the given context object is a
|
||||
* component, then it will be used to initialize the {@code sourceComponent} of the created
|
||||
* context.
|
||||
*
|
||||
* @param contextObject the provider-specific context object
|
||||
* @return the new context
|
||||
* @deprecated instead use
|
||||
* {@code new DefaultActionContext(ComponentProvider.this).setContextObject(contextObject)}
|
||||
*/
|
||||
@Deprecated(since = "12.2", forRemoval = true)
|
||||
protected ActionContext createContext(Object contextObject) {
|
||||
return new DefaultActionContext(this).setContextObject(contextObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* A default method for creating an action context for this provider
|
||||
* @return the new context
|
||||
* @deprecated instead use {@code new DefaultActionContext(ComponentProvider.this)}
|
||||
*/
|
||||
@Deprecated(since = "12.2", forRemoval = true)
|
||||
protected ActionContext createContext() {
|
||||
return new DefaultActionContext(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A default method for creating an action context for this provider, using the given
|
||||
* {@link ActionContext#getContextObject() context object}
|
||||
*
|
||||
* @param contextObject the provider-specific context object
|
||||
* @return the new context
|
||||
*/
|
||||
protected ActionContext createContext(Object contextObject) {
|
||||
return new DefaultActionContext(this).setContextObject(contextObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* A default method for creating an action context for this provider, using the given
|
||||
* {@link ActionContext#getContextObject() context object} and component
|
||||
@@ -530,7 +556,11 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
|
||||
* @param sourceComponent the component that is the target of the context being created
|
||||
* @param contextObject the provider-specific context object
|
||||
* @return the new context
|
||||
* @deprecated this method is still called from {@link #getActionContext(MouseEvent)}, but this
|
||||
* will change in a future release. Clients calling this method can replace that call with
|
||||
* {@code new DefaultActionContext(this, sourceComponent).setContextObject(contextObject)}.
|
||||
*/
|
||||
@Deprecated(since = "12.2", forRemoval = true)
|
||||
protected ActionContext createContext(Component sourceComponent, Object contextObject) {
|
||||
return new DefaultActionContext(this, sourceComponent).setContextObject(contextObject);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package docking;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import docking.action.ActionContextProvider;
|
||||
|
||||
/**
|
||||
* The default implementation of ActionContext
|
||||
*/
|
||||
@@ -33,6 +35,10 @@ public class DefaultActionContext implements ActionContext {
|
||||
// has not already been set.
|
||||
private Component sourceComponent;
|
||||
|
||||
// Initialized by the framework. This will be null if clients create their own context outside
|
||||
// of the framework and do not set the provider.
|
||||
private ActionContextProvider contextProvider;
|
||||
|
||||
/**
|
||||
* Default constructor with no provider, context object, or source component
|
||||
*/
|
||||
@@ -118,11 +124,6 @@ public class DefaultActionContext implements ActionContext {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSourceObject() {
|
||||
return sourceObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEventClickModifiers(int modifiers) {
|
||||
this.eventClickModifiers = modifiers;
|
||||
@@ -138,12 +139,28 @@ public class DefaultActionContext implements ActionContext {
|
||||
return (eventClickModifiers & modifiersMask) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSourceObject() {
|
||||
return sourceObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultActionContext setSourceObject(Object sourceObject) {
|
||||
this.sourceObject = sourceObject;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionContext setContextProvider(ActionContextProvider provider) {
|
||||
this.contextProvider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionContextProvider getContextProvider() {
|
||||
return contextProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultActionContext setMouseEvent(MouseEvent e) {
|
||||
if (e != null) {
|
||||
|
||||
@@ -16,30 +16,24 @@
|
||||
package docking;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.Objects;
|
||||
|
||||
import docking.action.ActionContextProvider;
|
||||
|
||||
/**
|
||||
* Action context for {@link DialogComponentProvider}s.
|
||||
* <p>
|
||||
* Note: due to context changes related to the addition of
|
||||
* {@link #setContextProvider(ActionContextProvider)}, this class serves no real purpose at the time
|
||||
* this comment was made.
|
||||
*/
|
||||
public class DialogActionContext extends DefaultActionContext {
|
||||
|
||||
private DialogComponentProvider dialogProvider;
|
||||
|
||||
public DialogActionContext(DialogComponentProvider dialogProvider, Component sourceComponent) {
|
||||
super(null, dialogProvider, sourceComponent);
|
||||
this.dialogProvider = Objects.requireNonNull(dialogProvider);
|
||||
}
|
||||
|
||||
// this constructor allows clients to set the dialog later
|
||||
// An unusual constructor for when clients don't yet have a dialog in hand
|
||||
public DialogActionContext(Object contextObject, Component sourceComponent) {
|
||||
super(null, contextObject, sourceComponent);
|
||||
}
|
||||
|
||||
public void setDialogComponentProvider(DialogComponentProvider dialogProvider) {
|
||||
this.dialogProvider = dialogProvider;
|
||||
}
|
||||
|
||||
public DialogComponentProvider getDialogComponentProvider() {
|
||||
return dialogProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,10 +198,9 @@ public class DialogComponentProvider
|
||||
DockingAction closeAction = new ActionBuilder(CLOSE_ACTION_NAME, owner)
|
||||
.sharedKeyBinding()
|
||||
.keyBinding(ESC_KEYSTROKE)
|
||||
.withContext(DialogActionContext.class)
|
||||
.enabledWhen(c -> c.getDialogComponentProvider() != null)
|
||||
.enabledWhen(c -> c.getContextProvider() instanceof DialogComponentProvider)
|
||||
.onAction(c -> {
|
||||
DialogComponentProvider dcp = c.getDialogComponentProvider();
|
||||
DialogComponentProvider dcp = (DialogComponentProvider) c.getContextProvider();
|
||||
dcp.escapeCallback();
|
||||
})
|
||||
.build();
|
||||
@@ -1253,7 +1252,7 @@ public class DialogComponentProvider
|
||||
/**
|
||||
* An optional extension point for subclasses to provider action context for the actions used by
|
||||
* this provider.
|
||||
*
|
||||
*
|
||||
* @param event The mouse event used (may be null) to generate a popup menu
|
||||
*/
|
||||
@Override
|
||||
@@ -1274,7 +1273,10 @@ public class DialogComponentProvider
|
||||
if (sourceComponent != null) {
|
||||
c = sourceComponent;
|
||||
}
|
||||
return new DialogActionContext(this, c).setSourceObject(event.getSource());
|
||||
|
||||
DialogActionContext context = new DialogActionContext(this, c);
|
||||
context.setSourceObject(event.getSource());
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1286,6 +1288,9 @@ public class DialogComponentProvider
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext();
|
||||
}
|
||||
|
||||
context.setContextProvider(this);
|
||||
|
||||
Set<DockingActionIf> keySet = toolbarButtonsByAction.keySet();
|
||||
for (DockingActionIf action : keySet) {
|
||||
action.setEnabled(action.isEnabledForContext(context));
|
||||
@@ -1460,8 +1465,11 @@ public class DialogComponentProvider
|
||||
|
||||
@Override
|
||||
public void popupTriggered(MouseEvent e) {
|
||||
ActionContext actionContext = getActionContext(e);
|
||||
popupManager.popupMenu(actionContext, e);
|
||||
ActionContext context = getActionContext(e);
|
||||
if (context != null) {
|
||||
context.setContextProvider(DialogComponentProvider.this);
|
||||
}
|
||||
popupManager.popupMenu(context, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1500,15 +1508,8 @@ public class DialogComponentProvider
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (context instanceof DialogActionContext dialogContext) {
|
||||
DialogComponentProvider contextProvider =
|
||||
dialogContext.getDialogComponentProvider();
|
||||
if (provider != contextProvider) {
|
||||
return false;
|
||||
}
|
||||
return dockingAction.isEnabledForContext(context);
|
||||
}
|
||||
return false;
|
||||
ActionContextProvider contextProvider = context.getContextProvider();
|
||||
return provider == contextProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +62,7 @@ public class DialogComponentProviderPopupActionManager {
|
||||
actionContext = new DefaultActionContext();
|
||||
}
|
||||
|
||||
// If the source is null, must set it or we won't have
|
||||
// any popups shown.
|
||||
// If the source is null, must set it or we won't have any popups shown.
|
||||
if (actionContext.getSourceObject() == null) {
|
||||
actionContext.setSourceObject(e.getSource());
|
||||
}
|
||||
|
||||
@@ -57,12 +57,13 @@ public abstract class DockingKeyBindingAction extends AbstractAction {
|
||||
return new DefaultActionContext();
|
||||
}
|
||||
|
||||
ActionContext actionContext = localProvider.getActionContext(null);
|
||||
if (actionContext != null) {
|
||||
return actionContext;
|
||||
ActionContext context = localProvider.getActionContext(null);
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext(localProvider);
|
||||
}
|
||||
|
||||
return new DefaultActionContext(localProvider, null);
|
||||
context.setContextProvider(localProvider);
|
||||
return context;
|
||||
}
|
||||
|
||||
public List<DockingActionIf> getActions() {
|
||||
|
||||
@@ -2516,10 +2516,16 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||
*/
|
||||
public ActionContext getDefaultActionContext(Class<? extends ActionContext> contextType) {
|
||||
ActionContextProvider actionContextProvider = defaultContextProviderMap.get(contextType);
|
||||
if (actionContextProvider != null) {
|
||||
return actionContextProvider.getActionContext(null);
|
||||
if (actionContextProvider == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
ActionContext context = actionContextProvider.getActionContext(null);
|
||||
if (context != null) {
|
||||
context.setContextProvider(actionContextProvider);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2532,7 +2538,13 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||
defaultContextProviderMap.entrySet();
|
||||
|
||||
for (Entry<Class<? extends ActionContext>, ActionContextProvider> entry : entrySet) {
|
||||
contextMap.put(entry.getKey(), entry.getValue().getActionContext(null));
|
||||
Class<? extends ActionContext> clazz = entry.getKey();
|
||||
ActionContextProvider provider = entry.getValue();
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
if (context != null) {
|
||||
context.setContextProvider(provider);
|
||||
}
|
||||
contextMap.put(clazz, context);
|
||||
}
|
||||
return contextMap;
|
||||
}
|
||||
@@ -2549,8 +2561,11 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||
public ActionContext createActionContext(DockingActionIf action) {
|
||||
ComponentProvider provider = getActiveComponentProvider();
|
||||
ActionContext context = provider == null ? null : provider.getActionContext(null);
|
||||
if (context != null && action.isValidContext(context)) {
|
||||
return context;
|
||||
if (context != null) {
|
||||
context.setContextProvider(provider);
|
||||
if (action.isValidContext(context)) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
// Some actions work on a non-active, default component provider. See if this action
|
||||
@@ -2574,10 +2589,16 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||
|
||||
private ActionContext getDefaultContext(Class<? extends ActionContext> contextType) {
|
||||
ActionContextProvider contextProvider = defaultContextProviderMap.get(contextType);
|
||||
if (contextProvider != null) {
|
||||
return contextProvider.getActionContext(null);
|
||||
if (contextProvider == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
ActionContext context = contextProvider.getActionContext(null);
|
||||
if (context != null) {
|
||||
context.setContextProvider(contextProvider);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -218,6 +218,7 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||
if (provider != null) {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
if (context != null) {
|
||||
context.setContextProvider(provider);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -231,17 +232,22 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||
return new DefaultActionContext();
|
||||
}
|
||||
|
||||
ComponentProvider provider = null;
|
||||
ActionContext context = null;
|
||||
ComponentPlaceholder placeholder = windowNode.getLastFocusedProviderInWindow();
|
||||
if (placeholder != null) {
|
||||
ComponentProvider provider = placeholder.getProvider();
|
||||
provider = placeholder.getProvider();
|
||||
if (provider != null) {
|
||||
context = provider.getActionContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext();
|
||||
}
|
||||
|
||||
context.setContextProvider(provider);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -26,7 +26,8 @@ import javax.swing.JPopupMenu;
|
||||
|
||||
import org.apache.commons.collections4.IteratorUtils;
|
||||
|
||||
import docking.action.*;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.MenuData;
|
||||
import docking.menu.*;
|
||||
|
||||
public class PopupActionManager implements PropertyChangeListener {
|
||||
@@ -77,6 +78,7 @@ public class PopupActionManager implements PropertyChangeListener {
|
||||
actionContext = new DefaultActionContext();
|
||||
}
|
||||
|
||||
actionContext.setContextProvider(popupProvider);
|
||||
actionContext.setSourceObject(popupContext.getSource());
|
||||
actionContext.setMouseEvent(event);
|
||||
|
||||
@@ -115,9 +117,6 @@ public class PopupActionManager implements PropertyChangeListener {
|
||||
void populatePopupMenuActions(Iterator<DockingActionIf> localActions,
|
||||
ActionContext actionContext, MenuManager menuMgr) {
|
||||
|
||||
// Unregistered actions are those used by special-needs components, on-the-fly
|
||||
addUnregisteredActions(actionContext, menuMgr);
|
||||
|
||||
// Include temporary actions
|
||||
List<DockingActionIf> tempActions = windowManager.getTemporaryPopupActions(actionContext);
|
||||
if (tempActions != null) {
|
||||
@@ -131,11 +130,7 @@ public class PopupActionManager implements PropertyChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Include global actions
|
||||
Iterator<DockingActionIf> iter = popupActions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
DockingActionIf action = iter.next();
|
||||
|
||||
for (DockingActionIf action : popupActions) {
|
||||
MenuData popupMenuData = action.getPopupMenuData();
|
||||
if (popupMenuData != null && action.isValidContext(actionContext) &&
|
||||
action.isAddToPopup(actionContext)) {
|
||||
@@ -157,25 +152,6 @@ public class PopupActionManager implements PropertyChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void addUnregisteredActions(ActionContext actionContext, MenuManager menuMgr) {
|
||||
|
||||
Object source = actionContext.getSourceObject();
|
||||
|
||||
// this interface is deprecated in favor the code that calls this method; this will be deleted
|
||||
if (source instanceof DockingActionProviderIf) {
|
||||
DockingActionProviderIf actionProvider = (DockingActionProviderIf) source;
|
||||
List<DockingActionIf> dockingActions = actionProvider.getDockingActions();
|
||||
for (DockingActionIf action : dockingActions) {
|
||||
MenuData popupMenuData = action.getPopupMenuData();
|
||||
if (popupMenuData != null && action.isValidContext(actionContext) &&
|
||||
action.isAddToPopup(actionContext)) {
|
||||
action.setEnabled(action.isEnabledForContext(actionContext));
|
||||
menuMgr.addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRemovingFromPopup(MenuData oldData, MenuData newData) {
|
||||
return oldData != null && newData == null;
|
||||
}
|
||||
|
||||
@@ -1,43 +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 docking.action;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import docking.Tool;
|
||||
|
||||
/**
|
||||
* An interface for objects (really Components) to implement that signals they provide actions
|
||||
* for the Docking environment. This interface will be called when the implementor is the source
|
||||
* of a Java event, like a MouseEvent.
|
||||
* <p>
|
||||
* As an example, a JTable that wishes to provide popup menu actions can implement this interface.
|
||||
* When the user right-clicks on said table, then Docking system will ask this object for its
|
||||
* actions. Further, in this example, the actions given will be inserted into the popup menu
|
||||
* that is shown.
|
||||
*
|
||||
* @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)
|
||||
public interface DockingActionProviderIf {
|
||||
|
||||
/**
|
||||
* Returns actions that are compatible with the given context.
|
||||
* @return the actions
|
||||
*/
|
||||
public List<DockingActionIf> getDockingActions();
|
||||
}
|
||||
@@ -352,6 +352,8 @@ public class MultipleKeyAction extends DockingKeyBindingAction {
|
||||
return multiAction;
|
||||
}
|
||||
|
||||
context.setContextProvider(provider);
|
||||
|
||||
/*
|
||||
See the note in createNonDialogExecutableAction().
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,9 @@ public class ShowActionChooserDialogAction extends DockingAction {
|
||||
Tool tool = DockingWindowManager.getActiveInstance().getTool();
|
||||
|
||||
if (focusedWindow instanceof DockingDialog dialog) {
|
||||
context = dialog.getDialogComponent().getActionContext(null);
|
||||
DialogComponentProvider provider = dialog.getDialogComponent();
|
||||
context = provider.getActionContext(null);
|
||||
context.setContextProvider(provider);
|
||||
showActionsDialog(tool, dialog, context);
|
||||
}
|
||||
else if (focusedWindow instanceof DockingFrame dockingFrame) {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -120,11 +120,15 @@ public class ActionAdapter implements Action, PropertyChangeListener {
|
||||
ActionContext context = null;
|
||||
if (contextProvider != null) {
|
||||
context = contextProvider.getActionContext(null);
|
||||
context.setContextProvider(contextProvider);
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext();
|
||||
context.setSourceObject(e.getSource());
|
||||
}
|
||||
|
||||
context.setSourceObject(e.getSource());
|
||||
|
||||
if (dockingAction.isEnabledForContext(context)) {
|
||||
dockingAction.actionPerformed(context);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -18,8 +18,7 @@ package docking.menu;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
import docking.DockingWindowManager;
|
||||
import docking.EmptyBorderToggleButton;
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
@@ -64,7 +63,17 @@ public class DialogToolbarButton extends EmptyBorderToggleButton {
|
||||
}
|
||||
|
||||
// Give the Swing thread a chance to repaint
|
||||
Swing.runLater(() -> dockingAction.actionPerformed(contextProvider.getActionContext(null)));
|
||||
Swing.runLater(() -> {
|
||||
ActionContext context = contextProvider.getActionContext(null);
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext();
|
||||
}
|
||||
|
||||
context.setSourceObject(e.getSource());
|
||||
context.setContextProvider(contextProvider);
|
||||
|
||||
dockingAction.actionPerformed(context);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,7 +27,6 @@ import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
import docking.*;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.util.Swing;
|
||||
@@ -198,21 +197,6 @@ public class MultiStateButton<T> extends JButton {
|
||||
addMouseListener(popupListener);
|
||||
}
|
||||
|
||||
protected ActionContext getActionContext() {
|
||||
ComponentProvider provider = getComponentProvider();
|
||||
ActionContext context = provider == null ? null : provider.getActionContext(null);
|
||||
final ActionContext actionContext = context == null ? new DefaultActionContext() : context;
|
||||
return actionContext;
|
||||
}
|
||||
|
||||
private ComponentProvider getComponentProvider() {
|
||||
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
|
||||
if (manager == null) {
|
||||
return null;
|
||||
}
|
||||
return manager.getActiveComponentProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a popup containing all the actions below the button
|
||||
*
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -134,9 +134,17 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
|
||||
|
||||
protected ActionContext getActionContext() {
|
||||
ComponentProvider provider = getComponentProvider();
|
||||
ActionContext context = provider == null ? null : provider.getActionContext(null);
|
||||
final ActionContext actionContext = context == null ? new DefaultActionContext() : context;
|
||||
return actionContext;
|
||||
ActionContext context = null;
|
||||
if (provider != null) {
|
||||
context = provider.getActionContext(null);
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
context = new DefaultActionContext();
|
||||
}
|
||||
|
||||
context.setContextProvider(provider);
|
||||
return context;
|
||||
}
|
||||
|
||||
private ComponentProvider getComponentProvider() {
|
||||
@@ -198,7 +206,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
|
||||
|
||||
// a custom Ghidra UI that handles alignment issues and allows for tabulating presentation
|
||||
item.setUI(DockingMenuItemUI.createUI(item));
|
||||
final DockingActionIf delegateAction = dockingAction;
|
||||
DockingActionIf delegateAction = dockingAction;
|
||||
item.addActionListener(e -> {
|
||||
ActionContext context = getActionContext();
|
||||
context.setSourceObject(e.getSource());
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.junit.*;
|
||||
|
||||
import docking.*;
|
||||
@@ -351,19 +352,19 @@ public abstract class AbstractDockingTest extends AbstractGuiTest {
|
||||
}
|
||||
|
||||
String title = dialog.getTitle();
|
||||
boolean isSavePrompt = StringUtils.containsAny(title, "Changed", "Saved");
|
||||
boolean isSavePrompt = Strings.CS.containsAny(title, "Changed", "Saved");
|
||||
if (!isSavePrompt) {
|
||||
throw new AssertionError("Unexpected dialog with title '" + title + "'; " +
|
||||
"Expected a dialog alerting to program changes");
|
||||
}
|
||||
|
||||
if (StringUtils.contains(title, "Program Changed")) {
|
||||
if (Strings.CS.contains(title, "Program Changed")) {
|
||||
// the program is read-only or not in a writable project
|
||||
pressButtonByText(dialog, "Continue");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.contains(title, "Save Program?")) {
|
||||
if (Strings.CS.contains(title, "Save Program?")) {
|
||||
pressButtonByText(dialog, "Cancel");
|
||||
return;
|
||||
}
|
||||
@@ -1283,6 +1284,7 @@ public abstract class AbstractDockingTest extends AbstractGuiTest {
|
||||
|
||||
ActionContext providerContext = provider.getActionContext(null);
|
||||
if (providerContext != null) {
|
||||
providerContext.setContextProvider(provider);
|
||||
return providerContext;
|
||||
}
|
||||
|
||||
@@ -1338,11 +1340,13 @@ public abstract class AbstractDockingTest extends AbstractGuiTest {
|
||||
|
||||
ActionContext newContext = provider.getActionContext(null);
|
||||
if (newContext == null) {
|
||||
actionContext.setContextProvider(provider);
|
||||
return actionContext;
|
||||
}
|
||||
|
||||
actionContext = newContext;
|
||||
actionContext.setSourceObject(provider.getComponent());
|
||||
actionContext.setContextProvider(provider);
|
||||
|
||||
return actionContext;
|
||||
});
|
||||
@@ -1366,6 +1370,7 @@ public abstract class AbstractDockingTest extends AbstractGuiTest {
|
||||
ActionContext actionContext = provider.getActionContext(null);
|
||||
if (actionContext != null) {
|
||||
actionContext.setSourceObject(provider.getComponent());
|
||||
actionContext.setContextProvider(provider);
|
||||
}
|
||||
return actionContext;
|
||||
});
|
||||
@@ -2183,7 +2188,17 @@ public abstract class AbstractDockingTest extends AbstractGuiTest {
|
||||
}
|
||||
|
||||
public static boolean isEnabled(DockingActionIf action, ActionContextProvider contextProvider) {
|
||||
return runSwing(() -> action.isEnabledForContext(contextProvider.getActionContext(null)));
|
||||
return runSwing(() -> action.isEnabledForContext(createActionContext(contextProvider)));
|
||||
}
|
||||
|
||||
public static ActionContext createActionContext(ActionContextProvider provider) {
|
||||
return runSwing(() -> {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
if (context != null) {
|
||||
context.setContextProvider(provider);
|
||||
}
|
||||
return context;
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isEnabled(AbstractButton button) {
|
||||
|
||||
@@ -98,9 +98,9 @@ public class DataPluginScreenShots extends GhidraScreenShotGenerator {
|
||||
public void testDefaultSettings() {
|
||||
positionListingTop(0x40d3a4);
|
||||
ComponentProvider componentProvider = getProvider(CodeViewerProvider.class);
|
||||
ActionContext actionContext = componentProvider.getActionContext(null);
|
||||
DockingActionIf action = getAction("Default Settings", actionContext);
|
||||
performAction(action, actionContext, false);
|
||||
ActionContext context = createActionContext(componentProvider);
|
||||
DockingActionIf action = getAction("Default Settings", context);
|
||||
performAction(action, context, false);
|
||||
captureDialog();
|
||||
}
|
||||
|
||||
|
||||
@@ -1450,7 +1450,7 @@ public class ClipboardPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
private ActionContext getActionContext(ComponentProviderWrapper wrapper) {
|
||||
return runSwing(() -> {
|
||||
ComponentProvider provider = wrapper.getComponentProvider();
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
ActionContext context = createActionContext(provider);
|
||||
return context;
|
||||
});
|
||||
}
|
||||
@@ -1622,7 +1622,7 @@ public class ClipboardPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
@Override
|
||||
public ActionContext getContext() {
|
||||
return provider.getActionContext(null);
|
||||
return createActionContext(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -320,7 +320,7 @@ public class FrontEndPluginOpenProgramActionsTest extends AbstractGhidraHeadedIn
|
||||
|
||||
private ActionContext getFrontEndContext() {
|
||||
ComponentProvider provider = env.getFrontEndProvider();
|
||||
return runSwing(() -> provider.getActionContext(null));
|
||||
return createActionContext(provider);
|
||||
}
|
||||
|
||||
private DomainFile openInDefaultTool(String fileName) throws Exception {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -302,7 +302,7 @@ public class FrontEndTestEnv {
|
||||
|
||||
DockingActionIf terminateCheckoutAction =
|
||||
AbstractDockingTest.getAction(provider, "Terminate Checkout");
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
ActionContext context = AbstractDockingTest.createActionContext(provider);
|
||||
AbstractDockingTest.performAction(terminateCheckoutAction, context, false);
|
||||
OptionDialog optDialog = AbstractDockingTest.waitForDialogComponent(OptionDialog.class);
|
||||
AbstractGuiTest.pressButtonByText(optDialog.getComponent(), "Yes", true);
|
||||
@@ -341,7 +341,7 @@ public class FrontEndTestEnv {
|
||||
public void performFrontEndAction(DockingActionIf action) {
|
||||
ComponentProvider provider = env.getFrontEndProvider();
|
||||
runSwing(() -> {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
ActionContext context = AbstractDockingTest.createActionContext(provider);
|
||||
action.actionPerformed(context);
|
||||
}, false);
|
||||
waitForSwing();
|
||||
|
||||
Reference in New Issue
Block a user