Merge remote-tracking branch 'origin/GP-1398-dragonmacher-function-editor-cancel--SQUASHED'

This commit is contained in:
Ryan Kurtz 2021-10-15 07:54:48 -04:00
commit d595352e71
5 changed files with 120 additions and 107 deletions

View file

@ -368,7 +368,7 @@ public class FunctionEditorModel {
private boolean isValidParamType(ParamInfo param) {
DataType dataType = param.getDataType();
if (dataType.isEquivalent(DataType.VOID)) {
if (dataType.isEquivalent(VoidDataType.dataType)) {
statusText = "\"void\" is not allowed as a parameter datatype.";
return false;
}
@ -440,8 +440,8 @@ public class FunctionEditorModel {
return returnInfo.getFormalDataType();
}
public void setFormalReturnType(DataType formalReturnType) {
setParameterFormalDataType(returnInfo, formalReturnType);
public boolean setFormalReturnType(DataType formalReturnType) {
return setParameterFormalDataType(returnInfo, formalReturnType);
}
public String getStatusText() {
@ -775,18 +775,20 @@ public class FunctionEditorModel {
notifyDataChanged();
}
public void setParameterFormalDataType(ParamInfo param, DataType formalDataType) {
public boolean setParameterFormalDataType(ParamInfo param, DataType formalDataType) {
boolean isReturn = (param.getOrdinal() == Parameter.RETURN_ORIDINAL);
try {
formalDataType = VariableUtilities.checkDataType(formalDataType, isReturn, 0, program);
}
catch (InvalidInputException e) {
Msg.showError(this, null, "Invalid Data Type", e.getMessage());
return;
return false;
}
if (formalDataType.equals(param.getFormalDataType())) {
return;
return true;
}
param.setFormalDataType(formalDataType.clone(program.getDataTypeManager()));
if (allowCustomStorage) {
if (isReturn && (formalDataType instanceof VoidDataType)) {
@ -808,6 +810,7 @@ public class FunctionEditorModel {
updateParameterAndReturnStorage();
}
notifyDataChanged();
return true;
}
private void adjustStorageSize(ParamInfo param, VariableStorage curStorage, int newSize) {
@ -1180,7 +1183,7 @@ public class FunctionEditorModel {
/**
* Sets the change state of the model. Normally, the model sets the modelChanged variable to true
* every time something is changed. This provides a way to for applications to make some initial changes
* but make the dialog think that nothing has changed.
* but make the dialog think that nothing has changed.
* @param b the new changeState for this model
*/
public void setModelChanged(boolean b) {

View file

@ -25,7 +25,7 @@ interface FunctionVariableData {
public void setName(String name);
public void setFormalDataType(DataType dataType);
public boolean setFormalDataType(DataType dataType);
public VariableStorage getStorage();

View file

@ -109,6 +109,14 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
fireTableDataChanged();
}
public void setAllowStorageEditing(boolean canCustomizeStorage) {
this.canCustomizeStorage = canCustomizeStorage;
}
//==================================================================================================
// Inner Classes
//==================================================================================================
private abstract class ParamCol {
private String name;
private boolean isEditable;
@ -229,11 +237,7 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
}
}
public void setAllowStorageEditing(boolean canCustomizeStorage) {
this.canCustomizeStorage = canCustomizeStorage;
}
class ParameterRowData implements FunctionVariableData {
private class ParameterRowData implements FunctionVariableData {
private ParamInfo param;
ParameterRowData(ParamInfo paramInfo) {
@ -265,8 +269,8 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
}
@Override
public void setFormalDataType(DataType dataType) {
functionModel.setParameterFormalDataType(param, dataType);
public boolean setFormalDataType(DataType dataType) {
return functionModel.setParameterFormalDataType(param, dataType);
}
@Override
@ -280,7 +284,7 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
}
}
class ReturnRowData implements FunctionVariableData {
private class ReturnRowData implements FunctionVariableData {
private DataType formalDataType;
private VariableStorage storage;
@ -310,8 +314,8 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
}
@Override
public void setFormalDataType(DataType dataType) {
functionModel.setFormalReturnType(dataType);
public boolean setFormalDataType(DataType dataType) {
return functionModel.setFormalReturnType(dataType);
}
@Override
@ -321,8 +325,7 @@ class ParameterTableModel extends AbstractGTableModel<FunctionVariableData> {
@Override
public void setName(String name) {
// TODO Auto-generated method stub
// no name for return type
}
}
}

View file

@ -19,6 +19,7 @@ import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.event.*;
@ -41,9 +42,7 @@ import ghidra.util.layout.VerticalLayout;
public class StorageAddressEditorDialog extends DialogComponentProvider
implements ModelChangeListener {
private FunctionVariableData variableData;
private StorageAddressModel model;
private VarnodeTableModel varnodeTableModel;
private ParameterDataTypeCellEditor dataTypeEditor;
private GTable varnodeTable;
private ListSelectionListener selectionListener;
@ -52,23 +51,34 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
private JButton removeButton;
private JButton upButton;
private JButton downButton;
private int size;
private JLabel currentSizeLabel;
private FunctionVariableData variableData;
private StorageAddressModel model;
private VarnodeTableModel varnodeTableModel;
private int size;
private boolean cancelled = true;
private boolean adjustingDataType = false;
private DataType previousDataType;
private DataType currentDataType;
/**
* Constructor
* @param program
* @param service
* @param storage
* @param variableData
* @param program the program
* @param service the data type manager service
* @param storage the variable storage
* @param variableData the variable data
*/
public StorageAddressEditorDialog(Program program, DataTypeManagerService service,
VariableStorage storage, FunctionVariableData variableData) {
super("Storage Address Editor");
this.variableData = variableData;
model = new StorageAddressModel(program, storage, this);
setDataType(variableData.getFormalDataType());
currentDataType = variableData.getFormalDataType();
previousDataType = currentDataType;
setDataType(currentDataType);
setHelpLocation(new HelpLocation("FunctionPlugin", "Edit_Parameter_Storage"));
addWorkPanel(buildMainPanel(service));
addOKButton();
@ -78,50 +88,14 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
/**
* Read-only use constructor for Help screenshot
* @param program
* @param service
* @param program the program
* @param service the data type manager service
* @param var function parameter to be displayed in editor dialog
* @param ordinal parameter ordinal (-1 for return)
*/
public StorageAddressEditorDialog(Program program, DataTypeManagerService service,
final Variable var, final int ordinal) {
this(program, service, var.getVariableStorage(), new FunctionVariableData() {
@Override
public void setStorage(VariableStorage storage) {
// unsupported
}
@Override
public void setName(String name) {
// unsupported
}
@Override
public void setFormalDataType(DataType dataType) {
// unsupported
}
@Override
public VariableStorage getStorage() {
return var.getVariableStorage();
}
@Override
public String getName() {
return var.getName();
}
@Override
public Integer getIndex() {
return ordinal;
}
@Override
public DataType getFormalDataType() {
return var.getDataType();
}
});
this(program, service, var.getVariableStorage(), new ReadOnlyVariableData(ordinal, var));
}
@Override
@ -131,6 +105,15 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
return;
}
}
if (!Objects.equals(previousDataType, currentDataType)) {
boolean isValid = variableData.setFormalDataType(currentDataType);
if (!isValid) {
setStatusText("Invalid data type");
return;
}
}
cancelled = false;
close();
}
@ -147,13 +130,12 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
}
private void setDataType(DataType dt) {
DataType dataType = variableData.getFormalDataType();
size = dataType.getLength();
boolean unconstrained =
(dataType instanceof AbstractFloatDataType) || Undefined.isUndefined(dataType);
currentDataType = dt;
size = dt.getLength();
boolean unconstrained = (dt instanceof AbstractFloatDataType) || Undefined.isUndefined(dt);
model.setRequiredSize(size, unconstrained);
if (sizeLabel != null) {
sizeLabel.setText("" + size);
sizeLabel.setText(Integer.toString(size));
dataChanged();
}
}
@ -171,7 +153,6 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
@Override
public void editingStopped(ChangeEvent e) {
DataType dt = (DataType) dataTypeEditor.getCellEditorValue();
variableData.setFormalDataType(dt);
setDataType(dt);
}
@ -213,7 +194,7 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
panel.add(dataTypeEditComponent);
panel.add(new GLabel("Datatype Size: "));
sizeLabel = new GDLabel("" + size);
sizeLabel = new GDLabel(Integer.toString(size));
panel.add(sizeLabel);
panel.add(new GLabel("Allocated Size:"));
currentSizeLabel = new GDLabel("");
@ -312,7 +293,6 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
private void updateTableSelection() {
int[] selectedRows = model.getSelectedVarnodeRows();
if (!Arrays.equals(selectedRows, varnodeTable.getSelectedRows())) {
varnodeTable.clearSelection();
for (int i : selectedRows) {
@ -342,14 +322,11 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
}
private void updateCurrentSize() {
currentSizeLabel.setText("" + model.getCurrentSize());
currentSizeLabel.setText(Integer.toString(model.getCurrentSize()));
}
private boolean adjustingDataType = false;
private void updateDataType() {
// If storage size has changed with an undefined datatype,
// alter the size of the undefined type
if (adjustingDataType) {
return;
}
@ -358,7 +335,7 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
int currentSize = model.getCurrentSize();
if (currentSize > 0 && Undefined.isUndefined(variableData.getFormalDataType())) {
DataType adjustedUndefinedtype = Undefined.getUndefinedDataType(currentSize);
variableData.setFormalDataType(adjustedUndefinedtype);
currentDataType = adjustedUndefinedtype;
dataTypeEditor.getEditor().setCellEditorValue(adjustedUndefinedtype);
setDataType(adjustedUndefinedtype);
}
@ -368,22 +345,6 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
}
}
// public static void main(String[] args) throws Exception {
//// DockingWindowsLookAndFeelUtils.setLookAndFeel("Metal");
// ProgramBuilder builder = new ProgramBuilder();
// builder.addMemory("1000", 1000);
// Function fun = builder.addFunction("foo", "1000", 20, new VoidDataType());
//
// Program program = builder.getProgram();
// AddressSpace stackSpace = program.getAddressFactory().getStackSpace();
// Address address = stackSpace.getAddress(4);
// VariableStorage storage = new VariableStorage(program, address, 4);
//
// DockingWindowManager dwm = new DockingWindowManager("Test", null, null);
// dwm.showDialog(new StorageAddressEditorDialog(program, storage, 8));
// System.exit(0);
// }
@Override
public void tableRowsChanged() {
TableCellEditor cellEditor = varnodeTable.getCellEditor();
@ -397,4 +358,51 @@ public class StorageAddressEditorDialog extends DialogComponentProvider
public boolean wasCancelled() {
return cancelled;
}
private static class ReadOnlyVariableData implements FunctionVariableData {
private int ordinal;
private Variable variable;
private ReadOnlyVariableData(int ordinal, Variable variable) {
this.ordinal = ordinal;
this.variable = variable;
}
@Override
public void setStorage(VariableStorage storage) {
// unsupported
}
@Override
public boolean setFormalDataType(DataType dataType) {
return false;
}
@Override
public void setName(String name) {
// unsupported
}
@Override
public VariableStorage getStorage() {
return variable.getVariableStorage();
}
@Override
public String getName() {
return variable.getName();
}
@Override
public Integer getIndex() {
return ordinal;
}
@Override
public DataType getFormalDataType() {
return variable.getDataType();
}
}
}