mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 19:15:53 +08:00
Merge remote-tracking branch 'origin/GP-910_ghidra1_BitViewHexDisplay--SQUASHED'
This commit is contained in:
@@ -1273,7 +1273,8 @@
|
||||
<P>While the Bitfield Editor is displayed local popup menu actions
|
||||
are provided which can facilitate additional component manipulations (e.g., <B>Add Bitfield</B>,
|
||||
<B>Edit Bitfield</B>, <B>Delete</B>). These actions relate to the component at the current
|
||||
mouse cursor location. Invoking either the <B>Add Bitfield</B> or
|
||||
mouse cursor location. An addition popup menu toggle action available over the bitfield
|
||||
viewer is <B>Show Byte Offsets in Hexadecimal</B>. Invoking either the <B>Add Bitfield</B> or
|
||||
<B>Edit Bitfield</B> local popup menu actions will immediately cancel the current bitfield
|
||||
operation if one is active.</P>
|
||||
|
||||
|
||||
+2
-1
@@ -54,7 +54,8 @@ public class AddBitFieldAction extends CompositeEditorTableAction {
|
||||
|
||||
BitFieldEditorDialog dlg =
|
||||
new BitFieldEditorDialog(editorModel.viewComposite, provider.dtmService,
|
||||
-(rowIndex + 1), ordinal -> refreshTableAndSelection(editorModel, ordinal));
|
||||
-(rowIndex + 1), model.showHexNumbers,
|
||||
ordinal -> refreshTableAndSelection(editorModel, ordinal));
|
||||
Component c = provider.getComponent();
|
||||
DockingWindowManager.showDialog(c, dlg);
|
||||
requestTableFocus();
|
||||
|
||||
+93
-10
@@ -17,13 +17,12 @@ package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.menu.DockingCheckboxMenuItemUI;
|
||||
import docking.widgets.OptionDialog;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
@@ -42,7 +41,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
private BitFieldEditorPanel bitFieldEditorPanel; // for unaligned use case
|
||||
|
||||
BitFieldEditorDialog(Composite composite, DataTypeManagerService dtmService, int editOrdinal,
|
||||
CompositeChangeListener listener) {
|
||||
boolean showOffsetsInHex, CompositeChangeListener listener) {
|
||||
super("Edit " + getCompositeType(composite) + " Bitfield");
|
||||
this.composite = composite;
|
||||
this.listener = listener;
|
||||
@@ -52,6 +51,8 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
setRememberLocation(false);
|
||||
setRememberSize(false);
|
||||
|
||||
bitFieldEditorPanel.setShowOffsetsInHex(showOffsetsInHex);
|
||||
|
||||
addActions();
|
||||
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Bitfield_Editor"));
|
||||
@@ -79,6 +80,27 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean startEditAllowed() {
|
||||
if (bitFieldEditorPanel.isEditing()) {
|
||||
int option = OptionDialog.showOptionDialog(rootPanel, "Edit in Progress",
|
||||
"Apply or Discard current changes before starting new edit?", "Apply", "Discard",
|
||||
OptionDialog.QUESTION_MESSAGE);
|
||||
if (option == OptionDialog.OPTION_ONE) {
|
||||
if (!bitFieldEditorPanel.apply(listener)) {
|
||||
return false;
|
||||
}
|
||||
setApplyEnabled(false);
|
||||
}
|
||||
else if (option == OptionDialog.CANCEL_OPTION) {
|
||||
return false;
|
||||
}
|
||||
else if (!bitFieldEditorPanel.endCurrentEdit()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private class EditBitFieldAction extends DockingAction {
|
||||
|
||||
EditBitFieldAction() {
|
||||
@@ -90,7 +112,10 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
DataTypeComponent bitfieldDtc = getEditComponent(context, true);
|
||||
if (bitfieldDtc == null || !bitFieldEditorPanel.endCurrentEdit()) {
|
||||
if (bitfieldDtc == null) {
|
||||
return;
|
||||
}
|
||||
if (!startEditAllowed()) {
|
||||
return;
|
||||
}
|
||||
initEdit(bitfieldDtc.getOrdinal(), true);
|
||||
@@ -112,9 +137,10 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (!bitFieldEditorPanel.endCurrentEdit()) {
|
||||
if (!startEditAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BitFieldEditorPanel.BitFieldEditorContext editorContext =
|
||||
(BitFieldEditorPanel.BitFieldEditorContext) context;
|
||||
|
||||
@@ -135,6 +161,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
DeleteComponentAction() {
|
||||
super("Delete", "BitFieldEditorDialog");
|
||||
setPopupMenuData(new MenuData(new String[] { getName() }, DELETE_ICON));
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Bitfield_Editor"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,10 +184,56 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private class ToggleHexUseAction extends DockingAction implements ToggleDockingActionIf {
|
||||
|
||||
private boolean isSelected;
|
||||
|
||||
ToggleHexUseAction() {
|
||||
super("Show Byte Offsets in Hexadecimal", "BitFieldEditorDialog");
|
||||
setEnabled(true);
|
||||
setSelected(bitFieldEditorPanel.isShowOffsetsInHex());
|
||||
setPopupMenuData(new MenuData(new String[] { getName() }));
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Bitfield_Editor"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
bitFieldEditorPanel.setShowOffsetsInHex(isSelected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean newValue) {
|
||||
if (isSelected == newValue) {
|
||||
return;
|
||||
}
|
||||
isSelected = newValue;
|
||||
firePropertyChanged(SELECTED_STATE_PROPERTY, !isSelected, isSelected);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JMenuItem doCreateMenuItem() {
|
||||
DockingCheckBoxMenuItem menuItem = new DockingCheckBoxMenuItem(isSelected);
|
||||
menuItem.setUI(
|
||||
(DockingCheckboxMenuItemUI) DockingCheckboxMenuItemUI.createUI(menuItem));
|
||||
return menuItem;
|
||||
}
|
||||
}
|
||||
|
||||
private void addActions() {
|
||||
addAction(new AddBitFieldAction());
|
||||
addAction(new EditBitFieldAction());
|
||||
addAction(new DeleteComponentAction());
|
||||
addAction(new ToggleHexUseAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +269,9 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
}
|
||||
|
||||
private JComponent buildWorkPanel(int editOrdinal) {
|
||||
bitFieldEditorPanel = new BitFieldEditorPanel(composite, dtmService);
|
||||
bitFieldEditorPanel = new BitFieldEditorPanel(composite, dtmService, dt -> {
|
||||
return baseDataTypeChanged(dt);
|
||||
});
|
||||
if (editOrdinal < 0) {
|
||||
initAdd(-editOrdinal - 1);
|
||||
}
|
||||
@@ -206,6 +281,14 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
return bitFieldEditorPanel;
|
||||
}
|
||||
|
||||
boolean baseDataTypeChanged(DataType bitfieldBaseDataType) {
|
||||
// BitFieldEditorPanel checks should be adequate
|
||||
boolean allowed = bitfieldBaseDataType != null;
|
||||
setOkEnabled(allowed);
|
||||
setApplyEnabled(allowed);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
private static String getCompositeType(Composite composite) {
|
||||
// currently supports unaligned case only!
|
||||
if (composite.isInternallyAligned()) {
|
||||
|
||||
+141
-20
@@ -22,9 +22,12 @@ import javax.swing.*;
|
||||
import javax.swing.event.CellEditorListener;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.widgets.DropDownSelectionTextField;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import ghidra.app.plugin.core.compositeeditor.BitFieldPlacementComponent.BitAttributes;
|
||||
import ghidra.app.plugin.core.compositeeditor.BitFieldPlacementComponent.BitFieldAllocation;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
@@ -32,7 +35,6 @@ import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
||||
import ghidra.app.util.datatype.NavigationDirection;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Composite;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
||||
import ghidra.util.layout.*;
|
||||
import resources.ResourceManager;
|
||||
@@ -46,10 +48,9 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
private static final Icon DECREMENT_ICON = ResourceManager.loadImage("images/Minus.png");
|
||||
private static final Icon INCREMENT_ICON = ResourceManager.loadImage("images/Plus.png");
|
||||
|
||||
private static final String ENTRY_ERROR_DIALOG_TITLE = "Bitfield Entry Error";
|
||||
|
||||
private DataTypeManagerService dtmService;
|
||||
private Composite composite;
|
||||
private Predicate<DataType> dataTypeValidator;
|
||||
|
||||
private JLabel allocationOffsetLabel;
|
||||
JButton decrementButton;
|
||||
@@ -68,11 +69,15 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
private SpinnerNumberModel bitSizeModel;
|
||||
private JSpinnerWithMouseWheel bitSizeInput;
|
||||
|
||||
private GDLabel statusTextField;
|
||||
|
||||
private BitSelectionHandler bitSelectionHandler;
|
||||
|
||||
|
||||
private boolean updating = false;
|
||||
|
||||
BitFieldEditorPanel(Composite composite, DataTypeManagerService dtmService) {
|
||||
BitFieldEditorPanel(Composite composite, DataTypeManagerService dtmService,
|
||||
Predicate<DataType> dataTypeValidator) {
|
||||
super();
|
||||
this.composite = composite;
|
||||
|
||||
@@ -85,8 +90,9 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
setFocusTraversalKeysEnabled(true);
|
||||
|
||||
this.dtmService = dtmService;
|
||||
this.dataTypeValidator = dataTypeValidator;
|
||||
|
||||
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
|
||||
|
||||
if (composite instanceof Structure) {
|
||||
add(createAllocationOffsetPanel());
|
||||
@@ -94,10 +100,20 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
add(createPlacementPanel());
|
||||
add(createLegendPanel());
|
||||
add(createEntryPanel());
|
||||
add(createStatusPanel());
|
||||
|
||||
enableControls(false);
|
||||
}
|
||||
|
||||
void setShowOffsetsInHex(boolean useHex) {
|
||||
placementComponent.setShowOffsetsInHex(useHex);
|
||||
updateAllocationOffsetLabel();
|
||||
}
|
||||
|
||||
boolean isShowOffsetsInHex() {
|
||||
return placementComponent.isShowOffsetsInHex();
|
||||
}
|
||||
|
||||
private JPanel createLegendPanel() {
|
||||
JPanel legendPanel = new JPanel(new BorderLayout());
|
||||
legendPanel.add(new BitFieldPlacementComponent.BitFieldLegend(null), BorderLayout.WEST);
|
||||
@@ -139,8 +155,16 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
|
||||
private void updateAllocationOffsetLabel() {
|
||||
if (composite instanceof Structure) {
|
||||
int allocOffset = placementComponent.getAllocationOffset();
|
||||
String allocOffsetStr;
|
||||
if (placementComponent.isShowOffsetsInHex()) {
|
||||
allocOffsetStr = "0x" + Integer.toHexString(allocOffset);
|
||||
}
|
||||
else {
|
||||
allocOffsetStr = Integer.toString(allocOffset);
|
||||
}
|
||||
String text =
|
||||
"Structure Offset of Allocation Unit: " + placementComponent.getAllocationOffset();
|
||||
"Structure Offset of Allocation Unit: " + allocOffsetStr;
|
||||
allocationOffsetLabel.setText(text);
|
||||
|
||||
int offset = placementComponent.getAllocationOffset();
|
||||
@@ -150,6 +174,31 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private Component createStatusPanel() {
|
||||
JPanel statusPanel = new JPanel(new BorderLayout());
|
||||
|
||||
statusTextField = new GDLabel(" ");
|
||||
statusTextField.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
statusTextField.setForeground(Color.red);
|
||||
|
||||
// use a strut panel so the size of the message area does not change if we make
|
||||
// the message label not visible
|
||||
int height = statusTextField.getPreferredSize().height;
|
||||
|
||||
statusPanel.add(Box.createVerticalStrut(height), BorderLayout.WEST);
|
||||
statusPanel.add(statusTextField, BorderLayout.CENTER);
|
||||
|
||||
return statusPanel;
|
||||
}
|
||||
|
||||
private void setStatus(String text) {
|
||||
statusTextField.setText(text);
|
||||
}
|
||||
|
||||
private void clearStatus() {
|
||||
statusTextField.setText("");
|
||||
}
|
||||
|
||||
private JPanel createEntryPanel() {
|
||||
|
||||
JComponent baseDataTypeEditor = createDataTypeChoiceEditor();
|
||||
@@ -211,7 +260,7 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
|
||||
final DropDownSelectionTextField<DataType> dtChoiceTextField =
|
||||
dtChoiceEditor.getDropDownTextField();
|
||||
dtChoiceTextField.setBorder(UIManager.getBorder("TextField.border"));
|
||||
dtChoiceTextField.setBorder((new JTextField()).getBorder());
|
||||
|
||||
dtChoiceEditor.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
@@ -242,10 +291,6 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
dtChoiceTextField.requestFocus();
|
||||
}
|
||||
else {
|
||||
baseDataType = dtChoiceEditor.getCellEditorValueAsDataType();
|
||||
if (baseDataType != null) {
|
||||
baseDataType = baseDataType.clone(composite.getDataTypeManager());
|
||||
}
|
||||
updateBitSizeModel();
|
||||
NavigationDirection direction = dtChoiceEditor.getNavigationDirection();
|
||||
if (direction == NavigationDirection.FORWARD) {
|
||||
@@ -271,12 +316,57 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
private boolean selectionActive = false;
|
||||
private int startBit;
|
||||
private int lastBit;
|
||||
private int lastX;
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (bitOffsetInput.isEnabled() || e.isConsumed() || e.getClickCount() != 2 ||
|
||||
!placementComponent.isWithinBitCell(e.getPoint())) {
|
||||
return;
|
||||
}
|
||||
BitAttributes bitAttributes = placementComponent.getBitAttributes(e.getPoint());
|
||||
if (bitAttributes != null) {
|
||||
DataTypeComponent dtc = bitAttributes.getDataTypeComponent(true);
|
||||
if (dtc == null || !dtc.isBitFieldComponent()) {
|
||||
return;
|
||||
}
|
||||
e.consume();
|
||||
initEdit(dtc, placementComponent.getAllocationOffset(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
if (!selectionActive && bitOffsetInput.isEnabled()) {
|
||||
boolean inBounds = placementComponent.isWithinBitCell(e.getPoint());
|
||||
setCursor(Cursor.getPredefinedCursor(
|
||||
inBounds ? Cursor.HAND_CURSOR : Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (!selectionActive && bitOffsetInput.isEnabled() &&
|
||||
placementComponent.isWithinBitCell(e.getPoint())) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
if (!selectionActive) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.isConsumed()) {
|
||||
return;
|
||||
}
|
||||
if (!placementComponent.isWithinBitCell(e.getPoint())) {
|
||||
return;
|
||||
}
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
e.consume();
|
||||
selectionActive = false;
|
||||
@@ -285,6 +375,10 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
startBit = setBitFieldOffset(e.getPoint());
|
||||
lastBit = startBit;
|
||||
selectionActive = startBit >= 0;
|
||||
if (selectionActive) {
|
||||
lastX = e.getPoint().x;
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,6 +392,15 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
e.consume();
|
||||
|
||||
Point p = e.getPoint();
|
||||
|
||||
if (p.x == lastX) {
|
||||
return;
|
||||
}
|
||||
Cursor cursor = Cursor.getPredefinedCursor(
|
||||
p.x < lastX ? Cursor.W_RESIZE_CURSOR : Cursor.E_RESIZE_CURSOR);
|
||||
setCursor(cursor);
|
||||
lastX = p.x;
|
||||
|
||||
int bitOffset = placementComponent.getBitOffset(p);
|
||||
if (bitOffset == lastBit) {
|
||||
return;
|
||||
@@ -328,6 +431,11 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
if (selectionActive && !e.isConsumed()) {
|
||||
e.consume();
|
||||
selectionActive = false;
|
||||
|
||||
Point p = e.getPoint();
|
||||
boolean inBounds = placementComponent.getVisibleRect().contains(p);
|
||||
setCursor(Cursor.getPredefinedCursor(
|
||||
inBounds ? Cursor.HAND_CURSOR : Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +453,7 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
|
||||
JPanel bitViewPanel = new JPanel(new PairLayout(0, 5));
|
||||
|
||||
JPanel labelPanel = new JPanel(new VerticalLayout(7));
|
||||
JPanel labelPanel = new JPanel(new VerticalLayout(5));
|
||||
labelPanel.setBorder(BorderFactory.createEmptyBorder(7, 5, 0, 0));
|
||||
JLabel byteOffsetLabel = new JLabel("Byte Offset:", SwingConstants.RIGHT);
|
||||
labelPanel.add(byteOffsetLabel);
|
||||
@@ -365,20 +473,32 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
private boolean checkValidBaseDataType() {
|
||||
DropDownSelectionTextField<DataType> textField = dtChoiceEditor.getDropDownTextField();
|
||||
String dtName = textField.getText().trim();
|
||||
boolean isValid = true;
|
||||
try {
|
||||
if (dtName.length() == 0 || !dtChoiceEditor.validateUserSelection()) {
|
||||
Msg.showError(BitFieldEditorPanel.class, textField, ENTRY_ERROR_DIALOG_TITLE,
|
||||
"Valid bitfield base datatype entry required");
|
||||
return false;
|
||||
setStatus("Valid bitfield base datatype entry required");
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
Msg.showError(BitFieldEditorPanel.class, textField, ENTRY_ERROR_DIALOG_TITLE,
|
||||
"Invalid bitfield base datatype: " + e.getMessage());
|
||||
return false;
|
||||
setStatus("Invalid bitfield base datatype: " + e.getMessage());
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (isValid) {
|
||||
DataType dt = dtChoiceEditor.getCellEditorValueAsDataType();
|
||||
if (!dataTypeValidator.apply(baseDataType)) {
|
||||
setStatus("Valid bitfield base datatype entry required");
|
||||
isValid = false;
|
||||
}
|
||||
else {
|
||||
baseDataType = dt.clone(composite.getDataTypeManager());
|
||||
clearStatus();
|
||||
}
|
||||
}
|
||||
else {
|
||||
dataTypeValidator.apply(null); // affects button enablement
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
void initAdd(DataType initialBaseDataType, int allocationOffset, int bitOffset,
|
||||
@@ -449,6 +569,7 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
updating = true;
|
||||
try {
|
||||
baseDataType = initialBaseDataType;
|
||||
dataTypeValidator.apply(baseDataType);
|
||||
dtChoiceEditor.setCellEditorValue(initialBaseDataType);
|
||||
fieldNameTextField.setText(initialFieldName);
|
||||
fieldCommentTextField.setText(initialComment);
|
||||
|
||||
+30
-1
@@ -38,6 +38,7 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
private static final int BYTE_SEPARATOR_THICKNESS = 2;
|
||||
private static final int SCROLLBAR_THICKNESS = 15;
|
||||
private static final int MY_HEIGHT = (2 * CELL_HEIGHT) + (3 * BYTE_SEPARATOR_THICKNESS);
|
||||
private static final int BYTE_ROW_HEIGHT = CELL_HEIGHT + (2 * BYTE_SEPARATOR_THICKNESS);
|
||||
|
||||
private static final int LENEND_BOX_SIZE = 16;
|
||||
|
||||
@@ -66,6 +67,7 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
private EditMode editMode = EditMode.NONE;
|
||||
private int editOrdinal = -1;
|
||||
private DataTypeComponent editComponent;
|
||||
private boolean showOffsetsInHex = false;
|
||||
|
||||
public static class BitFieldLegend extends JPanel {
|
||||
|
||||
@@ -161,6 +163,18 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
init(null);
|
||||
}
|
||||
|
||||
public void setShowOffsetsInHex(boolean useHex) {
|
||||
this.showOffsetsInHex = useHex;
|
||||
if (bitFieldAllocation != null) {
|
||||
bitFieldAllocation.refresh(true);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowOffsetsInHex() {
|
||||
return showOffsetsInHex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
return getPreferredSize();
|
||||
@@ -248,6 +262,15 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
return MY_HEIGHT + SCROLLBAR_THICKNESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if specified point is within bit cell region
|
||||
* @param p point within this component's bounds
|
||||
* @return true if p is within bit cell region
|
||||
*/
|
||||
public boolean isWithinBitCell(Point p) {
|
||||
return p.y < MY_HEIGHT && p.y > BYTE_ROW_HEIGHT;
|
||||
}
|
||||
|
||||
private int getPreferredWidth() {
|
||||
int extraLineSpace = BYTE_SEPARATOR_THICKNESS - BIT_SEPARATOR_THICKNESS;
|
||||
return (allocationByteSize * byteWidth) + BYTE_SEPARATOR_THICKNESS + extraLineSpace;
|
||||
@@ -658,7 +681,13 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
|
||||
g.setColor(TEXT_COLOR);
|
||||
|
||||
String offsetStr = Integer.toString(offset);
|
||||
String offsetStr;
|
||||
if (showOffsetsInHex) {
|
||||
offsetStr = "0x" + Integer.toHexString(offset);
|
||||
}
|
||||
else {
|
||||
offsetStr = Integer.toString(offset);
|
||||
}
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
int textY = y + (CELL_HEIGHT + fontMetrics.getMaxAscent() - BYTE_SEPARATOR_THICKNESS) / 2;
|
||||
int textX = x + (width - BYTE_SEPARATOR_THICKNESS - fontMetrics.stringWidth(offsetStr)) / 2;
|
||||
|
||||
+4
@@ -118,6 +118,9 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
@Override
|
||||
public void compositeInfoChanged() {
|
||||
adjustCompositeInfo();
|
||||
if (model.showHexNumbers != bitViewComponent.isShowOffsetsInHex()) {
|
||||
bitViewComponent.setShowOffsetsInHex(model.showHexNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +159,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||
protected JPanel createBitViewerPanel() {
|
||||
|
||||
bitViewComponent = new BitFieldPlacementComponent(model.viewComposite, false);
|
||||
bitViewComponent.setShowOffsetsInHex(model.showHexNumbers);
|
||||
model.addCompositeViewerModelListener(new CompositeEditorModelAdapter() {
|
||||
@Override
|
||||
public void selectionChanged() {
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
table.getCellEditor().cancelCellEditing();
|
||||
|
||||
BitFieldEditorDialog dlg = new BitFieldEditorDialog(model.viewComposite,
|
||||
provider.dtmService, editingRow, ordinal -> {
|
||||
provider.dtmService, editingRow, model.showHexNumbers, ordinal -> {
|
||||
model.notifyCompositeChanged();
|
||||
});
|
||||
Component c = provider.getComponent();
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class EditBitFieldAction extends CompositeEditorTableAction {
|
||||
}
|
||||
|
||||
BitFieldEditorDialog dlg = new BitFieldEditorDialog(editorModel.viewComposite,
|
||||
provider.dtmService, dtComponent.getOrdinal(),
|
||||
provider.dtmService, dtComponent.getOrdinal(), model.showHexNumbers,
|
||||
ordinal -> refreshTableAndSelection(editorModel, ordinal));
|
||||
Component c = provider.getComponent();
|
||||
DockingWindowManager.showDialog(c, dlg);
|
||||
|
||||
Reference in New Issue
Block a user