GP-2308 - Function Call Graph - Added an option to disable name

truncation.
This commit is contained in:
dragonmacher 2025-04-05 12:37:45 -04:00
parent 8441563165
commit 8785636939
4 changed files with 82 additions and 20 deletions

View file

@ -28,6 +28,7 @@ import javax.swing.border.LineBorder;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import functioncalls.plugin.FcgOptions;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui; import generic.theme.Gui;
@ -94,6 +95,7 @@ public class FcgVertex extends AbstractVisualVertex implements VertexShapeProvid
private Paint outPaint; private Paint outPaint;
private FcgLevel level; private FcgLevel level;
private FcgOptions options;
/** /**
* Constructor * Constructor
@ -101,11 +103,13 @@ public class FcgVertex extends AbstractVisualVertex implements VertexShapeProvid
* @param function the function represented by this vertex * @param function the function represented by this vertex
* @param level the level of this vertex * @param level the level of this vertex
* @param expansionListener the listener for expanding connections to this vertex * @param expansionListener the listener for expanding connections to this vertex
* @param options the tool options
*/ */
public FcgVertex(Function function, FcgLevel level, public FcgVertex(Function function, FcgLevel level,
FcgVertexExpansionListener expansionListener) { FcgVertexExpansionListener expansionListener, FcgOptions options) {
this.function = function; this.function = function;
this.level = level; this.level = level;
this.options = options;
Objects.requireNonNull(expansionListener); Objects.requireNonNull(expansionListener);
toggleInsButton.addActionListener(e -> { toggleInsButton.addActionListener(e -> {
@ -154,8 +158,13 @@ public class FcgVertex extends AbstractVisualVertex implements VertexShapeProvid
createPaints(); createPaints();
// init the components // init the components
String truncated = StringUtilities.trimMiddle(getName(), MAX_NAME_LENGTH); boolean truncate = options.useTruncatedFunctionNames();
nameLabel.setText(truncated); String name = getName();
if (truncate) {
name = StringUtilities.trimMiddle(getName(), MAX_NAME_LENGTH);
}
nameLabel.setText(name);
buildVertexShape(); buildVertexShape();
// calculate the needed size // calculate the needed size

View file

@ -0,0 +1,51 @@
/* ###
* 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 functioncalls.plugin;
import ghidra.framework.options.Options;
import ghidra.graph.viewer.options.VisualGraphOptions;
import ghidra.util.HelpLocation;
public class FcgOptions extends VisualGraphOptions {
public static final String FUNCTION_NAME_TRUNCATION_KEY = "Truncate Function Name";
public static final String FUNCTDION_NAME_TRUNCTION_DESCRIPTION =
"Long function names will be truncated";
private boolean useTruncatedFunctionNames = true;
public boolean useTruncatedFunctionNames() {
return useTruncatedFunctionNames;
}
public void setUseTruncatedFunctionNames(boolean b) {
this.useTruncatedFunctionNames = b;
}
@Override
public void registerOptions(Options options, HelpLocation help) {
super.registerOptions(options, help);
options.registerOption(FUNCTION_NAME_TRUNCATION_KEY, useTruncatedFunctionNames(), help,
FUNCTDION_NAME_TRUNCTION_DESCRIPTION);
}
@Override
public void loadOptions(Options options) {
useTruncatedFunctionNames =
options.getBoolean(FUNCTION_NAME_TRUNCATION_KEY, useTruncatedFunctionNames);
}
}

View file

@ -240,7 +240,9 @@ public class FcgProvider
setLayout(graph); setLayout(graph);
FcgLevel source = FcgLevel.sourceLevel(); FcgLevel source = FcgLevel.sourceLevel();
FcgVertex sourceVertex = new FcgVertex(graphData.getFunction(), source, expansionListener); FcgOptions options = plugin.getOptions();
FcgVertex sourceVertex =
new FcgVertex(graphData.getFunction(), source, expansionListener, options);
graph.setSource(sourceVertex); graph.setSource(sourceVertex);
trackFunctionEdges(sourceVertex); trackFunctionEdges(sourceVertex);
@ -264,7 +266,8 @@ public class FcgProvider
return v; return v;
} }
v = new FcgVertex(f, level, expansionListener); FcgOptions options = plugin.getOptions();
v = new FcgVertex(f, level, expansionListener, options);
trackFunctionEdges(v); trackFunctionEdges(v);
return v; return v;
} }

View file

@ -26,11 +26,10 @@ import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginInfo; import ghidra.framework.plugintool.PluginInfo;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.graph.viewer.options.VisualGraphOptions;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.SystemUtilities; import ghidra.util.Swing;
import ghidra.util.bean.opteditor.OptionsVetoException; import ghidra.util.bean.opteditor.OptionsVetoException;
import ghidra.util.task.SwingUpdateManager; import ghidra.util.task.SwingUpdateManager;
@ -55,7 +54,7 @@ public class FunctionCallGraphPlugin extends ProgramPlugin implements OptionsCha
FunctionCallGraphPlugin.class.getSimpleName()); FunctionCallGraphPlugin.class.getSimpleName());
private FcgProvider provider; private FcgProvider provider;
private VisualGraphOptions vgOptions = new VisualGraphOptions(); private FcgOptions fcgOptions = new FcgOptions();
// enough time for users to click around without the graph starting its work // enough time for users to click around without the graph starting its work
private static final int MIN_UPDATE_DELAY = 750; private static final int MIN_UPDATE_DELAY = 750;
@ -83,8 +82,8 @@ public class FunctionCallGraphPlugin extends ProgramPlugin implements OptionsCha
HelpLocation help = new HelpLocation(getName(), "Options"); HelpLocation help = new HelpLocation(getName(), "Options");
Options callGraphOptions = options.getOptions(NAME); Options callGraphOptions = options.getOptions(NAME);
vgOptions.registerOptions(callGraphOptions, help); fcgOptions.registerOptions(callGraphOptions, help);
vgOptions.loadOptions(callGraphOptions); fcgOptions.loadOptions(callGraphOptions);
provider.optionsChanged(); provider.optionsChanged();
} }
@ -93,7 +92,7 @@ public class FunctionCallGraphPlugin extends ProgramPlugin implements OptionsCha
Object newValue) throws OptionsVetoException { Object newValue) throws OptionsVetoException {
Options callGraphOptions = options.getOptions(NAME); Options callGraphOptions = options.getOptions(NAME);
vgOptions.loadOptions(callGraphOptions); fcgOptions.loadOptions(callGraphOptions);
provider.optionsChanged(); provider.optionsChanged();
} }
@ -128,7 +127,7 @@ public class FunctionCallGraphPlugin extends ProgramPlugin implements OptionsCha
} }
// do later so the current event processing can finish // do later so the current event processing can finish
SystemUtilities.runSwingLater(() -> { Swing.runLater(() -> {
goTo.goTo(location); goTo.goTo(location);
}); });
} }
@ -168,7 +167,7 @@ public class FunctionCallGraphPlugin extends ProgramPlugin implements OptionsCha
return currentLocation; return currentLocation;
} }
VisualGraphOptions getOptions() { FcgOptions getOptions() {
return vgOptions; return fcgOptions;
} }
} }