mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 11:31:43 +00:00
Merge remote-tracking branch 'origin/GP-1-dragonmacher-dialog-escape-bug'
This commit is contained in:
commit
58e48456de
@ -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.
|
||||||
@ -61,7 +61,7 @@ public class LabelMgrPlugin extends Plugin {
|
|||||||
// Setup list of actions
|
// Setup list of actions
|
||||||
setupActions();
|
setupActions();
|
||||||
|
|
||||||
addEditDialog = new AddEditDialog("", tool);
|
addEditDialog = new AddEditDialog("Add/Edit Label", tool);
|
||||||
addEditDialog.setReusable(true);
|
addEditDialog.setReusable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ public class LabelMgrPlugin extends Plugin {
|
|||||||
addr = loc.getAddress();
|
addr = loc.getAddress();
|
||||||
}
|
}
|
||||||
else if (location instanceof OperandFieldLocation) {
|
else if (location instanceof OperandFieldLocation) {
|
||||||
Address a = ((OperandFieldLocation) location).getRefAddress();
|
Address a = location.getRefAddress();
|
||||||
addr = (a == null) ? addr : a;
|
addr = (a == null) ? addr : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
@ -237,6 +237,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
|||||||
public void performAction(String actionName, String owner, ComponentProvider contextProvider,
|
public void performAction(String actionName, String owner, ComponentProvider contextProvider,
|
||||||
boolean wait) {
|
boolean wait) {
|
||||||
DockingActionIf action = getAction(tool, owner, actionName);
|
DockingActionIf action = getAction(tool, owner, actionName);
|
||||||
|
assertNotNull("Could not find action: " + actionName + " for owner " + owner, action);
|
||||||
performAction(action, contextProvider, wait);
|
performAction(action, contextProvider, wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
@ -225,7 +225,7 @@ public abstract class GhidraScreenShotGenerator extends AbstractScreenShotGenera
|
|||||||
showDialog(dialog);
|
showDialog(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDialog(final DialogComponentProvider dialogComponent) {
|
private void showDialog(DialogComponentProvider dialogComponent) {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
DockingDialog dialog = DockingDialog.createDialog(null, dialogComponent, null);
|
DockingDialog dialog = DockingDialog.createDialog(null, dialogComponent, null);
|
||||||
dialog.setLocation(WindowUtilities.centerOnScreen(dialog.getSize()));
|
dialog.setLocation(WindowUtilities.centerOnScreen(dialog.getSize()));
|
||||||
|
@ -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,7 +25,7 @@ import javax.swing.*;
|
|||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import docking.DockingDialog;
|
import docking.DockingWindowManager;
|
||||||
import docking.options.editor.OptionsDialog;
|
import docking.options.editor.OptionsDialog;
|
||||||
import docking.options.editor.StringWithChoicesEditor;
|
import docking.options.editor.StringWithChoicesEditor;
|
||||||
import docking.widgets.tree.GTree;
|
import docking.widgets.tree.GTree;
|
||||||
@ -34,26 +34,22 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
|||||||
|
|
||||||
public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private DockingDialog dialog;
|
private OptionsDialog dialog;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
if (dialog != null) {
|
if (dialog != null) {
|
||||||
dialog.setVisible(false);
|
close(dialog);
|
||||||
dialog.dispose();
|
|
||||||
}
|
}
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DockingDialog showEditor(Options options) {
|
private OptionsDialog showEditor(Options options) {
|
||||||
OptionsDialog dialogComponent =
|
OptionsDialog dialogComponent =
|
||||||
new OptionsDialog("Test Properties", "Properties", new Options[] { options }, null);
|
new OptionsDialog("Test Properties", "Properties", new Options[] { options }, null);
|
||||||
final DockingDialog editorDialog =
|
runSwing(() -> DockingWindowManager.showDialog(dialogComponent), false);
|
||||||
runSwing(() -> DockingDialog.createDialog(null, dialogComponent, null));
|
|
||||||
SwingUtilities.invokeLater(() -> editorDialog.setVisible(true));
|
|
||||||
|
|
||||||
waitForJDialog("Test Properties");
|
OptionsDialog editorDialog = waitForDialogComponent(OptionsDialog.class);
|
||||||
assertNotNull("Dialog failed to launch", editorDialog);
|
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
waitForOptionsTree(dialogComponent);
|
waitForOptionsTree(dialogComponent);
|
||||||
return editorDialog;
|
return editorDialog;
|
||||||
@ -65,10 +61,9 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
waitForTree(tree);
|
waitForTree(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component findPairedComponent(final Container container, final String labelText) {
|
private Component findPairedComponent(final String labelText) {
|
||||||
final Component[] box = new Component[1];
|
JComponent component = dialog.getComponent();
|
||||||
runSwing(() -> box[0] = doFindPairedComponent(container, labelText));
|
return runSwing(() -> doFindPairedComponent(component, labelText));
|
||||||
return box[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component doFindPairedComponent(Container container, String labelText) {
|
private Component doFindPairedComponent(Container container, String labelText) {
|
||||||
@ -102,7 +97,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestInt");
|
Component editor = findPairedComponent("TestInt");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertyText.class, editor.getClass());
|
assertEquals(PropertyText.class, editor.getClass());
|
||||||
final PropertyText textField = (PropertyText) editor;
|
final PropertyText textField = (PropertyText) editor;
|
||||||
@ -125,7 +120,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestLong");
|
Component editor = findPairedComponent("TestLong");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertyText.class, editor.getClass());
|
assertEquals(PropertyText.class, editor.getClass());
|
||||||
final PropertyText textField = (PropertyText) editor;
|
final PropertyText textField = (PropertyText) editor;
|
||||||
@ -148,7 +143,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestFloat");
|
Component editor = findPairedComponent("TestFloat");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertyText.class, editor.getClass());
|
assertEquals(PropertyText.class, editor.getClass());
|
||||||
final PropertyText textField = (PropertyText) editor;
|
final PropertyText textField = (PropertyText) editor;
|
||||||
@ -173,7 +168,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestDouble");
|
Component editor = findPairedComponent("TestDouble");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertyText.class, editor.getClass());
|
assertEquals(PropertyText.class, editor.getClass());
|
||||||
final PropertyText textField = (PropertyText) editor;
|
final PropertyText textField = (PropertyText) editor;
|
||||||
@ -197,7 +192,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestString");
|
Component editor = findPairedComponent("TestString");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertyText.class, editor.getClass());
|
assertEquals(PropertyText.class, editor.getClass());
|
||||||
final PropertyText textField = (PropertyText) editor;
|
final PropertyText textField = (PropertyText) editor;
|
||||||
@ -222,7 +217,7 @@ public class PropertyEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
|
|
||||||
dialog = showEditor(options);
|
dialog = showEditor(options);
|
||||||
|
|
||||||
Component editor = findPairedComponent(dialog, "TestStringWithChoices");
|
Component editor = findPairedComponent("TestStringWithChoices");
|
||||||
assertNotNull("Could not find editor component", editor);
|
assertNotNull("Could not find editor component", editor);
|
||||||
assertEquals(PropertySelector.class, editor.getClass());
|
assertEquals(PropertySelector.class, editor.getClass());
|
||||||
final PropertySelector textSelector = (PropertySelector) editor;
|
final PropertySelector textSelector = (PropertySelector) editor;
|
||||||
|
@ -91,11 +91,14 @@ public class DialogComponentProvider
|
|||||||
private Component focusComponent;
|
private Component focusComponent;
|
||||||
private JPanel toolbar;
|
private JPanel toolbar;
|
||||||
|
|
||||||
private final Map<DockingActionIf, DialogToolbarButton> actionMap = new HashMap<>();
|
private Map<DockingActionIf, DialogToolbarButton> toolbarButtonsByAction = new HashMap<>();
|
||||||
private final DialogComponentProviderPopupActionManager popupManager =
|
private DialogComponentProviderPopupActionManager popupManager =
|
||||||
new DialogComponentProviderPopupActionManager(this);
|
new DialogComponentProviderPopupActionManager(this);
|
||||||
private final PopupHandler popupHandler = new PopupHandler();
|
private PopupHandler popupHandler = new PopupHandler();
|
||||||
private final Set<DockingActionIf> dialogActions = new HashSet<>();
|
private Set<DockingActionIf> dialogActions = new HashSet<>();
|
||||||
|
|
||||||
|
// we track these separately so that we can remove them on dispose
|
||||||
|
private Set<DialogActionProxy> keyBindingProxyActions = new HashSet<>();
|
||||||
|
|
||||||
private Point initialLocation;
|
private Point initialLocation;
|
||||||
private boolean resizeable = true;
|
private boolean resizeable = true;
|
||||||
@ -106,6 +109,7 @@ public class DialogComponentProvider
|
|||||||
|
|
||||||
private Dimension defaultSize;
|
private Dimension defaultSize;
|
||||||
private String accessibleDescription;
|
private String accessibleDescription;
|
||||||
|
private Tool tool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for a DialogComponentProvider that will be modal and will include a status line and
|
* Constructor for a DialogComponentProvider that will be modal and will include a status line and
|
||||||
@ -177,13 +181,13 @@ public class DialogComponentProvider
|
|||||||
panel.add(buttonPanel);
|
panel.add(buttonPanel);
|
||||||
rootPanel.add(panel, BorderLayout.SOUTH);
|
rootPanel.add(panel, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
installEscapeAction();
|
installEscapeAction();
|
||||||
|
|
||||||
doInitialize();
|
doInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installEscapeAction() {
|
private void installEscapeAction() {
|
||||||
|
|
||||||
closeAction = new ActionBuilder("Close Dialog", title)
|
closeAction = new ActionBuilder("Close Dialog", title)
|
||||||
.sharedKeyBinding()
|
.sharedKeyBinding()
|
||||||
.keyBinding(ESC_KEYSTROKE)
|
.keyBinding(ESC_KEYSTROKE)
|
||||||
@ -933,11 +937,16 @@ public class DialogComponentProvider
|
|||||||
|
|
||||||
closeDialog();
|
closeDialog();
|
||||||
|
|
||||||
|
if (tool != null) {
|
||||||
|
keyBindingProxyActions.forEach(a -> tool.removeAction(a));
|
||||||
|
}
|
||||||
|
keyBindingProxyActions.clear();
|
||||||
|
|
||||||
popupManager.dispose();
|
popupManager.dispose();
|
||||||
|
|
||||||
dialogActions.forEach(DockingActionIf::dispose);
|
dialogActions.forEach(DockingActionIf::dispose);
|
||||||
|
|
||||||
actionMap.clear();
|
toolbarButtonsByAction.clear();
|
||||||
dialogActions.clear();
|
dialogActions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1153,6 +1162,38 @@ public class DialogComponentProvider
|
|||||||
return ((dialog != null) && dialog.isShowing());
|
return ((dialog != null) && dialog.isShowing());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called each time the dialog is show. The given tool is the parent tool of the dialog.
|
||||||
|
* @param t the tool
|
||||||
|
*/
|
||||||
|
void dialogShown(Tool t) {
|
||||||
|
setTool(t);
|
||||||
|
dialogShown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTool(Tool tool) {
|
||||||
|
|
||||||
|
if (this.tool != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize the first time we are shown
|
||||||
|
this.tool = tool;
|
||||||
|
|
||||||
|
if (tool == null) {
|
||||||
|
// The tool can be null for dialogs shown before the framework is initialized, like
|
||||||
|
// dialogs shown over the splash screen. Without a tool, we cannot add key binding
|
||||||
|
// actions.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any actions in this list already were added before we had a tool. Add them now. Any
|
||||||
|
// future calls to addKeyBindingAction() will get added to the tool at that time.
|
||||||
|
for (DockingActionIf proxy : keyBindingProxyActions) {
|
||||||
|
tool.addAction(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method if you want to do something when the dialog is made visible
|
* Override this method if you want to do something when the dialog is made visible
|
||||||
*/
|
*/
|
||||||
@ -1232,7 +1273,7 @@ public class DialogComponentProvider
|
|||||||
if (context == null) {
|
if (context == null) {
|
||||||
context = new DefaultActionContext();
|
context = new DefaultActionContext();
|
||||||
}
|
}
|
||||||
Set<DockingActionIf> keySet = actionMap.keySet();
|
Set<DockingActionIf> keySet = toolbarButtonsByAction.keySet();
|
||||||
for (DockingActionIf action : keySet) {
|
for (DockingActionIf action : keySet) {
|
||||||
action.setEnabled(action.isEnabledForContext(context));
|
action.setEnabled(action.isEnabledForContext(context));
|
||||||
}
|
}
|
||||||
@ -1255,7 +1296,7 @@ public class DialogComponentProvider
|
|||||||
|
|
||||||
DialogToolbarButton button = new DialogToolbarButton(action, this);
|
DialogToolbarButton button = new DialogToolbarButton(action, this);
|
||||||
toolbar.add(button);
|
toolbar.add(button);
|
||||||
actionMap.put(action, button);
|
toolbarButtonsByAction.put(action, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1264,7 +1305,7 @@ public class DialogComponentProvider
|
|||||||
* the tool, as this dialog will do that for you.
|
* the tool, as this dialog will do that for you.
|
||||||
* @param action the action
|
* @param action the action
|
||||||
*/
|
*/
|
||||||
public void addAction(final DockingActionIf action) {
|
public void addAction(DockingActionIf action) {
|
||||||
dialogActions.add(action);
|
dialogActions.add(action);
|
||||||
addToolbarAction(action);
|
addToolbarAction(action);
|
||||||
popupManager.addAction(action);
|
popupManager.addAction(action);
|
||||||
@ -1273,25 +1314,49 @@ public class DialogComponentProvider
|
|||||||
|
|
||||||
private void addKeyBindingAction(DockingActionIf action) {
|
private void addKeyBindingAction(DockingActionIf action) {
|
||||||
|
|
||||||
// add the action to the tool in order get key event management (key bindings
|
DialogActionProxy proxy = new DialogActionProxy(action);
|
||||||
// options and key event processing)
|
keyBindingProxyActions.add(proxy);
|
||||||
DockingWindowManager dwm = DockingWindowManager.getActiveInstance();
|
|
||||||
if (dwm == null) {
|
|
||||||
// This implies the client dialog has been shown outside of the plugin framework. In
|
|
||||||
// that case, the client will not get key event processing for dialog actions.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tool tool = dwm.getTool();
|
// The tool will be null when clients add actions to this dialog before it has been shown.
|
||||||
tool.addAction(new DialogActionProxy(action));
|
// This is different than ComponentProviders, which require a Tool at construction. The
|
||||||
|
// DialogComponentProvider did not originally require a Tool at construction. Rather than
|
||||||
|
// refactor the dialog to require a Tool, it was easier to simply delay adding actions until
|
||||||
|
// the Tool is set when the dialog is first shown.
|
||||||
|
if (tool != null) {
|
||||||
|
tool.addAction(proxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAction(DockingActionIf action) {
|
public void removeAction(DockingActionIf action) {
|
||||||
dialogActions.remove(action);
|
dialogActions.remove(action);
|
||||||
JButton button = actionMap.remove(action);
|
JButton button = toolbarButtonsByAction.remove(action);
|
||||||
if (button != null && toolbar != null) {
|
if (button != null && toolbar != null) {
|
||||||
toolbar.remove(button);
|
toolbar.remove(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popupManager.removeAction(action);
|
||||||
|
|
||||||
|
removeKeyBindingAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeKeyBindingAction(DockingActionIf action) {
|
||||||
|
|
||||||
|
DialogActionProxy proxy = null;
|
||||||
|
for (DialogActionProxy actionProxy : keyBindingProxyActions) {
|
||||||
|
if (action == actionProxy.getAction()) {
|
||||||
|
proxy = actionProxy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxy == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyBindingProxyActions.remove(proxy);
|
||||||
|
if (tool != null) {
|
||||||
|
tool.removeAction(proxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
||||||
@ -49,6 +49,10 @@ public class DialogComponentProviderPopupActionManager {
|
|||||||
popupActions.add(action);
|
popupActions.add(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeAction(DockingActionIf action) {
|
||||||
|
popupActions.remove(action);
|
||||||
|
}
|
||||||
|
|
||||||
void popupMenu(ActionContext actionContext, MouseEvent e) {
|
void popupMenu(ActionContext actionContext, MouseEvent e) {
|
||||||
if (e.isConsumed()) {
|
if (e.isConsumed()) {
|
||||||
return;
|
return;
|
||||||
|
@ -210,7 +210,11 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowOpened(WindowEvent e) {
|
public void windowOpened(WindowEvent e) {
|
||||||
component.dialogShown();
|
Tool tool = null;
|
||||||
|
if (owningWindowManager != null) {
|
||||||
|
tool = owningWindowManager.getTool();
|
||||||
|
}
|
||||||
|
component.dialogShown(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1814,7 +1814,8 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
|||||||
bestCenter = centeredOnComponent;
|
bestCenter = centeredOnComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
DockingDialog dialog = DockingDialog.createDialog(bestParent, provider, bestCenter);
|
DockingDialog dialog =
|
||||||
|
DockingDialog.createDialog(bestParent, provider, bestCenter);
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -216,8 +216,9 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
|
|||||||
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
|
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
|
||||||
|
|
||||||
// note: this call has no effect if 'action' is null
|
// note: this call has no effect if 'action' is null
|
||||||
SwingUtilities.notifyAction(action, keyStroke, event, event.getSource(),
|
Object source = event.getSource();
|
||||||
event.getModifiersEx());
|
int modifiersEx = event.getModifiersEx();
|
||||||
|
SwingUtilities.notifyAction(action, keyStroke, event, source, modifiersEx);
|
||||||
|
|
||||||
}
|
}
|
||||||
return wasInProgress;
|
return wasInProgress;
|
||||||
|
@ -350,7 +350,6 @@ public abstract class DockingAction implements DockingActionIf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setKeyBindingData(KeyBindingData newKeyBindingData) {
|
public void setKeyBindingData(KeyBindingData newKeyBindingData) {
|
||||||
|
|
||||||
if (!supportsKeyBinding(newKeyBindingData)) {
|
if (!supportsKeyBinding(newKeyBindingData)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -365,6 +364,11 @@ public abstract class DockingAction implements DockingActionIf {
|
|||||||
firePropertyChanged(KEYBINDING_DATA_PROPERTY, oldData, keyBindingData);
|
firePropertyChanged(KEYBINDING_DATA_PROPERTY, oldData, keyBindingData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this allows framework classes to directly set the default value
|
||||||
|
protected void setDefaultKeyBindingData(KeyBindingData kbd) {
|
||||||
|
defaultKeyBindingData = kbd;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean supportsKeyBinding(KeyBindingData kbData) {
|
private boolean supportsKeyBinding(KeyBindingData kbData) {
|
||||||
|
|
||||||
KeyBindingType type = getKeyBindingType();
|
KeyBindingType type = getKeyBindingType();
|
||||||
|
@ -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.
|
||||||
@ -363,9 +363,14 @@ public class KeyBindings {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1) update the options with the new value
|
||||||
ActionTrigger newTrigger = keyBinding.getActionTrigger();
|
ActionTrigger newTrigger = keyBinding.getActionTrigger();
|
||||||
String fullName = getFullName();
|
String fullName = getFullName();
|
||||||
keyStrokeOptions.setActionTrigger(fullName, newTrigger);
|
keyStrokeOptions.setActionTrigger(fullName, newTrigger);
|
||||||
|
|
||||||
|
// 2) update our state so the UI shows the new value
|
||||||
|
currentKeyStroke = newTrigger.getKeyStroke();
|
||||||
|
currentMouseBinding = newTrigger.getMouseBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChanged() {
|
private boolean hasChanged() {
|
||||||
@ -409,11 +414,11 @@ public class KeyBindings {
|
|||||||
DockingActionIf action = getRepresentativeAction();
|
DockingActionIf action = getRepresentativeAction();
|
||||||
KeyBindingData defaultBinding = action.getDefaultKeyBindingData();
|
KeyBindingData defaultBinding = action.getDefaultKeyBindingData();
|
||||||
|
|
||||||
|
cancelChanges();
|
||||||
|
|
||||||
if (!matches(defaultBinding)) {
|
if (!matches(defaultBinding)) {
|
||||||
apply(options, defaultBinding);
|
apply(options, defaultBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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,14 +120,21 @@ public class SharedStubKeyBindingAction extends DockingAction implements Options
|
|||||||
void addClientAction(DockingActionIf action) {
|
void addClientAction(DockingActionIf action) {
|
||||||
|
|
||||||
// 1) Validate new action keystroke against existing actions
|
// 1) Validate new action keystroke against existing actions
|
||||||
ActionTrigger defaultKs = validateActionsHaveTheSameDefaultKeyStroke(action);
|
ActionTrigger defaultTrigger = validateActionsHaveTheSameDefaultKeyStroke(action);
|
||||||
|
|
||||||
// 2) Add the action and the validated keystroke, as this is the default keystroke
|
// 2) Add the action and the validated keystroke, as this is the default keystroke
|
||||||
clientActions.put(action, defaultKs);
|
clientActions.put(action, defaultTrigger);
|
||||||
|
|
||||||
// 3) Update the given action with the current option value. This allows clients to
|
// 3) Update the given action with the current option value. This allows clients to
|
||||||
// add and remove actions after the tool has been initialized.
|
// add and remove actions after the tool has been initialized.
|
||||||
updateActionKeyStrokeFromOptions(action, defaultKs);
|
updateActionKeyStrokeFromOptions(action, defaultTrigger);
|
||||||
|
|
||||||
|
// 4) Store the default value for this stub so later requests to Restore Defaults will have
|
||||||
|
// the correct value.
|
||||||
|
if (defaultTrigger != null) {
|
||||||
|
KeyBindingData defaultKbd = new KeyBindingData(defaultTrigger);
|
||||||
|
setDefaultKeyBindingData(defaultKbd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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.
|
||||||
@ -48,7 +48,7 @@ public class OptionsDialog extends ReusableDialogComponentProvider {
|
|||||||
|
|
||||||
public OptionsDialog(String title, String rootNodeName, Options[] options,
|
public OptionsDialog(String title, String rootNodeName, Options[] options,
|
||||||
OptionsEditorListener listener, boolean showRestoreDefaultsButton) {
|
OptionsEditorListener listener, boolean showRestoreDefaultsButton) {
|
||||||
super("OptionsDialog.Foofoo", true, false, true, false);
|
super("Options Dialog", true, false, true, false);
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
panel = new OptionsPanel(rootNodeName, options, showRestoreDefaultsButton,
|
panel = new OptionsPanel(rootNodeName, options, showRestoreDefaultsButton,
|
||||||
new OptionsPropertyChangeListener());
|
new OptionsPropertyChangeListener());
|
||||||
|
@ -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.
|
||||||
@ -52,14 +52,14 @@ public class BookmarkPluginScreenShots extends GhidraScreenShotGenerator {
|
|||||||
public void testBookmarks() {
|
public void testBookmarks() {
|
||||||
removeFlowArrows();
|
removeFlowArrows();
|
||||||
createBookmarks();
|
createBookmarks();
|
||||||
performAction("Show Bookmarks", "BookmarkPlugin", true);
|
performAction("Bookmarks", "BookmarkPlugin", true);
|
||||||
captureIsolatedProvider(BookmarkProvider.class, 900, 300);
|
captureIsolatedProvider(BookmarkProvider.class, 900, 300);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBookmarksFilter() {
|
public void testBookmarksFilter() {
|
||||||
performAction("Show Bookmarks", "BookmarkPlugin", true);
|
performAction("Bookmarks", "BookmarkPlugin", true);
|
||||||
performAction("Filter Bookmarks", "BookmarkPlugin", false);
|
performAction("Filter Bookmarks", "BookmarkPlugin", false);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user