mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-875 - Hovers - Fixed how we choose locations to display the reference
hover window; added a formatted tooltip provider for function signatures; fixed a bug that prevented the reference hover from being correctly sized
This commit is contained in:
parent
1b0bd54560
commit
a9acf8bdf8
6 changed files with 429 additions and 53 deletions
|
@ -0,0 +1,92 @@
|
|||
/* ###
|
||||
* 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.codebrowser.hover;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToolTip;
|
||||
|
||||
import docking.widgets.fieldpanel.field.Field;
|
||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.plugin.core.hover.AbstractConfigurableHover;
|
||||
import ghidra.app.util.ToolTipUtils;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.*;
|
||||
|
||||
/**
|
||||
* A Listing hover to show tool tips for function signatures
|
||||
*/
|
||||
public class FunctionSignatureListingHover extends AbstractConfigurableHover
|
||||
implements ListingHoverService {
|
||||
|
||||
private static final String NAME = "Function Signature Display";
|
||||
private static final String DESCRIPTION =
|
||||
"Toggle whether function signature is displayed in a tooltip " +
|
||||
"when the mouse hovers over a function signature.";
|
||||
|
||||
// note: guilty knowledge that the Truncated Text service has a priority of 10
|
||||
private static final int POPUP_PRIORITY = 20;
|
||||
|
||||
public FunctionSignatureListingHover(PluginTool tool) {
|
||||
super(tool, POPUP_PRIORITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDescription() {
|
||||
return DESCRIPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getOptionsCategory() {
|
||||
return GhidraOptions.CATEGORY_BROWSER_POPUPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getHoverComponent(Program program, ProgramLocation programLocation,
|
||||
FieldLocation fieldLocation, Field field) {
|
||||
|
||||
if (!enabled || programLocation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<? extends ProgramLocation> clazz = programLocation.getClass();
|
||||
if (clazz != FunctionSignatureFieldLocation.class &&
|
||||
clazz != FunctionNameFieldLocation.class) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// is the label local to the function
|
||||
FunctionSignatureFieldLocation functionLocation =
|
||||
(FunctionSignatureFieldLocation) programLocation;
|
||||
|
||||
Address entry = functionLocation.getFunctionAddress();
|
||||
FunctionManager functionManager = program.getFunctionManager();
|
||||
Function function = functionManager.getFunctionAt(entry);
|
||||
|
||||
String toolTipText = ToolTipUtils.getToolTipText(function, true);
|
||||
JToolTip toolTip = new JToolTip();
|
||||
toolTip.setTipText(toolTipText);
|
||||
return toolTip;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 ghidra.app.plugin.core.codebrowser.hover;
|
||||
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
||||
/**
|
||||
* A plugin to show tool tip text for a function signature
|
||||
*/
|
||||
//@formatter:off
|
||||
@PluginInfo(
|
||||
status = PluginStatus.RELEASED,
|
||||
packageName = CorePluginPackage.NAME,
|
||||
category = PluginCategoryNames.CODE_VIEWER,
|
||||
shortDescription = "Shows formatted tool tip text over function signatures",
|
||||
description = "This plugin extends the functionality of the code browser by adding a "
|
||||
+ "\tooltip\" over function signaturefields in Listing.",
|
||||
servicesProvided = { ListingHoverService.class }
|
||||
)
|
||||
//@formatter:on
|
||||
public class FunctionSignatureListingHoverPlugin extends Plugin {
|
||||
|
||||
private FunctionSignatureListingHover functionSignatureHover;
|
||||
|
||||
public FunctionSignatureListingHoverPlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
functionSignatureHover = new FunctionSignatureListingHover(tool);
|
||||
registerServiceProvided(ListingHoverService.class, functionSignatureHover);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
functionSignatureHover.dispose();
|
||||
}
|
||||
}
|
|
@ -123,9 +123,9 @@ public class ProgramAddressRelationshipListingHover extends AbstractConfigurable
|
|||
return;
|
||||
}
|
||||
|
||||
String dataDescr = "Data Offset";
|
||||
String description = "Data Offset";
|
||||
if (data.getDataType() instanceof Structure) {
|
||||
dataDescr = "Structure Offset";
|
||||
description = "Structure Offset";
|
||||
}
|
||||
|
||||
String name = data.getLabel(); // prefer the label
|
||||
|
@ -133,12 +133,14 @@ public class ProgramAddressRelationshipListingHover extends AbstractConfigurable
|
|||
name = data.getDataType().getName();
|
||||
}
|
||||
|
||||
name = StringUtilities.trimMiddle(name, 60);
|
||||
|
||||
if (name == null) {
|
||||
// don't think we can get here
|
||||
name = italic("Unnamed");
|
||||
}
|
||||
|
||||
appendTableRow(sb, dataDescr, name, dataOffset);
|
||||
appendTableRow(sb, description, name, dataOffset);
|
||||
}
|
||||
|
||||
private void addByteSourceInfo(Program program, Address loc, StringBuilder sb) {
|
||||
|
@ -150,7 +152,8 @@ public class ProgramAddressRelationshipListingHover extends AbstractConfigurable
|
|||
if (addressSourceInfo.getFileName() == null) {
|
||||
return;
|
||||
}
|
||||
String filename = StringUtilities.trim(addressSourceInfo.getFileName(), MAX_FILENAME_SIZE);
|
||||
String filename =
|
||||
StringUtilities.trimMiddle(addressSourceInfo.getFileName(), MAX_FILENAME_SIZE);
|
||||
long fileOffset = addressSourceInfo.getFileOffset();
|
||||
String dataDescr = "Byte Source Offset";
|
||||
appendTableRow(sb, dataDescr, "File: " + filename, fileOffset);
|
||||
|
@ -160,7 +163,10 @@ public class ProgramAddressRelationshipListingHover extends AbstractConfigurable
|
|||
Function function = program.getFunctionManager().getFunctionContaining(loc);
|
||||
if (function != null) {
|
||||
long functionOffset = loc.subtract(function.getEntryPoint());
|
||||
appendTableRow(sb, "Function Offset", HTMLUtilities.escapeHTML(function.getName()),
|
||||
|
||||
String functionName = function.getName();
|
||||
functionName = StringUtilities.trimMiddle(functionName, 60);
|
||||
appendTableRow(sb, "Function Offset", HTMLUtilities.escapeHTML(functionName),
|
||||
functionOffset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,14 +91,15 @@ public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
|||
|
||||
String hoverName = getName();
|
||||
options.getOptions(hoverName).setOptionsHelpLocation(help);
|
||||
|
||||
options.registerOption(hoverName, true, null, getDescription());
|
||||
enabled = options.getBoolean(hoverName, true);
|
||||
|
||||
options.registerOption(hoverName + Options.DELIMITER + "Dialog Height", 400, help,
|
||||
"Height of the popup window");
|
||||
options.registerOption(hoverName + Options.DELIMITER + "Dialog Width", 600, help,
|
||||
"Width of the popup window");
|
||||
|
||||
setOptions(options, hoverName);
|
||||
options.addOptionsChangeListener(this);
|
||||
}
|
||||
|
||||
|
@ -152,10 +153,18 @@ public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
|||
return;
|
||||
}
|
||||
|
||||
toolTip = new JToolTip();
|
||||
|
||||
panel = new ListingPanel(codeFormatService.getFormatManager());// share the manager from the code viewer
|
||||
panel.setTextBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
toolTip = new JToolTip();
|
||||
String name = getName();
|
||||
String widthOptionName = name + Options.DELIMITER + "Dialog Width";
|
||||
String heightOptionName = name + Options.DELIMITER + "Dialog Height";
|
||||
int dialogWidth = options.getInt(widthOptionName, 600);
|
||||
int dialogHeight = options.getInt(heightOptionName, 400);
|
||||
Dimension d = new Dimension(dialogWidth, dialogHeight);
|
||||
panel.setPreferredSize(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
*/
|
||||
package ghidra.app.services;
|
||||
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import docking.widgets.fieldpanel.field.Field;
|
||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
|
||||
/**
|
||||
* <code>HoverService</code> provides the ability to popup data Windows over a Field viewer
|
||||
|
@ -30,7 +29,8 @@ import docking.widgets.fieldpanel.support.FieldLocation;
|
|||
public interface HoverService {
|
||||
|
||||
/**
|
||||
* Returns the priority of this hover service.
|
||||
* Returns the priority of this hover service. A lower priority is more important.
|
||||
* @return the priority
|
||||
*/
|
||||
public int getPriority();
|
||||
|
||||
|
@ -41,7 +41,8 @@ public interface HoverService {
|
|||
public void scroll(int amount);
|
||||
|
||||
/**
|
||||
* Return whether hover mode is "on."
|
||||
* Return whether hover mode is "on"
|
||||
* @return the priority
|
||||
*/
|
||||
public boolean hoverModeSelected();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue