Fixed bug in Function Graph format chooser that made the minimal format

too large
This commit is contained in:
dragonmacher
2026-08-04 18:58:26 -04:00
parent ae024e2f20
commit 58e29550b0
7 changed files with 66 additions and 22 deletions

View File

@@ -16,6 +16,7 @@
package ghidra.app.util.viewer.format; package ghidra.app.util.viewer.format;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import org.jdom2.Element; import org.jdom2.Element;
@@ -283,6 +284,13 @@ public class FieldFormatModel {
} }
} }
@Override
public String toString() {
return name + ":\n" + Arrays.stream(factories)
.map(f -> f.getClass().getSimpleName())
.collect(Collectors.joining(",\n"));
}
/** /**
* Saves this format to XML. * Saves this format to XML.
* @return the XML element for the saved format * @return the XML element for the saved format
@@ -324,10 +332,11 @@ public class FieldFormatModel {
*/ */
public void restoreFromXml(Element root) { public void restoreFromXml(Element root) {
List<?> list = root.getChildren("ROW"); List<?> list = root.getChildren("ROW");
Iterator<?> rowIter = list.iterator(); Iterator<?> it = list.iterator();
rows = new ArrayList<>(list.size()); rows = new ArrayList<>();
while (rowIter.hasNext()) { while (it.hasNext()) {
Row row = createRow((Element) rowIter.next()); Element element = (Element) it.next();
Row row = createRow(element);
rows.add(row); rows.add(row);
} }
findWidth(); findWidth();
@@ -462,6 +471,7 @@ public class FieldFormatModel {
row.fieldOptionsChanged(options, optionName, oldValue, newValue); row.fieldOptionsChanged(options, optionName, oldValue, newValue);
} }
} }
//================================================================================================== //==================================================================================================
//Inner Classes //Inner Classes
//================================================================================================== //==================================================================================================
@@ -564,6 +574,8 @@ class Row {
@Override @Override
public String toString() { public String toString() {
return fields.toString(); return fields.stream()
.map(f -> f.getClass().getSimpleName())
.collect(Collectors.joining(","));
} }
} }

View File

