mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 02:10:47 +08:00
Merge branch 'GP-5557_ghidra1_CompositeEditorFixes' into patch
This commit is contained in:
+4
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -217,8 +217,8 @@ public class DBTraceDataTypeManager extends ProgramBasedDataTypeManagerDB
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction(int transactionID, boolean commit) {
|
||||
trace.endTransaction(transactionID, commit);
|
||||
public boolean endTransaction(int transactionID, boolean commit) {
|
||||
return trace.endTransaction(transactionID, commit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1173,8 +1173,8 @@ public class DBTraceProgramView implements TraceProgramView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction(int transactionID, boolean commit) {
|
||||
trace.endTransaction(transactionID, commit);
|
||||
public boolean endTransaction(int transactionID, boolean commit) {
|
||||
return trace.endTransaction(transactionID, commit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -384,8 +384,8 @@ public class DBTraceProgramViewRegisters implements TraceProgramView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction(int transactionID, boolean commit) {
|
||||
view.endTransaction(transactionID, commit);
|
||||
public boolean endTransaction(int transactionID, boolean commit) {
|
||||
return view.endTransaction(transactionID, commit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ public class AddBitFieldAction extends CompositeEditorTableAction {
|
||||
"Add a bitfield at the position of a selected component";
|
||||
private static String[] POPUP_PATH = new String[] { ACTION_NAME };
|
||||
|
||||
public AddBitFieldAction(CompositeEditorProvider provider) {
|
||||
public AddBitFieldAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, null);
|
||||
setDescription(DESCRIPTION);
|
||||
if (!(model instanceof CompEditorModel)) {
|
||||
@@ -46,9 +46,9 @@ public class AddBitFieldAction extends CompositeEditorTableAction {
|
||||
return false;
|
||||
}
|
||||
boolean enabled = true;
|
||||
CompEditorModel editorModel = (CompEditorModel) model;
|
||||
CompEditorModel<?> editorModel = (CompEditorModel<?>) model;
|
||||
// Unions do not support non-packed manipulation of bitfields
|
||||
if (!(provider instanceof StructureEditorProvider structProvider) ||
|
||||
if (!(provider instanceof StructureEditorProvider) ||
|
||||
editorModel.isPackingEnabled() || editorModel.getNumSelectedRows() != 1) {
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class ApplyAction extends CompositeEditorTableAction {
|
||||
private final static Icon ICON = new GIcon("icon.plugin.composite.editor.apply");
|
||||
private final static String[] POPUP_PATH = new String[] { "Apply Edits" };
|
||||
|
||||
public ApplyAction(CompositeEditorProvider provider) {
|
||||
public ApplyAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
|
||||
setDescription("Apply editor changes");
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class ArrayAction extends CompositeEditorTableAction {
|
||||
private final static KeyStroke KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_OPEN_BRACKET, 0);
|
||||
private static String[] POPUP_PATH = new String[] { ACTION_NAME };
|
||||
|
||||
public ArrayAction(CompositeEditorProvider provider) {
|
||||
public ArrayAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class ClearAction extends CompositeEditorTableAction {
|
||||
private final static String[] POPUP_PATH = new String[] { "Clear" };
|
||||
private final static KeyStroke KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C, 0);
|
||||
|
||||
public ClearAction(CompositeEditorProvider provider) {
|
||||
public ClearAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
|
||||
setDescription("Clear the selected components");
|
||||
|
||||
+27
-50
@@ -29,7 +29,7 @@ import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public abstract class CompEditorModel<T extends Composite> extends CompositeEditorModel<T> {
|
||||
|
||||
private volatile boolean consideringReplacedDataType = false;
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
* Creates a model for editing a composite data type.
|
||||
* @param provider the provider that is using this model for editing.
|
||||
*/
|
||||
CompEditorModel(CompositeEditorProvider provider) {
|
||||
CompEditorModel(CompositeEditorProvider<T, ? extends CompEditorModel<T>> provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
* @param dataType the composite data type being edited.
|
||||
*/
|
||||
@Override
|
||||
public void load(Composite dataType) {
|
||||
public void load(T dataType) {
|
||||
super.load(dataType);
|
||||
fixSelection();
|
||||
selectionChanged();
|
||||
@@ -76,7 +76,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
FieldSelection saveSelection = new FieldSelection(selection);
|
||||
Composite originalDt = getOriginalComposite();
|
||||
T originalDt = getOriginalComposite();
|
||||
if (originalDt == null || originalDTM == null) {
|
||||
throw new IllegalStateException(
|
||||
"Can't apply edits without a data type or data type manager.");
|
||||
@@ -118,7 +118,8 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
load(originalDt);
|
||||
}
|
||||
else {
|
||||
Composite dt = (Composite) originalDTM.resolve(viewComposite, null);
|
||||
@SuppressWarnings("unchecked")
|
||||
T dt = (T) originalDTM.resolve(viewComposite, null);
|
||||
load(dt);
|
||||
}
|
||||
return true;
|
||||
@@ -376,7 +377,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
int componentOrdinal = convertRowToOrdinal(rowIndex);
|
||||
delete(componentOrdinal);
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
@@ -411,8 +411,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
viewDTM.withTransaction("Delete Components", () -> viewComposite.delete(ordinals));
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
notifyCompositeChanged();
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
@@ -427,12 +425,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
|
||||
int[] selectedComponents = getSelectedComponentRows();
|
||||
int firstRowIndex = !selection.isEmpty() ? selectedComponents[0] : getRowCount();
|
||||
try {
|
||||
delete(selectedComponents);
|
||||
}
|
||||
finally {
|
||||
componentEdited();
|
||||
}
|
||||
delete(selectedComponents);
|
||||
selection.addRange(firstRowIndex, firstRowIndex + 1);
|
||||
fixSelection();
|
||||
selectionChanged();
|
||||
@@ -532,7 +525,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
DataTypeComponent dtc = insert(rowIndex, datatype, length, null, null);
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -562,7 +554,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
checkIsAllowableDataType(dataType);
|
||||
insertMultiple(rowIndex, dataType, dtLen, multiple, monitor);
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
@@ -601,7 +592,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
});
|
||||
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
// componentEdited();
|
||||
selectionChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -637,7 +628,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
//componentEdited();
|
||||
selectionChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -753,7 +744,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
replace(rowIndex, datatype, newCompSize, oldDtc.getFieldName(), oldDtc.getComment());
|
||||
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -806,7 +796,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
dtc.setComment(oldDtc.getComment());
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -994,7 +983,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
int newIndex = startIndex - 1;
|
||||
moved = shiftComponentsUp(startIndex, endIndex);
|
||||
if (moved) {
|
||||
componentEdited();
|
||||
FieldSelection tmpFieldSelection = new FieldSelection();
|
||||
tmpFieldSelection.addRange(newIndex, newIndex + numSelected);
|
||||
setSelection(tmpFieldSelection);
|
||||
@@ -1018,7 +1006,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
int newIndex = startIndex + 1;
|
||||
moved = shiftComponentsDown(startIndex, endIndex);
|
||||
if (moved) {
|
||||
componentEdited();
|
||||
FieldSelection tmpFieldSelection = new FieldSelection();
|
||||
tmpFieldSelection.addRange(newIndex, newIndex + numSelected);
|
||||
setSelection(tmpFieldSelection);
|
||||
@@ -1038,7 +1025,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
// Adjust the selection since we added some components. Select last component added.
|
||||
setSelection(new int[] { rowIndex + multiple });
|
||||
|
||||
componentEdited();
|
||||
lastNumDuplicates = multiple;
|
||||
}
|
||||
|
||||
@@ -1143,9 +1129,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public void setValueAt(Object aValue, int rowIndex, int modelColumnIndex) {
|
||||
try {
|
||||
settingValueAt = true;
|
||||
if (fieldEdited(aValue, rowIndex, modelColumnIndex)) {
|
||||
componentEdited();
|
||||
}
|
||||
fieldEdited(aValue, rowIndex, modelColumnIndex);
|
||||
}
|
||||
finally {
|
||||
settingValueAt = false;
|
||||
@@ -1284,7 +1268,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
return;
|
||||
}
|
||||
|
||||
Composite composite = getOriginalComposite();
|
||||
T composite = getOriginalComposite();
|
||||
boolean reload = true;
|
||||
if (hasChanges || !viewComposite.isEquivalent(composite)) {
|
||||
hasChanges = true;
|
||||
@@ -1323,7 +1307,11 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public void dataTypeRemoved(DataTypeManager dtm, DataTypePath path) {
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DataType dataType = viewDTM.getDataType(path.getCategoryPath(), path.getDataTypeName());
|
||||
@@ -1380,7 +1368,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public void dataTypeRenamed(DataTypeManager dtm, DataTypePath oldPath, DataTypePath newPath) {
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
|
||||
if (!isLoaded()) {
|
||||
@@ -1434,7 +1422,11 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public void dataTypeMoved(DataTypeManager dtm, DataTypePath oldPath, DataTypePath newPath) {
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DataType dt = viewDTM.getDataType(oldPath);
|
||||
@@ -1468,20 +1460,14 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
public void dataTypeChanged(DataTypeManager dtm, DataTypePath path) {
|
||||
try {
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dtm instanceof CompositeViewerDataTypeManager) {
|
||||
// required to detect settings changes
|
||||
componentEdited();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
}
|
||||
|
||||
// If we don't currently have any modifications that need applying and
|
||||
// the structure in the editor just changed, then show the changed
|
||||
// structure.
|
||||
@@ -1566,7 +1552,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
DataType newDataType) {
|
||||
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
|
||||
if (!isLoaded()) {
|
||||
@@ -1723,15 +1709,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
return lastNumDuplicates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the data structure's modification state changes.
|
||||
*/
|
||||
void componentEdited() {
|
||||
updateAndCheckChangeState(); // Update the composite's change state information.
|
||||
fireTableDataChanged();
|
||||
componentDataChanged();
|
||||
}
|
||||
|
||||
protected int convertRowToOrdinal(int rowIndex) {
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
+31
-24
@@ -32,7 +32,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.button.GRadioButton;
|
||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.textfield.GFormattedTextField;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
@@ -50,8 +49,12 @@ import ghidra.util.layout.VerticalLayout;
|
||||
/**
|
||||
* Panel for editing a composite with a blank line at the bottom of the table
|
||||
* when in unlocked mode.
|
||||
*
|
||||
* @param <T> Specific {@link Composite} type being edited
|
||||
* @param <M> Specific {@link CompEditorModel} implementation which supports editing T
|
||||
*/
|
||||
public class CompEditorPanel extends CompositeEditorPanel {
|
||||
public class CompEditorPanel<T extends Composite, M extends CompEditorModel<T>>
|
||||
extends CompositeEditorPanel<T, M> {
|
||||
|
||||
protected final static Insets LEFT_INSETS = new Insets(2, 3, 1, 0);
|
||||
protected final static Insets VERTICAL_INSETS = new Insets(2, 2, 1, 0);
|
||||
@@ -93,7 +96,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
* @param provider
|
||||
* the editor provider furnishing this panel for editing.
|
||||
*/
|
||||
public CompEditorPanel(CompEditorModel model, CompositeEditorProvider provider) {
|
||||
public CompEditorPanel(M model, CompositeEditorProvider<T, M> provider) {
|
||||
super(model, provider);
|
||||
}
|
||||
|
||||
@@ -356,6 +359,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
e.consume();
|
||||
setStatus("");
|
||||
// revert to model state when escape is hit
|
||||
setCompositeName(model.getCompositeName());
|
||||
}
|
||||
@@ -406,6 +410,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
e.consume();
|
||||
setStatus("");
|
||||
// revert to model state when escape is hit
|
||||
setDescription(model.getDescription());
|
||||
}
|
||||
@@ -523,7 +528,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
"setting and the alignment of each component data type.</html>";
|
||||
|
||||
defaultAlignButton.addActionListener(e -> {
|
||||
((CompEditorModel) model).setAlignmentType(AlignmentType.DEFAULT, -1);
|
||||
model.setAlignmentType(AlignmentType.DEFAULT, -1);
|
||||
});
|
||||
|
||||
defaultAlignButton.setToolTipText(alignmentToolTip);
|
||||
@@ -532,7 +537,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
|
||||
private void setupMachineMinAlignButton() {
|
||||
DataOrganization dataOrganization =
|
||||
((CompEditorModel) model).viewComposite.getDataOrganization();
|
||||
model.viewComposite.getDataOrganization();
|
||||
int machineAlignment = dataOrganization.getMachineAlignment();
|
||||
|
||||
machineAlignButton = new GRadioButton("machine: " + machineAlignment);
|
||||
@@ -546,7 +551,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
machineAlignButton.setToolTipText(alignmentToolTip);
|
||||
|
||||
machineAlignButton.addActionListener(e -> {
|
||||
((CompEditorModel) model).setAlignmentType(AlignmentType.MACHINE, -1);
|
||||
model.setAlignmentType(AlignmentType.MACHINE, -1);
|
||||
});
|
||||
|
||||
provider.registerHelp(machineAlignButton, "Align");
|
||||
@@ -634,7 +639,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
((CompEditorModel) model).setAlignmentType(AlignmentType.EXPLICIT, minAlignment);
|
||||
model.setAlignmentType(AlignmentType.EXPLICIT, minAlignment);
|
||||
adjustCompositeInfo();
|
||||
}
|
||||
catch (IllegalArgumentException e1) {
|
||||
@@ -664,7 +669,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
infoPanel.add(actualAlignmentPanel, gridBagConstraints);
|
||||
|
||||
actualAlignmentValueLabel = new JLabel();
|
||||
int actualAlignment = ((CompEditorModel) model).getActualAlignment();
|
||||
int actualAlignment = model.getActualAlignment();
|
||||
actualAlignmentValueLabel.setText(Integer.toString(actualAlignment));
|
||||
actualAlignmentValueLabel.setToolTipText(actualAlignmentToolTip);
|
||||
actualAlignmentValueLabel.setBackground(getBackground());
|
||||
@@ -765,7 +770,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
"<font color=\"" + Palette.BLUE.toHexString() +
|
||||
"\" size=\"-2\">(<F1> for help)</font></html>";
|
||||
packingEnablementButton.addActionListener(e -> {
|
||||
((CompEditorModel) model).setPackingType(
|
||||
model.setPackingType(
|
||||
packingEnablementButton.isSelected() ? PackingType.DEFAULT : PackingType.DISABLED,
|
||||
-1);
|
||||
});
|
||||
@@ -783,7 +788,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
"<html>Indicates <B>default</B> compiler packing rules should be applied.</html>";
|
||||
|
||||
defaultPackingButton.addActionListener(e -> {
|
||||
((CompEditorModel) model).setPackingType(PackingType.DEFAULT, -1);
|
||||
model.setPackingType(PackingType.DEFAULT, -1);
|
||||
});
|
||||
|
||||
defaultPackingButton.setToolTipText(packingToolTipText);
|
||||
@@ -860,7 +865,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
}
|
||||
|
||||
private void chooseByValuePacking() {
|
||||
((CompEditorModel) model).setPackingType(PackingType.EXPLICIT, 1);
|
||||
model.setPackingType(PackingType.EXPLICIT, 1);
|
||||
explicitPackingTextField.selectAll();
|
||||
explicitPackingTextField.requestFocus();
|
||||
}
|
||||
@@ -873,7 +878,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
if (explicitPacking <= 0) {
|
||||
return;
|
||||
}
|
||||
((CompEditorModel) model).setPackingType(PackingType.EXPLICIT, explicitPacking);
|
||||
model.setPackingType(PackingType.EXPLICIT, explicitPacking);
|
||||
adjustCompositeInfo();
|
||||
}
|
||||
|
||||
@@ -881,7 +886,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
* Sets the currently displayed structure packing value (maximum component alignment)
|
||||
*/
|
||||
public void refreshGUIPackingValue() {
|
||||
PackingType packingType = ((CompEditorModel) model).getPackingType();
|
||||
PackingType packingType = model.getPackingType();
|
||||
String packingString = "";
|
||||
|
||||
boolean packingEnabled = packingType != PackingType.DISABLED;
|
||||
@@ -895,7 +900,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
defaultPackingButton.setSelected(true);
|
||||
}
|
||||
else if (packingType == PackingType.EXPLICIT) {
|
||||
int packValue = ((CompEditorModel) model).getExplicitPackingValue();
|
||||
int packValue = model.getExplicitPackingValue();
|
||||
packingString =
|
||||
model.showHexNumbers ? CompositeViewerModel.getHexString(packValue, true)
|
||||
: Integer.toString(packValue);
|
||||
@@ -985,7 +990,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((CompEditorModel) model).isSizeEditable()) {
|
||||
if (!model.isSizeEditable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1022,13 +1027,13 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
}
|
||||
|
||||
private void chooseExplicitAlign() {
|
||||
if (((CompEditorModel) model).getAlignmentType() != AlignmentType.EXPLICIT) {
|
||||
Composite viewComposite = ((CompEditorModel) model).viewComposite;
|
||||
if (model.getAlignmentType() != AlignmentType.EXPLICIT) {
|
||||
Composite viewComposite = model.viewComposite;
|
||||
int defaultValue = 1;
|
||||
if (viewComposite.isPackingEnabled()) {
|
||||
defaultValue = viewComposite.getDataOrganization().getMachineAlignment();
|
||||
}
|
||||
((CompEditorModel) model).setAlignmentType(AlignmentType.EXPLICIT, defaultValue);
|
||||
model.setAlignmentType(AlignmentType.EXPLICIT, defaultValue);
|
||||
}
|
||||
explicitAlignTextField.selectAll();
|
||||
explicitAlignTextField.requestFocus();
|
||||
@@ -1118,6 +1123,8 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus("");
|
||||
|
||||
// Adjust the value.
|
||||
String newName = nameTextField.getText().trim();
|
||||
if (!DataUtilities.isValidDataTypeName(newName)) {
|
||||
@@ -1163,6 +1170,8 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus("");
|
||||
|
||||
String newValue = this.descriptionTextField.getText().trim();
|
||||
if (!newValue.equals(model.getDescription())) {
|
||||
model.setDescription(newValue);
|
||||
@@ -1197,7 +1206,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
nameTextField.setText(name);
|
||||
nameTextField.setDefaultValue(name);
|
||||
nameTextField.setIsError(false);
|
||||
setStatus("");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1209,12 +1217,11 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
descriptionTextField.setText(description);
|
||||
descriptionTextField.setDefaultValue(description);
|
||||
descriptionTextField.setIsError(false);
|
||||
setStatus("");
|
||||
}
|
||||
|
||||
public void refreshGUIMinimumAlignmentValue() {
|
||||
|
||||
AlignmentType alignmentType = ((CompEditorModel) model).getAlignmentType();
|
||||
AlignmentType alignmentType = model.getAlignmentType();
|
||||
String minimumAlignmentStr = "";
|
||||
if (alignmentType == AlignmentType.DEFAULT) {
|
||||
defaultAlignButton.setSelected(true);
|
||||
@@ -1224,7 +1231,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
}
|
||||
else {
|
||||
explicitAlignButton.setSelected(true);
|
||||
int minimumAlignment = ((CompEditorModel) model).getExplicitMinimumAlignment();
|
||||
int minimumAlignment = model.getExplicitMinimumAlignment();
|
||||
minimumAlignmentStr =
|
||||
model.showHexNumbers ? CompositeViewerModel.getHexString(minimumAlignment, true)
|
||||
: Integer.toString(minimumAlignment);
|
||||
@@ -1238,7 +1245,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
* Updates the GUI display of the actual alignment value.
|
||||
*/
|
||||
public void refreshGUIActualAlignmentValue() {
|
||||
int actualAlignment = ((CompEditorModel) model).getActualAlignment();
|
||||
int actualAlignment = model.getActualAlignment();
|
||||
String alignmentStr =
|
||||
model.showHexNumbers ? CompositeViewerModel.getHexString(actualAlignment, true)
|
||||
: Integer.toString(actualAlignment);
|
||||
@@ -1259,7 +1266,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
* @param size the new size
|
||||
*/
|
||||
private void setCompositeSize(int size) {
|
||||
boolean sizeIsEditable = ((CompEditorModel) model).isSizeEditable();
|
||||
boolean sizeIsEditable = model.isSizeEditable();
|
||||
if (sizeTextField.isEditable() != sizeIsEditable) {
|
||||
setSizeEditable(sizeIsEditable);
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -29,7 +29,7 @@ public class ComponentProgramActionContext extends ProgramActionContext
|
||||
private DataTypeComponent component;
|
||||
private Composite composite;
|
||||
|
||||
public ComponentProgramActionContext(CompositeEditorProvider compositeEditorProvider,
|
||||
public ComponentProgramActionContext(CompositeEditorProvider<?, ?> compositeEditorProvider,
|
||||
Program program, DataTypeComponent component) {
|
||||
super(compositeEditorProvider, program);
|
||||
this.component = component;
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -29,7 +29,7 @@ public class ComponentStandAloneActionContext extends DefaultActionContext
|
||||
private DataTypeComponent component;
|
||||
private Composite composite;
|
||||
|
||||
public ComponentStandAloneActionContext(CompositeEditorProvider compositeEditorProvider,
|
||||
public ComponentStandAloneActionContext(CompositeEditorProvider<?, ?> compositeEditorProvider,
|
||||
DataTypeComponent component) {
|
||||
super(compositeEditorProvider);
|
||||
this.component = component;
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -26,7 +26,7 @@ import ghidra.program.model.data.*;
|
||||
* Other CompositeEditorActions can be added for it to manage.
|
||||
*/
|
||||
public class CompositeEditorActionManager {
|
||||
private CompositeEditorProvider provider;
|
||||
private CompositeEditorProvider<?, ?> provider;
|
||||
private ArrayList<CompositeEditorTableAction> editorActions =
|
||||
new ArrayList<CompositeEditorTableAction>();
|
||||
private ArrayList<CompositeEditorTableAction> favoritesActions =
|
||||
@@ -45,7 +45,7 @@ public class CompositeEditorActionManager {
|
||||
* @param provider the provider that owns this composite editor action manager
|
||||
* favorites and cycle groups.
|
||||
*/
|
||||
public CompositeEditorActionManager(CompositeEditorProvider provider) {
|
||||
public CompositeEditorActionManager(CompositeEditorProvider<?, ?> provider) {
|
||||
this.provider = provider;
|
||||
this.dataTypeMgrService = provider.dtmService;
|
||||
adapter = new DataTypeManagerChangeListenerAdapter() {
|
||||
|
||||
+32
-14
@@ -43,8 +43,12 @@ import ghidra.util.task.TaskMonitor;
|
||||
/**
|
||||
* Model for editing a composite data type. Specific composite data type editors
|
||||
* should extend this class.
|
||||
*
|
||||
* @param <T> Specific {@link Composite} type being managed
|
||||
*/
|
||||
abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
abstract public class CompositeEditorModel<T extends Composite> extends CompositeViewerModel<T> {
|
||||
|
||||
// TODO: This class should be combined with CompositeViewerModel since we only support editor use
|
||||
|
||||
/**
|
||||
* Whether or not an apply is occurring. Need to ignore changes to the
|
||||
@@ -71,7 +75,8 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
* Construct abstract composite editor model
|
||||
* @param provider composite editor provider
|
||||
*/
|
||||
protected CompositeEditorModel(CompositeEditorProvider provider) {
|
||||
protected CompositeEditorModel(
|
||||
CompositeEditorProvider<T, ? extends CompositeEditorModel<T>> provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
@@ -88,7 +93,7 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
endFieldEditing();
|
||||
}
|
||||
|
||||
CompositeViewerDataTypeManager oldViewDTM = viewDTM;
|
||||
CompositeViewerDataTypeManager<T> oldViewDTM = viewDTM;
|
||||
|
||||
originalComposite = viewDTM.getResolvedViewComposite();
|
||||
originalCompositeId = DataTypeManager.NULL_DATATYPE_ID;
|
||||
@@ -96,8 +101,8 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
currentName = originalComposite.getName();
|
||||
|
||||
// Use temporary standalone view datatype manager
|
||||
viewDTM = new CompositeViewerDataTypeManager(viewDTM.getName(),
|
||||
viewDTM.getResolvedViewComposite(), () -> restoreEditor());
|
||||
viewDTM = new CompositeViewerDataTypeManager<>(viewDTM.getName(),
|
||||
viewDTM.getResolvedViewComposite(), this::componentEdited, this::restoreEditor);
|
||||
|
||||
viewComposite = viewDTM.getResolvedViewComposite();
|
||||
|
||||
@@ -108,7 +113,9 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
// as they get resolved into the view datatype manager. This may result in the incorrect
|
||||
// underlying datatype default setting value being presented when adjusting component
|
||||
// default settings.
|
||||
cloneAllComponentSettings(originalComposite, viewComposite);
|
||||
viewDTM.withTransaction("Load Settings",
|
||||
() -> cloneAllComponentSettings(originalComposite, viewComposite));
|
||||
viewDTM.clearUndo();
|
||||
|
||||
// Dispose previous view DTM
|
||||
oldViewDTM.close();
|
||||
@@ -124,7 +131,7 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Composite dataType) {
|
||||
public void load(T dataType) {
|
||||
Objects.requireNonNull(dataType);
|
||||
|
||||
DataTypeManager dtm = dataType.getDataTypeManager();
|
||||
@@ -179,19 +186,30 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
currentName = viewComposite.getName();
|
||||
updateAndCheckChangeState();
|
||||
|
||||
clearStatus();
|
||||
compositeInfoChanged();
|
||||
fireTableDataChanged();
|
||||
componentDataChanged();
|
||||
}
|
||||
|
||||
protected void componentEdited() {
|
||||
|
||||
// NOTE: This method relies heavily on the viewDTM with transaction support
|
||||
// and this method specified as the changeCallback method. If viewDTM has been
|
||||
// instantiated with a single open transaction this method will never be used
|
||||
// and provisions must be made for proper notification when changes are made.
|
||||
|
||||
updateAndCheckChangeState(); // Update the composite's change state information.
|
||||
fireTableDataChanged();
|
||||
componentDataChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code viewComposite} and associated view datatype manager ({@code viewDTM}) and
|
||||
* changes listener(s) if required.
|
||||
*
|
||||
* @param original original composite being loaded
|
||||
*/
|
||||
protected void createViewCompositeFromOriginalComposite(Composite original) {
|
||||
protected void createViewCompositeFromOriginalComposite(T original) {
|
||||
|
||||
if (viewDTM != null) {
|
||||
viewDTM.close();
|
||||
@@ -199,8 +217,8 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
}
|
||||
|
||||
// Use temporary standalone view datatype manager
|
||||
viewDTM = new CompositeViewerDataTypeManager(original.getDataTypeManager().getName(),
|
||||
original, () -> restoreEditor());
|
||||
viewDTM = new CompositeViewerDataTypeManager<>(original.getDataTypeManager().getName(),
|
||||
original, this::componentEdited, this::restoreEditor);
|
||||
|
||||
viewComposite = viewDTM.getResolvedViewComposite();
|
||||
|
||||
@@ -211,7 +229,7 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
// as they get resolved into the view datatype manager. This may result in the incorrect
|
||||
// underlying datatype default setting value being presented when adjusting component
|
||||
// default settings.
|
||||
viewDTM.withTransaction("Apply Settings",
|
||||
viewDTM.withTransaction("Load Settings",
|
||||
() -> cloneAllComponentSettings(original, viewComposite));
|
||||
viewDTM.clearUndo();
|
||||
}
|
||||
@@ -236,7 +254,7 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
* Returns the docking windows component provider associated with this edit model.
|
||||
* @return the component provider
|
||||
*/
|
||||
protected CompositeEditorProvider getProvider() {
|
||||
protected CompositeEditorProvider<T, ?> getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@@ -1485,7 +1503,7 @@ abstract public class CompositeEditorModel extends CompositeViewerModel {
|
||||
* Get the composite edtor's datatype manager
|
||||
* @return composite edtor's datatype manager
|
||||
*/
|
||||
public CompositeViewerDataTypeManager getViewDataTypeManager() {
|
||||
public CompositeViewerDataTypeManager<T> getViewDataTypeManager() {
|
||||
return viewDTM;
|
||||
}
|
||||
|
||||
|
||||
+2
-13
@@ -1,13 +1,12 @@
|
||||
/* ###
|
||||
* 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.
|
||||
* 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.
|
||||
@@ -52,16 +51,6 @@ public interface CompositeEditorModelListener extends CompositeViewerModelListen
|
||||
* COMPOSITE_LOADED, NO_COMPOSITE_LOADED, EDIT_STARTED, EDIT_ENDED.
|
||||
*/
|
||||
public abstract void compositeEditStateChanged(int type);
|
||||
|
||||
// /**
|
||||
// * Called when the data type for one of our components changes.
|
||||
// * This means that any component that has this data type may have consumed
|
||||
// * undefined bytes which followed it. Therefore any change that has been
|
||||
// * started, but not finished yet, may not be allowable and should be
|
||||
// * cancelled.
|
||||
// * @param dt the data type that has changed.
|
||||
// */
|
||||
// public abstract void componentDataTypeChanged(DataType dt);
|
||||
|
||||
/**
|
||||
* Called when the model wants to end cell editing that is in progress.
|
||||
|
||||
+10
-27
@@ -32,7 +32,6 @@ import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.DockingWindowManager;
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import docking.dnd.DropTgtAdapter;
|
||||
import docking.dnd.Droppable;
|
||||
@@ -64,14 +63,18 @@ import help.HelpService;
|
||||
* This provides a table with cell edit functionality and drag and drop capability.
|
||||
* Below the table is an information area for non-component information about the
|
||||
* composite data type. To add your own info panel override the createInfoPanel() method.
|
||||
*
|
||||
* @param <T> Specific {@link Composite} type being edited
|
||||
* @param <M> Specific {@link CompositeEditorModel} implementation which supports editing T
|
||||
*/
|
||||
public abstract class CompositeEditorPanel extends JPanel
|
||||
public abstract class CompositeEditorPanel<T extends Composite, M extends CompositeEditorModel<T>>
|
||||
extends JPanel
|
||||
implements CompositeEditorModelListener, ComponentCellEditorListener, Droppable {
|
||||
|
||||
protected static final Border BEVELED_BORDER = BorderFactory.createLoweredBevelBorder();
|
||||
|
||||
protected CompositeEditorProvider provider;
|
||||
protected CompositeEditorModel model;
|
||||
protected CompositeEditorProvider<T, M> provider;
|
||||
protected M model;
|
||||
protected GTable table;
|
||||
private JLabel statusLabel;
|
||||
|
||||
@@ -90,7 +93,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
|
||||
protected SearchControlPanel searchPanel;
|
||||
|
||||
public CompositeEditorPanel(CompositeEditorModel model, CompositeEditorProvider provider) {
|
||||
public CompositeEditorPanel(M model, CompositeEditorProvider<T, M> provider) {
|
||||
super(new BorderLayout());
|
||||
this.provider = provider;
|
||||
this.model = model;
|
||||
@@ -145,7 +148,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
return table;
|
||||
}
|
||||
|
||||
protected CompositeEditorModel getModel() {
|
||||
protected M getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -165,30 +168,10 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
table.setDefaultRenderer(DataTypeInstance.class, dtiCellRenderer);
|
||||
}
|
||||
|
||||
private boolean launchBitFieldEditor(int modelRow, int modelColumn) {
|
||||
if (model.viewComposite instanceof Structure && !model.viewComposite.isPackingEnabled() &&
|
||||
model.getDataTypeColumn() == modelColumn && modelRow < model.getNumComponents()) {
|
||||
// check if we are attempting to edit a bitfield
|
||||
DataTypeComponent dtComponent = model.getComponent(modelRow);
|
||||
if (dtComponent.isBitFieldComponent()) {
|
||||
table.getCellEditor().cancelCellEditing();
|
||||
CompEditorModel editorModel = (CompEditorModel) model;
|
||||
BitFieldEditorDialog dlg = new BitFieldEditorDialog(model.viewComposite,
|
||||
provider.dtmService, modelRow, model.showHexNumbers,
|
||||
ordinal -> refreshTableAndSelection(editorModel, ordinal));
|
||||
Component c = provider.getComponent();
|
||||
DockingWindowManager.showDialog(c, dlg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
boolean launchBitFieldEditor(int modelRow, int modelColumn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void refreshTableAndSelection(CompEditorModel editorModel, int ordinal) {
|
||||
editorModel.notifyCompositeChanged();
|
||||
editorModel.setSelection(new int[] { ordinal, ordinal });
|
||||
}
|
||||
|
||||
private void setupTableCellEditor() {
|
||||
|
||||
table.addPropertyChangeListener("tableCellEditor", evt -> {
|
||||
|
||||
+11
-6
@@ -17,7 +17,8 @@ package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JTable;
|
||||
|
||||
import docking.*;
|
||||
import docking.widgets.OptionDialog;
|
||||
@@ -41,16 +42,20 @@ import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* Editor provider for a Composite Data Type.
|
||||
*
|
||||
* @param <T> Specific {@link Composite} type being edited
|
||||
* @param <M> Specific {@link CompositeEditorModel} implementation which supports editing T
|
||||
*/
|
||||
public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
public abstract class CompositeEditorProvider<T extends Composite, M extends CompositeEditorModel<T>>
|
||||
extends ComponentProviderAdapter
|
||||
implements EditorProvider, EditorActionListener {
|
||||
|
||||
protected static final Icon EDITOR_ICON = new GIcon("icon.plugin.composite.editor.provider");
|
||||
|
||||
protected Plugin plugin;
|
||||
protected Category category;
|
||||
protected CompositeEditorPanel editorPanel;
|
||||
protected CompositeEditorModel editorModel;
|
||||
protected CompositeEditorPanel<T, M> editorPanel;
|
||||
protected CompositeEditorModel<T> editorModel;
|
||||
protected WeakSet<EditorListener> listeners; // listeners for the editor closing.
|
||||
|
||||
protected DataTypeManagerService dtmService;
|
||||
@@ -90,7 +95,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
setTitle(getName() + " - " + getProviderSubTitle(editorModel.originalComposite));
|
||||
}
|
||||
|
||||
protected CompositeEditorModel getModel() {
|
||||
protected CompositeEditorModel<T> getModel() {
|
||||
return this.editorModel;
|
||||
}
|
||||
|
||||
@@ -178,7 +183,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
public CompositeEditorPanel<T, M> getComponent() {
|
||||
return editorPanel;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -39,8 +39,8 @@ abstract public class CompositeEditorTableAction extends DockingAction {
|
||||
static final String COMPONENT_ACTION_GROUP = "4_COMPONENT_EDITOR_ACTION";
|
||||
static final String BITFIELD_ACTION_GROUP = "5_COMPONENT_EDITOR_ACTION";
|
||||
|
||||
protected CompositeEditorProvider provider;
|
||||
protected CompositeEditorModel model;
|
||||
protected CompositeEditorProvider<?, ?> provider;
|
||||
protected CompositeEditorModel<?> model;
|
||||
protected String tooltip;
|
||||
protected ImageIcon icon;
|
||||
protected ActionListener listener;
|
||||
@@ -53,12 +53,13 @@ abstract public class CompositeEditorTableAction extends DockingAction {
|
||||
|
||||
// note: Only call this constructor if you know you do not want to use the shared editor prefix;
|
||||
// If you call this, then you must manage your own menu/popup/toolbar data installation
|
||||
protected CompositeEditorTableAction(CompositeEditorProvider provider, String name) {
|
||||
protected CompositeEditorTableAction(CompositeEditorProvider<?, ?> provider, String name) {
|
||||
super(name, provider.plugin.getName());
|
||||
init(provider);
|
||||
}
|
||||
|
||||
public CompositeEditorTableAction(CompositeEditorProvider provider, String name, String group,
|
||||
public CompositeEditorTableAction(CompositeEditorProvider<?, ?> provider, String name,
|
||||
String group,
|
||||
String[] popupPath, String[] menuPath, Icon icon) {
|
||||
super(name, provider.plugin.getName(), KeyBindingType.SHARED);
|
||||
init(provider);
|
||||
@@ -73,7 +74,7 @@ abstract public class CompositeEditorTableAction extends DockingAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void init(CompositeEditorProvider editorProvider) {
|
||||
private void init(CompositeEditorProvider<?, ?> editorProvider) {
|
||||
this.provider = editorProvider;
|
||||
this.model = provider.getModel();
|
||||
this.plugin = provider.plugin;
|
||||
|
||||
+49
-21
@@ -23,6 +23,7 @@ import db.util.ErrorHandler;
|
||||
import ghidra.program.database.DatabaseObject;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.ProgramArchitecture;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -30,11 +31,12 @@ import utility.function.Callback;
|
||||
|
||||
/**
|
||||
* {@link CompositeViewerDataTypeManager} provides a data type manager that the structure editor
|
||||
* will use internally for updating the structure being edited and tracking all directly and
|
||||
* will use internally for updating the structure being edited and tracks all directly and
|
||||
* indirectly referenced datatypes. This manager also facilitates undo/redo support within
|
||||
* the editor.
|
||||
* @param <T> Specific {@link Composite} type being managed
|
||||
*/
|
||||
public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
public class CompositeViewerDataTypeManager<T extends Composite> extends StandAloneDataTypeManager
|
||||
implements ErrorHandler {
|
||||
|
||||
/**
|
||||
@@ -42,16 +44,18 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
* This is where the edited datatype will be written back to.
|
||||
*/
|
||||
private final DataTypeManager originalDTM;
|
||||
private final Composite originalComposite; // may be null if not resolved into this DTM
|
||||
private final Composite viewComposite; // may be null if not resolved into this DTM
|
||||
private final T originalComposite; // may be null if not resolved into this DTM
|
||||
private final T viewComposite; // may be null if not resolved into this DTM
|
||||
|
||||
// Database-backed datatype ID map, view to/from original DTM
|
||||
// This is needed to account for datatype use and ID alterations across undo/redo
|
||||
private final IDMapDB dataTypeIDMap;
|
||||
|
||||
// single editor transaction use only - undo/redo not supported when used
|
||||
// Editor transaction use only - undo/redo not supported if restoreCallback is null
|
||||
private Callback restoredCallback;
|
||||
private Callback changeCallback;
|
||||
private int transactionId = 0;
|
||||
private boolean dataTypeChanged;
|
||||
|
||||
// Modification count used to signal optional clearing of undo/redo stack at the end of a
|
||||
// transaction should any database modifications occur.
|
||||
@@ -64,13 +68,13 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
/**
|
||||
* Creates a data type manager that the structure editor will use internally for managing
|
||||
* dependencies for an unmanaged structure being edited. A single transaction will be started
|
||||
* with this instantiation and held open until this instance is closed and undo/redo will
|
||||
* with this instantiation and held open until this instance is closed. Undo/redo is
|
||||
* not be supported.
|
||||
* @param rootName the root name for this data type manager (usually the program name).
|
||||
* @param originalDTM the original data type manager.
|
||||
*/
|
||||
public CompositeViewerDataTypeManager(String rootName, DataTypeManager originalDTM) {
|
||||
this(rootName, originalDTM, null, null);
|
||||
this(rootName, originalDTM, null, null, null);
|
||||
clearUndo();
|
||||
transactionId = startTransaction("Composite Edit");
|
||||
}
|
||||
@@ -80,11 +84,13 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
* structure being edited and its dependencies.
|
||||
* @param rootName the root name for this data type manager (usually the program name).
|
||||
* @param originalComposite the original composite data type that is being edited.
|
||||
* @param changeCallback Callback will be invoked when any change is made to the view composite.
|
||||
* @param restoredCallback Callback will be invoked following any undo/redo.
|
||||
*/
|
||||
public CompositeViewerDataTypeManager(String rootName, Composite originalComposite,
|
||||
Callback restoredCallback) {
|
||||
this(rootName, originalComposite.getDataTypeManager(), originalComposite, restoredCallback);
|
||||
public CompositeViewerDataTypeManager(String rootName, T originalComposite,
|
||||
Callback changeCallback, Callback restoredCallback) {
|
||||
this(rootName, originalComposite.getDataTypeManager(), originalComposite, changeCallback,
|
||||
restoredCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,13 +98,15 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
* @param rootName the root name for this data type manager (usually the program name).
|
||||
* @param originalDTM the original datatype manager
|
||||
* @param originalComposite the original composite data type that is being edited. (may be null)
|
||||
* @param changeCallback Callback will be invoked when any change is made to the view composite.
|
||||
* @param restoredCallback Callback will be invoked following any undo/redo.
|
||||
*/
|
||||
private CompositeViewerDataTypeManager(String rootName, DataTypeManager originalDTM,
|
||||
Composite originalComposite, Callback restoredCallback) {
|
||||
T originalComposite, Callback changeCallback, Callback restoredCallback) {
|
||||
super(rootName, originalDTM.getDataOrganization());
|
||||
this.originalDTM = originalDTM;
|
||||
this.originalComposite = originalComposite;
|
||||
this.changeCallback = changeCallback;
|
||||
this.restoredCallback = restoredCallback;
|
||||
|
||||
int txId = startTransaction("Setup for Edit");
|
||||
@@ -113,8 +121,9 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
clearUndo();
|
||||
}
|
||||
|
||||
private Composite resolveViewComposite() {
|
||||
return originalComposite != null ? (Composite) super.resolve(originalComposite, null)
|
||||
@SuppressWarnings("unchecked")
|
||||
private T resolveViewComposite() {
|
||||
return originalComposite != null ? (T) super.resolve(originalComposite, null)
|
||||
: null;
|
||||
}
|
||||
|
||||
@@ -160,10 +169,10 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the view composite if requested during instantiation.
|
||||
* Return the view composite
|
||||
* @return view composite or null if not resolved during instantiation.
|
||||
*/
|
||||
public Composite getResolvedViewComposite() {
|
||||
public T getResolvedViewComposite() {
|
||||
return viewComposite;
|
||||
}
|
||||
|
||||
@@ -325,15 +334,24 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyRestored() {
|
||||
super.notifyRestored();
|
||||
if (restoredCallback != null) {
|
||||
restoredCallback.call();
|
||||
public void dataTypeChanged(DataType dt, boolean isAutoChange) {
|
||||
super.dataTypeChanged(dt, isAutoChange);
|
||||
if (dt == viewComposite) {
|
||||
// Set dataTypeChanged which will trigger changeCallback when transaction fully comitted
|
||||
dataTypeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void endTransaction(int transactionID, boolean commit) {
|
||||
public void notifyRestored() {
|
||||
super.notifyRestored();
|
||||
if (restoredCallback != null) {
|
||||
Swing.runLater(() -> restoredCallback.call());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean endTransaction(int transactionID, boolean commit) {
|
||||
|
||||
if (viewComposite != null && getTransactionCount() == 1) {
|
||||
// Perform orphan removal only at the end of the outer-most transaction
|
||||
@@ -342,7 +360,7 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
}
|
||||
}
|
||||
|
||||
super.endTransaction(transactionID, commit);
|
||||
boolean committed = super.endTransaction(transactionID, commit);
|
||||
|
||||
if (!isTransactionActive() && flattenModCount != -1) {
|
||||
if (flattenModCount != dbHandle.getModCount()) {
|
||||
@@ -351,6 +369,16 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager
|
||||
}
|
||||
flattenModCount = -1;
|
||||
}
|
||||
|
||||
if (committed && dataTypeChanged && changeCallback != null) {
|
||||
Swing.runLater(() -> changeCallback.call());
|
||||
}
|
||||
|
||||
if (getTransactionCount() == 0) {
|
||||
dataTypeChanged = false;
|
||||
}
|
||||
|
||||
return committed;
|
||||
}
|
||||
|
||||
private void checkOrphansForRemoval(boolean cleanupIdMaps) {
|
||||
|
||||
+34
-17
@@ -27,11 +27,17 @@ import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import utility.function.Callback;
|
||||
|
||||
abstract class CompositeViewerModel extends AbstractTableModel
|
||||
/**
|
||||
* {@link CompositeViewerModel} provides the base composite viewer/editor implementation
|
||||
*
|
||||
* @param <T> Specific {@link Composite} type being managed
|
||||
*/
|
||||
abstract class CompositeViewerModel<T extends Composite> extends AbstractTableModel
|
||||
implements DataTypeManagerChangeListener {
|
||||
|
||||
/**
|
||||
@@ -40,13 +46,13 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
*/
|
||||
protected boolean updatingSelection = false;
|
||||
|
||||
protected Composite originalComposite;
|
||||
protected T originalComposite;
|
||||
protected DataTypePath originalDataTypePath;
|
||||
protected long originalCompositeId;
|
||||
protected DataTypeManager originalDTM;
|
||||
|
||||
protected Composite viewComposite;
|
||||
protected CompositeViewerDataTypeManager viewDTM;
|
||||
protected T viewComposite;
|
||||
protected CompositeViewerDataTypeManager<T> viewDTM;
|
||||
|
||||
private List<CompositeViewerModelListener> modelListeners = new ArrayList<>();
|
||||
|
||||
@@ -79,10 +85,11 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
protected int currentEditRow = -1;
|
||||
/** the current column for a field edit */
|
||||
protected int currentEditColumn = -1;
|
||||
protected CompositeEditorProvider provider;
|
||||
protected boolean showHexNumbers = false;
|
||||
|
||||
CompositeViewerModel(CompositeEditorProvider provider) {
|
||||
protected final CompositeEditorProvider<T, ?> provider;
|
||||
|
||||
CompositeViewerModel(CompositeEditorProvider<T, ?> provider) {
|
||||
this.provider = provider;
|
||||
selection = new FieldSelection();
|
||||
adjustWidth();
|
||||
@@ -165,7 +172,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
*
|
||||
* @param dataType the composite date type to be viewed.
|
||||
*/
|
||||
protected abstract void load(Composite dataType);
|
||||
protected abstract void load(T dataType);
|
||||
|
||||
/**
|
||||
* Unloads the currently loaded composite data type.
|
||||
@@ -276,8 +283,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
* @return the original composite being viewed or null if nothing is currently loaded in
|
||||
* the model.
|
||||
*/
|
||||
protected Composite getOriginalComposite() {
|
||||
Composite existingOriginal = getExistingOriginalComposite();
|
||||
protected T getOriginalComposite() {
|
||||
T existingOriginal = getExistingOriginalComposite();
|
||||
return existingOriginal != null ? existingOriginal : originalComposite;
|
||||
}
|
||||
|
||||
@@ -292,14 +299,15 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
return getExistingOriginalComposite() != null;
|
||||
}
|
||||
|
||||
private Composite getExistingOriginalComposite() {
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getExistingOriginalComposite() {
|
||||
long originalId = getCompositeID();
|
||||
if (originalId != DataTypeManager.NULL_DATATYPE_ID && originalDataTypePath != null &&
|
||||
originalDTM != null) {
|
||||
DataType dt = originalDTM.getDataType(originalId);
|
||||
if (dt instanceof Composite &&
|
||||
DataTypeUtilities.isSameKindDataType(originalComposite, dt)) {
|
||||
return (Composite) dt;
|
||||
return (T) dt;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -729,7 +737,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
@Override
|
||||
public void categoryRemoved(DataTypeManager dtm, CategoryPath path) {
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
if (originalDataTypePath.isAncestor(path)) {
|
||||
String msg = "\"" + originalDataTypePath.getDataTypeName() + "\" had its category \"" +
|
||||
@@ -754,7 +765,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
@Override
|
||||
public void categoryRenamed(DataTypeManager dtm, CategoryPath oldPath, CategoryPath newPath) {
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
if (!viewDTM.containsCategory(oldPath)) {
|
||||
return;
|
||||
@@ -782,7 +796,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
@Override
|
||||
public void categoryMoved(DataTypeManager dtm, CategoryPath oldPath, CategoryPath newPath) {
|
||||
if (dtm != originalDTM) {
|
||||
return; // Different DTM than the one for this data type.
|
||||
throw new AssertException("Listener only supports original DTM");
|
||||
}
|
||||
if (!isLoaded()) {
|
||||
return;
|
||||
}
|
||||
if (!viewDTM.containsCategory(oldPath)) {
|
||||
return;
|
||||
@@ -1162,13 +1179,13 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
* 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
|
||||
* @param <L> the type of the listener
|
||||
* @param listeners the listeners
|
||||
* @param method the method to call
|
||||
*/
|
||||
protected <T> void notify(List<T> listeners, Consumer<T> method) {
|
||||
protected <L> void notify(List<L> listeners, Consumer<L> method) {
|
||||
swing(() -> {
|
||||
for (T listener : listeners) {
|
||||
for (L listener : listeners) {
|
||||
method.accept(listener);
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class CycleGroupAction extends CompositeEditorTableAction {
|
||||
private final static String GROUP_NAME = DATA_ACTION_GROUP;
|
||||
private CycleGroup cycleGroup;
|
||||
|
||||
public CycleGroupAction(CompositeEditorProvider provider, CycleGroup cycleGroup) {
|
||||
public CycleGroupAction(CompositeEditorProvider<?, ?> provider, CycleGroup cycleGroup) {
|
||||
super(provider, cycleGroup.getName());
|
||||
|
||||
setMenuBarData(
|
||||
|
||||
+12
-10
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -75,7 +75,8 @@ public class DataTypeHelper {
|
||||
* @throws UsrException if the specified data type can't be used at the
|
||||
* specified index in the composite.
|
||||
*/
|
||||
public static DataType parseDataType(int index, String dtValue, CompositeEditorModel editModel,
|
||||
public static DataType parseDataType(int index, String dtValue,
|
||||
CompositeEditorModel<?> editModel,
|
||||
DataTypeManager dtManager, DataTypeManagerService dtmService)
|
||||
throws InvalidDataTypeException, UsrException {
|
||||
|
||||
@@ -98,7 +99,7 @@ public class DataTypeHelper {
|
||||
return newDt;
|
||||
}
|
||||
|
||||
static DataTypeInstance getSizedDataType(CompositeEditorProvider provider, DataType dt,
|
||||
static DataTypeInstance getSizedDataType(CompositeEditorProvider<?, ?> provider, DataType dt,
|
||||
int defaultSize, int maxSize) throws InvalidDataTypeException {
|
||||
if (dt instanceof FactoryDataType) {
|
||||
throw new InvalidDataTypeException("Factory data types are not allowed.");
|
||||
@@ -137,7 +138,7 @@ public class DataTypeHelper {
|
||||
provider.editorModel.usesAlignedLengthComponents());
|
||||
}
|
||||
|
||||
public static int requestDtSize(CompositeEditorProvider provider, String dtName,
|
||||
public static int requestDtSize(CompositeEditorProvider<?, ?> provider, String dtName,
|
||||
int defaultSize, int maxBytes) throws CancelledException {
|
||||
NumberInputDialog dtSizeDialog =
|
||||
new NumberInputDialog(dtName + " bytes", defaultSize, 1, maxBytes);
|
||||
@@ -149,7 +150,7 @@ public class DataTypeHelper {
|
||||
}
|
||||
int resultBytes = dtSizeDialog.getValue();
|
||||
|
||||
CompositeEditorModel model = provider.getModel();
|
||||
CompositeEditorModel<?> model = provider.getModel();
|
||||
model.setLastNumBytes(resultBytes);
|
||||
|
||||
return resultBytes;
|
||||
@@ -162,7 +163,8 @@ public class DataTypeHelper {
|
||||
* index where it will be located. If the data type is a valid size, it
|
||||
* will be returned unchanged. If the user cancels from the size dialog,
|
||||
* then a null is returned.
|
||||
*
|
||||
*
|
||||
* @param model The composite editor model
|
||||
* @param index the component index of where to add the data type.
|
||||
* @param dt the data type to add
|
||||
* @param useAlignedLength if true a fixed-length primitive data type will use its
|
||||
@@ -171,7 +173,7 @@ public class DataTypeHelper {
|
||||
* @return the data type and its size or null if the user canceled when
|
||||
* prompted for a size.
|
||||
*/
|
||||
public static DataTypeInstance getFixedLength(CompositeEditorModel model, int index,
|
||||
public static DataTypeInstance getFixedLength(CompositeEditorModel<?> model, int index,
|
||||
DataType dt, boolean useAlignedLength) {
|
||||
if (dt instanceof FactoryDataType) {
|
||||
model.setStatus("Factory data types are not allowed in a composite data type.");
|
||||
@@ -196,9 +198,9 @@ public class DataTypeHelper {
|
||||
return DataTypeInstance.getDataTypeInstance(dt, length, useAlignedLength);
|
||||
}
|
||||
|
||||
public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType dt,
|
||||
public static DataTypeInstance requestBytes(CompositeEditorModel<?> model, DataType dt,
|
||||
int maxBytes) {
|
||||
CompositeEditorProvider provider = model.getProvider();
|
||||
CompositeEditorProvider<?, ?> provider = model.getProvider();
|
||||
DataType actualDt = dt;
|
||||
if (actualDt instanceof TypeDef) {
|
||||
actualDt = ((TypeDef) actualDt).getBaseDataType();
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ public class DeleteAction extends CompositeEditorTableAction {
|
||||
private final static String[] popupPath = new String[] { "Delete" };
|
||||
private final static KeyStroke KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
|
||||
|
||||
public DeleteAction(CompositeEditorProvider provider) {
|
||||
public DeleteAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, popupPath, null, ICON);
|
||||
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -214,11 +214,11 @@ public class DndTableCellRenderer implements TableCellRenderer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inserting true indicates that only the top of the row is highlighted for feedback.
|
||||
* @param isInsert true indicates that only the top of the row is highlighted for feedback.
|
||||
* false indicates that the entire selection should be bordered on all sides.
|
||||
*/
|
||||
public void selectRange(boolean inserting) {
|
||||
this.inserting = inserting;
|
||||
public void selectRange(boolean isInsert) {
|
||||
this.inserting = isInsert;
|
||||
int tmpRow = rowForFeedback;
|
||||
rowForFeedback = -1;
|
||||
rangeMin = -1;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class DuplicateAction extends CompositeEditorTableAction {
|
||||
private final static KeyStroke KEY_STROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.ALT_DOWN_MASK);
|
||||
|
||||
public DuplicateAction(CompositeEditorProvider provider) {
|
||||
public DuplicateAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class DuplicateMultipleAction extends CompositeEditorTableAction {
|
||||
|
||||
private KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.ALT_DOWN_MASK);
|
||||
|
||||
public DuplicateMultipleAction(CompositeEditorProvider provider) {
|
||||
public DuplicateMultipleAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public class EditBitFieldAction extends CompositeEditorTableAction {
|
||||
private final static String DESCRIPTION = "Edit an existing bitfield";
|
||||
private static String[] POPUP_PATH = new String[] { ACTION_NAME };
|
||||
|
||||
public EditBitFieldAction(CompositeEditorProvider provider) {
|
||||
public EditBitFieldAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, null);
|
||||
setDescription(DESCRIPTION);
|
||||
if (!(model instanceof CompEditorModel)) {
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class EditComponentAction extends CompositeEditorTableAction {
|
||||
private static String[] MENU_PATH = new String[] { ACTION_NAME };
|
||||
private DataTypeManagerService dtmService;
|
||||
|
||||
public EditComponentAction(CompositeEditorProvider provider) {
|
||||
public EditComponentAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, MENU_PATH, null);
|
||||
this.dtmService = provider.dtmService;
|
||||
setDescription(DESCRIPTION);
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class EditFieldAction extends CompositeEditorTableAction {
|
||||
private static String[] POPUP_PATH = new String[] { ACTION_NAME };
|
||||
private static String[] MENU_PATH = new String[] { ACTION_NAME };
|
||||
|
||||
public EditFieldAction(CompositeEditorProvider provider) {
|
||||
public EditFieldAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, MENU_PATH, null);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -16,7 +16,8 @@
|
||||
package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.DataTypePath;
|
||||
|
||||
/**
|
||||
* Interface implemented by data type editors.
|
||||
@@ -42,8 +43,7 @@ public interface EditorProvider {
|
||||
public ComponentProvider getComponentProvider();
|
||||
|
||||
/**
|
||||
* Get the datatype manager associated with this editor.
|
||||
* @return the datatype manager associated with this editor
|
||||
* {@return the edited datatype's original datatype manager.}
|
||||
*/
|
||||
public DataTypeManager getDataTypeManager();
|
||||
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class FavoritesAction extends CompositeEditorTableAction {
|
||||
* @param provider the provider that owns this action
|
||||
* @param dt the favorite data type
|
||||
*/
|
||||
public FavoritesAction(CompositeEditorProvider provider, DataType dt) {
|
||||
public FavoritesAction(CompositeEditorProvider<?, ?> provider, DataType dt) {
|
||||
super(provider, dt.getDisplayName());
|
||||
this.dataType = dt;
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class FindReferencesToStructureFieldAction extends CompositeEditorTableAc
|
||||
private final static String ACTION_NAME = "Find Uses of";
|
||||
private final static String DESCRIPTION = "Find uses of field in the selected row";
|
||||
|
||||
public FindReferencesToStructureFieldAction(CompositeEditorProvider provider) {
|
||||
public FindReferencesToStructureFieldAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, BASIC_ACTION_GROUP, new String[] { ACTION_NAME }, null, null);
|
||||
setDescription(DESCRIPTION);
|
||||
setHelpLocation(new HelpLocation(HelpTopics.FIND_REFERENCES, "Data_Types"));
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class HexNumbersAction extends CompositeEditorTableAction implements Togg
|
||||
private static String[] PATH = new String[] { DESCRIPTION };
|
||||
private boolean isSelected;
|
||||
|
||||
public HexNumbersAction(CompositeEditorProvider provider) {
|
||||
public HexNumbersAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, PATH, PATH, null);
|
||||
setDescription(DESCRIPTION);
|
||||
setSelected(model.isShowingNumbersInHex());
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
||||
private final static KeyStroke KEY_STROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_DOWN_MASK);
|
||||
|
||||
public InsertUndefinedAction(CompositeEditorProvider provider) {
|
||||
public InsertUndefinedAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class MoveDownAction extends CompositeEditorTableAction {
|
||||
private final static KeyStroke KEY_STROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK);
|
||||
|
||||
public MoveDownAction(CompositeEditorProvider provider) {
|
||||
public MoveDownAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class MoveUpAction extends CompositeEditorTableAction {
|
||||
private final static KeyStroke KEY_STROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK);
|
||||
|
||||
public MoveUpAction(CompositeEditorProvider provider) {
|
||||
public MoveUpAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KEY_STROKE));
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class PointerAction extends CompositeEditorTableAction {
|
||||
private final static String DESCRIPTION = "Create a pointer(s) on the selection";
|
||||
private final static DataType POINTER_DT = new PointerDataType();
|
||||
|
||||
public PointerAction(CompositeEditorProvider provider) {
|
||||
public PointerAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, null, null, null);
|
||||
setDescription(DESCRIPTION);
|
||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_P, 0));
|
||||
|
||||
+5
-3
@@ -32,7 +32,7 @@ public class RedoChangeAction extends CompositeEditorTableAction {
|
||||
private final static Icon ICON = new GIcon("icon.redo");
|
||||
private final static String[] POPUP_PATH = new String[] { DESCRIPTION };
|
||||
|
||||
public RedoChangeAction(CompositeEditorProvider provider) {
|
||||
public RedoChangeAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setKeyBindingData(new KeyBindingData("ctrl shift Z"));
|
||||
setDescription("Redo editor change");
|
||||
@@ -43,8 +43,10 @@ public class RedoChangeAction extends CompositeEditorTableAction {
|
||||
if (!isEnabledForContext(context)) {
|
||||
return;
|
||||
}
|
||||
CompositeViewerDataTypeManager viewDTM = model.getViewDataTypeManager();
|
||||
CompositeViewerDataTypeManager<?> viewDTM = model.getViewDataTypeManager();
|
||||
viewDTM.redo();
|
||||
|
||||
model.clearStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,7 +54,7 @@ public class RedoChangeAction extends CompositeEditorTableAction {
|
||||
if (hasIncompleteFieldEntry()) {
|
||||
return false;
|
||||
}
|
||||
CompositeViewerDataTypeManager viewDTM = model.getViewDataTypeManager();
|
||||
CompositeViewerDataTypeManager<?> viewDTM = model.getViewDataTypeManager();
|
||||
boolean canRedo = viewDTM.canRedo();
|
||||
setEnabled(canRedo);
|
||||
String description = DESCRIPTION + (canRedo ? (": " + viewDTM.getRedoName()) : "");
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -31,13 +31,13 @@ public class SearchControlPanel extends JPanel {
|
||||
|
||||
private static final Icon NEXT_ICON = new GIcon("icon.plugin.composite.editor.search.next");
|
||||
private static final Icon PREV_ICON = new GIcon("icon.plugin.composite.editor.search.previous");
|
||||
private CompositeEditorPanel editorPanel;
|
||||
private CompositeEditorPanel<?, ?> editorPanel;
|
||||
private JTextField textField;
|
||||
|
||||
private EmptyBorderButton searchNext;
|
||||
private EmptyBorderButton searchPrevious;
|
||||
|
||||
public SearchControlPanel(CompositeEditorPanel editorPanel) {
|
||||
public SearchControlPanel(CompositeEditorPanel<?, ?> editorPanel) {
|
||||
this.editorPanel = editorPanel;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class ShowComponentPathAction extends CompositeEditorTableAction {
|
||||
private static String[] POPUP_PATH = new String[] { ACTION_NAME };
|
||||
private static String[] MENU_PATH = new String[] { ACTION_NAME };
|
||||
|
||||
public ShowComponentPathAction(CompositeEditorProvider provider) {
|
||||
public ShowComponentPathAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, MENU_PATH, null);
|
||||
setDescription(DESCRIPTION);
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class ShowDataTypeInTreeAction extends CompositeEditorTableAction {
|
||||
private static final String TOOLBAR_GROUP = "4_COMPONENT_EDITOR_ACTION";
|
||||
private static final Icon ICON = new GIcon("icon.plugin.composite.editor.show.type");
|
||||
|
||||
public ShowDataTypeInTreeAction(CompositeEditorProvider provider) {
|
||||
public ShowDataTypeInTreeAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, TOOLBAR_GROUP, null /*popupPath*/, null /*menuPath*/, ICON);
|
||||
|
||||
setToolBarData(new ToolBarData(ICON, TOOLBAR_GROUP));
|
||||
|
||||
+12
-23
@@ -33,7 +33,7 @@ import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
class StructureEditorModel extends CompEditorModel {
|
||||
class StructureEditorModel extends CompEditorModel<Structure> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int OFFSET = 0;
|
||||
@@ -184,14 +184,13 @@ class StructureEditorModel extends CompEditorModel {
|
||||
if (rowIndex < 0 || rowIndex == numComponents) {
|
||||
return null;
|
||||
}
|
||||
Structure viewStruct = (Structure) viewComposite;
|
||||
if (rowIndex > numComponents) {
|
||||
return null;
|
||||
}
|
||||
if (isShowingUndefinedBytes()) {
|
||||
return viewComposite.getComponent(rowIndex);
|
||||
}
|
||||
DataTypeComponent[] definedComponents = viewStruct.getDefinedComponents();
|
||||
DataTypeComponent[] definedComponents = viewComposite.getDefinedComponents();
|
||||
return definedComponents[rowIndex];
|
||||
}
|
||||
|
||||
@@ -215,8 +214,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
|
||||
viewDTM.withTransaction("Set Size", () -> {
|
||||
Structure structure = (Structure) viewComposite;
|
||||
structure.setLength(size);
|
||||
viewComposite.setLength(size);
|
||||
});
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
@@ -278,7 +276,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
boolean isSelected = selection.containsEntirely(BigInteger.valueOf(indices[i]));
|
||||
int numBytes = comp.getLength();
|
||||
((Structure) viewComposite).clearComponent(indices[i]);
|
||||
viewComposite.clearComponent(indices[i]);
|
||||
|
||||
// Adjust the selection due to the clear.
|
||||
adjustSelection(indices[i] + 1, numBytes - 1);
|
||||
@@ -291,7 +289,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
}
|
||||
});
|
||||
componentEdited();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -366,7 +363,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
// Ensure that last added component is selected to allow for repeated duplication
|
||||
setSelection(new int[] { index + multiple });
|
||||
|
||||
componentEdited();
|
||||
lastNumDuplicates = multiple;
|
||||
}
|
||||
|
||||
@@ -485,7 +481,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
int newIndex = startRowIndex - 1;
|
||||
moved = shiftComponentsUp(startRowIndex, endRowIndex);
|
||||
if (moved) {
|
||||
componentEdited();
|
||||
FieldSelection tmpFieldSelection = new FieldSelection();
|
||||
tmpFieldSelection.addRange(newIndex, newIndex + numSelected);
|
||||
setSelection(tmpFieldSelection);
|
||||
@@ -509,7 +504,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
int newIndex = startIndex + 1;
|
||||
moved = shiftComponentsDown(startIndex, endIndex);
|
||||
if (moved) {
|
||||
componentEdited();
|
||||
FieldSelection tmpFieldSelection = new FieldSelection();
|
||||
tmpFieldSelection.addRange(newIndex, newIndex + numSelected);
|
||||
setSelection(tmpFieldSelection);
|
||||
@@ -865,7 +859,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
else {
|
||||
BitFieldDataType bitfield = (BitFieldDataType) dataType;
|
||||
dtc = ((Structure) viewComposite).insertBitField(rowIndex, length,
|
||||
dtc = viewComposite.insertBitField(rowIndex, length,
|
||||
bitfield.getBitOffset(), bitfield.getBaseDataType(),
|
||||
bitfield.getDeclaredBitSize(), name, comment);
|
||||
}
|
||||
@@ -927,7 +921,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
if (!isPackingEnabled() && !isAtEnd(rowIndex)) {
|
||||
int origLen = getComponent(rowIndex).getLength();
|
||||
dtc = viewDTM.withTransaction("Replace Component", () -> {
|
||||
return ((Structure) viewComposite).replace(componentOrdinal, dataType, length,
|
||||
return viewComposite.replace(componentOrdinal, dataType, length,
|
||||
name, comment);
|
||||
});
|
||||
diffLen = origLen - dtc.getLength();
|
||||
@@ -948,16 +942,15 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
else {
|
||||
dtc = viewDTM.withTransaction("Replace Component", () -> {
|
||||
Structure struct = (Structure) viewComposite;
|
||||
DataTypeComponent comp = getComponent(rowIndex);
|
||||
if (!isPackingEnabled()) {
|
||||
// We are at end with packing disabled - grow structure if needed
|
||||
int avail = comp.getLength() + getNumUndefinedBytesAfter(comp);
|
||||
if (length > avail) {
|
||||
struct.growStructure(length - avail);
|
||||
viewComposite.growStructure(length - avail);
|
||||
}
|
||||
}
|
||||
return ((Structure) viewComposite).replace(componentOrdinal, dataType, length,
|
||||
return viewComposite.replace(componentOrdinal, dataType, length,
|
||||
name, comment);
|
||||
});
|
||||
}
|
||||
@@ -1052,9 +1045,8 @@ class StructureEditorModel extends CompEditorModel {
|
||||
|
||||
@Override
|
||||
protected void replaceOriginalComponents() {
|
||||
Structure dt = (Structure) getOriginalComposite();
|
||||
if (dt != null) {
|
||||
dt.replaceWith(viewComposite);
|
||||
if (originalComposite != null) {
|
||||
originalComposite.replaceWith(viewComposite);
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("ERROR: Couldn't replace structure components in " +
|
||||
@@ -1302,8 +1294,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
|
||||
viewDTM.withTransaction("Unpack Component", () -> {
|
||||
Structure viewStruct = (Structure) viewComposite;
|
||||
|
||||
// Get the field name and comment before removing.
|
||||
String fieldName = currentComp.getFieldName();
|
||||
String comment = currentComp.getComment();
|
||||
@@ -1346,13 +1336,13 @@ class StructureEditorModel extends CompEditorModel {
|
||||
if (!isPackingEnabled()) {
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
BitFieldDataType bitfield = (BitFieldDataType) dt;
|
||||
viewStruct.insertBitFieldAt(currentOffset + dtc.getOffset(),
|
||||
viewComposite.insertBitFieldAt(currentOffset + dtc.getOffset(),
|
||||
compLength, bitfield.getBitOffset(), bitfield.getBaseDataType(),
|
||||
bitfield.getDeclaredBitSize(), dtc.getFieldName(),
|
||||
dtc.getComment());
|
||||
}
|
||||
else {
|
||||
viewStruct.insertAtOffset(currentOffset + dtc.getOffset(), dt,
|
||||
viewComposite.insertAtOffset(currentOffset + dtc.getOffset(), dt,
|
||||
compLength, dtc.getFieldName(), dtc.getComment());
|
||||
}
|
||||
}
|
||||
@@ -1379,7 +1369,6 @@ class StructureEditorModel extends CompEditorModel {
|
||||
comp.setComment(comment);
|
||||
});
|
||||
fixSelection();
|
||||
componentEdited();
|
||||
selectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/* ###
|
||||
* 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.
|
||||
* 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.compositeeditor;
|
||||
|
||||
|
||||
public interface StructureEditorModelListener extends CompositeEditorModelListener {
|
||||
|
||||
/**
|
||||
* Called whenever the structure data type editor internal packing state changes
|
||||
* for the data type being edited.
|
||||
* Whether the structure is free form, aligned, or packed to a particular maximum alignment.
|
||||
*
|
||||
* @param type the new packing state: FREE_FORM, ALIGN, PACK, PACK2, PACK4, or PACK8.
|
||||
*/
|
||||
public abstract void internalAlignmentStateChanged(boolean aligned);
|
||||
|
||||
/**
|
||||
* Called whenever the structure data type editor internal packing state changes
|
||||
* for the data type being edited.
|
||||
* Whether the structure is free form, aligned, or packed to a particular maximum alignment.
|
||||
*
|
||||
* @param type the new packing state: FREE_FORM, ALIGN, PACK, PACK2, PACK4, or PACK8.
|
||||
*/
|
||||
public abstract void packStateChanged(long packingValue);
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/* ###
|
||||
* 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.compositeeditor;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
import docking.DockingWindowManager;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.data.Structure;
|
||||
|
||||
/**
|
||||
* Editor panel for Union datatype
|
||||
*/
|
||||
public class StructureEditorPanel extends CompEditorPanel<Structure, StructureEditorModel> {
|
||||
|
||||
public StructureEditorPanel(StructureEditorModel model, StructureEditorProvider provider) {
|
||||
super(model, provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean launchBitFieldEditor(int modelRow, int modelColumn) {
|
||||
if (!model.viewComposite.isPackingEnabled() &&
|
||||
model.getDataTypeColumn() == modelColumn && modelRow < model.getNumComponents()) {
|
||||
// check if we are attempting to edit a bitfield
|
||||
DataTypeComponent dtComponent = model.getComponent(modelRow);
|
||||
if (dtComponent.isBitFieldComponent()) {
|
||||
table.getCellEditor().cancelCellEditing();
|
||||
BitFieldEditorDialog dlg = new BitFieldEditorDialog(model.viewComposite,
|
||||
provider.dtmService, modelRow, model.showHexNumbers,
|
||||
ordinal -> refreshTableAndSelection(model, ordinal));
|
||||
Component c = provider.getComponent();
|
||||
DockingWindowManager.showDialog(c, dlg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void refreshTableAndSelection(StructureEditorModel editorModel, int ordinal) {
|
||||
editorModel.notifyCompositeChanged();
|
||||
editorModel.setSelection(new int[] { ordinal, ordinal });
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -27,7 +27,8 @@ import ghidra.util.Msg;
|
||||
/**
|
||||
* Editor for a Structure Data Type.
|
||||
*/
|
||||
public class StructureEditorProvider extends CompositeEditorProvider {
|
||||
public class StructureEditorProvider
|
||||
extends CompositeEditorProvider<Structure, StructureEditorModel> {
|
||||
|
||||
private BitFieldEditorDialog bitFieldEditor;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class StructureEditorProvider extends CompositeEditorProvider {
|
||||
editorModel = new StructureEditorModel(this, showHexNumbers);
|
||||
editorModel.load(structureDataType);
|
||||
initializeActions();
|
||||
editorPanel = new CompEditorPanel((StructureEditorModel) editorModel, this);
|
||||
editorPanel = new StructureEditorPanel((StructureEditorModel) editorModel, this);
|
||||
plugin.getTool().addComponentProvider(this, true);
|
||||
updateTitle();
|
||||
addActionsToTool();
|
||||
|
||||
+5
-3
@@ -32,7 +32,7 @@ public class UndoChangeAction extends CompositeEditorTableAction {
|
||||
private final static Icon ICON = new GIcon("icon.undo");
|
||||
private final static String[] POPUP_PATH = new String[] { DESCRIPTION };
|
||||
|
||||
public UndoChangeAction(CompositeEditorProvider provider) {
|
||||
public UndoChangeAction(CompositeEditorProvider<?, ?> provider) {
|
||||
super(provider, ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
|
||||
setKeyBindingData(new KeyBindingData("ctrl Z"));
|
||||
setDescription(DESCRIPTION);
|
||||
@@ -43,8 +43,10 @@ public class UndoChangeAction extends CompositeEditorTableAction {
|
||||
if (!isEnabledForContext(context)) {
|
||||
return;
|
||||
}
|
||||
CompositeViewerDataTypeManager viewDTM = model.getViewDataTypeManager();
|
||||
CompositeViewerDataTypeManager<?> viewDTM = model.getViewDataTypeManager();
|
||||
viewDTM.undo();
|
||||
|
||||
model.clearStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,7 +54,7 @@ public class UndoChangeAction extends CompositeEditorTableAction {
|
||||
if (hasIncompleteFieldEntry()) {
|
||||
return false;
|
||||
}
|
||||
CompositeViewerDataTypeManager viewDTM = model.getViewDataTypeManager();
|
||||
CompositeViewerDataTypeManager<?> viewDTM = model.getViewDataTypeManager();
|
||||
boolean canUndo = viewDTM.canUndo();
|
||||
setEnabled(canUndo);
|
||||
String description = DESCRIPTION + (canUndo ? (": " + viewDTM.getUndoName()) : "");
|
||||
|
||||
+1
-2
@@ -48,7 +48,7 @@ import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.UsrException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
class UnionEditorModel extends CompEditorModel {
|
||||
class UnionEditorModel extends CompEditorModel<Union> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int LENGTH = 0;
|
||||
@@ -465,7 +465,6 @@ class UnionEditorModel extends CompEditorModel {
|
||||
selection.addRange(rowIndex, rowIndex + 1);
|
||||
fixSelection();
|
||||
}
|
||||
componentEdited();
|
||||
return dtc;
|
||||
}
|
||||
catch (IllegalArgumentException exc) {
|
||||
|
||||
+10
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -17,9 +17,15 @@ package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class UnionEditorPanel extends CompEditorPanel {
|
||||
import ghidra.program.model.data.Union;
|
||||
|
||||
public UnionEditorPanel(UnionEditorModel model, CompositeEditorProvider provider) {
|
||||
/**
|
||||
* Editor panel for Union datatype
|
||||
*/
|
||||
public class UnionEditorPanel extends CompEditorPanel<Union, UnionEditorModel> {
|
||||
|
||||
public UnionEditorPanel(UnionEditorModel model,
|
||||
CompositeEditorProvider<Union, UnionEditorModel> provider) {
|
||||
super(model, provider);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -24,7 +24,7 @@ import ghidra.program.model.data.Union;
|
||||
/**
|
||||
* Editor for a Union Data Type.
|
||||
*/
|
||||
public class UnionEditorProvider extends CompositeEditorProvider {
|
||||
public class UnionEditorProvider extends CompositeEditorProvider<Union, UnionEditorModel> {
|
||||
|
||||
protected static final Icon UNION_EDITOR_ICON =
|
||||
new GIcon("icon.plugin.composite.editor.provider.union");
|
||||
|
||||
+10
-12
@@ -23,8 +23,10 @@ import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
/**
|
||||
* BiDirectionDataType is a special structure data type that allows both positive and negative
|
||||
* offset values.
|
||||
* {@link BiDirectionDataType} is a special structure data type that allows both positive and
|
||||
* negative offset values.
|
||||
* <P>
|
||||
* NOTE: This special purpose datatype does not support resolving with a {@link DataTypeManager}
|
||||
*/
|
||||
public abstract class BiDirectionDataType extends StructureDataType
|
||||
implements BiDirectionStructure {
|
||||
@@ -36,8 +38,12 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
protected int splitOffset; // division offset between negative/positive halves
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param length
|
||||
* Construct {@link BiDirectionDataType}
|
||||
* @param name data type display name
|
||||
* @param negativeLength negative allocation size
|
||||
* @param positiveLength positive allocation size
|
||||
* @param splitOffset division offset between negative/positive halves
|
||||
* @param dtm associated datatype manager for component datatypes
|
||||
*/
|
||||
protected BiDirectionDataType(String name, int negativeLength, int positiveLength,
|
||||
int splitOffset, DataTypeManager dtm) {
|
||||
@@ -47,14 +53,6 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
this.splitOffset = splitOffset;
|
||||
}
|
||||
|
||||
protected BiDirectionDataType(CategoryPath catPath, String name, int negativeLength,
|
||||
int positiveLength, int splitOffset, DataTypeManager dtm) {
|
||||
super(catPath, name, negativeLength + positiveLength, dtm);
|
||||
this.negativeLength = negativeLength;
|
||||
this.positiveLength = positiveLength;
|
||||
this.splitOffset = splitOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataType validateDataType(DataType dataType) {
|
||||
if (DataTypeComponent.usesZeroLengthComponent(dataType)) {
|
||||
|
||||
+3
-4
@@ -1,13 +1,12 @@
|
||||
/* ###
|
||||
* 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.
|
||||
* 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.
|
||||
@@ -35,7 +34,7 @@ public interface BiDirectionStructure extends Structure {
|
||||
/**
|
||||
* Get the component offset which represents the division point
|
||||
* between the positive and negative halves of the structure.
|
||||
* @return
|
||||
* @return split offset
|
||||
*/
|
||||
public abstract int getSplitOffset();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user