GP-3189 corrected tool launch issue when file(s) dragged onto tool icon in toolchest. Removed single-DomainFile launch methods on ToolServices API.

This commit is contained in:
ghidra1 2023-03-13 19:23:19 -04:00
parent d84d6df8f6
commit 62501f70c1
9 changed files with 41 additions and 69 deletions

View file

@ -15,6 +15,8 @@
*/ */
package ghidra.framework.plugintool; package ghidra.framework.plugintool;
import java.util.List;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import docking.DockingWindowManager; import docking.DockingWindowManager;
@ -63,11 +65,12 @@ public enum PluginToolUtils {
* that case, it'll pick any compatible tool, no matter how recently it had focus. * that case, it'll pick any compatible tool, no matter how recently it had focus.
* *
* @param tool the front-end tool * @param tool the front-end tool
* @param domainFile the domain file to open * @param domainFile the domain file to open (may not be null)
* @return the (possibly new) plugin tool which accepted the domain file * @return the (possibly new) plugin tool which accepted the domain file
*/ */
public static PluginTool openInMostRecentOrLaunchedCompatibleTool(PluginTool tool, public static PluginTool openInMostRecentOrLaunchedCompatibleTool(PluginTool tool,
DomainFile domainFile) { DomainFile domainFile) {
Objects.requireNonNull(domainFile);
DomainFile[] data = new DomainFile[] { domainFile }; DomainFile[] data = new DomainFile[] { domainFile };
PluginTool result = inRunningToolsPreferringActive(tool, pt -> { PluginTool result = inRunningToolsPreferringActive(tool, pt -> {
return pt.acceptDomainFiles(data) ? pt : null; return pt.acceptDomainFiles(data) ? pt : null;
@ -75,7 +78,7 @@ public enum PluginToolUtils {
if (result != null) { if (result != null) {
return result; return result;
} }
return tool.getToolServices().launchDefaultTool(domainFile); return tool.getToolServices().launchDefaultTool(List.of(domainFile));
} }
/** /**

View file

@ -17,6 +17,7 @@ package ghidra.app.plugin.core.processors;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.List;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@ -316,7 +317,7 @@ public final class LanguageProviderPlugin extends Plugin implements ApplicationL
try { try {
SwingUtilities.invokeAndWait(() -> { SwingUtilities.invokeAndWait(() -> {
ToolServices toolServices = tool.getToolServices(); ToolServices toolServices = tool.getToolServices();
if (toolServices.launchDefaultTool(domainFile) == null) { if (toolServices.launchDefaultTool(List.of(domainFile)) == null) {
Msg.showError(this, tool.getToolFrame(), "Failed to Open Program", Msg.showError(this, tool.getToolFrame(), "Failed to Open Program",
"A suitable default tool could not found!"); "A suitable default tool could not found!");
} }

View file

@ -28,7 +28,6 @@ import docking.util.image.ToolIconURL;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin;
import ghidra.framework.main.FrontEndPlugin; import ghidra.framework.main.FrontEndPlugin;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.project.tool.GhidraTool; import ghidra.framework.project.tool.GhidraTool;
import ghidra.program.database.ProgramDB; import ghidra.program.database.ProgramDB;
import ghidra.test.ClassicSampleX86ProgramBuilder; import ghidra.test.ClassicSampleX86ProgramBuilder;
@ -47,8 +46,9 @@ public class DiffSaveSettingsTest extends DiffApplyTestAdapter {
private void launchTool() throws Exception { private void launchTool() throws Exception {
// Launch our own tool for the Diff so that we can close it and handle "Save Tool?". // Launch our own tool for the Diff so that we can close it and handle "Save Tool?".
runSwing(() -> tool = runSwing(() -> tool = frontEndTool.getProject()
(PluginTool) frontEndTool.getProject().getToolServices().launchTool("MyDiffTestTool", .getToolServices()
.launchTool("MyDiffTestTool",
null)); null));
cb = getPlugin(tool, CodeBrowserPlugin.class); cb = getPlugin(tool, CodeBrowserPlugin.class);

View file

@ -1112,7 +1112,7 @@ public class FrontEndPlugin extends Plugin
} }
} }
if (toolServices.launchDefaultTool(domainFile) != null) { if (toolServices.launchDefaultTool(List.of(domainFile)) != null) {
return; return;
} }

View file

@ -561,7 +561,11 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
plugin.getActiveWorkspace().runTool(template); plugin.getActiveWorkspace().runTool(template);
} }
else { else {
toolServices.launchDefaultTool(domainFiles); PluginTool tool = toolServices.launchTool(template.getName(), domainFiles);
if (tool == null) {
Msg.showError(this, getParent(), "Failed to Launch Tool",
"Failed to launch " + template.getName() + " tool.\nSee log for details.");
}
} }
} }
@ -569,21 +573,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
if (domainFiles == null) { if (domainFiles == null) {
return; return;
} }
boolean accepted = tool.acceptDomainFiles(domainFiles.toArray(DomainFile[]::new)); tool.acceptDomainFiles(domainFiles.toArray(DomainFile[]::new));
if (!accepted) {
showFilesNotAcceptedMessage(domainFiles);
}
}
private void showFilesNotAcceptedMessage(List<DomainFile> domainFiles) {
StringBuilder buffy = new StringBuilder("Tool did not accept files: ");
for (int i = 0; i < domainFiles.size(); i++) {
buffy.append(domainFiles.get(0).getName());
if (i != domainFiles.size() - 1) {
buffy.append(", ");
}
}
Msg.showError(this, null, "Error", buffy.toString());
} }
private void setUpDragDrop() { private void setUpDragDrop() {

View file

@ -344,10 +344,11 @@ public class VersionHistoryPanel extends JPanel implements Draggable {
if (versionedObj != null) { if (versionedObj != null) {
try { try {
if (toolName != null) { if (toolName != null) {
tool.getToolServices().launchTool(toolName, versionedObj.getDomainFile()); tool.getToolServices()
.launchTool(toolName, List.of(versionedObj.getDomainFile()));
} }
else { else {
tool.getToolServices().launchDefaultTool(versionedObj.getDomainFile()); tool.getToolServices().launchDefaultTool(List.of(versionedObj.getDomainFile()));
} }
} }
finally { finally {

View file

@ -119,31 +119,25 @@ public interface ToolServices {
public void setContentTypeToolAssociations(Set<ToolAssociationInfo> infos); public void setContentTypeToolAssociations(Set<ToolAssociationInfo> infos);
/** /**
* Launch the default tool and open the specified domainFile. * Launch the default {@link PluginTool tool} and open the specified domainFiles.
* NOTE: running tool reuse is implementation dependent * NOTE: running tool reuse is implementation dependent
* @param domainFile the file to open * @param domainFiles the files to open. A null or empty list will results in an immediate
* return of a null {@link PluginTool}. Null entries are not permitted.
* @return the launched tool. Null returned if a suitable default tool * @return the launched tool. Null returned if a suitable default tool
* for the file content type was not found. * for the file content type was not found or failed to launch.
*/ */
public PluginTool launchDefaultTool(DomainFile domainFile); public PluginTool launchDefaultTool(Collection<DomainFile> domainFiles);
/** /**
* Launch the default tool and open the specified domainFiles. * Launch the {@link PluginTool tool} with the given name and open the specified domainFiles.
* NOTE: running tool reuse is implementation dependent * Only those domainFiles with a content type supported by the specified tool will be opened.
* @param domainFile the file to open * NOTE: running tool reuse is implementation dependent.
* @return the launched tool. Null returned if a suitable default tool * @param toolName name of the {@link ToolTemplate tool template} to launch or re-use
* for the file content type was not found. * @param domainFiles the files to open; may be null or empty. Null entries are not permitted.
* @return the resulting {@link PluginTool tool} or null if the specified tool was not found
* or failed to launch
*/ */
public PluginTool launchDefaultTool(Collection<DomainFile> domainFile); public PluginTool launchTool(String toolName, Collection<DomainFile> domainFiles);
/**
* Launch the tool with the given name. A domainFile may be specified and will be opened
* if its content type is supported by the tool.
* @param toolName name of the tool to launch
* @param domainFile the file to open; may be null
* @return the requested tool or null if the specified tool not found.
*/
public PluginTool launchTool(String toolName, DomainFile domainFile);
/** /**
* Launch the default tool and open the specified Ghidra URL resource. * Launch the default tool and open the specified Ghidra URL resource.

View file

@ -74,18 +74,13 @@ public class ToolServicesAdapter implements ToolServices {
return null; return null;
} }
@Override
public PluginTool launchDefaultTool(DomainFile domainFile) {
return null;
}
@Override @Override
public PluginTool launchDefaultTool(Collection<DomainFile> domainFile) { public PluginTool launchDefaultTool(Collection<DomainFile> domainFile) {
return null; return null;
} }
@Override @Override
public PluginTool launchTool(String toolName, DomainFile domainFile) { public PluginTool launchTool(String toolName, Collection<DomainFile> domainFile) {
return null; return null;
} }

View file

@ -236,14 +236,6 @@ class ToolServicesImpl implements ToolServices {
return tool; return tool;
} }
@Override
public PluginTool launchDefaultTool(DomainFile domainFile) {
ToolTemplate template = getDefaultToolTemplate(domainFile);
return defaultLaunch(template, t -> {
return t.acceptDomainFiles(new DomainFile[] { domainFile });
});
}
@Override @Override
public PluginTool launchDefaultTool(Collection<DomainFile> domainFiles) { public PluginTool launchDefaultTool(Collection<DomainFile> domainFiles) {
if (CollectionUtils.isBlank(domainFiles)) { if (CollectionUtils.isBlank(domainFiles)) {
@ -256,21 +248,17 @@ class ToolServicesImpl implements ToolServices {
} }
@Override @Override
public PluginTool launchTool(String toolName, DomainFile domainFile) { public PluginTool launchTool(String toolName, Collection<DomainFile> domainFiles) {
ToolTemplate template = findToolChestToolTemplate(toolName); ToolTemplate template = findToolChestToolTemplate(toolName);
if (template == null) { if (template == null) {
return null; return null;
} }
Workspace workspace = toolManager.getActiveWorkspace(); return defaultLaunch(template, t -> {
PluginTool tool = workspace.runTool(template); if (CollectionUtils.isBlank(domainFiles)) {
if (tool == null) { return true;
return null; }
} return t.acceptDomainFiles(domainFiles.toArray(DomainFile[]::new));
tool.setVisible(true); });
if (domainFile != null) {
tool.acceptDomainFiles(new DomainFile[] { domainFile });
}
return tool;
} }
@Override @Override