mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Updated the Quick Edit Field to fix the menu name and to fix a data type
edit bug
This commit is contained in:
@@ -972,7 +972,7 @@
|
|||||||
<OL>
|
<OL>
|
||||||
<LI>Right mouse click on a structure member in the Listing</LI>
|
<LI>Right mouse click on a structure member in the Listing</LI>
|
||||||
|
|
||||||
<LI>Choose the <B>Data</B><IMG src="help/shared/arrow.gif"> <B>Quick Edit Field</B>
|
<LI>Choose the <B>Data</B><IMG src="help/shared/arrow.gif"> <B>Edit Field...</B>
|
||||||
action to bring the up the <A href=
|
action to bring the up the <A href=
|
||||||
"#Edit_Field_Dialog">Edit Field Dialog</A> </LI>
|
"#Edit_Field_Dialog">Edit Field Dialog</A> </LI>
|
||||||
|
|
||||||
@@ -1370,8 +1370,8 @@
|
|||||||
<P>As a convenience, a structure or union field can be edited directly from the listing without
|
<P>As a convenience, a structure or union field can be edited directly from the listing without
|
||||||
bringing up the entire structure or union editor. To edit a field, click anywhere on the line
|
bringing up the entire structure or union editor. To edit a field, click anywhere on the line
|
||||||
displaying that field in the listing and then right click and select <B>Data</B><IMG
|
displaying that field in the listing and then right click and select <B>Data</B><IMG
|
||||||
src="help/shared/arrow.gif"> <B>Edit Field</B> from the popup context menu.</P>
|
src="help/shared/arrow.gif"> <B>Edit Field...</B> from the popup context menu.</P>
|
||||||
<H3><A name="Edit_Field_Dialog"></A><A name="Quick_Edit_Field"></A>Edit Field Dialog</H3>
|
<H3><A name="Edit_Field_Dialog"></A>Edit Field Dialog</H3>
|
||||||
<P align="center"><IMG src="images/EditFieldDialog.png" alt=""> </P>
|
<P align="center"><IMG src="images/EditFieldDialog.png" alt=""> </P>
|
||||||
<UL>
|
<UL>
|
||||||
<LI><B>Field Name</B>: The name of the structure or union field can be changed here.</LI>
|
<LI><B>Field Name</B>: The name of the structure or union field can be changed here.</LI>
|
||||||
|
|||||||
@@ -146,9 +146,9 @@ public class DataPlugin extends Plugin implements DataService {
|
|||||||
pointerAction = new PointerDataAction(this);
|
pointerAction = new PointerDataAction(this);
|
||||||
tool.addAction(pointerAction);
|
tool.addAction(pointerAction);
|
||||||
|
|
||||||
new ActionBuilder("Quick Edit Field", getName())
|
new ActionBuilder("Edit Field", getName())
|
||||||
.helpLocation(new HelpLocation("DataPlugin", "Quick_Edit_Field"))
|
.helpLocation(new HelpLocation("DataPlugin", "Quick_Edit_Field"))
|
||||||
.popupMenuPath("Data", "Quick Edit Field...")
|
.popupMenuPath("Data", "Edit Field...")
|
||||||
.popupMenuGroup("BasicData")
|
.popupMenuGroup("BasicData")
|
||||||
.keyBinding("ctrl shift E")
|
.keyBinding("ctrl shift E")
|
||||||
.sharedKeyBinding()
|
.sharedKeyBinding()
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
private JCheckBox dateCheckBox;
|
private JCheckBox dateCheckBox;
|
||||||
|
|
||||||
private PluginTool tool;
|
private PluginTool tool;
|
||||||
private DataType newDataType;
|
|
||||||
private DataTypeManagerService dtmService;
|
private DataTypeManagerService dtmService;
|
||||||
|
|
||||||
private Composite composite;
|
private Composite composite;
|
||||||
@@ -108,6 +107,7 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
* @return the pending new datatype to change to
|
* @return the pending new datatype to change to
|
||||||
*/
|
*/
|
||||||
public DataType getNewDataType() {
|
public DataType getNewDataType() {
|
||||||
|
DataType newDataType = dataTypeEditor.getCellEditorValueAsDataType();
|
||||||
return newDataType != null ? newDataType : new Undefined1DataType();
|
return newDataType != null ? newDataType : new Undefined1DataType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,8 +149,7 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
* @param dataType the new pending datatype
|
* @param dataType the new pending datatype
|
||||||
*/
|
*/
|
||||||
public void setDataType(DataType dataType) {
|
public void setDataType(DataType dataType) {
|
||||||
newDataType = dataType;
|
dataTypeEditor.setCellEditorValue(dataType);
|
||||||
updateDataTypeTextField();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeFields() {
|
private void initializeFields() {
|
||||||
@@ -247,7 +246,8 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
|
|
||||||
boolean hasDataTypeChange() {
|
boolean hasDataTypeChange() {
|
||||||
DataType oldDt = getComponentDataType();
|
DataType oldDt = getComponentDataType();
|
||||||
return newDataType != null && !newDataType.equals(oldDt);
|
DataType newDt = dataTypeEditor.getCellEditorValueAsDataType();
|
||||||
|
return newDt != null && !newDt.equals(oldDt);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasNameChange() {
|
boolean hasNameChange() {
|
||||||
@@ -321,16 +321,6 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDataTypeTextField() {
|
|
||||||
if (newDataType != null) {
|
|
||||||
dataTypeEditor.setCellEditorValue(newDataType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DataType dt = getComponentDataType();
|
|
||||||
dataTypeEditor.setCellEditorValue(dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateTitle() {
|
private String generateTitle() {
|
||||||
String compositeName = composite.getName();
|
String compositeName = composite.getName();
|
||||||
return "Edit " + compositeName + ", Field " + ordinal;
|
return "Edit " + compositeName + ", Field " + ordinal;
|
||||||
@@ -394,6 +384,10 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
return dataTypeEditor.getCellEditorValueAsText();
|
return dataTypeEditor.getCellEditorValueAsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataTypeSelectionEditor getDataTypeEditor() {
|
||||||
|
return dataTypeEditor;
|
||||||
|
}
|
||||||
|
|
||||||
private class UpdateDataComponentCommand implements Command<Program> {
|
private class UpdateDataComponentCommand implements Command<Program> {
|
||||||
private String statusMessage = null;
|
private String statusMessage = null;
|
||||||
|
|
||||||
@@ -420,17 +414,43 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
growStructureAsNeeded(struct);
|
||||||
|
ensureDataTypeComponentRecordExists(struct);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void growStructureAsNeeded(Structure struct) {
|
||||||
|
// This should not happen when editing from the Listing, since you must click on a valid
|
||||||
|
// ordinal to start an edit. It is not clear if the Decompiler has a use case where
|
||||||
|
// this can happen.
|
||||||
int n = composite.getNumComponents();
|
int n = composite.getNumComponents();
|
||||||
if (ordinal >= n) {
|
if (ordinal >= n) {
|
||||||
int amount = ordinal - n;
|
int amount = ordinal - n;
|
||||||
struct.growStructure(amount);
|
struct.growStructure(amount);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureDataTypeComponentRecordExists(Structure struct) {
|
||||||
DataTypeComponent dtc = composite.getComponent(ordinal);
|
DataTypeComponent dtc = composite.getComponent(ordinal);
|
||||||
if (dtc.getDataType() == DataType.DEFAULT) { // remove placeholder type
|
if (dtc.getDataType() != DataType.DEFAULT) {
|
||||||
DataType newtype = new Undefined1DataType();
|
return; // the record exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default type does not have a record for the data type component. We need to
|
||||||
|
// replace that default type with a type that will force a record to be get created.
|
||||||
|
// We need a record to exist in order to set a comment or name.
|
||||||
|
DataType newtype = new Undefined1DataType();
|
||||||
|
DataTypeComponent newDtc =
|
||||||
struct.replaceAtOffset(dtc.getOffset(), newtype, 1, "tempName",
|
struct.replaceAtOffset(dtc.getOffset(), newtype, 1, "tempName",
|
||||||
"Created by Edit Data Field action");
|
"Created by Edit Data Field action");
|
||||||
|
|
||||||
|
DataType oldDt = dtc.getDataType();
|
||||||
|
DataType editorDt = dataTypeEditor.getCellEditorValueAsDataType();
|
||||||
|
if (oldDt.equals(editorDt)) {
|
||||||
|
// If the user has changed the type, we want to keep that change. Otherwise, the
|
||||||
|
// editor should always track what is in the structure so we know if the user has
|
||||||
|
// made a change to the data type. When the user changes the type, we need to apply
|
||||||
|
// that change.
|
||||||
|
dataTypeEditor.setCellEditorValue(newDtc.getDataType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,8 +504,9 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateStructure(Structure struct) {
|
private void updateStructure(Structure struct) {
|
||||||
|
DataType newDt = dataTypeEditor.getCellEditorValueAsDataType();
|
||||||
DataTypeComponent dtc = composite.getComponent(ordinal);
|
DataTypeComponent dtc = composite.getComponent(ordinal);
|
||||||
DataType resolvedDt = program.getDataTypeManager().resolve(newDataType, null);
|
DataType resolvedDt = program.getDataTypeManager().resolve(newDt, null);
|
||||||
if (resolvedDt == DataType.DEFAULT) {
|
if (resolvedDt == DataType.DEFAULT) {
|
||||||
struct.clearComponent(ordinal);
|
struct.clearComponent(ordinal);
|
||||||
return;
|
return;
|
||||||
@@ -501,8 +522,9 @@ public class EditDataFieldDialog extends DialogComponentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateUnion(Union union) throws DuplicateNameException {
|
private void updateUnion(Union union) throws DuplicateNameException {
|
||||||
|
DataType newDt = dataTypeEditor.getCellEditorValueAsDataType();
|
||||||
DataTypeComponent dtc = composite.getComponent(ordinal);
|
DataTypeComponent dtc = composite.getComponent(ordinal);
|
||||||
DataType resolvedDt = program.getDataTypeManager().resolve(newDataType, null);
|
DataType resolvedDt = program.getDataTypeManager().resolve(newDt, null);
|
||||||
String comment = dtc.getComment();
|
String comment = dtc.getComment();
|
||||||
String fieldName = dtc.getFieldName();
|
String fieldName = dtc.getFieldName();
|
||||||
union.insert(ordinal, resolvedDt);
|
union.insert(ordinal, resolvedDt);
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ import java.util.Date;
|
|||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
|
import docking.widgets.DropDownSelectionTextField;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
|
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
@@ -188,6 +190,22 @@ public class EditFieldDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
assertEquals("byte", structure.getComponent(1).getDataType().getDisplayName());
|
assertEquals("byte", structure.getComponent(1).getDataType().getDisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEditUndefinedDataType_ByTypingText() {
|
||||||
|
goTo(0x101);
|
||||||
|
showFieldEditDialog();
|
||||||
|
assertNull(structure.getComponent(1).getComment());
|
||||||
|
assertEquals("undefined", getDataTypeText());
|
||||||
|
|
||||||
|
DataTypeSelectionEditor editor = dialog.getDataTypeEditor();
|
||||||
|
DropDownSelectionTextField<DataType> textField = editor.getDropDownTextField();
|
||||||
|
setText(textField, "byte");
|
||||||
|
|
||||||
|
pressOk();
|
||||||
|
waitForTasks();
|
||||||
|
assertEquals("byte", structure.getComponent(1).getDataType().getDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddAddressCheckbox() {
|
public void testAddAddressCheckbox() {
|
||||||
goTo(0x101);
|
goTo(0x101);
|
||||||
|
|||||||
Reference in New Issue
Block a user