GP-671: Opting to use sub-titles

This commit is contained in:
Dan 2021-02-08 15:08:14 -05:00
parent 991da5eb17
commit e8a73da383
7 changed files with 132 additions and 81 deletions

View File

@ -143,7 +143,7 @@ public interface DebuggerResources {
HelpLocation HELP_PROVIDER_BREAKPOINTS = new HelpLocation(
PluginUtils.getPluginNameFromClass(DebuggerBreakpointsPlugin.class), HELP_ANCHOR_PLUGIN);
String TITLE_PROVIDER_LISTING = "Listing";
String TITLE_PROVIDER_LISTING = "Dynamic";
ImageIcon ICON_PROVIDER_LISTING = ICON_LISTING;
HelpLocation HELP_PROVIDER_LISTING = new HelpLocation(
PluginUtils.getPluginNameFromClass(DebuggerListingPlugin.class), HELP_ANCHOR_PLUGIN);
@ -198,6 +198,8 @@ public interface DebuggerResources {
HelpLocation HELP_PROVIDER_WATCHES = new HelpLocation(
PluginUtils.getPluginNameFromClass(DebuggerWatchesPlugin.class), HELP_ANCHOR_PLUGIN);
String TITLE_PROVIDER_INTERPRETER = "Interpreter";
String BOOKMARK_CATEGORY_MEMORY_READ_ERROR = "Debugger Memory Read Error";
String OPTION_NAME_COLORS_STALE_MEMORY = "Colors.Stale Memory";

View File

@ -28,6 +28,7 @@ import docking.action.ToggleDockingAction;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.PinInterpreterAction;
import ghidra.app.plugin.core.interpreter.InterpreterComponentProvider;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.dbg.target.TargetConsole.Channel;
import ghidra.dbg.target.TargetConsole.TargetConsoleListener;
@ -35,6 +36,7 @@ import ghidra.dbg.target.TargetInterpreter;
import ghidra.dbg.target.TargetInterpreter.TargetInterpreterListener;
import ghidra.dbg.target.TargetObject;
import ghidra.util.Msg;
import ghidra.util.Swing;
public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetObject>
implements DebuggerInterpreterConnection {
@ -71,26 +73,29 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
@Override
public void displayChanged(TargetObject object, String display) {
// TODO: Would rather update the sub-title
guiConsole.updateTitle();
// TODO: Add setSubTitle(String) to InterpreterConsole
InterpreterComponentProvider provider = (InterpreterComponentProvider) guiConsole;
Swing.runLater(() -> provider.setSubTitle(display));
}
@Override
public void promptChanged(TargetInterpreter<?> i, String prompt) {
guiConsole.setPrompt(prompt);
Swing.runLater(() -> guiConsole.setPrompt(prompt));
}
@Override
public void invalidated(TargetObject object, String reason) {
if (object == targetConsole) { // Redundant
if (pinned) {
running.set(false);
plugin.disableConsole(targetConsole, guiConsole);
Swing.runLater(() -> {
if (object == targetConsole) { // Redundant
if (pinned) {
running.set(false);
plugin.disableConsole(targetConsole, guiConsole);
}
else {
plugin.destroyConsole(targetConsole, guiConsole);
}
}
else {
plugin.destroyConsole(targetConsole, guiConsole);
}
}
});
}
}
@ -108,9 +113,6 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
protected ToggleDockingAction actionPin;
protected boolean pinned = false;
// TODO: Fix InterpreterPanelService to take plugin name instead of just using title
protected boolean firstTimeAskedTitle = true;
public AbstractDebuggerWrappedConsoleConnection(DebuggerInterpreterPlugin plugin,
T targetConsole) {
this.plugin = plugin;
@ -122,12 +124,7 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
@Override
public String getTitle() {
// This is kruft. Would be better to have control of the sub-title.
if (firstTimeAskedTitle) {
firstTimeAskedTitle = false;
return plugin.getName();
}
return targetConsole.getDisplay();
return DebuggerResources.TITLE_PROVIDER_INTERPRETER;
}
@Override
@ -145,6 +142,10 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
public void setConsole(InterpreterConsole guiConsole) {
assert this.guiConsole == null;
this.guiConsole = guiConsole;
InterpreterComponentProvider provider = (InterpreterComponentProvider) guiConsole;
provider.setSubTitle(targetConsole.getDisplay());
setErrWriter(guiConsole.getErrWriter());
setOutWriter(guiConsole.getOutWriter());
setStdIn(guiConsole.getStdin());

View File

@ -23,8 +23,7 @@ import javax.swing.SwingUtilities;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.debug.AbstractDebuggerPlugin;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.app.plugin.core.interpreter.InterpreterPanelService;
import ghidra.app.plugin.core.interpreter.*;
import ghidra.app.services.DebuggerInterpreterService;
import ghidra.dbg.target.*;
import ghidra.framework.plugintool.PluginInfo;
@ -33,17 +32,17 @@ import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.framework.plugintool.util.PluginStatus;
@PluginInfo( //
shortDescription = "Debugger interpreter panel service", //
description = "Manage interpreter panels within debug sessions", //
category = PluginCategoryNames.DEBUGGER, //
packageName = DebuggerPluginPackage.NAME, //
status = PluginStatus.RELEASED, //
servicesRequired = { //
InterpreterPanelService.class //
}, //
servicesProvided = {
DebuggerInterpreterService.class //
} //
shortDescription = "Debugger interpreter panel service", //
description = "Manage interpreter panels within debug sessions", //
category = PluginCategoryNames.DEBUGGER, //
packageName = DebuggerPluginPackage.NAME, //
status = PluginStatus.RELEASED, //
servicesRequired = { //
InterpreterPanelService.class //
}, //
servicesProvided = {
DebuggerInterpreterService.class //
} //
)
public class DebuggerInterpreterPlugin extends AbstractDebuggerPlugin
implements DebuggerInterpreterService {
@ -94,7 +93,10 @@ public class DebuggerInterpreterPlugin extends AbstractDebuggerPlugin
}
protected void createConsole(AbstractDebuggerWrappedConsoleConnection<?> connection) {
InterpreterConsole console = consoleService.createInterpreterPanel(connection, true);
//InterpreterConsole console = consoleService.createInterpreterPanel(connection, true);
// TODO: Just fix the console plugin
InterpreterConsole console = new DebuggerInterpreterProvider(
(InterpreterPanelPlugin) consoleService, connection, true);
connection.setConsole(console);
connection.runInBackground();
}

View File

@ -0,0 +1,42 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.debug.gui.interpreters;
import ghidra.app.plugin.core.interpreter.*;
public class DebuggerInterpreterProvider extends InterpreterComponentProvider {
// If only ComponentProvider#subTitle weren't private
// Really, if only InterpreterComponentProvider#getSubTitle weren't overridden
// TODO: Have it just call setSubTitle in its constructor
protected String subTitle;
public DebuggerInterpreterProvider(InterpreterPanelPlugin plugin,
InterpreterConnection interpreter, boolean visible) {
super(plugin, interpreter, visible);
}
@Override
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
super.setSubTitle(subTitle);
}
@Override
public String getSubTitle() {
return subTitle;
}
}

View File

@ -15,7 +15,8 @@
*/
package ghidra.app.plugin.core.debug.gui.listing;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.ICON_REGISTER_MARKER;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.OPTION_NAME_COLORS_REGISTER_MARKERS;
import java.awt.Color;
import java.io.File;
@ -29,6 +30,7 @@ import javax.swing.JLabel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.commons.lang3.StringUtils;
import org.jdom.Element;
import docking.ActionContext;
@ -416,7 +418,13 @@ public class DebuggerListingProvider extends CodeViewerProvider implements Listi
addListingDisplayListener(this);
this.setNorthComponent(locationLabel);
updateTitle();
if (isConnected) {
setTitle(DebuggerResources.TITLE_PROVIDER_LISTING);
}
else {
setTitle("[" + DebuggerResources.TITLE_PROVIDER_LISTING + "]");
}
updateTitle(); // Actually, the subtitle
setHelpLocation(DebuggerResources.HELP_PROVIDER_LISTING);
}
@ -630,28 +638,25 @@ public class DebuggerListingProvider extends CodeViewerProvider implements Listi
}
}
protected String computeTitle() {
protected String computeSubTitle() {
TraceProgramView view = current.getView();
String prefix = trackingSpec == null ? "Dynamic" : trackingSpec.computeTitle(current);
if (prefix == null) {
prefix = "Dynamic";
List<String> parts = new ArrayList<>();
if (trackingSpec != null) {
String specTitle = trackingSpec.computeTitle(current);
if (specTitle != null) {
parts.add(specTitle);
}
}
String title;
if (view == null) {
title = prefix;
if (view != null) {
parts.add(current.getTrace().getDomainFile().getName());
}
else {
title = prefix + ": " + current.getTrace().getDomainFile().getName();
}
if (followsCurrentThread) {
return title;
}
return "[" + title + "]";
return StringUtils.join(parts, ", ");
}
@Override
// TODO: Once refactored, this is not part of the abstract impl.
@Override // Since we want to override, we can't rename updateSubTitle
protected void updateTitle() {
setTitle(computeTitle());
setSubTitle(computeSubTitle());
}
protected TraceSection getSmallestSectionAt(Address address) {

View File

@ -378,21 +378,25 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
@SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring;
@AutoOptionDefined(name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_STALE, //
description = "Text color for registers whose value is not known", //
help = @HelpInfo(anchor = "colors"))
@AutoOptionDefined(
name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_STALE, //
description = "Text color for registers whose value is not known", //
help = @HelpInfo(anchor = "colors"))
protected Color registerStaleColor = DebuggerResources.DEFAULT_COLOR_REGISTER_STALE;
@AutoOptionDefined(name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_STALE_SEL, //
description = "Selected text color for registers whose value is not known", //
help = @HelpInfo(anchor = "colors"))
@AutoOptionDefined(
name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_STALE_SEL, //
description = "Selected text color for registers whose value is not known", //
help = @HelpInfo(anchor = "colors"))
protected Color registerStaleSelColor = DebuggerResources.DEFAULT_COLOR_REGISTER_STALE_SEL;
@AutoOptionDefined(name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_CHANGED, //
description = "Text color for registers whose value just changed", //
help = @HelpInfo(anchor = "colors"))
@AutoOptionDefined(
name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_CHANGED, //
description = "Text color for registers whose value just changed", //
help = @HelpInfo(anchor = "colors"))
protected Color registerChangesColor = DebuggerResources.DEFAULT_COLOR_REGISTER_CHANGED;
@AutoOptionDefined(name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_CHANGED_SEL, //
description = "Selected text color for registers whose value just changed", //
help = @HelpInfo(anchor = "colors"))
@AutoOptionDefined(
name = DebuggerResources.OPTION_NAME_COLORS_REGISTER_CHANGED_SEL, //
description = "Selected text color for registers whose value just changed", //
help = @HelpInfo(anchor = "colors"))
protected Color registerChangesSelColor = DebuggerResources.DEFAULT_COLOR_REGISTER_CHANGED_SEL;
@SuppressWarnings("unused")
@ -638,18 +642,13 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
return isClone;
}
protected String computeTitle() {
protected String computeSubTitle() {
TraceThread curThread = current.getThread();
String threadPart = curThread == null ? "" : (": " + curThread.getName());
if (isClone) {
return "[" + DebuggerResources.TITLE_PROVIDER_REGISTERS + threadPart + ", " +
current.getSnap() + "]";
}
return DebuggerResources.TITLE_PROVIDER_REGISTERS + threadPart;
return curThread == null ? "" : curThread.getName();
}
protected void updateTitle() {
setTitle(computeTitle());
protected void updateSubTitle() {
setSubTitle(computeSubTitle());
}
private void removeOldTraceListener() {
@ -711,7 +710,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
readTheseCoords = false;
doSetTrace(current.getTrace());
doSetRecorder(current.getRecorder());
updateTitle();
updateSubTitle();
loadRegistersAndValues();
contextChanged();

View File

@ -218,6 +218,7 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
this.autoServiceWiring = AutoService.wireServicesConsumed(plugin, this);
setTitle(DebuggerResources.TITLE_PROVIDER_STACK);
setIcon(DebuggerResources.ICON_PROVIDER_STACK);
setHelpLocation(DebuggerResources.HELP_PROVIDER_STACK);
setWindowMenuGroup(DebuggerPluginPackage.NAME);
@ -394,14 +395,13 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
selectCurrentFrame();
}
protected String computeTitle() {
protected String computeSubTitle() {
TraceThread curThread = current.getThread();
String threadPart = curThread == null ? "" : (": " + curThread.getName());
return DebuggerResources.TITLE_PROVIDER_STACK + threadPart;
return curThread == null ? "" : curThread.getName();
}
protected void updateTitle() {
setTitle(computeTitle());
protected void updateSubTitle() {
setSubTitle(computeSubTitle());
}
private void removeOldListeners() {
@ -437,7 +437,7 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
doSetTrace(current.getTrace());
loadStack();
updateTitle();
updateSubTitle();
}
protected void selectCurrentFrame() {