mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-19 16:40:38 -09:00
GP-3123 - Fixed broken tool button animation
This commit is contained in:
@@ -485,11 +485,11 @@ public class FrontEndPlugin extends Plugin
|
||||
* general project utility that brings up a file chooser for
|
||||
* the user to specify a directory and filename that are used
|
||||
* for the Project location and name
|
||||
*
|
||||
*
|
||||
* @param fileChooser the chooser used to pick the project
|
||||
* @param mode read-only or not
|
||||
* @param preferenceName the preference property name used to save the last opened project
|
||||
* @return the project locator for the opened project
|
||||
* @return the project locator for the opened project
|
||||
*/
|
||||
ProjectLocator chooseProject(GhidraFileChooser fileChooser, String mode,
|
||||
String preferenceName) {
|
||||
@@ -703,9 +703,9 @@ public class FrontEndPlugin extends Plugin
|
||||
|
||||
connectionButton.setContentAreaFilled(false);
|
||||
connectionButton.setSelected(isConnected);
|
||||
connectionButton.setBorder(
|
||||
isConnected ? BorderFactory.createBevelBorder(BevelBorder.LOWERED)
|
||||
: BorderFactory.createBevelBorder(BevelBorder.RAISED));
|
||||
connectionButton
|
||||
.setBorder(isConnected ? BorderFactory.createBevelBorder(BevelBorder.LOWERED)
|
||||
: BorderFactory.createBevelBorder(BevelBorder.RAISED));
|
||||
connectionIconPanel.add(connectionButton);
|
||||
if (isConnected) {
|
||||
|
||||
@@ -716,8 +716,8 @@ public class FrontEndPlugin extends Plugin
|
||||
Msg.debug(this, "Unexpected exception retrieving user from repository", e);
|
||||
}
|
||||
}
|
||||
repositoryLabel.setText(
|
||||
"Project Repository: " + repository.getName() + getAccessString(user));
|
||||
repositoryLabel
|
||||
.setText("Project Repository: " + repository.getName() + getAccessString(user));
|
||||
|
||||
String serverName = repository.getServerInfo().getServerName();
|
||||
connectionButton.setToolTipText(
|
||||
@@ -988,8 +988,8 @@ public class FrontEndPlugin extends Plugin
|
||||
}
|
||||
};
|
||||
renameToolAction.setPopupMenuData(new MenuData(new String[] { "Rename..." }, "tool"));
|
||||
renameToolAction.setHelpLocation(
|
||||
new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Rename Tool"));
|
||||
renameToolAction
|
||||
.setHelpLocation(new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Rename Tool"));
|
||||
|
||||
propertiesAction = new ToolButtonAction(PROPERTIES_ACTION_NAME) {
|
||||
@Override
|
||||
@@ -1012,8 +1012,8 @@ public class FrontEndPlugin extends Plugin
|
||||
propertiesAction.setPopupMenuData(
|
||||
new MenuData(new String[] { "Configure Plugins..." }, "zproperties"));
|
||||
|
||||
propertiesAction.setHelpLocation(
|
||||
new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Configure_Tool"));
|
||||
propertiesAction
|
||||
.setHelpLocation(new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Configure_Tool"));
|
||||
|
||||
tool.addLocalAction(frontEndProvider, exportToolAction);
|
||||
tool.addLocalAction(frontEndProvider, renameToolAction);
|
||||
@@ -1103,6 +1103,15 @@ public class FrontEndPlugin extends Plugin
|
||||
|
||||
Project project = tool.getProject();
|
||||
ToolServices toolServices = project.getToolServices();
|
||||
ToolTemplate defaultToolTemplate = toolServices.getDefaultToolTemplate(domainFile);
|
||||
if (defaultToolTemplate != null) {
|
||||
ToolButton button = toolBar.getToolButtonForToolConfig(defaultToolTemplate);
|
||||
if (button != null) {
|
||||
button.launchTool(domainFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (toolServices.launchDefaultTool(domainFile) != null) {
|
||||
return;
|
||||
}
|
||||
@@ -1132,7 +1141,7 @@ public class FrontEndPlugin extends Plugin
|
||||
|
||||
DomainFolder domainFolder = linkedFolder.getLinkedFolder();
|
||||
if (domainFolder != null) {
|
||||
// delayed to ensure tree is displayd
|
||||
// delayed to ensure tree is displayed
|
||||
Swing.runLater(() -> dtp.selectDomainFolder(domainFolder));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import ghidra.util.bean.GGlassPane;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
import util.CollectionUtils;
|
||||
import utility.function.Dummy;
|
||||
|
||||
/**
|
||||
@@ -53,8 +54,6 @@ import utility.function.Dummy;
|
||||
*/
|
||||
class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
|
||||
private static final Runnable DUMMY_RUNNABLE = Dummy.runnable();
|
||||
|
||||
private DropTarget dropTarget;
|
||||
private DropTgtAdapter dropTargetAdapter;
|
||||
private DataFlavor[] acceptableFlavors; // data flavors that this component can support
|
||||
@@ -145,57 +144,24 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
}
|
||||
|
||||
public void launchTool(DomainFile domainFile) {
|
||||
doLaunchTool(new DomainFile[] { domainFile });
|
||||
openFilesAndOpenToolAsNecessary(List.of(domainFile), null);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Droppable interface
|
||||
//==================================================================================================
|
||||
|
||||
/**
|
||||
* Set drag feedback according to the OK parameter.
|
||||
* @param ok true means the drop action is OK
|
||||
* @param e event that has current state of drag and drop operation
|
||||
*/
|
||||
@Override
|
||||
public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if is OK to drop the transferable at the location
|
||||
* specified the event.
|
||||
* @param e event that has current state of drag and drop operation
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
// our data; cast is OK
|
||||
public boolean isDropOk(DropTargetDragEvent e) {
|
||||
DataFlavor[] flavors = e.getCurrentDataFlavors();
|
||||
Transferable transferable = e.getTransferable();
|
||||
try {
|
||||
for (DataFlavor element : flavors) {
|
||||
if (element.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
|
||||
Object draggedData = e.getTransferable()
|
||||
.getTransferData(DataTreeDragNDropHandler.localDomainFileFlavor);
|
||||
return containsSupportedDataTypes((List<DomainFile>) draggedData);
|
||||
}
|
||||
else if (element.equals(ToolButtonTransferable.localToolButtonFlavor)) {
|
||||
Object draggedData = e.getTransferable()
|
||||
.getTransferData(ToolButtonTransferable.localToolButtonFlavor);
|
||||
ToolButton draggedButton = (ToolButton) draggedData;
|
||||
if (draggedButton != null) {
|
||||
if (draggedButton.associatedRunningTool == associatedRunningTool) {
|
||||
// tool chest -> tool chest is not allowed (both runningTools are null).
|
||||
// runningTool -> same runningTool is not allowed.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (element.equals(VersionInfoTransferable.localVersionInfoFlavor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return checkForDrop(flavors, transferable);
|
||||
}
|
||||
catch (UnsupportedFlavorException e1) {
|
||||
// don't care; return false
|
||||
@@ -206,6 +172,36 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // our data; cast is OK
|
||||
private boolean checkForDrop(DataFlavor[] flavors, Transferable transferable)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
|
||||
for (DataFlavor flavor : flavors) {
|
||||
if (flavor.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
|
||||
Object draggedData =
|
||||
transferable.getTransferData(DataTreeDragNDropHandler.localDomainFileFlavor);
|
||||
return containsSupportedDataTypes((List<DomainFile>) draggedData);
|
||||
}
|
||||
else if (flavor.equals(ToolButtonTransferable.localToolButtonFlavor)) {
|
||||
Object draggedData =
|
||||
transferable.getTransferData(ToolButtonTransferable.localToolButtonFlavor);
|
||||
ToolButton draggedButton = (ToolButton) draggedData;
|
||||
if (draggedButton != null) {
|
||||
if (draggedButton.associatedRunningTool == associatedRunningTool) {
|
||||
// tool chest -> tool chest is not allowed (both runningTools are null).
|
||||
// runningTool -> same runningTool is not allowed.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (flavor.equals(VersionInfoTransferable.localVersionInfoFlavor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The given list must contain only valid domain files (i.e., no folders or null items)
|
||||
* @param fileList The list of file objects to validate
|
||||
@@ -223,23 +219,11 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
return fileList.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert back to normal if any drag feedback was set.
|
||||
*/
|
||||
@Override
|
||||
public void undoDragUnderFeedback() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object to the droppable component. The DropTgtAdapter
|
||||
* calls this method from its drop() method.
|
||||
*
|
||||
* @param obj Transferable object that is to be dropped.
|
||||
* @param event has current state of drop operation
|
||||
* @param f represents the opaque concept of a data format as
|
||||
* would appear on a clipboard, during drag and drop.
|
||||
*/
|
||||
@Override
|
||||
public void add(Object obj, DropTargetDropEvent event, DataFlavor f) {
|
||||
|
||||
@@ -249,8 +233,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
@SuppressWarnings("unchecked")
|
||||
// we put the data in
|
||||
List<DomainFile> list = (List<DomainFile>) obj;
|
||||
DomainFile[] domainFiles = list.toArray(new DomainFile[list.size()]);
|
||||
openFilesAndOpenToolAsNecessary(domainFiles);
|
||||
openFilesAndOpenToolAsNecessary(list, null);
|
||||
}
|
||||
else if (f.equals(VersionInfoTransferable.localVersionInfoFlavor)) {
|
||||
VersionInfo info = (VersionInfo) obj;
|
||||
@@ -264,7 +247,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
DomainFile domainFile = versionedObj.getDomainFile();
|
||||
if (isSupportedDataType(domainFile)) {
|
||||
resetButtonAfterDrag(this);
|
||||
openFilesAndOpenToolAsNecessary(new DomainFile[] { domainFile },
|
||||
openFilesAndOpenToolAsNecessary(List.of(domainFile),
|
||||
() -> versionedObj.release(ToolButton.this));
|
||||
}
|
||||
else {
|
||||
@@ -280,23 +263,12 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
}
|
||||
}
|
||||
|
||||
private void showFilesNotAcceptedMessage(DomainFile[] domainFiles) {
|
||||
StringBuffer buffer = new StringBuffer("Tool did not accept files: ");
|
||||
for (int i = 0; i < domainFiles.length; i++) {
|
||||
buffer.append(domainFiles[i].getName());
|
||||
if (i != domainFiles.length - 1) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
}
|
||||
Msg.showError(this, null, "Error", buffer.toString());
|
||||
}
|
||||
|
||||
private void addFromToolButton(ToolButton toolButton) {
|
||||
plugin.setToolButtonTransferable(null);
|
||||
PluginTool tool = null;
|
||||
if (associatedRunningTool != null && toolButton.associatedRunningTool != null) {
|
||||
final PluginTool t2 = toolButton.associatedRunningTool;
|
||||
SwingUtilities.invokeLater(() -> connectTools(associatedRunningTool, t2));
|
||||
Swing.runLater(() -> connectTools(associatedRunningTool, t2));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -305,14 +277,14 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
tool = plugin.getActiveWorkspace().runTool(toolButton.template);
|
||||
accepted = tool.acceptDomainFiles(associatedRunningTool.getDomainFiles());
|
||||
final PluginTool t = tool;
|
||||
SwingUtilities.invokeLater(() -> connectTools(t, associatedRunningTool));
|
||||
Swing.runLater(() -> connectTools(t, associatedRunningTool));
|
||||
}
|
||||
else {
|
||||
tool = plugin.getActiveWorkspace().runTool(template);
|
||||
accepted = tool.acceptDomainFiles(toolButton.associatedRunningTool.getDomainFiles());
|
||||
final PluginTool t = tool;
|
||||
final PluginTool t2 = toolButton.associatedRunningTool;
|
||||
SwingUtilities.invokeLater(() -> connectTools(t, t2));
|
||||
Swing.runLater(() -> connectTools(t, t2));
|
||||
}
|
||||
|
||||
if (!accepted) {
|
||||
@@ -332,9 +304,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
connectAll(tc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect all events in the connection object.
|
||||
*/
|
||||
private void connectAll(ToolConnection tc) {
|
||||
String[] events = tc.getEvents();
|
||||
for (String element : events) {
|
||||
@@ -345,10 +314,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
tc.getConsumer().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the domain file's object class is supported by
|
||||
* this tool.
|
||||
*/
|
||||
private boolean isSupportedDataType(DomainFile file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
@@ -436,19 +401,11 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the DragGestureAdapter to start the drag.
|
||||
*/
|
||||
@Override
|
||||
public DragSourceListener getDragSourceListener() {
|
||||
return dragSourceAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object to transfer.
|
||||
* @param p location of object to transfer
|
||||
* @return object to transfer
|
||||
*/
|
||||
@Override
|
||||
public Transferable getTransferable(Point p) {
|
||||
return plugin.getToolButtonTransferable();
|
||||
@@ -459,16 +416,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
resetButtonAfterDrag(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the drag actions supported by this drag source:
|
||||
* <UL>
|
||||
* <li>DnDConstants.ACTION_MOVE
|
||||
* <li>DnDConstants.ACTION_COPY
|
||||
* <li>DnDConstants.ACTION_COPY_OR_MOVE
|
||||
* </li>
|
||||
*
|
||||
* @return the drag actions
|
||||
*/
|
||||
@Override
|
||||
public int getDragAction() {
|
||||
return dragAction;
|
||||
@@ -517,24 +464,18 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
private void activateTool() {
|
||||
if (associatedRunningTool == null) {
|
||||
// this is a button on the tool bar, so launch a new tool
|
||||
doLaunchTool(null);
|
||||
openFilesAndOpenToolAsNecessary(null, null);
|
||||
}
|
||||
else {
|
||||
associatedRunningTool.toFront();
|
||||
}
|
||||
}
|
||||
|
||||
private void doLaunchTool(DomainFile[] domainFiles) {
|
||||
openFilesAndOpenToolAsNecessary(domainFiles);
|
||||
}
|
||||
|
||||
private void openFilesAndOpenToolAsNecessary(final DomainFile[] domainFiles) {
|
||||
openFilesAndOpenToolAsNecessary(domainFiles, DUMMY_RUNNABLE);
|
||||
}
|
||||
|
||||
private void openFilesAndOpenToolAsNecessary(final DomainFile[] domainFiles,
|
||||
private void openFilesAndOpenToolAsNecessary(List<DomainFile> domainFiles,
|
||||
Runnable finishedCallback) {
|
||||
|
||||
finishedCallback = Dummy.ifNull(finishedCallback);
|
||||
|
||||
if (associatedRunningTool != null) {
|
||||
// this button has a running tool, no need to open one
|
||||
openDomainFiles(associatedRunningTool, domainFiles);
|
||||
@@ -559,9 +500,8 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
finishedCallback);
|
||||
}
|
||||
|
||||
private void launchToolWithAnimationAndOpenFiles(final DomainFile[] domainFiles,
|
||||
final JFrame toolFrame, final GGlassPane toolGlassPane,
|
||||
final Runnable finishedCallback) {
|
||||
private void launchToolWithAnimationAndOpenFiles(List<DomainFile> domainFiles, JFrame toolFrame,
|
||||
GGlassPane toolGlassPane, Runnable finishedCallback) {
|
||||
|
||||
Icon icon = getIcon();
|
||||
Point buttonLocation = getLocation();
|
||||
@@ -591,8 +531,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
MoveImageRunner moveRunner =
|
||||
new MoveImageRunner(toolGlassPane, startBounds, endBounds, painter);
|
||||
|
||||
// a callback that lets us know when to open the given files and restore the state of
|
||||
// the GhidraGlassPane
|
||||
TimingTarget finishedTarget = new TimingTargetAdapter() {
|
||||
@Override
|
||||
public void end() {
|
||||
@@ -600,8 +538,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
try {
|
||||
// cleanup any residual painting effects
|
||||
toolGlassPane.paintImmediately(toolGlassPane.getBounds());
|
||||
PluginTool newTool = plugin.getActiveWorkspace().runTool(template);
|
||||
openDomainFiles(newTool, domainFiles);
|
||||
openDomainFiles(domainFiles);
|
||||
}
|
||||
finally {
|
||||
// always restore the cursor
|
||||
@@ -619,19 +556,36 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
||||
zoomRunner.run();
|
||||
}
|
||||
|
||||
private void openDomainFiles(PluginTool tool, DomainFile[] domainFiles) {
|
||||
private void openDomainFiles(List<DomainFile> domainFiles) {
|
||||
if (CollectionUtils.isBlank(domainFiles)) {
|
||||
plugin.getActiveWorkspace().runTool(template);
|
||||
}
|
||||
else {
|
||||
toolServices.launchDefaultTool(domainFiles);
|
||||
}
|
||||
}
|
||||
|
||||
private void openDomainFiles(PluginTool tool, List<DomainFile> domainFiles) {
|
||||
if (domainFiles == null) {
|
||||
return;
|
||||
}
|
||||
boolean accepted = tool.acceptDomainFiles(domainFiles);
|
||||
boolean accepted = tool.acceptDomainFiles(domainFiles.toArray(DomainFile[]::new));
|
||||
if (!accepted) {
|
||||
showFilesNotAcceptedMessage(domainFiles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the objects so we can be a drag and drop site.
|
||||
*/
|
||||
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() {
|
||||
|
||||
acceptableFlavors = new DataFlavor[] { DataTreeDragNDropHandler.localDomainFileFlavor,
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ProjectDataOpenDefaultToolAction extends FrontendProjectTreeAction
|
||||
@Override
|
||||
protected void actionPerformed(ProjectDataContext context) {
|
||||
List<DomainFile> selectedFiles = context.getSelectedFiles();
|
||||
AppInfo.getActiveProject().getToolServices().launchDefaultTool(selectedFiles.get(0));
|
||||
AppInfo.getActiveProject().getToolServices().launchDefaultTool(selectedFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@ package ghidra.framework.model;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.framework.plugintool.PluginEvent;
|
||||
@@ -33,22 +34,22 @@ public interface ToolServices {
|
||||
|
||||
/**
|
||||
* Notify the framework that the tool is closing.
|
||||
*
|
||||
*
|
||||
* @param tool tool that is closing
|
||||
*/
|
||||
public void closeTool(PluginTool tool);
|
||||
|
||||
/**
|
||||
* Saves the tool's configuration in the standard
|
||||
* tool location.
|
||||
*
|
||||
* tool location.
|
||||
*
|
||||
* @param tool tool to save.
|
||||
*/
|
||||
public void saveTool(PluginTool tool);
|
||||
|
||||
/**
|
||||
* Save the tool to the given location on the local file system.
|
||||
*
|
||||
*
|
||||
* @param tool the tool template to write
|
||||
* @return the file to which the tool was saved
|
||||
* @throws FileNotFoundException thrown if the file's directory doesn't exist.
|
||||
@@ -67,7 +68,7 @@ public interface ToolServices {
|
||||
* If it finds a matching tool, then it is brought to the front.
|
||||
* Otherwise, it creates one and runs it.
|
||||
* It then invokes the specified event on the running tool.
|
||||
*
|
||||
*
|
||||
* @param tool find/create a tool like this one.
|
||||
* @param domainFile open this file in the found/created tool.
|
||||
* @param event invoke this event on the found/created tool
|
||||
@@ -75,18 +76,18 @@ public interface ToolServices {
|
||||
public void displaySimilarTool(PluginTool tool, DomainFile domainFile, PluginEvent event);
|
||||
|
||||
/**
|
||||
* Returns the default/preferred tool template which should be used to open the specified
|
||||
* Returns the default/preferred tool template which should be used to open the specified
|
||||
* domain file, whether defined by the user or the system default.
|
||||
*
|
||||
*
|
||||
* @param domainFile The file whose preferred tool should be found.
|
||||
* @return The preferred tool that should be used to open the given file or null if none found.
|
||||
*/
|
||||
public ToolTemplate getDefaultToolTemplate(DomainFile domainFile);
|
||||
|
||||
/**
|
||||
* Returns the default/preferred tool template which should be used to open the specified
|
||||
* Returns the default/preferred tool template which should be used to open the specified
|
||||
* domain file content type, whether defined by the user or the system default.
|
||||
*
|
||||
*
|
||||
* @param contentType The content type whose preferred tool should be found.
|
||||
* @return The preferred tool that should be used to open the given file or null if none found.
|
||||
*/
|
||||
@@ -100,18 +101,18 @@ public interface ToolServices {
|
||||
public Set<ToolTemplate> getCompatibleTools(Class<? extends DomainObject> domainClass);
|
||||
|
||||
/**
|
||||
* Returns the {@link ToolAssociationInfo associations}, which describe content
|
||||
* Returns the {@link ToolAssociationInfo associations}, which describe content
|
||||
* types and the tools used to open them, for all content types known to the system.
|
||||
*
|
||||
*
|
||||
* @return the associations
|
||||
* @see #setContentTypeToolAssociations(Set)
|
||||
*/
|
||||
public Set<ToolAssociationInfo> getContentTypeToolAssociations();
|
||||
|
||||
/**
|
||||
* Sets the {@link ToolAssociationInfo associations}, which describe content
|
||||
* types and the tools used to open them, for the system.
|
||||
*
|
||||
* Sets the {@link ToolAssociationInfo associations}, which describe content
|
||||
* types and the tools used to open them, for the system.
|
||||
*
|
||||
* @param infos The associations to be applied
|
||||
* @see #getContentTypeToolAssociations()
|
||||
*/
|
||||
@@ -119,13 +120,22 @@ public interface ToolServices {
|
||||
|
||||
/**
|
||||
* Launch the default tool and open the specified domainFile.
|
||||
* NOTE: running tool re-use is implementation dependent
|
||||
* NOTE: running tool reuse is implementation dependent
|
||||
* @param domainFile the file to open
|
||||
* @return the launched tool. Null returned if a suitable default tool
|
||||
* for the file content type was not found.
|
||||
*/
|
||||
public PluginTool launchDefaultTool(DomainFile domainFile);
|
||||
|
||||
/**
|
||||
* Launch the default tool and open the specified domainFiles.
|
||||
* NOTE: running tool reuse is implementation dependent
|
||||
* @param domainFile the file to open
|
||||
* @return the launched tool. Null returned if a suitable default tool
|
||||
* for the file content type was not found.
|
||||
*/
|
||||
public PluginTool launchDefaultTool(Collection<DomainFile> domainFile);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -137,7 +147,7 @@ public interface ToolServices {
|
||||
|
||||
/**
|
||||
* Launch the default tool and open the specified Ghidra URL resource.
|
||||
* The tool choosen will be based upon the content type of the specified resource.
|
||||
* The tool chosen will be based upon the content type of the specified resource.
|
||||
* NOTE: running tool re-use is implementation dependent
|
||||
* @param ghidraUrl resource to be opened (see {@link GhidraURL})
|
||||
* @return the launched tool. Null returned if a failure occurs while accessing the specified
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
|
||||
@@ -17,6 +17,7 @@ package ghidra.framework.plugintool;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.framework.model.*;
|
||||
@@ -78,6 +79,11 @@ public class ToolServicesAdapter implements ToolServices {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginTool launchDefaultTool(Collection<DomainFile> domainFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginTool launchTool(String toolName, DomainFile domainFile) {
|
||||
return null;
|
||||
|
||||
@@ -41,6 +41,7 @@ import ghidra.util.filechooser.GhidraFileChooserModel;
|
||||
import ghidra.util.filechooser.GhidraFileFilter;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.xml.GenericXMLOutputter;
|
||||
import util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Implementation of service used to manipulate tools.
|
||||
@@ -243,6 +244,17 @@ class ToolServicesImpl implements ToolServices {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginTool launchDefaultTool(Collection<DomainFile> domainFiles) {
|
||||
if (CollectionUtils.isBlank(domainFiles)) {
|
||||
throw new IllegalArgumentException("Domain files cannot be empty");
|
||||
}
|
||||
ToolTemplate template = getDefaultToolTemplate(CollectionUtils.any(domainFiles));
|
||||
return defaultLaunch(template, t -> {
|
||||
return t.acceptDomainFiles(domainFiles.toArray(DomainFile[]::new));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginTool launchTool(String toolName, DomainFile domainFile) {
|
||||
ToolTemplate template = findToolChestToolTemplate(toolName);
|
||||
@@ -530,9 +542,9 @@ class ToolServicesImpl implements ToolServices {
|
||||
|
||||
/**
|
||||
* Get all running tools that have the same tool chest tool name as this one.
|
||||
*
|
||||
*
|
||||
* @param tool the tool for comparison.
|
||||
*
|
||||
*
|
||||
* @return array of tools that are running and named the same as this one.
|
||||
*/
|
||||
private PluginTool[] getSameNamedRunningTools(PluginTool tool) {
|
||||
@@ -554,10 +566,10 @@ class ToolServicesImpl implements ToolServices {
|
||||
|
||||
/**
|
||||
* Search the array of tools for one using the given domainFile.
|
||||
*
|
||||
*
|
||||
* @param tools array of tools to search
|
||||
* @param domainFile domain file to find user of
|
||||
*
|
||||
*
|
||||
* @return first tool found to be using the domainFile
|
||||
*/
|
||||
private PluginTool findToolUsingFile(PluginTool[] tools, DomainFile domainFile) {
|
||||
|
||||
Reference in New Issue
Block a user