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