Merge remote-tracking branch 'origin/GP-0-dragonmacher-11-4-test-fixes-5-13-25' into Ghidra_11.4

This commit is contained in:
Ryan Kurtz 2025-05-14 05:59:57 -04:00
commit fb04408b0a
6 changed files with 32 additions and 80 deletions

View file

@ -126,8 +126,6 @@ public class FunctionTagProvider extends ComponentProviderAdapter implements Dom
createActions(); createActions();
} }
@Override @Override
public void componentShown() { public void componentShown() {
updateView(); updateView();
@ -445,7 +443,7 @@ public class FunctionTagProvider extends ComponentProviderAdapter implements Dom
dropped.add(name); dropped.add(name);
} }
else { else {
Command cmd = new CreateFunctionTagCmd(name); Command<Program> cmd = new CreateFunctionTagCmd(name);
tool.execute(cmd, program); tool.execute(cmd, program);
} }
} }

View file

@ -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 ghidra.app.cmd.function.AddFunctionTagCmd;
import ghidra.app.cmd.function.CreateFunctionTagCmd; import ghidra.app.cmd.function.CreateFunctionTagCmd;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.*;
import ghidra.program.model.listing.FunctionTag;
/** /**
* List for displaying all tags in the programs * List for displaying all tags in the programs
@ -59,11 +58,11 @@ public class SourceTagsPanel extends TagListPanel {
// If the tag is one that has not yet been created (a temp tag), first create it, // If the tag is one that has not yet been created (a temp tag), first create it,
// then add it to the function. // then add it to the function.
if (tag instanceof InMemoryFunctionTag) { if (tag instanceof InMemoryFunctionTag) {
Command cmd = new CreateFunctionTagCmd(tag.getName(), tag.getComment()); Command<Program> cmd = new CreateFunctionTagCmd(tag.getName(), tag.getComment());
tool.execute(cmd, program); tool.execute(cmd, program);
} }
Command cmd = new AddFunctionTagCmd(tag.getName(), function.getEntryPoint()); Command<Program> cmd = new AddFunctionTagCmd(tag.getName(), function.getEntryPoint());
tool.execute(cmd, program); tool.execute(cmd, program);
} }
} }

View file

@ -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.
@ -86,15 +86,13 @@ public abstract class TagListPanel extends JPanel {
table.setAccessibleNamePrefix(name); table.setAccessibleNamePrefix(name);
filterPanel.setAccessibleNamePrefix(name); filterPanel.setAccessibleNamePrefix(name);
table.addMouseListener(new MouseAdapter() { table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
@Override
public void mousePressed(MouseEvent e) {
// Click events aren't reliably captured for some reason,
// but presses are, so this is the best way to ensure that
// user selections are handled
provider.selectionChanged(TagListPanel.this); provider.selectionChanged(TagListPanel.this);
} }
});
table.addMouseListener(new MouseAdapter() {
// Handles the double-click event on table rows, which will bring up // Handles the double-click event on table rows, which will bring up
// a dialog for editing the tag name and/or comment. // a dialog for editing the tag name and/or comment.
@ -173,14 +171,14 @@ public abstract class TagListPanel extends JPanel {
// Only process the name edit if the name actually changed. // Only process the name edit if the name actually changed.
if (!newName.equals(tagName)) { if (!newName.equals(tagName)) {
Command cmd = Command<Program> cmd =
new ChangeFunctionTagCmd(tagName, newName, ChangeFunctionTagCmd.TAG_NAME_CHANGED); new ChangeFunctionTagCmd(tagName, newName, ChangeFunctionTagCmd.TAG_NAME_CHANGED);
tool.execute(cmd, program); tool.execute(cmd, program);
} }
// Only process the comment edit if the comment actually changed. // Only process the comment edit if the comment actually changed.
if (!newComment.equals(comment)) { if (!newComment.equals(comment)) {
Command cmd = new ChangeFunctionTagCmd(tagName, newComment, Command<Program> cmd = new ChangeFunctionTagCmd(tagName, newComment,
ChangeFunctionTagCmd.TAG_COMMENT_CHANGED); ChangeFunctionTagCmd.TAG_COMMENT_CHANGED);
tool.execute(cmd, program); tool.execute(cmd, program);
} }
@ -259,7 +257,7 @@ public abstract class TagListPanel extends JPanel {
if (option == OptionDialog.OPTION_ONE) { if (option == OptionDialog.OPTION_ONE) {
for (FunctionTag tag : selectedTags) { for (FunctionTag tag : selectedTags) {
Command cmd = new DeleteFunctionTagCmd(tag.getName()); Command<Program> cmd = new DeleteFunctionTagCmd(tag.getName());
tool.execute(cmd, program); tool.execute(cmd, program);
} }
} }

View file

@ -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.
@ -401,15 +401,15 @@ public class FunctionTagPluginTest extends AbstractGhidraHeadedIntegrationTest {
goTo(tool, program, addr("00000000")); goTo(tool, program, addr("00000000"));
FunctionTagTable table = getSourceTable(); FunctionTagTable table = getSourceTable();
selectTagInTable(tagName1, table); selectTagInTable(tagName1, table);
int index = table.getSelectedRow(); int row = table.getSelectedRow();
table.addRowSelectionInterval(index, index + 1); table.addRowSelectionInterval(row, row + 1);
clickTableRange(table, index, 2); clickTableRange(table, row, 2);
waitForTableModel(functionsPanel.getTableModel()); waitForTableModel(functionsPanel.getTableModel());
// Verify that all 3 functions are in the function panel // Verify that all 3 functions are in the function panel
functions = functionsPanel.getFunctions(); functions = functionsPanel.getFunctions();
assertTrue(functions.size() == 3); assertEquals(3, functions.size());
Function f1 = functions.get(0); Function f1 = functions.get(0);
Function f2 = functions.get(1); Function f2 = functions.get(1);
Function f3 = functions.get(2); Function f3 = functions.get(2);

View file

@ -1778,8 +1778,8 @@ public class GnuDemanglerParser {
Matcher arrayMatcher = ARRAY_DATA_PATTERN.matcher(type); Matcher arrayMatcher = ARRAY_DATA_PATTERN.matcher(type);
if (arrayMatcher.matches()) { if (arrayMatcher.matches()) {
// keep only the type information, dropping the array definition // keep only the type information, dropping the array definition
type = arrayMatcher.group(1); this.type = arrayMatcher.group(1);
arrayType = arrayMatcher.group(2).trim(); this.arrayType = arrayMatcher.group(2).trim();
} }
} }

View file

@ -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,7 +18,6 @@ package docking;
import java.awt.*; import java.awt.*;
import java.awt.dnd.*; import java.awt.dnd.*;
import java.awt.event.*; import java.awt.event.*;
import java.util.List;
import javax.swing.*; import javax.swing.*;
@ -26,7 +25,6 @@ import docking.action.DockingActionIf;
import ghidra.util.CascadedDropTarget; import ghidra.util.CascadedDropTarget;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import help.HelpService; import help.HelpService;
import util.CollectionUtils;
/** /**
* Wrapper class for user components. Adds the title, local toolbar and provides the drag target * Wrapper class for user components. Adds the title, local toolbar and provides the drag target
@ -152,10 +150,6 @@ public class DockableComponent extends JPanel implements ContainerListener {
return; return;
} }
if (!e.isPopupTrigger()) {
return;
}
Component component = e.getComponent(); Component component = e.getComponent();
if (component == null) { if (component == null) {
return; // not sure this can happen return; // not sure this can happen
@ -168,13 +162,11 @@ public class DockableComponent extends JPanel implements ContainerListener {
} }
Point point = e.getPoint(); Point point = e.getPoint();
if (!bounds.contains(point)) { boolean withinBounds = bounds.contains(point);
return; if (e.isPopupTrigger() && withinBounds) {
PopupMenuContext popupContext = new PopupMenuContext(e);
actionMgr.showPopupMenu(placeholder, popupContext);
} }
e.consume();
PopupMenuContext popupContext = new PopupMenuContext(e);
actionMgr.showPopupMenu(placeholder, popupContext);
} }
@Override @Override
@ -336,46 +328,11 @@ public class DockableComponent extends JPanel implements ContainerListener {
} }
if (comp.isFocusable()) { if (comp.isFocusable()) {
installPopupListener(comp); comp.removeMouseListener(popupListener);
comp.addMouseListener(popupListener);
} }
} }
/**
* Remove, reorder and re-add all mouse listeners so Java listeners go last. This allows our
* popup listener to consume the event, preventing Java UI listeners from changing the table
* selection when the user is performing a Ctrl-Mouse click on the Mac.
*
* @param comp the component
*/
private void installPopupListener(Component comp) {
// remove and add the listeners according to the sorted order so that will be installed as
// they are ordered in the list
List<MouseListener> listeners = createOrderedListeners(comp);
for (MouseListener l : listeners) {
comp.removeMouseListener(l);
comp.addMouseListener(l);
}
}
private List<MouseListener> createOrderedListeners(Component comp) {
// Get the current listeners, add the popup mouse listener for this class, then move any
// Java listeners to the back of the list by removing them and re-adding them.
MouseListener[] listeners = comp.getMouseListeners();
List<MouseListener> orderedListeners = CollectionUtils.asList(listeners);
orderedListeners.add(popupListener);
for (MouseListener l : listeners) {
String name = l.getClass().getName();
if (name.startsWith("javax.") || name.startsWith("sun.")) {
orderedListeners.remove(l);
orderedListeners.add(l);
}
}
return orderedListeners;
}
private void deinitializeComponents(Component comp) { private void deinitializeComponents(Component comp) {
if (comp instanceof CellRendererPane) { if (comp instanceof CellRendererPane) {
return; return;