mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 11:37:00 +08:00
Merge remote-tracking branch
'origin/GP-3647-dragonmacher-structure-editor-fixes' into patch (Closes #5566)
This commit is contained in:
+22
-6
@@ -1254,13 +1254,20 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentName(int rowIndex, String name)
|
||||
throws InvalidInputException, InvalidNameException, DuplicateNameException {
|
||||
public boolean setComponentName(int rowIndex, String name)
|
||||
throws InvalidNameException {
|
||||
|
||||
String oldName = getComponent(rowIndex).getFieldName();
|
||||
if (Objects.equals(oldName, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nameExistsElsewhere(name, rowIndex)) {
|
||||
throw new InvalidNameException("Name \"" + name + "\" already exists.");
|
||||
}
|
||||
try {
|
||||
getComponent(rowIndex).setFieldName(name); // setFieldName handles trimming
|
||||
return true;
|
||||
}
|
||||
catch (DuplicateNameException exc) {
|
||||
throw new InvalidNameException(exc.getMessage());
|
||||
@@ -1268,13 +1275,22 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentComment(int rowIndex, String comment) throws InvalidInputException {
|
||||
if (comment.equals("")) {
|
||||
comment = null;
|
||||
public boolean setComponentComment(int rowIndex, String comment) {
|
||||
|
||||
String oldComment = getComponent(rowIndex).getComment();
|
||||
String newComment = comment;
|
||||
if (newComment.equals("")) {
|
||||
newComment = null;
|
||||
}
|
||||
getComponent(rowIndex).setComment(comment);
|
||||
|
||||
if (Objects.equals(oldComment, newComment)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getComponent(rowIndex).setComment(newComment);
|
||||
fireTableCellUpdated(rowIndex, getCommentColumn());
|
||||
componentDataChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-27
@@ -271,18 +271,15 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
try {
|
||||
applyingFieldEdit = true;
|
||||
if (columnIndex == getDataTypeColumn()) {
|
||||
setComponentDataType(rowIndex, value);
|
||||
return setComponentDataType(rowIndex, value);
|
||||
}
|
||||
else if (columnIndex == getNameColumn()) {
|
||||
setComponentName(rowIndex, ((String) value).trim());
|
||||
return setComponentName(rowIndex, ((String) value).trim());
|
||||
}
|
||||
else if (columnIndex == getCommentColumn()) {
|
||||
setComponentComment(rowIndex, (String) value);
|
||||
return setComponentComment(rowIndex, (String) value);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
catch (UsrException e) {
|
||||
setStatus(e.getMessage());
|
||||
@@ -368,7 +365,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentDataType(int rowIndex, Object dataTypeObject) throws UsrException {
|
||||
public boolean setComponentDataType(int rowIndex, Object dataTypeObject) throws UsrException {
|
||||
DataType previousDt = null;
|
||||
int previousLength = 0;
|
||||
String dtName = "";
|
||||
@@ -392,7 +389,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
else if (dataTypeObject instanceof String) {
|
||||
String dtString = (String) dataTypeObject;
|
||||
if (dtString.equals(dtName)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
DataTypeManager originalDTM = getOriginalDataTypeManager();
|
||||
newDt = DataTypeHelper.parseDataType(rowIndex, dtString, this, originalDTM,
|
||||
@@ -400,7 +397,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
newLength = newDt.getLength();
|
||||
}
|
||||
if (newDt == null) {
|
||||
return; // Was nothing and is nothing.
|
||||
return false; // Was nothing and is nothing.
|
||||
}
|
||||
|
||||
if (DataTypeComponent.usesZeroLengthComponent(newDt)) {
|
||||
@@ -417,7 +414,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
DataTypeInstance sizedDataType = DataTypeHelper.getSizedDataType(provider, newDt,
|
||||
suggestedLength, getMaxReplaceLength(rowIndex));
|
||||
if (sizedDataType == null) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
newDt = resolveDataType(sizedDataType.getDataType(), viewDTM,
|
||||
DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
@@ -427,7 +424,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
}
|
||||
}
|
||||
if ((previousDt != null) && newDt.isEquivalent(previousDt) && newLength == previousLength) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int maxLength = getMaxReplaceLength(rowIndex);
|
||||
@@ -437,6 +434,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
}
|
||||
setComponentDataTypeInstance(rowIndex, newDt, newLength);
|
||||
notifyCompositeChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,15 +701,15 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
//==================================================================================================
|
||||
|
||||
@Override
|
||||
public boolean beginEditingField(int rowIndex, int columnIndex) {
|
||||
public boolean beginEditingField(int modelRow, int modelColumn) {
|
||||
if (isEditingField()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
stillBeginningEdit = true; // We want to know we are still beginning an edit when we fix the selection.
|
||||
editingField = true;
|
||||
setLocation(rowIndex, columnIndex);
|
||||
setSelection(new int[] { rowIndex });
|
||||
setLocation(modelRow, modelColumn);
|
||||
setSelection(new int[] { modelRow });
|
||||
notifyEditingChanged();
|
||||
}
|
||||
finally {
|
||||
@@ -735,17 +733,6 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
return !settingValueAt && editingField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstEditableColumn(int rowIndex) {
|
||||
int numFields = this.getColumnCount();
|
||||
for (int i = 0; i < numFields; i++) {
|
||||
if (this.isCellEditable(rowIndex, i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void notifyEditingChanged() {
|
||||
for (CompositeEditorModelListener listener : listeners) {
|
||||
listener.compositeEditStateChanged(
|
||||
@@ -946,7 +933,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditFieldAllowed(int rowIndex, int columnIndex) {
|
||||
public boolean isEditFieldAllowed() {
|
||||
return !isEditingField();
|
||||
}
|
||||
|
||||
|
||||
+69
-57
@@ -150,17 +150,17 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
table.setDefaultRenderer(DataTypeInstance.class, dtiCellRenderer);
|
||||
}
|
||||
|
||||
private boolean launchBitFieldEditor(int modelColumn, int editingRow) {
|
||||
private boolean launchBitFieldEditor(int modelRow, int modelColumn) {
|
||||
if (model.viewComposite instanceof Structure &&
|
||||
!model.viewComposite.isPackingEnabled() &&
|
||||
model.getDataTypeColumn() == modelColumn && editingRow < model.getNumComponents()) {
|
||||
model.getDataTypeColumn() == modelColumn && modelRow < model.getNumComponents()) {
|
||||
// check if we are attempting to edit a bitfield
|
||||
DataTypeComponent dtComponent = model.getComponent(editingRow);
|
||||
DataTypeComponent dtComponent = model.getComponent(modelRow);
|
||||
if (dtComponent.isBitFieldComponent()) {
|
||||
table.getCellEditor().cancelCellEditing();
|
||||
|
||||
BitFieldEditorDialog dlg = new BitFieldEditorDialog(model.viewComposite,
|
||||
provider.dtmService, editingRow, model.showHexNumbers, ordinal -> {
|
||||
provider.dtmService, modelRow, model.showHexNumbers, ordinal -> {
|
||||
model.notifyCompositeChanged();
|
||||
});
|
||||
Component c = provider.getComponent();
|
||||
@@ -187,9 +187,11 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
return;
|
||||
}
|
||||
|
||||
int modelColumn = table.convertColumnIndexToModel(table.getEditingColumn());
|
||||
if (!launchBitFieldEditor(modelColumn, editingRow)) {
|
||||
model.beginEditingField(editingRow, modelColumn);
|
||||
int modelRow = table.convertRowIndexToModel(editingRow);
|
||||
int editingColumn = table.getEditingColumn();
|
||||
int modelColumn = table.convertColumnIndexToModel(editingColumn);
|
||||
if (!launchBitFieldEditor(modelRow, modelColumn)) {
|
||||
model.beginEditingField(modelRow, modelColumn);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -287,9 +289,6 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
editBelowField();
|
||||
break;
|
||||
}
|
||||
if (table.isEditing()) {
|
||||
table.getEditorComponent().requestFocus();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
editorAdjusting = false;
|
||||
@@ -313,6 +312,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
// Handle the editing for this field.
|
||||
int viewColumn = table.convertColumnIndexToView(modelColumn);
|
||||
scrollToCell(row, viewColumn);
|
||||
table.setColumnSelectionInterval(viewColumn, viewColumn);
|
||||
startCellEditing(row, viewColumn);
|
||||
return table.isEditing();
|
||||
}
|
||||
@@ -331,20 +331,20 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
int index = row;
|
||||
int fieldNum = table.convertColumnIndexToView(modelColumn);
|
||||
|
||||
int numFields = model.getColumnCount();
|
||||
int numFields = table.getColumnCount();
|
||||
int numComps = model.getRowCount();
|
||||
do {
|
||||
// Determine the new location for the cursor.
|
||||
if (index < numComps) { // on component row
|
||||
if (++fieldNum < (numFields)) { // not on last field
|
||||
if (model.isCellEditable(index, table.convertColumnIndexToModel(fieldNum))) {
|
||||
if (table.isCellEditable(index, fieldNum)) {
|
||||
foundEditable = true;
|
||||
}
|
||||
}
|
||||
else if ((++index < numComps) // on last field for other than last component
|
||||
|| (index == numComps)) { // Last field and row but unlocked
|
||||
fieldNum = 0; // Set it to first field.
|
||||
if (model.isCellEditable(index, table.convertColumnIndexToModel(fieldNum))) {
|
||||
if (table.isCellEditable(index, fieldNum)) {
|
||||
foundEditable = true;
|
||||
}
|
||||
}
|
||||
@@ -365,6 +365,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
model.setRow(row);
|
||||
model.setColumn(modelColumn);
|
||||
}
|
||||
|
||||
return foundEditable;
|
||||
}
|
||||
|
||||
@@ -464,6 +465,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
if (locateNextEditField(currentRow)) {
|
||||
return beginEditField(model.getRow(), model.getColumn());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -559,7 +561,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
table = new GTable(model);
|
||||
table = new CompositeEditorTable(model);
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
if (columnModel instanceof GTableColumnModel) {
|
||||
@@ -570,16 +572,9 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
}
|
||||
}
|
||||
|
||||
table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
|
||||
table.addMouseListener(new CompositeTableMouseListener());
|
||||
table.setAutoEditEnabled(false); // do not edit when typing
|
||||
|
||||
CompositeEditorTableAction action = provider.actionMgr.getNamedAction(
|
||||
CompositeEditorTableAction.EDIT_ACTION_PREFIX + EditFieldAction.ACTION_NAME);
|
||||
Action swingAction = KeyBindingUtils.adaptDockingActionToNonContextAction(action);
|
||||
InputMap map = table.getInputMap();
|
||||
map.put(action.getKeyBinding(), "StartEditing");
|
||||
ActionMap amap = table.getActionMap();
|
||||
amap.put("StartEditing", swingAction);
|
||||
table.addMouseListener(new CompositeTableMouseListener());
|
||||
|
||||
table.getSelectionModel().addListSelectionListener(e -> {
|
||||
if (e.getValueIsAdjusting()) {
|
||||
@@ -599,7 +594,9 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
TableColumnModel cm = table.getColumnModel();
|
||||
int[] selected = cm.getSelectedColumns();
|
||||
if (selected.length == 1) {
|
||||
model.setColumn(selected[0]);
|
||||
int viewIndex = selected[0];
|
||||
int modelIndex = table.convertColumnIndexToModel(viewIndex);
|
||||
model.setColumn(modelIndex);
|
||||
}
|
||||
else {
|
||||
model.setColumn(-1);
|
||||
@@ -892,7 +889,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* drop() method.
|
||||
*
|
||||
* @param obj Transferable object that is to be dropped.
|
||||
@@ -920,7 +917,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* drop() method.
|
||||
*
|
||||
* @param p the point of insert
|
||||
@@ -939,7 +936,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* Add the object to the droppable component. The DragSrcAdapter calls this method from its
|
||||
* drop() method.
|
||||
*
|
||||
* @param p the point of insert
|
||||
@@ -1158,9 +1155,9 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
BigInteger endIndex = range.getEnd().getIndex();
|
||||
lsm.addSelectionInterval(startIndex.intValue(), endIndex.intValue() - 1);
|
||||
}
|
||||
int column = model.getColumn();
|
||||
clsm.setAnchorSelectionIndex(column);
|
||||
clsm.setLeadSelectionIndex(column);
|
||||
int modelColumn = model.getColumn();
|
||||
int viewColumn = table.convertColumnIndexToView(modelColumn);
|
||||
clsm.setSelectionInterval(viewColumn, viewColumn);
|
||||
}
|
||||
|
||||
private class ComponentStringCellEditor extends ComponentCellEditor {
|
||||
@@ -1344,18 +1341,15 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
@Override
|
||||
public boolean stopCellEditing() {
|
||||
|
||||
ListSelectionModel columnSelectionModel = table.getColumnModel().getSelectionModel();
|
||||
columnSelectionModel.setValueIsAdjusting(true);
|
||||
|
||||
int editingColumn = table.getEditingColumn();
|
||||
|
||||
model.setStatus("");
|
||||
|
||||
if (!isEmptyEditorCell() && !validateUserChoice()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int editingRow = model.getRow();
|
||||
ListSelectionModel columnSelectionModel = table.getColumnModel().getSelectionModel();
|
||||
columnSelectionModel.setValueIsAdjusting(true);
|
||||
|
||||
DataType dataType = (DataType) editor.getCellEditorValue();
|
||||
if (dataType != null) {
|
||||
@@ -1371,10 +1365,10 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
fireEditingCanceled();
|
||||
}
|
||||
|
||||
columnSelectionModel.setAnchorSelectionIndex(editingColumn);
|
||||
columnSelectionModel.setLeadSelectionIndex(editingColumn);
|
||||
columnSelectionModel.setSelectionInterval(editingColumn, editingColumn);
|
||||
columnSelectionModel.setValueIsAdjusting(false);
|
||||
|
||||
int editingRow = model.getRow();
|
||||
NavigationDirection navigationDirection = editor.getNavigationDirection();
|
||||
if (navigationDirection == NavigationDirection.BACKWARD) {
|
||||
editPreviousField(editingRow);
|
||||
@@ -1450,39 +1444,35 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
int column = table.columnAtPoint(point);
|
||||
int modelColumn = table.convertColumnIndexToModel(column);
|
||||
int clickCount = e.getClickCount();
|
||||
if (!table.isEditing() && (e.getID() == MouseEvent.MOUSE_PRESSED)) {
|
||||
model.clearStatus(); // Only want to clear status when starting new actions (pressed).
|
||||
if (!table.isEditing() && e.getID() == MouseEvent.MOUSE_PRESSED) {
|
||||
model.clearStatus(); // Only clear status when starting new actions (pressed).
|
||||
}
|
||||
|
||||
if (isPopup) {
|
||||
if (!table.isRowSelected(row)) {
|
||||
table.setRowSelectionInterval(row, row);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((clickCount < 2) || (e.getButton() != MouseEvent.BUTTON1)) {
|
||||
|
||||
if (clickCount < 2 || e.getButton() != MouseEvent.BUTTON1) {
|
||||
return;
|
||||
}
|
||||
String status = null;
|
||||
|
||||
if (model.isCellEditable(row, modelColumn)) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = model.getColumnName(modelColumn) + " field is not editable";
|
||||
if ((row >= 0) && (row < model.getNumComponents()) &&
|
||||
((modelColumn == model.getNameColumn()) ||
|
||||
(modelColumn == model.getCommentColumn()))) {
|
||||
if (!model.isCellEditable(row, modelColumn)) {
|
||||
DataType dt = model.getComponent(row).getDataType();
|
||||
if (dt == DataType.DEFAULT) {
|
||||
if (modelColumn == model.getNameColumn()) {
|
||||
status = model.getColumnName(modelColumn) +
|
||||
" field is not editable for Undefined byte.";
|
||||
}
|
||||
else if (modelColumn == model.getCommentColumn()) {
|
||||
status = model.getColumnName(modelColumn) +
|
||||
" field is not editable for Undefined byte.";
|
||||
}
|
||||
}
|
||||
String columnName = model.getColumnName(modelColumn);
|
||||
String status = columnName + " field is not editable";
|
||||
|
||||
boolean isValidRow = row >= 0 && row < model.getNumComponents();
|
||||
boolean isStringColumn = modelColumn == model.getNameColumn() ||
|
||||
modelColumn == model.getCommentColumn();
|
||||
if (isValidRow && isStringColumn) {
|
||||
DataType dt = model.getComponent(row).getDataType();
|
||||
if (dt == DataType.DEFAULT) {
|
||||
status = columnName + " field is not editable for Undefined byte.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1491,4 +1481,26 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
private class CompositeEditorTable extends GTable {
|
||||
|
||||
public CompositeEditorTable(TableModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installEditKeyBinding() {
|
||||
// We use a tool action instead of the default action. We must signal to the table to
|
||||
// not use the default action to prevent the table from getting the action.
|
||||
|
||||
// This code will insert a placeholder of 'none' in the table for this keystroke, which
|
||||
// is the default edit keystroke in Swing. The actual binding for this keystroke is in
|
||||
// a parent input map of the table. By placing this keystroke in the table's input map,
|
||||
// we prevent the key processing code from traversing into the parent input map's
|
||||
// bindings.
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke("pressed F2");
|
||||
KeyBindingUtils.clearKeyBinding(this, keyStroke);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-2
@@ -53,7 +53,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
protected CompositeEditorActionManager actionMgr;
|
||||
|
||||
/**
|
||||
* Construct a new stack editor provider.
|
||||
* Construct a new stack editor provider.
|
||||
* @param plugin owner of this provider
|
||||
*/
|
||||
protected CompositeEditorProvider(Plugin plugin) {
|
||||
@@ -94,6 +94,20 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
return editorPanel.getTable();
|
||||
}
|
||||
|
||||
public int getFirstEditableColumn(int row) {
|
||||
if (editorPanel == null) {
|
||||
return -1;
|
||||
}
|
||||
JTable table = editorPanel.getTable();
|
||||
int n = table.getColumnCount();
|
||||
for (int col = 0; col < n; col++) {
|
||||
if (table.isCellEditable(row, col)) {
|
||||
return col;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected void initializeActions() {
|
||||
actionMgr = new CompositeEditorActionManager(this);
|
||||
actionMgr.setEditorActions(createActions());
|
||||
@@ -281,7 +295,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
* Prompts the user if the editor has unsaved changes. Saves the changes if
|
||||
* the user indicates to do so.
|
||||
* @param allowCancel true if allowed to cancel
|
||||
* @return 0 if the user canceled; 1 if the user saved changes;
|
||||
* @return 0 if the user canceled; 1 if the user saved changes;
|
||||
* 2 if the user did not to save changes; 3 if there was an error when
|
||||
* the changes were applied.
|
||||
*/
|
||||
|
||||
+26
-25
@@ -34,9 +34,9 @@ import utility.function.Callback;
|
||||
abstract class CompositeViewerModel extends AbstractTableModel
|
||||
implements DataTypeManagerChangeListener {
|
||||
|
||||
/**
|
||||
* Flag indicating that the model is updating the selection and should ignore any attempts to
|
||||
* set the selection until it is no longer updating.
|
||||
/**
|
||||
* Flag indicating that the model is updating the selection and should ignore any attempts to
|
||||
* set the selection until it is no longer updating.
|
||||
*/
|
||||
protected boolean updatingSelection = false;
|
||||
|
||||
@@ -170,7 +170,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
* Unloads the currently loaded composite data type.
|
||||
* This should be called when the viewer is removed from view and
|
||||
* and category/dataType changes no longer need to be listened for.
|
||||
* It can also be called to unload the current composite before loading
|
||||
* It can also be called to unload the current composite before loading
|
||||
* a new composite data type.
|
||||
*/
|
||||
void unload() {
|
||||
@@ -238,6 +238,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
// clear our notion of the last selected column
|
||||
return;
|
||||
}
|
||||
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@@ -299,7 +300,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
|
||||
/**
|
||||
* Return the path of the data category for the structure being viewed
|
||||
* @return the path
|
||||
* @return the path
|
||||
*/
|
||||
public final CategoryPath getOriginalCategoryPath() {
|
||||
if (originalDataTypePath != null) {
|
||||
@@ -322,7 +323,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
|
||||
/**
|
||||
* Return the size of the structure being viewed in bytes
|
||||
* @return this size
|
||||
* @return this size
|
||||
*/
|
||||
public int getLength() {
|
||||
if (viewComposite != null && !viewComposite.isZeroLength()) {
|
||||
@@ -332,7 +333,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the structure being viewed in bytes as a hex or decimal string depending
|
||||
* Return the size of the structure being viewed in bytes as a hex or decimal string depending
|
||||
* on the model's current display setting for numbers
|
||||
* @return the length
|
||||
*/
|
||||
@@ -360,7 +361,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
/**
|
||||
* Return a header name for the indicated column.
|
||||
*
|
||||
* @param columnIndex the index number indicating the component field (column) to get the
|
||||
* @param columnIndex the index number indicating the component field (column) to get the
|
||||
* header for.
|
||||
*/
|
||||
@Override
|
||||
@@ -371,7 +372,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
/**
|
||||
* Return a header name for the indicated field (column)
|
||||
*
|
||||
* @param columnIndex the index number indicating the component field (column) to get the
|
||||
* @param columnIndex the index number indicating the component field (column) to get the
|
||||
* header for
|
||||
* @return the name
|
||||
*/
|
||||
@@ -484,8 +485,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of component rows in the viewer. There may be a blank row at the end for
|
||||
* selecting. Therefore this number can be different than the actual number of components
|
||||
* Returns the number of component rows in the viewer. There may be a blank row at the end for
|
||||
* selecting. Therefore this number can be different than the actual number of components
|
||||
* currently in the structure being viewed.
|
||||
*
|
||||
* @return the number of rows in the model
|
||||
@@ -504,8 +505,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nth component for the structure being viewed. Since the number of rows can exceed
|
||||
* the number of components defined within the composite ({@link Composite#getNumComponents()})
|
||||
* Return the nth component for the structure being viewed. Since the number of rows can exceed
|
||||
* the number of components defined within the composite ({@link Composite#getNumComponents()})
|
||||
* this method will return null for a blank row.
|
||||
*
|
||||
* @param rowIndex the index of the component to return. First component is index of 0
|
||||
@@ -519,7 +520,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns (display fields) for each component in this structure or
|
||||
* Returns the number of columns (display fields) for each component in this structure or
|
||||
* union.
|
||||
*
|
||||
* @return the number of display fields for each component
|
||||
@@ -635,7 +636,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes up the original name and category because a program restoration may have changed the
|
||||
* Fixes up the original name and category because a program restoration may have changed the
|
||||
* original composite.
|
||||
* @param composite the restored copy of our original composite
|
||||
*/
|
||||
@@ -671,7 +672,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the composite's non-component information changes. For example, the name,
|
||||
* Called whenever the composite's non-component information changes. For example, the name,
|
||||
* or description change.
|
||||
*/
|
||||
protected void compositeInfoChanged() {
|
||||
@@ -686,7 +687,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the full path name for the composite data type based on the original composite
|
||||
* Determines the full path name for the composite data type based on the original composite
|
||||
* and original category.
|
||||
* @return the full path name
|
||||
*/
|
||||
@@ -960,10 +961,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
|
||||
//=================================================================================================
|
||||
// Helper methods for CategoryChangeListener methods.
|
||||
//=================================================================================================
|
||||
//=================================================================================================
|
||||
|
||||
/**
|
||||
* Determines whether the indicated composite data type has any sub-components that are within
|
||||
* Determines whether the indicated composite data type has any sub-components that are within
|
||||
* the indicated category or one of its sub-categories.
|
||||
* @param parentDt the composite data type
|
||||
* @param catPath the category's path
|
||||
@@ -971,7 +972,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
*/
|
||||
boolean hasSubDtInCategory(Composite parentDt, String catPath) {
|
||||
DataTypeComponent components[] = parentDt.getDefinedComponents();
|
||||
// FUTURE Add a structure to keep track of which composites were searched so they aren't
|
||||
// FUTURE Add a structure to keep track of which composites were searched so they aren't
|
||||
// searched multiple times.
|
||||
for (DataTypeComponent component : components) {
|
||||
DataType subDt = component.getDataType();
|
||||
@@ -989,7 +990,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the indicated composite data type has any sub-components that are the
|
||||
* Determines whether the indicated composite data type has any sub-components that are the
|
||||
* indicated data type.
|
||||
* @param parentDt the composite data type
|
||||
* @param dtPath the data type to be detected
|
||||
@@ -1040,7 +1041,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
|
||||
/**
|
||||
* Returns the number of rows currently selected.
|
||||
*
|
||||
*
|
||||
* <p>Note: In unlocked mode this can include the additional blank line.
|
||||
*
|
||||
* @return the selected row count
|
||||
@@ -1152,7 +1153,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selection range containing the specified row index if there is one that contains
|
||||
* Returns the selection range containing the specified row index if there is one that contains
|
||||
* it. Otherwise, returns null.
|
||||
*
|
||||
* @param rowIndex the row index
|
||||
@@ -1214,7 +1215,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the model's current selection to the indicated selection. If the selection is empty,
|
||||
* Sets the model's current selection to the indicated selection. If the selection is empty,
|
||||
* it gets adjusted to the empty last line when in unlocked mode.
|
||||
* @param selection the new selection
|
||||
*/
|
||||
@@ -1289,7 +1290,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
}
|
||||
|
||||
/**
|
||||
* A notify method to take the listens to notify, along with the method that should be called
|
||||
* A notify method to take the listens to notify, along with the method that should be called
|
||||
* on each listener.
|
||||
*
|
||||
* @param <T> the type of the listener
|
||||
|
||||
+6
-5
@@ -17,6 +17,7 @@ package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import docking.ActionContext;
|
||||
@@ -54,8 +55,10 @@ public class EditFieldAction extends CompositeEditorTableAction {
|
||||
}
|
||||
|
||||
// just go to the first editable cell, since the current one is not editable
|
||||
int firstEditableColumn = model.getFirstEditableColumn(row);
|
||||
model.beginEditingField(row, firstEditableColumn);
|
||||
int firstEditableColumn = provider.getFirstEditableColumn(row);
|
||||
JTable table = provider.getTable();
|
||||
int modelColumn = table.convertColumnIndexToModel(firstEditableColumn);
|
||||
model.beginEditingField(row, modelColumn);
|
||||
}
|
||||
requestTableFocus();
|
||||
}
|
||||
@@ -64,9 +67,7 @@ public class EditFieldAction extends CompositeEditorTableAction {
|
||||
public void adjustEnablement() {
|
||||
boolean shouldEnableEdit = false;
|
||||
if (model.isSingleRowSelection()) {
|
||||
int[] rows = model.getSelectedRows();
|
||||
int firstEditableColumn = model.getFirstEditableColumn(rows[0]);
|
||||
shouldEnableEdit = model.isEditFieldAllowed(rows[0], firstEditableColumn);
|
||||
shouldEnableEdit = model.isEditFieldAllowed();
|
||||
}
|
||||
setEnabled(shouldEnableEdit);
|
||||
}
|
||||
|
||||
+44
-143
@@ -18,16 +18,17 @@ package ghidra.app.plugin.core.compositeeditor;
|
||||
import ghidra.app.util.datatype.EmptyCompositeException;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.UsrException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public interface EditorModel {
|
||||
|
||||
// TODO: This model interface serves no real purpose and could be collapsed into the
|
||||
// TODO: This model interface serves no real purpose and could be collapsed into the
|
||||
// abstract class CompositeEditorModel implementation.
|
||||
|
||||
/**
|
||||
* Called when the model is no longer needed.
|
||||
* Called when the model is no longer needed.
|
||||
* This is where all cleanup code for the model should be placed.
|
||||
*/
|
||||
public void dispose();
|
||||
@@ -119,22 +120,7 @@ public interface EditorModel {
|
||||
*/
|
||||
public boolean isEditComponentAllowed();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
public boolean isEditFieldAllowed(int rowIndex, int column);
|
||||
|
||||
// /**
|
||||
// * Returns whether or not insertion of the specified data type is allowed
|
||||
// * at the specified index.
|
||||
// *
|
||||
// * @param index index of the component in the union.
|
||||
// * @param datatype the data type to be inserted.
|
||||
// */
|
||||
// public boolean isInsertAllowed(DataType datatype);
|
||||
public boolean isEditFieldAllowed();
|
||||
|
||||
/**
|
||||
* Returns whether or not insertion of the specified data type is allowed
|
||||
@@ -155,29 +141,18 @@ public interface EditorModel {
|
||||
*/
|
||||
public boolean isMoveUpAllowed();
|
||||
|
||||
// /**
|
||||
// *
|
||||
// * @param dataType
|
||||
// * @return
|
||||
// */
|
||||
// public boolean isReplaceAllowed(DataType dataType);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex row index of the component in the composite data type.
|
||||
* @param dataType
|
||||
* @return
|
||||
*/
|
||||
public boolean isReplaceAllowed(int rowIndex, DataType dataType);
|
||||
|
||||
/**
|
||||
* Returns whether the selected component can be unpackaged.
|
||||
* @return whether the selected component can be unpackaged.
|
||||
*/
|
||||
public boolean isUnpackageAllowed();
|
||||
|
||||
/**
|
||||
* Returns whether or not the editor has changes that haven't been applied.
|
||||
* Changes can also mean a new data type that hasn't yet been saved.
|
||||
* @return if there are changes
|
||||
*/
|
||||
public boolean hasChanges();
|
||||
|
||||
@@ -187,6 +162,7 @@ public interface EditorModel {
|
||||
* @param name the new name.
|
||||
*
|
||||
* @throws DuplicateNameException if the name already exists.
|
||||
* @throws InvalidNameException if the name is invalid
|
||||
*/
|
||||
public void setName(String name) throws DuplicateNameException, InvalidNameException;
|
||||
|
||||
@@ -199,14 +175,16 @@ public interface EditorModel {
|
||||
|
||||
/**
|
||||
* Sets the data type for the component at the indicated rowIndex.
|
||||
* @param rowIndex the row index of the component
|
||||
* @param rowIndex the row index of the component
|
||||
* @param dataTypeObject a String or a DataType
|
||||
* @return true if changed
|
||||
* @throws UsrException if the type cannot be used
|
||||
*/
|
||||
public void setComponentDataType(int rowIndex, Object dataTypeObject) throws UsrException;
|
||||
public boolean setComponentDataType(int rowIndex, Object dataTypeObject) throws UsrException;
|
||||
|
||||
/**
|
||||
* Sets the data type for the component at the indicated row index.
|
||||
* @param rowIndex the row index of the component
|
||||
* @param rowIndex the row index of the component
|
||||
* @param dt component datatype
|
||||
* @param length component length
|
||||
* @throws UsrException if invalid datatype or length specified
|
||||
@@ -216,18 +194,20 @@ public interface EditorModel {
|
||||
|
||||
/**
|
||||
* Sets the data type for the component at the indicated index.
|
||||
* @param rowIndex the row index of the component
|
||||
* @param name
|
||||
* @param rowIndex the row index of the component
|
||||
* @param name the name
|
||||
* @return true if a change was made
|
||||
* @throws InvalidNameException if the name is invalid
|
||||
*/
|
||||
public void setComponentName(int rowIndex, String name)
|
||||
throws InvalidInputException, InvalidNameException, DuplicateNameException;
|
||||
public boolean setComponentName(int rowIndex, String name) throws InvalidNameException;
|
||||
|
||||
/**
|
||||
* Sets the data type for the component at the indicated index.
|
||||
* @param rowIndex the row index of the component
|
||||
* @param comment
|
||||
* @param rowIndex the row index of the component
|
||||
* @param comment the comment
|
||||
* @return true if a change was made
|
||||
*/
|
||||
public void setComponentComment(int rowIndex, String comment) throws InvalidInputException;
|
||||
public boolean setComponentComment(int rowIndex, String comment);
|
||||
|
||||
/**
|
||||
* Returns whether or not the editor is showing undefined bytes.
|
||||
@@ -235,62 +215,26 @@ public interface EditorModel {
|
||||
*/
|
||||
public boolean isShowingUndefinedBytes();
|
||||
|
||||
/**
|
||||
* Gets the column number of the first editable field found for the indicated row.
|
||||
*
|
||||
* @param rowIndex the index number of the row
|
||||
* @return the index number of the editable column or -1 if no fields are editable.
|
||||
*/
|
||||
public int getFirstEditableColumn(int rowIndex);
|
||||
public boolean beginEditingField(int modelRow, int modelColumn);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
public boolean beginEditingField(int rowIndex, int column);
|
||||
|
||||
/**
|
||||
* Change the edit state to indicate no longer editing a field.
|
||||
* Change the edit state to indicate no longer editing a field.
|
||||
* @return the edit state to indicate no longer editing a field.
|
||||
*/
|
||||
public boolean endEditingField();
|
||||
|
||||
/**
|
||||
* Returns whether the user is currently editing a field's value.
|
||||
* Returns whether the user is currently editing a field's value.
|
||||
* @return whether the user is currently editing a field's value.
|
||||
*/
|
||||
public boolean isEditingField();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void endFieldEditing();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dataType
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent add(DataType dataType) throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param dataType
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent add(int rowIndex, DataType dataType) throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param dt
|
||||
* @param dtLength
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent add(int rowIndex, DataType dt, int dtLength) throws UsrException;
|
||||
|
||||
/**
|
||||
@@ -305,21 +249,10 @@ public interface EditorModel {
|
||||
|
||||
public void clearComponent(int rowIndex);
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws UsrException
|
||||
*/
|
||||
public void clearSelectedComponents() throws UsrException;
|
||||
|
||||
/**
|
||||
* @param cycleGroup
|
||||
*/
|
||||
public void cycleDataType(CycleGroup cycleGroup);
|
||||
|
||||
/**
|
||||
* Create array component
|
||||
* @throws UsrException
|
||||
*/
|
||||
public void createArray() throws UsrException;
|
||||
|
||||
/**
|
||||
@@ -331,7 +264,7 @@ public interface EditorModel {
|
||||
|
||||
/**
|
||||
* Creates multiple duplicates of the indicated component.
|
||||
* The duplicates will be created at the index immediately after the
|
||||
* The duplicates will be created at the index immediately after the
|
||||
* indicated component.
|
||||
* @param rowIndex the index of the row whose component is to be duplicated.
|
||||
* @param multiple the number of duplicates to create.
|
||||
@@ -341,77 +274,45 @@ public interface EditorModel {
|
||||
public void duplicateMultiple(int rowIndex, int multiple, TaskMonitor monitor)
|
||||
throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dataType
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent insert(DataType dataType) throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param dataType
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent insert(int rowIndex, DataType dataType) throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param dt
|
||||
* @param dtLength
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent insert(int rowIndex, DataType dt, int dtLength) throws UsrException;
|
||||
|
||||
/**
|
||||
* Moves a contiguous selection of components up by a single position.
|
||||
* The component that was immediately above
|
||||
* (at the index immediately preceeding the selection)
|
||||
* the selection will be moved below the selection
|
||||
* (to what was the maximum selected component index).
|
||||
* Moves a contiguous selection of components up by a single position. The component that was
|
||||
* immediately above (at the index immediately preceding the selection) the selection will be
|
||||
* moved below the selection (to what was the maximum selected component index).
|
||||
* @return true if selected components were moved up.
|
||||
* @throws UsrException if components can't be moved up.
|
||||
*/
|
||||
public boolean moveUp() throws UsrException;
|
||||
|
||||
/**
|
||||
* Moves a contiguous selection of components down by a single position.
|
||||
* The component that was immediately below
|
||||
* (at the index immediately following the selection)
|
||||
* the selection will be moved above the selection
|
||||
* (to what was the minimum selected component index).
|
||||
* Moves a contiguous selection of components down by a single position. The component that was
|
||||
* immediately below (at the index immediately following the selection) the selection will be
|
||||
* moved above the selection (to what was the minimum selected component index).
|
||||
* @return true if selected components were moved down.
|
||||
* @throws UsrException if components can't be moved down.
|
||||
*/
|
||||
public boolean moveDown() throws UsrException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rowIndex
|
||||
* @param dt
|
||||
* @param dtLength
|
||||
* @return
|
||||
* @throws UsrException
|
||||
*/
|
||||
public DataTypeComponent replace(int rowIndex, DataType dt, int dtLength) throws UsrException;
|
||||
|
||||
/**
|
||||
* Gets the maximum number of bytes available for a data type that is added at the indicated
|
||||
* index. This can vary based on whether or not it is in a selection.
|
||||
* index. This can vary based on whether or not it is in a selection.
|
||||
*
|
||||
* @param rowIndex index of the row in the editor's composite data type.
|
||||
* @return the length
|
||||
*/
|
||||
public int getMaxAddLength(int rowIndex);
|
||||
|
||||
/**
|
||||
* Determine the maximum number of duplicates that can be created for
|
||||
* Determine the maximum number of duplicates that can be created for
|
||||
* the component at the indicated index. The duplicates would follow
|
||||
* the component. The number allowed depends on how many fit based on
|
||||
* the component. The number allowed depends on how many fit based on
|
||||
* the current lock/unlock state of the editor.
|
||||
* <br>Note: This method doesn't care whether there is a selection or not.
|
||||
*
|
||||
@@ -421,7 +322,7 @@ public interface EditorModel {
|
||||
public int getMaxDuplicates(int rowIndex);
|
||||
|
||||
/**
|
||||
* Determine the maximum number of array elements that can be created for
|
||||
* Determine the maximum number of array elements that can be created for
|
||||
* the current selection. The array data type is assumed to become the
|
||||
* data type of the first component in the selection. The current selection
|
||||
* must be contiguous or 0 is returned.
|
||||
@@ -431,9 +332,9 @@ public interface EditorModel {
|
||||
public int getMaxElements();
|
||||
|
||||
/**
|
||||
* Gets the maximum number of bytes available for a new data type that
|
||||
* Gets the maximum number of bytes available for a new data type that
|
||||
* will replace the current data type at the indicated component index.
|
||||
* If there isn't a component with the indicated index, the max length
|
||||
* If there isn't a component with the indicated index, the max length
|
||||
* will be determined by the lock mode.
|
||||
*
|
||||
* @param rowIndex index of the row for the component to replace.
|
||||
@@ -442,21 +343,21 @@ public interface EditorModel {
|
||||
public int getMaxReplaceLength(int rowIndex);
|
||||
|
||||
/**
|
||||
* Return the last number of bytes the user entered when prompted for
|
||||
* Return the last number of bytes the user entered when prompted for
|
||||
* a data type size.
|
||||
* @return the number of bytes
|
||||
*/
|
||||
public int getLastNumBytes();
|
||||
|
||||
/**
|
||||
* Return the last number of duplicates the user entered when prompted for
|
||||
* Return the last number of duplicates the user entered when prompted for
|
||||
* creating duplicates of a component.
|
||||
* @return the number of duplicates
|
||||
*/
|
||||
public int getLastNumDuplicates();
|
||||
|
||||
/**
|
||||
* Return the last number of elements the user entered when prompted for
|
||||
* Return the last number of elements the user entered when prompted for
|
||||
* creating an array.
|
||||
* @return the number of elements
|
||||
*/
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
if ((rowIndex < 0) || (rowIndex >= getRowCount())) {
|
||||
return false;
|
||||
}
|
||||
// There shouldn't be a selection when this is called.
|
||||
|
||||
switch (columnIndex) {
|
||||
case DATATYPE:
|
||||
return true;
|
||||
|
||||
+19
-21
@@ -104,6 +104,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
super.load(dataType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Composite createViewCompositeFromOriginalComposite(Composite original) {
|
||||
return (Composite) original.copy(original.getDataTypeManager());
|
||||
}
|
||||
@@ -208,7 +209,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
if (fieldName == null) {
|
||||
fieldName = "";
|
||||
}
|
||||
// if ((fieldName.length() == 0)
|
||||
// if ((fieldName.length() == 0)
|
||||
// && (element.getOffset() == ((StackFrameDataType)viewComposite).getReturnAddressOffset())) {
|
||||
// return "<RETURN_ADDRESS>";
|
||||
// }
|
||||
@@ -632,7 +633,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
boolean existingPointer = (compDt instanceof Pointer);
|
||||
boolean isPointer = (dataType instanceof Pointer) || existingPointer;
|
||||
int newLength = dataType.getLength();
|
||||
// NOTE : Allow the generic pointer, but don't allow -1 length data
|
||||
// NOTE : Allow the generic pointer, but don't allow -1 length data
|
||||
// types (i.e. string) except on pointers.
|
||||
if (!isPointer && (newLength <= 0)) {
|
||||
return false;
|
||||
@@ -797,7 +798,8 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentDataTypeInstance(int index, DataType dt, int length) throws UsrException {
|
||||
public void setComponentDataTypeInstance(int index, DataType dt, int length)
|
||||
throws UsrException {
|
||||
checkIsAllowableDataType(dt);
|
||||
((StackFrameDataType) viewComposite).setDataType(index, dt, length);
|
||||
}
|
||||
@@ -811,27 +813,19 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentName(int rowIndex, String newName)
|
||||
throws InvalidInputException, InvalidNameException, DuplicateNameException {
|
||||
public boolean setComponentName(int rowIndex, String newName)
|
||||
throws InvalidNameException {
|
||||
|
||||
if (newName.trim().length() == 0) {
|
||||
newName = null;
|
||||
}
|
||||
// if (nameExistsElsewhere(newName, currentIndex)) {
|
||||
// throw new InvalidNameException("Name \"" + newName + "\" already exists.");
|
||||
// }
|
||||
// try {
|
||||
// getComponent(currentIndex).setFieldName(newName);
|
||||
// } catch (DuplicateNameException exc) {
|
||||
// throw new InvalidNameException(exc.getMessage());
|
||||
// }
|
||||
|
||||
// prevent user names that are default values, unless the value is the original name
|
||||
String nameInEditor = (String) getValueAt(rowIndex, NAME);
|
||||
StackFrameDataType stackFrameDataType = ((StackFrameDataType) viewComposite);
|
||||
if (stackFrameDataType.isDefaultName(newName) && !isOriginalFieldName(newName, rowIndex)) {
|
||||
if (SystemUtilities.isEqual(nameInEditor, newName)) {
|
||||
return; // same as current name in the table; do nothing
|
||||
if (Objects.equals(nameInEditor, newName)) {
|
||||
return false; // same as current name in the table; do nothing
|
||||
}
|
||||
throw new InvalidNameException("Cannot set a stack variable name to a default value");
|
||||
}
|
||||
@@ -840,7 +834,9 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
updateAndCheckChangeState();
|
||||
fireTableCellUpdated(rowIndex, getNameColumn());
|
||||
notifyCompositeChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Gets the original field name within the parent data type for a given row in the editor */
|
||||
@@ -851,12 +847,14 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponentComment(int currentIndex, String comment) throws InvalidInputException {
|
||||
public boolean setComponentComment(int currentIndex, String comment) {
|
||||
if (((StackFrameDataType) viewComposite).setComment(currentIndex, comment)) {
|
||||
updateAndCheckChangeState();
|
||||
fireTableRowsUpdated(currentIndex, currentIndex);
|
||||
componentDataChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -912,7 +910,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
@Override
|
||||
public boolean apply() throws EmptyCompositeException, InvalidDataTypeException {
|
||||
|
||||
// commit changes for any fields under edit
|
||||
// commit changes for any fields under edit
|
||||
if (isEditingField()) {
|
||||
endFieldEditing();
|
||||
}
|
||||
@@ -940,7 +938,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
original.setLocalSize(edited.getLocalSize());
|
||||
original.setReturnAddressOffset(edited.getReturnAddressOffset());
|
||||
|
||||
// first-pass: remove deleted params from end of param list if possible
|
||||
// first-pass: remove deleted params from end of param list if possible
|
||||
// to avoid custom storage enablement
|
||||
Parameter[] origParams = function.getParameters();
|
||||
for (int i = origParams.length - 1; i >= 0; --i) {
|
||||
@@ -1214,7 +1212,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't try to actually rename, since we shouldn't get name change on a
|
||||
// Don't try to actually rename, since we shouldn't get name change on a
|
||||
// fabricated stack data type.
|
||||
OffsetPairs offsetSelection = getRelOffsetSelection();
|
||||
fireTableDataChanged();
|
||||
@@ -1285,7 +1283,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
|
||||
//**************************************************************************
|
||||
// The methods below were overridden to prevent data types with a length of
|
||||
// -1 from being applied in the stack editor. We also don't want to get
|
||||
// -1 from being applied in the stack editor. We also don't want to get
|
||||
// prompted for a length when the user tries to apply a -1 length data type.
|
||||
//**************************************************************************
|
||||
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
@@ -1299,7 +1297,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overrides the CompositeEditorModel to wrap the resolve of the data type
|
||||
* This method overrides the CompositeEditorModel to wrap the resolve of the data type
|
||||
* in a transaction.
|
||||
*/
|
||||
@Override
|
||||
|
||||
@@ -15,7 +15,13 @@
|
||||
*/
|
||||
package docking;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import docking.action.DockingActionIf;
|
||||
|
||||
@@ -290,13 +296,23 @@ class PlaceholderManager {
|
||||
String name = newInfo.getName();
|
||||
String group = newInfo.getGroup();
|
||||
|
||||
for (ComponentPlaceholder placeholder : activePlaceholders) {
|
||||
if (name.equals(placeholder.getName()) && group.equals(placeholder.getGroup())) {
|
||||
return placeholder;
|
||||
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
Component focusOwner = kfm.getFocusOwner();
|
||||
List<ComponentPlaceholder> matching = activePlaceholders.stream()
|
||||
.filter(p -> name.equals(p.getName()) && group.equals(p.getGroup()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// prefer using the focused window
|
||||
for (ComponentPlaceholder placeholder : matching) {
|
||||
JComponent component = placeholder.getProviderComponent();
|
||||
if (focusOwner != null && component != null) {
|
||||
if (SwingUtilities.isDescendingFrom(focusOwner, component)) {
|
||||
return placeholder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return matching.stream().findAny().orElse(null);
|
||||
}
|
||||
|
||||
private ComponentPlaceholder findBestUnusedPlaceholder(
|
||||
|
||||
@@ -419,6 +419,13 @@ public class KeyBindingUtils {
|
||||
|
||||
KeyStroke keyStroke = null;
|
||||
KeyStroke[] keys = inputMap.allKeys();
|
||||
if (keys == null) {
|
||||
Msg.debug(KeyBindingUtils.class,
|
||||
"Cannot remove action by name; does not exist: '" + actionName + "' " +
|
||||
"on component: " + component.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
for (KeyStroke ks : keys) {
|
||||
Object object = inputMap.get(ks);
|
||||
if (actionName.equals(object)) {
|
||||
|
||||
@@ -419,7 +419,7 @@ public class GTable extends JTable {
|
||||
putClientProperty("JTable.autoStartsEdit", allowAutoEdit);
|
||||
}
|
||||
|
||||
private void installEditKeyBinding() {
|
||||
protected void installEditKeyBinding() {
|
||||
AbstractAction action = new AbstractAction("StartEdit") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
|
||||
+10
-12
@@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,24 +15,23 @@
|
||||
*/
|
||||
package ghidra.util.exception;
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown whenever a method tries give something a name and that name is already used.
|
||||
*/
|
||||
public class DuplicateNameException extends UsrException {
|
||||
|
||||
/**
|
||||
* constructs a new DuplicatenameException with a default message.
|
||||
*/
|
||||
public DuplicateNameException() {
|
||||
|
||||
/**
|
||||
* constructs a new DuplicatenameException with a default message.
|
||||
*/
|
||||
public DuplicateNameException() {
|
||||
super("That name is already in use.");
|
||||
}
|
||||
|
||||
/**
|
||||
* construct a new DuplicateNameException with a given message.
|
||||
*
|
||||
* @param usrMessage overides the default message.
|
||||
*/
|
||||
/**
|
||||
* construct a new DuplicateNameException with a given message.
|
||||
*
|
||||
* @param usrMessage overrides the default message.
|
||||
*/
|
||||
public DuplicateNameException(String usrMessage) {
|
||||
super(usrMessage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user