GP-825 - Task Dialog - fixed expanding task dialog

This commit is contained in:
dragonmacher 2021-04-26 12:53:23 -04:00
parent ec22f78db9
commit 9c9dcc927a
5 changed files with 102 additions and 64 deletions

View File

@ -485,7 +485,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
* NOTE: method may only be invoked within the analysis thread
* (i.e., by an Analyzer or AnalysisWorker). Care must be taken to control depth
* of yield, although this may be difficult to control.
* @param monitor
* @param monitor the monitor
*/
private void yield(Integer limitPriority, TaskMonitor monitor) {
@ -516,7 +516,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
* (i.e., lower values correspond to higher priority) will be permitted to run. A value
* of null will allow all pending analysis to complete (excluding any tasks which had
* previously yielded).
* @param monitor
* @param monitor the monitor
* @throws IllegalStateException if not invoked from the analysis thread.
*/
public void waitForAnalysis(final Integer limitPriority, TaskMonitor monitor) {
@ -626,7 +626,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
* yield method so that their limit-priority may be established during the yield.
* <br>
* If analysis is performed, a summary of task execution times will be printed to the log.
* @param monitor
* @param monitor the monitor
*/
public void startAnalysis(TaskMonitor monitor) {
startAnalysis(monitor, true);
@ -642,7 +642,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
* performed in which all queued tasks of a higher priority (smaller priority value) than the current
* task will be executed prior to this method returning. AnalysisWorker's should use the
* yield method so that their limit-priority may be established during the yield.
* @param monitor
* @param monitor the monitor
* @param printTaskTimes if true and analysis is performed, a summary of task execution times
* will be printed to the log.
*/
@ -722,7 +722,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
/**
* Start auto-analysis if it is ENABLED and not yet running.
* @param monitor
* @param monitor the monitor
* @param yield if true the current thread is the analysis thread and is yielding to the currently
* executing task.
* @param limitPriority the threshold priority value. All queued tasks with a priority value
@ -1204,7 +1204,8 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
/**
* Get the time taken by a named task
* The names of tasks that have run can be retrieved using getTimedTasks
* @param taskName
* @param map the times by task names
* @param taskName the task name
* @return the time taken by a named task
*/
public long getTaskTime(Map<String, Long> map, String taskName) {
@ -1230,8 +1231,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
if (currentTime > 0) {
totalTime += currentTime;
}
Long l = new Long(totalTime);
return l.longValue();
return totalTime;
}
private void addToTaskTime(String taskName, long time) {
@ -1252,7 +1252,8 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
}
/**
* Print out the time for each task that ran for this auto analysis run.
* Get a summary of the time for each task that ran for this auto analysis run
* @return the string summary
*/
public String getTaskTimesString() {
@ -1331,11 +1332,12 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
* follow-on analysis of those changes. If false it is critical that the worker be associated with a modal
* task dialog which will prevent unrelated concurrent changes being made to the program while
* the worker is active.
* @param workerMonitor
* @param workerMonitor the worker's monitor
* @return boolean value returned by worker.analysisWorkerCallback
* @throws InvocationTargetException if worker throws exception while running (see cause)
* @throws InterruptedException if caller's thread is interrupted. If this occurs a cancel
* condition will be forced on the workerMonitor so that the worker will stop running.
* @throws CancelledException if the job is cancelled
* @see AnalysisPriority for priority values
*/
public boolean scheduleWorker(AnalysisWorker worker, Object workerContext,
@ -1472,17 +1474,17 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
private class JointTaskMonitor implements TaskMonitor {
TaskMonitor dominantMonitor;
TaskMonitor slaveMonitor;
private TaskMonitor primaryMonitor;
private TaskMonitor secondaryMonitor;
JointTaskMonitor(TaskMonitor dominantMonitor, TaskMonitor slaveMonitor) {
this.dominantMonitor = dominantMonitor;
this.slaveMonitor = slaveMonitor;
JointTaskMonitor(TaskMonitor primaryMonitor, TaskMonitor secondaryMonitor) {
this.primaryMonitor = primaryMonitor;
this.secondaryMonitor = secondaryMonitor;
}
@Override
public boolean isCancelled() {
return dominantMonitor.isCancelled() || slaveMonitor.isCancelled();
return primaryMonitor.isCancelled() || secondaryMonitor.isCancelled();
}
@Override
@ -1502,86 +1504,86 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
@Override
public void setMessage(String message) {
dominantMonitor.setMessage(message);
slaveMonitor.setMessage(message);
primaryMonitor.setMessage(message);
secondaryMonitor.setMessage(message);
}
@Override
public String getMessage() {
return dominantMonitor.getMessage();
return primaryMonitor.getMessage();
}
@Override
public void setProgress(long value) {
dominantMonitor.setProgress(value);
slaveMonitor.setProgress(value);
primaryMonitor.setProgress(value);
secondaryMonitor.setProgress(value);
}
@Override
public void initialize(long max) {
dominantMonitor.initialize(max);
slaveMonitor.initialize(max);
primaryMonitor.initialize(max);
secondaryMonitor.initialize(max);
}
@Override
public void setMaximum(long max) {
dominantMonitor.setMaximum(max);
slaveMonitor.setMaximum(max);
primaryMonitor.setMaximum(max);
secondaryMonitor.setMaximum(max);
}
@Override
public long getMaximum() {
return Math.max(dominantMonitor.getMaximum(), slaveMonitor.getMaximum());
return Math.max(primaryMonitor.getMaximum(), secondaryMonitor.getMaximum());
}
@Override
public void checkCanceled() throws CancelledException {
dominantMonitor.checkCanceled();
slaveMonitor.checkCanceled();
primaryMonitor.checkCanceled();
secondaryMonitor.checkCanceled();
}
@Override
public void incrementProgress(long incrementAmount) {
dominantMonitor.incrementProgress(incrementAmount);
slaveMonitor.incrementProgress(incrementAmount);
primaryMonitor.incrementProgress(incrementAmount);
secondaryMonitor.incrementProgress(incrementAmount);
}
@Override
public long getProgress() {
return Math.max(dominantMonitor.getProgress(), slaveMonitor.getProgress());
return Math.max(primaryMonitor.getProgress(), secondaryMonitor.getProgress());
}
@Override
public void cancel() {
dominantMonitor.cancel();
slaveMonitor.cancel();
primaryMonitor.cancel();
secondaryMonitor.cancel();
}
@Override
public void addCancelledListener(CancelledListener listener) {
dominantMonitor.addCancelledListener(listener);
primaryMonitor.addCancelledListener(listener);
}
@Override
public void removeCancelledListener(CancelledListener listener) {
dominantMonitor.addCancelledListener(listener);
primaryMonitor.addCancelledListener(listener);
}
@Override
public void setCancelEnabled(boolean enable) {
dominantMonitor.setCancelEnabled(enable);
slaveMonitor.setCancelEnabled(enable);
primaryMonitor.setCancelEnabled(enable);
secondaryMonitor.setCancelEnabled(enable);
}
@Override
public boolean isCancelEnabled() {
return dominantMonitor.isCancelEnabled();
return primaryMonitor.isCancelEnabled();
}
@Override
public void clearCanceled() {
dominantMonitor.clearCanceled();
slaveMonitor.clearCanceled();
primaryMonitor.clearCanceled();
secondaryMonitor.clearCanceled();
}
}

View File

@ -37,8 +37,7 @@ import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Program;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.Task;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.*;
class LoadPdbTask extends Task {
private File pdbFile;
@ -59,8 +58,15 @@ class LoadPdbTask extends Task {
@Override
public void run(final TaskMonitor monitor) {
final MessageLog log = new MessageLog();
WrappingTaskMonitor wrappedMonitor = new WrappingTaskMonitor(monitor) {
@Override
public void initialize(long max) {
// don't let called clients change our monitor type; we don't show progress
}
};
MessageLog log = new MessageLog();
AnalysisWorker worker = new AnalysisWorker() {
@Override
@ -74,11 +80,11 @@ class LoadPdbTask extends Task {
try {
if (useMsDiaParser) {
if (!parseWithMsDiaParser(log, monitor)) {
if (!parseWithMsDiaParser(log, wrappedMonitor)) {
return false;
}
}
else if (!parseWithNewParser(log, monitor)) {
else if (!parseWithNewParser(log, wrappedMonitor)) {
return false;
}
analyzeSymbols(currentMonitor, log);
@ -92,7 +98,7 @@ class LoadPdbTask extends Task {
try {
AutoAnalysisManager.getAnalysisManager(program)
.scheduleWorker(worker, null, true, monitor);
.scheduleWorker(worker, null, true, wrappedMonitor);
if (log.hasMessages()) {
MultiLineMessageDialog dialog = new MultiLineMessageDialog("Load PDB File",
"There were warnings/errors loading the PDB file.", log.toString(),

View File

@ -17,6 +17,8 @@ package pdb;
import java.io.File;
import javax.swing.SwingConstants;
import docking.action.MenuData;
import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser;
@ -36,6 +38,7 @@ import ghidra.program.util.GhidraProgramUtilities;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.filechooser.ExtensionFileFilter;
import ghidra.util.task.TaskBuilder;
import ghidra.util.task.TaskLauncher;
//@formatter:off
@ -134,8 +137,12 @@ public class PdbPlugin extends Plugin {
// note: We intentionally use a 0-delay here. Our underlying task may show modal
// dialog prompts. We want the task progress dialog to be showing before any
// promts appear.
// prompts appear.
LoadPdbTask task = new LoadPdbTask(program, pdb, useMsDiaParser, restrictions, service);
TaskBuilder.withTask(task)
.setStatusTextAlignment(SwingConstants.LEADING)
.setLaunchDelay(0);
new TaskLauncher(task, null, 0);
}
catch (Exception pe) {

View File

@ -33,37 +33,40 @@ import util.CollectionUtils;
* the {@link Task} interface, which means less boiler-plate code.
*
* <P>An example of usage:
* <pre>{@literal
* MonitoredRunnable r =
* monitor -> doWork(parameter, monitor);
* new TaskBuilder("Task Title", r)
* .setHasProgress(true)
* .setCanCancel(true)
* .setStatusTextAlignment(SwingConstants.LEADING)
* .launchModal();
* <pre>
* {@literal
* MonitoredRunnable r =
* monitor -> doWork(parameter, monitor);
*
* new TaskBuilder("Task Title", r)
* .setHasProgress(true)
* .setCanCancel(true)
* .setStatusTextAlignment(SwingConstants.LEADING)
* .launchModal();
* }</pre>
*
* Or,
*
* <pre>{@literal
* TaskBuilder.withRunnable(monitor -> doWork(parameter, monitor))
* .setTitle("Task Title")
* .setHasProgress(true)
* .setCanCancel(true)
* .setStatusTextAlignment(SwingConstants.LEADING)
* .launchModal();
* <pre>
* {@literal
* TaskBuilder.withRunnable(monitor -> doWork(parameter, monitor))
* .setTitle("Task Title")
* .setHasProgress(true)
* .setCanCancel(true)
* .setStatusTextAlignment(SwingConstants.LEADING)
* .launchModal();
* }</pre>
*
* Or,
*
* <pre>
* TaskBuilder.withTask(new AwesomeTask(awesomeStuff)).launchModal();
* TaskBuilder.withTask(new AwesomeTask(awesomeStuff)).launchModal();
* </pre>
*
* Or,
*
* <pre>
* {@link TaskLauncher#launch(Task) TaskLauncher.launch}(new AwesomeTask(awesomeStuff));
* {@link TaskLauncher#launch(Task) TaskLauncher.launch}(new AwesomeTask(awesomeStuff));
* </pre>
*
*

View File

@ -205,11 +205,26 @@ public class TaskDialog extends DialogComponentProvider implements TaskMonitor {
return userSaysYes;
}
private boolean isInstalled(Component c) {
Component[] components = mainPanel.getComponents();
for (Component component : components) {
if (c == component) {
return true;
}
}
return false;
}
/**
* Adds the panel that contains the progress bar to the dialog
*/
private void installProgressMonitor() {
Swing.runIfSwingOrRunLater(() -> {
if (isInstalled(monitorComponent)) {
return;
}
mainPanel.removeAll();
mainPanel.add(monitorComponent, BorderLayout.CENTER);
repack();
@ -222,6 +237,11 @@ public class TaskDialog extends DialogComponentProvider implements TaskMonitor {
*/
private void installActivityDisplay() {
Swing.runIfSwingOrRunLater(() -> {
if (isInstalled(activityPanel)) {
return;
}
mainPanel.removeAll();
mainPanel.add(activityPanel, BorderLayout.CENTER);
repack();