ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Scripting: version of TableChooserDialog.executor that runs on all selected rows

Open sad-dev opened this issue 3 years ago • 2 comments

Is your feature request related to a problem? Please describe. TableChooserDialog can be initialized with a TableChooserExecutor executor. When the button is clicked, the executor will be invoked on all selected row objects via public boolean execute(AddressableRowObject rowObject)

There are several major (and many minor) reasons why having the executor instead implement public boolean execute(Collection<AddressableRowObject> rowObjects) would be useful:

1.) Able to perform aggregates on selected objects e.g. sum of sizes without needing to do crazy hacks. 2.) Able to benefit from calling APIs that expect Collections, instead of calling once per object 3.) More control over transactions 4.) Some things are just extremely difficult to perform with the single element execute. For example, if I want to call either foo or bar on all elements depending on a call to askYesNo, I do not see an obvious way to do this with the original execute. I could store a private variable that records the result of the first askYesNo, but I have no way of knowing when the execution is finished so that I can clear the variable for subsequent runs.

The only downsides I see are: 1.) Refactoring old scripts - there are 4 (ShowConstantUse, FixupNoReturnFunctionsScript, GhidraScriptTest, FindSharedReturnFunctionsScript) that contain it, with ShowConstantUse not actually using it right now. Rewriting is fairly easy though. 2.) Easy for people to shoot themselves in the foot if they do not for example, check if an object is still in the model before calling something that would not make sense. Then again, I have not seen anyone else raise issues about the TableChooserDialog so...

Describe the solution you'd like A refactor of the executor interface to public boolean execute(Collection<AddressableRowObject> rowObjects), or at least the option to make a dialog of this form. I would also like the button to always be selectable even if no rows are selected - for times when the button's functionality is independent of the selection.

Describe alternatives you've considered

  • Modify the classes/ create alternate versions of TableChooserDialog myself
  • Very ugly reflection

sad-dev avatar Sep 20 '22 10:09 sad-dev

This is certainly a reasonable request.

The easiest thing I can think of is to update the interface to look like this:

public interface TableChooserExecutor {

	public String getButtonName();

	public boolean execute(AddressableRowObject rowObject);

	public default boolean executeInBulk(List<AddressableRowObject> rowObjects,
			List<AddressableRowObject> deleted, TaskMonitor monitor) {
		return false;
	}

This would allow users to override executeInBulk() to process the entire list, adding any deleted items to the deleted list. Returning true from this method would signal to us that we should not process each individual item.

Would this work for your scenario(s)?

dragonmacher avatar Sep 20 '22 14:09 dragonmacher

That sounds like a reasonable way to implement it while avoiding interfering with existing scripts that use the original execute, thanks :)

sad-dev avatar Sep 20 '22 16:09 sad-dev