BitFields - updated help screenshots and corrected bitfield conflict
detection issue and structure editor unload/load handling
|
@ -15,24 +15,34 @@
|
||||||
<P>The Structure Editor is used to define the contents of a structure data type. It can be used
|
<P>The Structure Editor is used to define the contents of a structure data type. It can be used
|
||||||
to create a new structure or to modify existing ones. Structures are user defined data types
|
to create a new structure or to modify existing ones. Structures are user defined data types
|
||||||
that contain components. A component is a data type of a particular size and at a specified
|
that contain components. A component is a data type of a particular size and at a specified
|
||||||
offset in the structure. The following illustrates the editor for a structure data type.<BR>
|
offset in the structure. The following illustrates the editor for a structure data type.
|
||||||
</P>
|
</P>
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
|
||||||
|
|
||||||
|
|
||||||
<DIV align="center" style="margin-top: 10px;">
|
<DIV align="center" style="margin-top: 10px;">
|
||||||
<IMG src="images/StructureEditor.png" alt=""><BR>
|
<IMG src="images/StructureEditor.png" alt=""><BR>
|
||||||
</DIV>
|
</DIV>
|
||||||
|
|
||||||
|
<BR>
|
||||||
|
<P>As shown above, the Structure Editor also includes a bit-level view of the structure layout to improve
|
||||||
|
understanding of bitfield placement when they are present. Note that the byte ordering is
|
||||||
|
reversed for little-endian data organizations to ensure that a bitfield is always rendered
|
||||||
|
as a contiguous bit range. If inadequate space is available for a component label,
|
||||||
|
within the bit view of the component, it will be omitted. However, holding down the Shift-key
|
||||||
|
while using the mouse wheel on a component will zoom the view in and out
|
||||||
|
allowing component labels to appear when space permits. The bit view may also be used to make
|
||||||
|
and reflect single component selections with the table. Within the bit view any padding bits not visible within
|
||||||
|
table view as a component will include a small dot in the center of the displayed bit cell.<BR>
|
||||||
|
|
||||||
<P>The Union Editor is very similar to the Structure Editor, but is used to create or modify a
|
<P>The Union Editor is very similar to the Structure Editor, but is used to create or modify a
|
||||||
union data type. All the components of a Union are at an offset of 0. The following illustrates
|
union data type. All the components of a Union are at an offset of 0. The following illustrates
|
||||||
the editor for a union data type.</P>
|
the editor for a union data type.</P>
|
||||||
|
<BR>
|
||||||
<DIV align="center" style="margin-top: 10px;">
|
<DIV align="center" style="margin-top: 10px;">
|
||||||
<IMG src="images/UnionEditor.png" alt=""><BR>
|
<IMG src="images/UnionEditor.png" alt=""><BR>
|
||||||
</DIV>
|
</DIV>
|
||||||
|
<BR>
|
||||||
<P>A Structure Editor or Union Editor can be launched from the <A href=
|
<P>A Structure Editor or Union Editor can be launched from the <A href=
|
||||||
"help/topics/DataTypeManagerPlugin/data_type_manager_description.htm">Data Type Manager</A>,
|
"help/topics/DataTypeManagerPlugin/data_type_manager_description.htm">Data Type Manager</A>,
|
||||||
the <A href="help/topics/CodeBrowserPlugin/CodeBrowser.htm">Code Browser</A>, or the <A href=
|
the <A href="help/topics/CodeBrowserPlugin/CodeBrowser.htm">Code Browser</A>, or the <A href=
|
||||||
|
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 34 KiB |
|
@ -55,11 +55,11 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
private int bitWidth = 10;
|
private int bitWidth = 10;
|
||||||
private int byteWidth = getByteWidth(bitWidth);
|
private int byteWidth = getByteWidth(bitWidth);
|
||||||
|
|
||||||
private final Composite composite;
|
private Composite composite;
|
||||||
private final boolean bigEndian;
|
private boolean bigEndian;
|
||||||
|
|
||||||
private int allocationByteOffset;
|
private int allocationByteOffset;
|
||||||
private int allocationByteSize;
|
private int allocationByteSize = 1;
|
||||||
private BitFieldAllocation bitFieldAllocation;
|
private BitFieldAllocation bitFieldAllocation;
|
||||||
|
|
||||||
private EditMode editMode = EditMode.NONE;
|
private EditMode editMode = EditMode.NONE;
|
||||||
|
@ -114,7 +114,9 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
|
|
||||||
BitFieldPlacementComponent(Composite composite) {
|
BitFieldPlacementComponent(Composite composite) {
|
||||||
this.composite = composite;
|
this.composite = composite;
|
||||||
|
if (composite != null) {
|
||||||
bigEndian = composite.getDataOrganization().isBigEndian();
|
bigEndian = composite.getDataOrganization().isBigEndian();
|
||||||
|
}
|
||||||
updatePreferredSize();
|
updatePreferredSize();
|
||||||
setSize(getPreferredSize());
|
setSize(getPreferredSize());
|
||||||
setMinimumSize(getPreferredSize());
|
setMinimumSize(getPreferredSize());
|
||||||
|
@ -122,11 +124,34 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
addMouseWheelListener(new MyMouseWheelListener());
|
addMouseWheelListener(new MyMouseWheelListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the composite associated with this component.
|
||||||
|
* @return composite or null
|
||||||
|
*/
|
||||||
|
public Composite getComposite() {
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current composite. State will reset to a non-edit mode.
|
||||||
|
* @param composite composite or null
|
||||||
|
*/
|
||||||
|
public void setComposite(Composite composite) {
|
||||||
|
this.composite = composite;
|
||||||
|
if (composite != null) {
|
||||||
|
bigEndian = composite.getDataOrganization().isBigEndian();
|
||||||
|
}
|
||||||
|
allocationByteOffset = 0;
|
||||||
|
allocationByteSize = 1;
|
||||||
|
init(null);
|
||||||
|
}
|
||||||
|
|
||||||
private class MyMouseWheelListener implements MouseWheelListener {
|
private class MyMouseWheelListener implements MouseWheelListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
if (e.getModifiersEx() != InputEvent.SHIFT_DOWN_MASK || e.isConsumed()) {
|
if (bitFieldAllocation == null || e.getModifiersEx() != InputEvent.SHIFT_DOWN_MASK ||
|
||||||
|
e.isConsumed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) {
|
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) {
|
||||||
|
@ -270,6 +295,9 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasApplyConflict() {
|
boolean hasApplyConflict() {
|
||||||
|
if (composite == null || bitFieldAllocation == null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
if (composite instanceof Union) {
|
if (composite instanceof Union) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -316,6 +344,9 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
|
|
||||||
void applyBitField(DataType baseDataType, String fieldName, boolean deleteConflicts,
|
void applyBitField(DataType baseDataType, String fieldName, boolean deleteConflicts,
|
||||||
CompositeChangeListener listener) {
|
CompositeChangeListener listener) {
|
||||||
|
if (composite == null) {
|
||||||
|
throw new IllegalStateException("Composite not loaded");
|
||||||
|
}
|
||||||
HashSet<Integer> ordinalDeleteSet = new HashSet<>();
|
HashSet<Integer> ordinalDeleteSet = new HashSet<>();
|
||||||
if (editOrdinal >= 0) {
|
if (editOrdinal >= 0) {
|
||||||
int initialLength = composite.getLength();
|
int initialLength = composite.getLength();
|
||||||
|
@ -732,6 +763,12 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void allocateBits() {
|
private void allocateBits() {
|
||||||
|
|
||||||
|
if (composite == null) {
|
||||||
|
bitAttributes = new BitAttributes[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bitAttributes = new BitAttributes[8 * allocationByteSize];
|
bitAttributes = new BitAttributes[8 * allocationByteSize];
|
||||||
|
|
||||||
if (composite instanceof Structure) {
|
if (composite instanceof Structure) {
|
||||||
|
@ -913,7 +950,8 @@ public class BitFieldPlacementComponent extends JPanel {
|
||||||
// offcut with another component (currently ignored)
|
// offcut with another component (currently ignored)
|
||||||
c = conflict.conflict;
|
c = conflict.conflict;
|
||||||
}
|
}
|
||||||
return c != null ? c.dtc : null;
|
// NOTE: DEFAULT undefined datatype can be ignored as conflict
|
||||||
|
return c != null && c.dtc.getDataType() != DataType.DEFAULT ? c.dtc : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void layout(int x, int y, int width, int height) {
|
void layout(int x, int y, int width, int height) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.awt.dnd.DropTargetDragEvent;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EmptyBorder;
|
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
import javax.swing.text.Document;
|
import javax.swing.text.Document;
|
||||||
|
@ -173,8 +172,18 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
DataTypeComponent dtc = null;
|
if (!model.isLoaded()) {
|
||||||
|
bitViewComponent.setComposite(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bitViewComponent.getComposite() != model.viewComposite) {
|
||||||
|
// must track instance changes caused by model unload/load invocations
|
||||||
|
bitViewComponent.setComposite(model.viewComposite);
|
||||||
|
}
|
||||||
|
|
||||||
bitViewComponent.updateAllocation(model.viewComposite.getLength(), 0);
|
bitViewComponent.updateAllocation(model.viewComposite.getLength(), 0);
|
||||||
|
|
||||||
|
DataTypeComponent dtc = null;
|
||||||
if (model.isSingleComponentRowSelection()) {
|
if (model.isSingleComponentRowSelection()) {
|
||||||
dtc = model.getComponent(model.getSelectedRows()[0]);
|
dtc = model.getComponent(model.getSelectedRows()[0]);
|
||||||
}
|
}
|
||||||
|
@ -206,9 +215,9 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
JPanel p = new JPanel(new BorderLayout());
|
JPanel p = new JPanel();
|
||||||
p.add(bitViewComponent, BorderLayout.WEST);
|
p.add(bitViewComponent);
|
||||||
p.setBorder(new EmptyBorder(0, 0, 5, 0));
|
//p.setBorder(new EmptyBorder(5, 5, 0, 15));
|
||||||
|
|
||||||
JScrollPane bitViewScrollPane =
|
JScrollPane bitViewScrollPane =
|
||||||
new JScrollPane(p, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
new JScrollPane(p, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||||
|
@ -247,7 +256,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
|
|
||||||
addFieldListeners();
|
addFieldListeners();
|
||||||
|
|
||||||
infoPanel.setBorder(BorderFactory.createEmptyBorder(30, 10, 0, 10));
|
infoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
|
||||||
|
|
||||||
return infoPanel;
|
return infoPanel;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +276,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
nameTextField = new JTextField("");
|
nameTextField = new JTextField("");
|
||||||
nameTextField.setToolTipText("Structure Name");
|
nameTextField.setToolTipText("Structure Name");
|
||||||
nameTextField.setEditable(true);
|
nameTextField.setEditable(true);
|
||||||
nameTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
gridBagConstraints.insets = VERTICAL_INSETS;
|
gridBagConstraints.insets = VERTICAL_INSETS;
|
||||||
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
||||||
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
@ -296,7 +304,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
infoPanel.add(descriptionLabel, gridBagConstraints);
|
infoPanel.add(descriptionLabel, gridBagConstraints);
|
||||||
|
|
||||||
descriptionTextField = new JTextField("");
|
descriptionTextField = new JTextField("");
|
||||||
descriptionTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
descriptionTextField.setToolTipText("Structure Description");
|
descriptionTextField.setToolTipText("Structure Description");
|
||||||
descriptionTextField.setEditable(true);
|
descriptionTextField.setEditable(true);
|
||||||
gridBagConstraints.insets = VERTICAL_INSETS;
|
gridBagConstraints.insets = VERTICAL_INSETS;
|
||||||
|
@ -329,7 +336,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
categoryStatusTextField = new JTextField(" ");
|
categoryStatusTextField = new JTextField(" ");
|
||||||
categoryStatusTextField.setEditable(false);
|
categoryStatusTextField.setEditable(false);
|
||||||
categoryStatusTextField.setToolTipText("Category of this composite data type.");
|
categoryStatusTextField.setToolTipText("Category of this composite data type.");
|
||||||
categoryStatusTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
gridBagConstraints.insets = VERTICAL_INSETS;
|
gridBagConstraints.insets = VERTICAL_INSETS;
|
||||||
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
||||||
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
@ -499,7 +505,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
|
|
||||||
minAlignValueTextField.setName("Minimum Alignment Value");
|
minAlignValueTextField.setName("Minimum Alignment Value");
|
||||||
minAlignValueTextField.setEditable(true);
|
minAlignValueTextField.setEditable(true);
|
||||||
minAlignValueTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
minAlignValueTextField.setToolTipText(alignmentToolTip);
|
minAlignValueTextField.setToolTipText(alignmentToolTip);
|
||||||
if (helpManager != null) {
|
if (helpManager != null) {
|
||||||
helpManager.registerHelp(minAlignValueTextField, new HelpLocation(
|
helpManager.registerHelp(minAlignValueTextField, new HelpLocation(
|
||||||
|
@ -575,7 +580,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
}
|
}
|
||||||
actualAlignmentValueTextField.setName("Actual Alignment Value");
|
actualAlignmentValueTextField.setName("Actual Alignment Value");
|
||||||
|
|
||||||
actualAlignmentValueTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
gridBagConstraints.insets = VERTICAL_INSETS;
|
gridBagConstraints.insets = VERTICAL_INSETS;
|
||||||
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
||||||
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
@ -676,7 +680,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
|
|
||||||
packingValueTextField.setName("Packing Value");
|
packingValueTextField.setName("Packing Value");
|
||||||
packingValueTextField.setEditable(true);
|
packingValueTextField.setEditable(true);
|
||||||
packingValueTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
|
|
||||||
packingValueTextField.addActionListener(e -> adjustPackingValue());
|
packingValueTextField.addActionListener(e -> adjustPackingValue());
|
||||||
|
|
||||||
|
@ -799,7 +802,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
||||||
sizeStatusTextField.setName("Total Length");
|
sizeStatusTextField.setName("Total Length");
|
||||||
sizeStatusTextField.setEditable(false);
|
sizeStatusTextField.setEditable(false);
|
||||||
sizeStatusTextField.setToolTipText("The current size in bytes.");
|
sizeStatusTextField.setToolTipText("The current size in bytes.");
|
||||||
sizeStatusTextField.setMargin(TEXTFIELD_INSETS);
|
|
||||||
gridBagConstraints.ipadx = 60;
|
gridBagConstraints.ipadx = 60;
|
||||||
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
gridBagConstraints.gridx = 1;
|
gridBagConstraints.gridx = 1;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||||
// Normal color for selecting components in the table.
|
// Normal color for selecting components in the table.
|
||||||
// TODO: Why do we choose a different selection color?
|
// TODO: Why do we choose a different selection color?
|
||||||
//private static final Color SELECTION_COLOR = Color.YELLOW.brighter().brighter();
|
//private static final Color SELECTION_COLOR = Color.YELLOW.brighter().brighter();
|
||||||
protected static final Insets TEXTFIELD_INSETS = new JTextField().getInsets();
|
//protected static final Insets TEXTFIELD_INSETS = new JTextField().getInsets();
|
||||||
|
|
||||||
protected static final Border BEVELED_BORDER = BorderFactory.createLoweredBevelBorder();
|
protected static final Border BEVELED_BORDER = BorderFactory.createLoweredBevelBorder();
|
||||||
|
|
||||||
|
|