@@ -116,7 +116,7 @@ public class FormatManager implements OptionsChangeListener {
FormatManager newManager = new FormatManager(displayOptions, fieldOptions); FormatManager newManager = new FormatManager(displayOptions, fieldOptions);
SaveState saveState = new SaveState(); SaveState saveState = new SaveState();
saveState(saveState); saveState(saveState);
newManager.readState(saveState); newManager.readState(saveState, false);
return newManager; return newManager;
} }
@@ -961,7 +961,10 @@ public class FormatManager implements OptionsChangeListener {
*/ */
public void saveState(SaveState saveState) { public void saveState(SaveState saveState) {
for (int i = 0; i < NUM_MODELS; i++) { for (int i = 0; i < NUM_MODELS; i++) {
saveState.putXmlElement(models[i].getName(), models[i].saveToXml()); FieldFormatModel model = models[i];
String name = model.getName();
Element element = model.saveToXml();
saveState.putXmlElement(name, element);
} }
} }
@@ -972,16 +975,30 @@ public class FormatManager implements OptionsChangeListener {
* @param saveState the SaveState to read from. * @param saveState the SaveState to read from.
*/ */
public void readState(SaveState saveState) { public void readState(SaveState saveState) {
readState(saveState, true);
}
// Note: only for clients that manage their own exact formats; remove when
// checkForMissingNewCriticalFields() gets removed
@Deprecated(since = "12.2", forRemoval = true)
public void readState(SaveState saveState, boolean checkForMissingFields) {
initialized = false; initialized = false;
for (int i = 0; i < NUM_MODELS; i++) { for (int i = 0; i < NUM_MODELS; i++) {
if (saveState.hasValue(models[i].getName())) { FieldFormatModel model = models[i];
models[i].restoreFromXml(saveState.getXmlElement(models[i].getName())); String name = model.getName();
// hack to make sure the new open/close variables field is present if (!saveState.hasValue(name)) {
// If missing, we are just going to reset it to the default format Element element = getDefaultModel(i);
checkForMissingNewCriticalFields(models[i]); model.restoreFromXml(element);
continue;
} }
else {
models[i].restoreFromXml(getDefaultModel(i)); Element element = saveState.getXmlElement(name);
model.restoreFromXml(element);
if (checkForMissingFields) {
// Hack to make sure the new open/close variables field is present. If missing, we
// are just going to reset it to the default format
checkForMissingNewCriticalFields(model);
} }
} }
initialized = true; initialized = true;
@@ -993,17 +1010,20 @@ public class FormatManager implements OptionsChangeListener {
private void checkForMissingNewCriticalFields(FieldFormatModel model) { private void checkForMissingNewCriticalFields(FieldFormatModel model) {
if (model.getName().equals("Variable")) { if (model.getName().equals("Variable")) {
if (!hasField(model, "+")) { if (!hasField(model, "+")) {
model.restoreFromXml(getDefaultVariableFormat()); Element element = getDefaultVariableFormat();
model.restoreFromXml(element);
} }
} }
if (model.getName().equals("Function")) { if (model.getName().equals("Function")) {
if (!hasField(model, "+")) { if (!hasField(model, "+")) {
model.restoreFromXml(getDefaultFunctionFormat()); Element element = getDefaultFunctionFormat();
model.restoreFromXml(element);
} }
} }
if (model.getName().equals("Address Break")) { if (model.getName().equals("Address Break")) {
if (!hasField(model, "Collapsed Code")) { if (!hasField(model, "Collapsed Code")) {
model.restoreFromXml(getDefaultDividerFormat()); Element element = getDefaultDividerFormat();
model.restoreFromXml(element);
} }
} }
} }

View File

@@ -177,7 +177,7 @@ public class ListingCodeComparisonView
private void changeRightToMatchLeftFormat(FieldFormatModel model) { private void changeRightToMatchLeftFormat(FieldFormatModel model) {
SaveState formatState = new SaveState(); SaveState formatState = new SaveState();
displays.get(LEFT).getFormatManager().saveState(formatState); displays.get(LEFT).getFormatManager().saveState(formatState);
displays.get(RIGHT).getFormatManager().readState(formatState); displays.get(RIGHT).getFormatManager().readState(formatState, false);
saveFormat(saveState); saveFormat(saveState);
tool.setConfigChanged(true); tool.setConfigChanged(true);

View File

@@ -259,7 +259,7 @@ public class FunctionGraphCodeComparisonView extends CodeComparisonView {
} }
FormatManager formatManager = new FormatManager(displayOptions, fieldOptions); FormatManager formatManager = new FormatManager(displayOptions, fieldOptions);
formatManager.readState(formatState); formatManager.readState(formatState, false);
leftController.updateMinimalFormatManager(formatManager); leftController.updateMinimalFormatManager(formatManager);
FgDisplay rightDisplay = displays.get(Side.RIGHT); FgDisplay rightDisplay = displays.get(Side.RIGHT);

View File

@@ -415,7 +415,7 @@ public class FunctionGraphPlugin extends ProgramPlugin
ToolOptions fieldOptions = options.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS); ToolOptions fieldOptions = options.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS);
userDefinedFormatManager = new FormatManager(displayOptions, fieldOptions); userDefinedFormatManager = new FormatManager(displayOptions, fieldOptions);
SaveState formatState = new SaveState(formatElement); SaveState formatState = new SaveState(formatElement);
userDefinedFormatManager.readState(formatState); userDefinedFormatManager.readState(formatState, false);
connectedProvider.formatChanged(); connectedProvider.formatChanged();
} }

View File

@@ -33,6 +33,8 @@ import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.util.Msg;
import ghidra.util.xml.XmlUtilities;
public class SetFormatDialogComponentProvider extends DialogComponentProvider { public class SetFormatDialogComponentProvider extends DialogComponentProvider {
@@ -164,7 +166,7 @@ public class SetFormatDialogComponentProvider extends DialogComponentProvider {
// update the dialog's GUI (which will later be used as the new format if the // update the dialog's GUI (which will later be used as the new format if the
// user presses OK) // user presses OK)
listingFormatManager.readState(saveState); listingFormatManager.readState(saveState, false);
} }
} }
@@ -189,6 +191,8 @@ public class SetFormatDialogComponentProvider extends DialogComponentProvider {
FieldFormatModel originalModel = defaultFormatManager.getModel(index); FieldFormatModel originalModel = defaultFormatManager.getModel(index);
Element originalXML = originalModel.saveToXml(); Element originalXML = originalModel.saveToXml();
Msg.debug(this, XmlUtilities.toString(originalXML));
// update the dialog's GUI (which will later be used as the new format if the // update the dialog's GUI (which will later be used as the new format if the
// user presses OK) // user presses OK)
FormatManager listingFormatManager = listingPanel.getFormatManager(); FormatManager listingFormatManager = listingPanel.getFormatManager();

View File

@@ -153,6 +153,14 @@ public class FGController implements ProgramLocationListener, ProgramSelectionLi
} }
/**
* The minimal format manager can also be called the 'user' format manager. We have a full
* format manager that the user cannot change. We also have a default format manager that the
* user cannot change. The minimal format manager can be updated by the user.
*
* <P>Even stranger, the minimal starts out as the default format.
* @return the minimal format
*/
public FormatManager getMinimalFormatManager() { public FormatManager getMinimalFormatManager() {
if (minimalFormatManager == null) { if (minimalFormatManager == null) {
setMinimalFormatManager(createMinimalFormatManager()); setMinimalFormatManager(createMinimalFormatManager());
@@ -173,7 +181,7 @@ public class FGController implements ProgramLocationListener, ProgramSelectionLi
SaveState saveState = new SaveState(); SaveState saveState = new SaveState();
newFormatManager.saveState(saveState); newFormatManager.saveState(saveState);
minimalFormatManager.readState(saveState); minimalFormatManager.readState(saveState, false);
env.setUserDefinedFormat(minimalFormatManager); env.setUserDefinedFormat(minimalFormatManager);
view.repaint(); view.repaint();
} }