Merge remote-tracking branch

'origin/GP-4281-dragonmacher-initial-address-fix' (Closes #6166)
This commit is contained in:
Ryan Kurtz 2024-02-05 11:43:24 -05:00
commit ef7dac45ae
8 changed files with 72 additions and 38 deletions

View file

@ -207,27 +207,29 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager, Opti
return program;
}
private Program doOpenProgramSwing(ProgramLocator programLocator, int state) {
private Program doOpenProgramSwing(ProgramLocator locator, int state) {
// see if already open
Program program = programMgr.getOpenProgram(programLocator);
Program program = programMgr.getOpenProgram(locator);
if (program != null) {
showProgram(program, programLocator, state);
showProgram(program, locator, state);
return program;
}
// see if cached
program = programCache.get(programLocator);
program = programCache.get(locator);
if (program != null) {
programMgr.addProgram(program, programLocator, state);
programMgr.addProgram(program, locator, state);
return program;
}
// ok, then open it
OpenProgramTask task = new OpenProgramTask(programLocator, this);
OpenProgramTask task = new OpenProgramTask(locator, this);
new TaskLauncher(task, tool.getToolFrame());
OpenProgramRequest openProgramReq = task.getOpenProgram();
if (openProgramReq != null) {
program = openProgramReq.getProgram();
programMgr.addProgram(program, programLocator, state);
openProgramReq.release();
OpenProgramRequest request = task.getOpenProgram();
if (request != null) {
program = request.getProgram();
programMgr.addProgram(program, locator, state);
request.release();
return program;
}
return null;

View file

@ -584,7 +584,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
* the screen. In that case, when this parameter is true, then the given location
* will be placed in the center of the screen; when the parameter is false, then the
* screen will be scrolled only enough to show the cursor.
* @return true if succussful
* @return true if successful
*/
public boolean goTo(ProgramLocation loc, boolean centerWhenNotVisible) {

View file

@ -21,14 +21,13 @@ import java.net.URL;
import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.go.ipc.GhidraGoListener;
import ghidra.framework.main.AppInfo;
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
import ghidra.framework.main.*;
import ghidra.framework.model.ToolServices;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.framework.protocol.ghidra.GhidraURL;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.Swing;
//@formatter:off
@PluginInfo(
@ -88,18 +87,19 @@ public class GhidraGoPlugin extends Plugin implements ApplicationLevelOnlyPlugin
*/
private void processGhidraURL(URL ghidraURL) {
Msg.info(GhidraGoPlugin.class, "GhidraGo processing " + ghidraURL);
Msg.info(this, "GhidraGo processing " + ghidraURL);
try {
Msg.info(GhidraGoPlugin.class,
Msg.info(this,
"Accepting the resource at " + GhidraURL.getProjectURL(ghidraURL));
SystemUtilities.runSwingNow(() -> {
AppInfo.getFrontEndTool().toFront();
AppInfo.getFrontEndTool().getToolServices().launchDefaultToolWithURL(ghidraURL);
Swing.runNow(() -> {
FrontEndTool frontEnd = AppInfo.getFrontEndTool();
frontEnd.toFront();
frontEnd.getToolServices().launchDefaultToolWithURL(ghidraURL);
});
}
catch (IllegalArgumentException e) {
Msg.showError(GhidraGoPlugin.class, null, "GhidraGo Unable to process GhidraURL",
Msg.showError(this, null, "GhidraGo Unable to process GhidraURL",
"GhidraGo could not process " + ghidraURL, e);
}
}

View file

@ -1911,6 +1911,7 @@ public class BufferMgr {
int bufCount = 0;
for (int id = 0; id < indexCnt; id++) {
monitor.checkCancelled();
monitor.setProgress(id);
BufferNode node = getCachedBufferNode(id);
if (node != null) {
// check nod which resides in cache
@ -1929,6 +1930,8 @@ public class BufferMgr {
}
}
monitor.initialize(indexCnt);
// write/update all non-empty buffers
try (OutputBlockStream out = LocalBufferFile.getOutputBlockStream(outFile, bufCount)) {
for (int id = 0; id < indexCnt; id++) {

View file

@ -654,6 +654,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
* signalling to use the clicked item. When pressing Enter, they may have been typing and
* ignoring the list, so we have to do some validation.
*/
@SuppressWarnings("unchecked") // for the cast to T
private void setTextFromListOnEnterPress() {
Object selectedItem = list.getSelectedValue();
if (selectedItem == null) {

View file

@ -16,15 +16,14 @@
package ghidra.util.task;
/**
* Similar to a {@link Runnable} except the {@link #monitoredRun(TaskMonitor) run}
* method is given a monitor to report progress and check for cancellation.
* Similar to a {@link Runnable} except the {@link #monitoredRun(TaskMonitor) run} method is given a
* monitor to report progress and check for cancellation.
*/
public interface MonitoredRunnable {
/**
* Similar to a runnable except the run method is given a monitor
* to report progress and check for cancellation.
* @param monitor the TaskMonitor to use.
/**
* Runs this runnable, given a monitor to report progress and check for cancellation.
* @param monitor the monitor.
*/
void monitoredRun(TaskMonitor monitor);
}

View file

@ -266,7 +266,6 @@ class ToolServicesImpl implements ToolServices {
Workspace workspace = toolManager.getActiveWorkspace();
PluginTool tool = workspace.runTool(template);
if (tool != null) {
tool.setVisible(true);
tool.accept(ghidraUrl);
}
return tool;

View file

@ -18,6 +18,8 @@ package ghidra.framework.project.tool;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.jdom.Element;
@ -25,7 +27,9 @@ import ghidra.framework.model.ToolTemplate;
import ghidra.framework.model.Workspace;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.PluginToolAccessUtils;
import ghidra.util.Swing;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.task.*;
/**
* WorkspaceImpl
@ -76,16 +80,42 @@ class WorkspaceImpl implements Workspace {
@Override
public PluginTool runTool(ToolTemplate template) {
PluginTool tool = toolManager.getTool(this, template);
if (tool != null) {
tool.setVisible(true);
runningTools.add(tool);
//
// Clients that launch a tool would like to have it ready to use when returned from this
// method. For the tool to be ready, it must be created, made visible and fully
// initialized. That process needs to happen on the Swing thread and can be slow. Since
// we may be called on the Swing thread, we use a TaskLauncher, which will show a modal
// dialog. This allows any pending Swing events, including any buffered events (like
// painting and attaching to a parent hierarchy) to be processed by the dialog's secondary
// Swing queue before returning control back to the caller of this method.
//
return launchSwing("Launching Tool", () -> {
PluginTool tool = toolManager.getTool(this, template);
if (tool != null) {
tool.setVisible(true);
runningTools.add(tool);
// alert the tool manager that we have changed
toolManager.setWorkspaceChanged(this);
toolManager.fireToolAddedEvent(this, tool);
}
return tool;
toolManager.setWorkspaceChanged(this);
toolManager.fireToolAddedEvent(this, tool);
}
return tool;
});
}
// This method could instead become TaskLauncher.launchSwing(). It seems too niche for general
// use though.
private <T> T launchSwing(String title, Supplier<T> supplier) {
AtomicReference<T> ref = new AtomicReference<>();
Task t = new Task(title, false, false, true) {
@Override
public void run(TaskMonitor monitor) {
ref.set(Swing.runNow(supplier));
}
};
int delay = 0;
new TaskLauncher(t, null, delay);
return ref.get();
}
@Override