GT-308 preserved graph satellite state between graph instantiations.

(also changed the timing for when preferences are loaded into the tool
so that they happen before plugins get initialized)
This commit is contained in:
ghidravore 2020-10-29 15:13:43 -04:00
parent 8dffa0384e
commit 490bc9ffa9
7 changed files with 46 additions and 21 deletions

View file

@ -202,6 +202,9 @@ public class DefaultGraphDisplay implements GraphDisplay {
componentProvider = new DefaultGraphDisplayComponentProvider(this, pluginTool);
componentProvider.addToTool();
satelliteViewer = createSatelliteViewer(viewer);
if (graphDisplayProvider.getDefaultSatelliteState()) {
viewer.getComponent().add(satelliteViewer.getComponent());
}
layoutTransitionManager =
new LayoutTransitionManager(viewer, this::isRoot);
@ -321,6 +324,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
new ToggleActionBuilder("SatelliteView", actionOwnerName).description("Show Satellite View")
.toolBarIcon(DefaultDisplayGraphIcons.SATELLITE_VIEW_ICON)
.onAction(this::toggleSatellite)
.selected(graphDisplayProvider.getDefaultSatelliteState())
.buildAndInstallLocal(componentProvider);
// create an icon button to reset the view transformations to identity (scaled to layout)
@ -576,7 +580,9 @@ public class DefaultGraphDisplay implements GraphDisplay {
* @param context information about the event
*/
private void toggleSatellite(ActionContext context) {
if (((AbstractButton) context.getSourceObject()).isSelected()) {
boolean selected = ((AbstractButton) context.getSourceObject()).isSelected();
graphDisplayProvider.setDefaultSatelliteState(selected);
if (selected) {
viewer.getComponent().add(satelliteViewer.getComponent());
}
else {
@ -770,7 +776,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
}
}
/**
* set the {@link AttributedGraph} for visualization
* @param attributedGraph the {@link AttributedGraph} to visualize
@ -1208,7 +1213,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
}
/**
* Use the hide selected action states to determine what vertices are shown:
* <ul>

View file

@ -19,6 +19,7 @@ import java.util.HashSet;
import java.util.Set;
import ghidra.framework.options.Options;
import ghidra.framework.options.PreferenceState;
import ghidra.framework.plugintool.PluginTool;
import ghidra.service.graph.GraphDisplay;
import ghidra.service.graph.GraphDisplayProvider;
@ -28,10 +29,14 @@ import ghidra.util.task.TaskMonitor;
public class DefaultGraphDisplayProvider implements GraphDisplayProvider {
private static final String PREFERENCES_KEY = "GRAPH_DISPLAY_SERVICE";
private static final String DEFAULT_SATELLITE_STATE = "DEFAULT_SATELLITE_STATE";
private final Set<DefaultGraphDisplay> displays = new HashSet<>();
private PluginTool pluginTool;
private Options options;
private int displayCounter = 1;
private boolean defaultSatelliteState;
private PreferenceState preferences;
@Override
public String getName() {
@ -66,6 +71,12 @@ public class DefaultGraphDisplayProvider implements GraphDisplayProvider {
public void initialize(PluginTool tool, Options graphOptions) {
this.pluginTool = tool;
this.options = graphOptions;
preferences = pluginTool.getWindowManager().getPreferenceState(PREFERENCES_KEY);
if (preferences == null) {
preferences = new PreferenceState();
pluginTool.getWindowManager().putPreferenceState(PREFERENCES_KEY, preferences);
}
defaultSatelliteState = preferences.getBoolean(DEFAULT_SATELLITE_STATE, false);
}
/**
@ -105,4 +116,14 @@ public class DefaultGraphDisplayProvider implements GraphDisplayProvider {
displays.remove(defaultGraphDisplay);
}
boolean getDefaultSatelliteState() {
return defaultSatelliteState;
}
void setDefaultSatelliteState(boolean b) {
defaultSatelliteState = b;
preferences.putBoolean(DEFAULT_SATELLITE_STATE, b);
}
}

View file

@ -931,17 +931,19 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
* @param rootXMLElement JDOM element from which to extract the state information.
*/
public void restoreFromXML(Element rootXMLElement) {
Element rootNodeElement = rootXMLElement.getChild(RootNode.ROOT_NODE_ELEMENT_NAME);
restoreWindowDataFromXml(rootNodeElement);
// load the tool preferences
restoreWindowDataFromXml(rootXMLElement);
restorePreferencesFromXML(rootXMLElement);
}
/**
* Restore to the docking window manager the layout and positioning information from XML.
* @param windowData The XML element containing the above information.
* @param rootXMLElement JDOM element from which to extract the state information.
*/
public void restoreWindowDataFromXml(Element windowData) {
public void restoreWindowDataFromXml(Element rootXMLElement) {
Element windowData = rootXMLElement.getChild(RootNode.ROOT_NODE_ELEMENT_NAME);
if (windowData == null) {
return;
}
//
// Clear our focus history, as we are changing placeholders' providers, so the old focus
// is no longer relevant.
@ -1576,7 +1578,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
return toolPreferencesElement;
}
private void restorePreferencesFromXML(Element rootElement) {
public void restorePreferencesFromXML(Element rootElement) {
Element toolPreferencesElement = rootElement.getChild(TOOL_PREFERENCES_XML_NAME);
if (toolPreferencesElement == null) {
return;

View file

@ -405,7 +405,7 @@ public abstract class PluginTool extends AbstractDockingTool {
"You cannot persist generic tools: " + getClass().getName());
}
public void restoreWindowingDataFromXml(Element windowData) {
public void restoreWindowingDataFromXml(Element element) {
throw new UnsupportedOperationException(
"You cannot persist generic tools: " + getClass().getName());
}
@ -555,6 +555,7 @@ public abstract class PluginTool extends AbstractDockingTool {
SplashScreen.updateSplashScreenStatus("Loading " + fullName + " ...");
restoreOptionsFromXml(root);
winMgr.restorePreferencesFromXML(root);
setDefaultOptionValues();
boolean hasErrors = false;
try {
@ -565,7 +566,7 @@ public abstract class PluginTool extends AbstractDockingTool {
Msg.showError(this, getToolFrame(), "Error Restoring Plugins", e.getMessage());
}
winMgr.restoreFromXML(root);
winMgr.restoreWindowDataFromXml(root);
winMgr.setToolName(fullName);
return hasErrors;
}

View file

@ -125,8 +125,8 @@ public class GhidraTool extends PluginTool {
}
@Override
public void restoreWindowingDataFromXml(Element windowData) {
winMgr.restoreWindowDataFromXml(windowData);
public void restoreWindowingDataFromXml(Element rootElement) {
winMgr.restoreWindowDataFromXml(rootElement);
}
@Override

View file

@ -166,8 +166,8 @@ class WorkspaceImpl implements Workspace {
Iterator<?> iter = root.getChildren("RUNNING_TOOL").iterator();
while (iter.hasNext()) {
Element elememnt = (Element) iter.next();
String toolName = elememnt.getAttributeValue(ToolTemplate.TOOL_NAME_XML_NAME);
Element element = (Element) iter.next();
String toolName = element.getAttributeValue(ToolTemplate.TOOL_NAME_XML_NAME);
if (toolName == null) {
continue;
}
@ -182,12 +182,9 @@ class WorkspaceImpl implements Workspace {
}
boolean hadChanges = tool.hasConfigChanged();
Element windowData = elememnt.getChild("ROOT_NODE");
if (windowData != null) { // backward compatibility
tool.restoreWindowingDataFromXml(windowData);
}
tool.restoreWindowingDataFromXml(element);
Element toolDataElem = elememnt.getChild("DATA_STATE");
Element toolDataElem = element.getChild("DATA_STATE");
tool.restoreDataStateFromXml(toolDataElem);
if (hadChanges) {
// restore the dirty state, which is cleared by the restoreDataState call

View file

@ -253,7 +253,7 @@ public class DummyTool extends PluginTool {
}
@Override
public void restoreWindowingDataFromXml(Element windowData) {
public void restoreWindowingDataFromXml(Element element) {
//do nothing
}