mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-12 13:40:15 +00:00
GP-1943 - Structure Editor - added the 'Offset' column
This commit is contained in:
parent
47f76c78d6
commit
acf8a9e1bf
@ -74,6 +74,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
*
|
*
|
||||||
* @param dataType the new composite data type.
|
* @param dataType the new composite data type.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void load(Composite dataType) {
|
public void load(Composite dataType) {
|
||||||
if (dataType == null) { // TODO: Why is this needed? Use case?
|
if (dataType == null) { // TODO: Why is this needed? Use case?
|
||||||
return;
|
return;
|
||||||
@ -104,7 +105,8 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
// Listen so we can update editor if name changes for this structure.
|
// Listen so we can update editor if name changes for this structure.
|
||||||
originalCompositeId = DataTypeManager.NULL_DATATYPE_ID;
|
originalCompositeId = DataTypeManager.NULL_DATATYPE_ID;
|
||||||
if (originalDTM.contains(dataType)) {
|
if (originalDTM.contains(dataType)) {
|
||||||
originalCompositeId = originalDTM.getID(dataType); // Get the id if editing an existing data type.
|
// Get the id if editing an existing data type.
|
||||||
|
originalCompositeId = originalDTM.getID(dataType);
|
||||||
}
|
}
|
||||||
originalDTM.addDataTypeManagerListener(this);
|
originalDTM.addDataTypeManagerListener(this);
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
|
|
||||||
editorStateChanged(CompositeEditorModelListener.COMPOSITE_LOADED);
|
editorStateChanged(CompositeEditorModelListener.COMPOSITE_LOADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create view composite with the appropriate datatype manager and
|
* Create view composite with the appropriate datatype manager and
|
||||||
* changes listener(s) if required.
|
* changes listener(s) if required.
|
||||||
@ -393,7 +395,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
if (newDt == null) {
|
if (newDt == null) {
|
||||||
return; // Was nothing and is nothing.
|
return; // Was nothing and is nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataTypeComponent.usesZeroLengthComponent(newDt)) {
|
if (DataTypeComponent.usesZeroLengthComponent(newDt)) {
|
||||||
newLength = 0;
|
newLength = 0;
|
||||||
}
|
}
|
||||||
@ -401,7 +403,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
checkIsAllowableDataType(newDt);
|
checkIsAllowableDataType(newDt);
|
||||||
|
|
||||||
newDt = resolveDataType(newDt, viewDTM, DataTypeConflictHandler.DEFAULT_HANDLER);
|
newDt = resolveDataType(newDt, viewDTM, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
|
|
||||||
if (newLength < 0) {
|
if (newLength < 0) {
|
||||||
// prefer previous size first
|
// prefer previous size first
|
||||||
int suggestedLength = (previousLength <= 0) ? lastNumBytes : previousLength;
|
int suggestedLength = (previousLength <= 0) ? lastNumBytes : previousLength;
|
||||||
@ -410,7 +412,8 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
if (sizedDataType == null) {
|
if (sizedDataType == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newDt = resolveDataType(sizedDataType.getDataType(), viewDTM, DataTypeConflictHandler.DEFAULT_HANDLER);
|
newDt = resolveDataType(sizedDataType.getDataType(), viewDTM,
|
||||||
|
DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
newLength = sizedDataType.getLength();
|
newLength = sizedDataType.getLength();
|
||||||
if (newLength <= 0) {
|
if (newLength <= 0) {
|
||||||
throw new UsrException("Can't currently add this data type.");
|
throw new UsrException("Can't currently add this data type.");
|
||||||
@ -430,9 +433,10 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the data type against the indicated data type manager using the specified conflictHandler.
|
* Resolves the data type against the indicated data type manager using the specified
|
||||||
* Transactions should have already been initiated prior to calling this method.
|
* conflictHandler. Transactions should have already been initiated prior to calling this
|
||||||
* If not then override this method to perform the transaction code around the resolve.
|
* method. If not then override this method to perform the transaction code around the
|
||||||
|
* resolve.
|
||||||
*
|
*
|
||||||
* @param dt the data type to be resolved
|
* @param dt the data type to be resolved
|
||||||
* @param resolveDtm the data type manager to resolve the data type against
|
* @param resolveDtm the data type manager to resolve the data type against
|
||||||
|
@ -23,6 +23,7 @@ import java.awt.event.*;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
@ -42,8 +43,7 @@ import docking.widgets.fieldpanel.support.FieldRange;
|
|||||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.GTableCellRenderer;
|
|
||||||
import docking.widgets.textfield.GValidatedTextField;
|
import docking.widgets.textfield.GValidatedTextField;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
||||||
@ -555,6 +555,16 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||||||
|
|
||||||
private void createTable() {
|
private void createTable() {
|
||||||
table = new CompositeTable(model);
|
table = new CompositeTable(model);
|
||||||
|
|
||||||
|
TableColumnModel columnModel = table.getColumnModel();
|
||||||
|
if (columnModel instanceof GTableColumnModel) {
|
||||||
|
GTableColumnModel gColumnModel = (GTableColumnModel) columnModel;
|
||||||
|
List<TableColumn> hiddenColumns = model.getHiddenColumns();
|
||||||
|
for (TableColumn column : hiddenColumns) {
|
||||||
|
gColumnModel.addHiddenColumn(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
|
table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
|
||||||
table.addMouseListener(new CompositeTableMouseListener());
|
table.addMouseListener(new CompositeTableMouseListener());
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
package ghidra.app.plugin.core.compositeeditor;
|
package ghidra.app.plugin.core.compositeeditor;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.support.FieldRange;
|
import docking.widgets.fieldpanel.support.FieldRange;
|
||||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||||
@ -34,9 +34,10 @@ import utility.function.Callback;
|
|||||||
abstract class CompositeViewerModel extends AbstractTableModel
|
abstract class CompositeViewerModel extends AbstractTableModel
|
||||||
implements DataTypeManagerChangeListener {
|
implements DataTypeManagerChangeListener {
|
||||||
|
|
||||||
/** Flag indicating that the model is updating the selection and
|
/**
|
||||||
* should ignore any attempts to set the selection until it is no
|
* Flag indicating that the model is updating the selection and should ignore any attempts to
|
||||||
* longer updating. */
|
* set the selection until it is no longer updating.
|
||||||
|
*/
|
||||||
protected boolean updatingSelection = false;
|
protected boolean updatingSelection = false;
|
||||||
|
|
||||||
protected Composite originalComposite;
|
protected Composite originalComposite;
|
||||||
@ -68,7 +69,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
/** Offset of each component field. */
|
/** Offset of each component field. */
|
||||||
protected int[] columnOffsets = new int[headers.length];
|
protected int[] columnOffsets = new int[headers.length];
|
||||||
/** Width of each component field. */
|
/** Width of each component field. */
|
||||||
protected int[] columnWidths = { 75, 75, 100, 100, 100, 150 }; // Initial default column widths.
|
protected int[] columnWidths = { 75, 75, 100, 100, 100, 150 }; // Initial default column widths
|
||||||
/** Total component area width. */
|
/** Total component area width. */
|
||||||
protected int width = 0;
|
protected int width = 0;
|
||||||
/** Width of left margin in pixels for the component area. */
|
/** Width of left margin in pixels for the component area. */
|
||||||
@ -88,10 +89,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>String.class</code> regardless of <code>columnIndex</code>.
|
* Returns <code>String.class</code> regardless of <code>columnIndex</code>.
|
||||||
*
|
*
|
||||||
* @param columnIndex the column being queried
|
* @param columnIndex the column being queried
|
||||||
* @return the String.class
|
* @return the String.class
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
@ -125,6 +126,11 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
return COMMENT;
|
return COMMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subclasses may supply columns
|
||||||
|
protected List<TableColumn> getHiddenColumns() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates listening for category change events within the model.
|
* Terminates listening for category change events within the model.
|
||||||
*/
|
*/
|
||||||
@ -135,19 +141,18 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the editor has a structure loaded.
|
* Returns whether or not the editor has a structure loaded. If no structure is loaded then
|
||||||
* If no structure is loaded then only unload() or dispose() methods
|
* only unload() or dispose() methods should be called.
|
||||||
* should be called.
|
*
|
||||||
* @return true if an editable structure is currently loaded in the model.
|
* @return true if an editable structure is currently loaded in the model.
|
||||||
*/
|
*/
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return (viewComposite != null);
|
return (viewComposite != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the model to now view the indicated data structure.
|
* Updates the model to now view the indicated data structure. This method should cleanup from
|
||||||
* This method should cleanup from a previous load if neccessary
|
* a previous load if necessary and must initialize the following model state:
|
||||||
* and must initilize the following model state:
|
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>originalComposite</li>
|
* <li>originalComposite</li>
|
||||||
* <li>originalDataTypePath</li>
|
* <li>originalDataTypePath</li>
|
||||||
@ -188,8 +193,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the indicated data type against the working copy in the
|
* Resolves the indicated data type against the working copy in the viewer's data type manager.
|
||||||
* viewer's data type manager.
|
|
||||||
* @param dataType the data type
|
* @param dataType the data type
|
||||||
* @return the working copy of the data type.
|
* @return the working copy of the data type.
|
||||||
*/
|
*/
|
||||||
@ -328,8 +332,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size of the structure being viewed in bytes as a hex or decimal string
|
* Return the size of the structure being viewed in bytes as a hex or decimal string depending
|
||||||
* depending on the model's current display setting for numbers
|
* on the model's current display setting for numbers
|
||||||
* @return the length
|
* @return the length
|
||||||
*/
|
*/
|
||||||
public String getLengthAsString() {
|
public String getLengthAsString() {
|
||||||
@ -354,10 +358,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a header name for the indicated column.
|
* Return a header name for the indicated column.
|
||||||
*
|
*
|
||||||
* @param columnIndex the index number indicating the component field (column)
|
* @param columnIndex the index number indicating the component field (column) to get the
|
||||||
* to get the header for.
|
* header for.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName(int columnIndex) {
|
public String getColumnName(int columnIndex) {
|
||||||
@ -365,25 +369,36 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a header name for the indicated field (column)
|
* Return a header name for the indicated field (column)
|
||||||
*
|
*
|
||||||
* @param columnIndex the index number indicating the component field (column)
|
* @param columnIndex the index number indicating the component field (column) to get the
|
||||||
* to get the header for
|
* header for
|
||||||
* @return the name
|
* @return the name
|
||||||
*/
|
*/
|
||||||
public String getFieldName(int columnIndex) {
|
public String getFieldName(int columnIndex) {
|
||||||
if (columnIndex < 0 || columnIndex > getColumnCount()) {
|
if (columnIndex < 0) {
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
return headers[columnIndex];
|
if (columnIndex < headers.length) {
|
||||||
|
return headers[columnIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TableColumn> hiddenColumns = getHiddenColumns();
|
||||||
|
for (TableColumn c : hiddenColumns) {
|
||||||
|
int modelIndex = c.getModelIndex();
|
||||||
|
if (modelIndex == columnIndex) {
|
||||||
|
return Objects.toString(c.getHeaderValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not a particular component row and field in this
|
* Returns whether or not a particular component row and field in this structure is an editable
|
||||||
* structure is an editable type of cell. However the cell still
|
* type of cell. However the cell still may not be editable currently. To check if the cell can
|
||||||
* may not be editable currently. To check if the cell can actually be
|
* actually be edited call isCellEditable().
|
||||||
* edited call isCellEditable().
|
|
||||||
*
|
*
|
||||||
* @param rowIndex the row index of the component
|
* @param rowIndex the row index of the component
|
||||||
* @param columnIndex the index for the field of the component
|
* @param columnIndex the index for the field of the component
|
||||||
@ -394,12 +409,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not a particular component row and field in this
|
* Returns whether or not a particular component row and field in this structure is editable
|
||||||
* structure is editable
|
|
||||||
*
|
*
|
||||||
* @param rowIndex index for the row (component within this structure).
|
* @param rowIndex index for the row (component within this structure).
|
||||||
* @param columnIndex index for the column (field of the component within
|
* @param columnIndex index for the column (field of the component within this structure).
|
||||||
* this structure).
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||||
@ -407,7 +420,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the display offset of the component field at the specified column index
|
* Gets the display offset of the component field at the specified column index.
|
||||||
*
|
*
|
||||||
* @param columnIndex the field index within the component.
|
* @param columnIndex the field index within the component.
|
||||||
* @return the offset in pixels of the component field.
|
* @return the offset in pixels of the component field.
|
||||||
@ -460,10 +473,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the display width of the component field at the specified column index
|
* Gets the display width of the component field at the specified column index.
|
||||||
*
|
*
|
||||||
* @param columnIndex the field index within the component.
|
* @param columnIndex the field index within the component
|
||||||
* @return the width of the component field.
|
* @return the width of the component field
|
||||||
*/
|
*/
|
||||||
public int getFieldWidth(int columnIndex) {
|
public int getFieldWidth(int columnIndex) {
|
||||||
return ((columnIndex < 0 || columnIndex >= getColumnCount()) ? 0
|
return ((columnIndex < 0 || columnIndex >= getColumnCount()) ? 0
|
||||||
@ -471,10 +484,9 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of component rows in the viewer. There may be a
|
* Returns the number of component rows in the viewer. There may be a blank row at the end for
|
||||||
* blank row at the end for selecting. Therefore this number can be
|
* selecting. Therefore this number can be different than the actual number of components
|
||||||
* different than the actual number of components currently in the
|
* currently in the structure being viewed.
|
||||||
* structure being viewed.
|
|
||||||
*
|
*
|
||||||
* @return the number of rows in the model
|
* @return the number of rows in the model
|
||||||
*/
|
*/
|
||||||
@ -492,11 +504,11 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the nth component for the structure being viewed. Since the number of rows
|
* Return the nth component for the structure being viewed. Since the number of rows can exceed
|
||||||
* can exceed the number of components defined within the composite
|
* the number of components defined within the composite ({@link Composite#getNumComponents()})
|
||||||
* ({@link Composite#getNumComponents()}) this method will return null for a blank
|
* this method will return null for a blank row.
|
||||||
* row.
|
*
|
||||||
* @param rowIndex the index of the component to return. First component is index of 0.
|
* @param rowIndex the index of the component to return. First component is index of 0
|
||||||
* @return the component
|
* @return the component
|
||||||
*/
|
*/
|
||||||
public DataTypeComponent getComponent(int rowIndex) {
|
public DataTypeComponent getComponent(int rowIndex) {
|
||||||
@ -507,10 +519,10 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of columns (display fields) for each component in
|
* Returns the number of columns (display fields) for each component in this structure or
|
||||||
* this structure or union.
|
* union.
|
||||||
*
|
*
|
||||||
* @return the number of display fields for each component.
|
* @return the number of display fields for each component
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getColumnCount() {
|
public int getColumnCount() {
|
||||||
@ -520,7 +532,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
/**
|
/**
|
||||||
* Returns the number of display fields for this structure or union.
|
* Returns the number of display fields for this structure or union.
|
||||||
*
|
*
|
||||||
* @return the number of display fields for each component.
|
* @return the number of display fields for each component
|
||||||
*/
|
*/
|
||||||
public int getNumFields() {
|
public int getNumFields() {
|
||||||
return getColumnCount();
|
return getColumnCount();
|
||||||
@ -573,7 +585,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current dataType name (Structure or Union) as a string
|
* Returns the current dataType name (Structure or Union) as a string.
|
||||||
* @return the name
|
* @return the name
|
||||||
*/
|
*/
|
||||||
protected String getTypeName() {
|
protected String getTypeName() {
|
||||||
@ -581,7 +593,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current status string
|
* Returns the current status string.
|
||||||
* @return the status
|
* @return the status
|
||||||
*/
|
*/
|
||||||
public String getStatus() {
|
public String getStatus() {
|
||||||
@ -597,10 +609,9 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current status string and performs notification to all
|
* Sets the current status string and performs notification to all listeners.
|
||||||
* CompositeModelStatusListeners.
|
|
||||||
* @param status the status message
|
* @param status the status message
|
||||||
* @param beep true indicates an audible beep should sound when the message is displayed.
|
* @param beep true indicates an audible beep should sound when the message is displayed
|
||||||
*/
|
*/
|
||||||
public void setStatus(String status, boolean beep) {
|
public void setStatus(String status, boolean beep) {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
@ -623,9 +634,9 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixes up the original name and category because a program restoration may
|
* Fixes up the original name and category because a program restoration may have changed the
|
||||||
* have changed the original composite.
|
* original composite.
|
||||||
* @param composite the restored copy of our original composite.
|
* @param composite the restored copy of our original composite
|
||||||
*/
|
*/
|
||||||
protected void fixupOriginalPath(Composite composite) {
|
protected void fixupOriginalPath(Composite composite) {
|
||||||
String newName = composite.getName();
|
String newName = composite.getName();
|
||||||
@ -659,8 +670,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever the composite's non-component information changes.
|
* Called whenever the composite's non-component information changes. For example, the name,
|
||||||
* For example, the name, or description change.
|
* or description change.
|
||||||
*/
|
*/
|
||||||
protected void compositeInfoChanged() {
|
protected void compositeInfoChanged() {
|
||||||
notify(modelListeners, CompositeViewerModelListener::compositeInfoChanged);
|
notify(modelListeners, CompositeViewerModelListener::compositeInfoChanged);
|
||||||
@ -674,8 +685,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the full path name for the composite data type based on
|
* Determines the full path name for the composite data type based on the original composite
|
||||||
* the original composite and original category.
|
* and original category.
|
||||||
* @return the full path name
|
* @return the full path name
|
||||||
*/
|
*/
|
||||||
public final DataTypePath getOriginalDataTypePath() {
|
public final DataTypePath getOriginalDataTypePath() {
|
||||||
@ -837,10 +848,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
fireTableDataChanged();
|
fireTableDataChanged();
|
||||||
componentDataChanged();
|
componentDataChanged();
|
||||||
}
|
}
|
||||||
catch (InvalidNameException e) {
|
catch (InvalidNameException | DuplicateNameException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
catch (DuplicateNameException e) {
|
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,22 +955,23 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
@Override
|
@Override
|
||||||
public void favoritesChanged(DataTypeManager dtm, DataTypePath path, boolean isFavorite) {
|
public void favoritesChanged(DataTypeManager dtm, DataTypePath path, boolean isFavorite) {
|
||||||
// Don't care.
|
// Don't care.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=================================================================================================
|
||||||
|
// Helper methods for CategoryChangeListener methods.
|
||||||
|
//=================================================================================================
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
* Helper methods for CategoryChangeListener methods.
|
|
||||||
********************************************************************/
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the indicated composite data type has any
|
* Determines whether the indicated composite data type has any sub-components that are within
|
||||||
* sub-components that are within the indicated category or one
|
* the indicated category or one of its sub-categories.
|
||||||
* of its sub-categories.
|
|
||||||
* @param parentDt the composite data type
|
* @param parentDt the composite data type
|
||||||
* @param catPath the category's path.
|
* @param catPath the category's path
|
||||||
* @return true if a sub-component is in the indicated category.
|
* @return true if a sub-component is in the indicated category
|
||||||
*/
|
*/
|
||||||
boolean hasSubDtInCategory(Composite parentDt, String catPath) {
|
boolean hasSubDtInCategory(Composite parentDt, String catPath) {
|
||||||
DataTypeComponent components[] = parentDt.getDefinedComponents();
|
DataTypeComponent components[] = parentDt.getDefinedComponents();
|
||||||
// FUTURE Add a structure to keep track of which composites were searched so they aren't searched multiple times.
|
// FUTURE Add a structure to keep track of which composites were searched so they aren't
|
||||||
|
// searched multiple times.
|
||||||
for (DataTypeComponent component : components) {
|
for (DataTypeComponent component : components) {
|
||||||
DataType subDt = component.getDataType();
|
DataType subDt = component.getDataType();
|
||||||
String subCatPath = subDt.getCategoryPath().getPath();
|
String subCatPath = subDt.getCategoryPath().getPath();
|
||||||
@ -979,11 +988,11 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the indicated composite data type has any
|
* Determines whether the indicated composite data type has any sub-components that are the
|
||||||
* sub-components that are the indicated data type.
|
* indicated data type.
|
||||||
* @param parentDt the composite data type
|
* @param parentDt the composite data type
|
||||||
* @param dtPath the data type to be detected.
|
* @param dtPath the data type to be detected
|
||||||
* @return true if the composite data type has the data type as a sub-component.
|
* @return true if the composite data type has the data type as a sub-component
|
||||||
*/
|
*/
|
||||||
protected boolean hasSubDt(Composite parentDt, DataTypePath dtPath) {
|
protected boolean hasSubDt(Composite parentDt, DataTypePath dtPath) {
|
||||||
DataTypeComponent components[] = parentDt.getDefinedComponents();
|
DataTypeComponent components[] = parentDt.getDefinedComponents();
|
||||||
@ -1032,6 +1041,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
* Returns the number of rows currently selected.
|
* Returns the number of rows currently selected.
|
||||||
*
|
*
|
||||||
* <p>Note: In unlocked mode this can include the additional blank line.
|
* <p>Note: In unlocked mode this can include the additional blank line.
|
||||||
|
*
|
||||||
* @return the selected row count
|
* @return the selected row count
|
||||||
*/
|
*/
|
||||||
public int getNumSelectedRows() {
|
public int getNumSelectedRows() {
|
||||||
@ -1048,6 +1058,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
* Returns the number of component rows currently selected.
|
* Returns the number of component rows currently selected.
|
||||||
*
|
*
|
||||||
* <p>Note: This only includes rows that are actually components.
|
* <p>Note: This only includes rows that are actually components.
|
||||||
|
*
|
||||||
* @return the selected row count
|
* @return the selected row count
|
||||||
*/
|
*/
|
||||||
public int getNumSelectedComponentRows() {
|
public int getNumSelectedComponentRows() {
|
||||||
@ -1065,7 +1076,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the component list selection is contiguous
|
* Returns true if the component list selection is contiguous.
|
||||||
* @return true if contiguous
|
* @return true if contiguous
|
||||||
*/
|
*/
|
||||||
public boolean isContiguousSelection() {
|
public boolean isContiguousSelection() {
|
||||||
@ -1073,7 +1084,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the component list selection is a single component
|
* Returns true if the component list selection is a single component.
|
||||||
* @return true if the component list selection is a single component
|
* @return true if the component list selection is a single component
|
||||||
*/
|
*/
|
||||||
public boolean isSingleComponentRowSelection() {
|
public boolean isSingleComponentRowSelection() {
|
||||||
@ -1086,7 +1097,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the selection is a single row
|
* Returns true if the selection is a single row.
|
||||||
* @return true if the selection is a single row
|
* @return true if the selection is a single row
|
||||||
*/
|
*/
|
||||||
public boolean isSingleRowSelection() {
|
public boolean isSingleRowSelection() {
|
||||||
@ -1098,7 +1109,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the list selection is contiguous and only contains component rows
|
* Returns true if the list selection is contiguous and only contains component rows.
|
||||||
* @return true if the list selection is contiguous and only contains component rows
|
* @return true if the list selection is contiguous and only contains component rows
|
||||||
*/
|
*/
|
||||||
public boolean isContiguousComponentSelection() {
|
public boolean isContiguousComponentSelection() {
|
||||||
@ -1107,7 +1118,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of the indices for all the selected rows
|
* Get an array of the indices for all the selected rows.
|
||||||
* @return the selected rows
|
* @return the selected rows
|
||||||
*/
|
*/
|
||||||
public int[] getSelectedRows() {
|
public int[] getSelectedRows() {
|
||||||
@ -1123,7 +1134,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of the row indices for all the selected components
|
* Get an array of the row indices for all the selected components.
|
||||||
* @return the selected rows
|
* @return the selected rows
|
||||||
*/
|
*/
|
||||||
public int[] getSelectedComponentRows() {
|
public int[] getSelectedComponentRows() {
|
||||||
@ -1140,8 +1151,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the selection range containing the specified row index
|
* Returns the selection range containing the specified row index if there is one that contains
|
||||||
* if there is one that contains it. Otherwise, returns null.
|
* it. Otherwise, returns null.
|
||||||
*
|
*
|
||||||
* @param rowIndex the row index
|
* @param rowIndex the row index
|
||||||
* @return the range or null
|
* @return the range or null
|
||||||
@ -1164,7 +1175,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the minimum row index that is selected or -1 if no index is selected
|
* Gets the minimum row index that is selected or -1 if no index is selected.
|
||||||
* @return the index
|
* @return the index
|
||||||
*/
|
*/
|
||||||
public int getMinIndexSelected() {
|
public int getMinIndexSelected() {
|
||||||
@ -1176,7 +1187,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current selection in the structure components viewing area
|
* Saves the current selection in the structure components viewing area.
|
||||||
*
|
*
|
||||||
* @param rows the indices for the selected rows.
|
* @param rows the indices for the selected rows.
|
||||||
*/
|
*/
|
||||||
@ -1202,8 +1213,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the model's current selection to the indicated selection.
|
* Sets the model's current selection to the indicated selection. If the selection is empty,
|
||||||
* If the selection is empty, it gets adjusted to the empty last line when in unlocked mode.
|
* it gets adjusted to the empty last line when in unlocked mode.
|
||||||
* @param selection the new selection
|
* @param selection the new selection
|
||||||
*/
|
*/
|
||||||
public void setSelection(FieldSelection selection) {
|
public void setSelection(FieldSelection selection) {
|
||||||
@ -1269,7 +1280,7 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to run the given task on the swing thread now if swing or later if not
|
* Convenience method to run the given task on the swing thread now if swing or later if not.
|
||||||
* @param r the runnable
|
* @param r the runnable
|
||||||
*/
|
*/
|
||||||
protected void swing(Runnable r) {
|
protected void swing(Runnable r) {
|
||||||
@ -1277,8 +1288,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A notify method to take the listens to notify, along with the method that should be
|
* A notify method to take the listens to notify, along with the method that should be called
|
||||||
* called on each listener
|
* on each listener.
|
||||||
*
|
*
|
||||||
* @param <T> the type of the listener
|
* @param <T> the type of the listener
|
||||||
* @param listeners the listeners
|
* @param listeners the listeners
|
||||||
@ -1293,8 +1304,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether or not the editor displays numeric values in hexadecimal.
|
* Sets whether or not the editor displays numeric values in hexadecimal.
|
||||||
* @param showHex true means show in hexadecimal. false means show in decimal.
|
* @param showHex true means show in hexadecimal. false means show in decimal
|
||||||
*/
|
*/
|
||||||
public void displayNumbersInHex(boolean showHex) {
|
public void displayNumbersInHex(boolean showHex) {
|
||||||
if (this.showHexNumbers != showHex) {
|
if (this.showHexNumbers != showHex) {
|
||||||
|
@ -16,14 +16,16 @@
|
|||||||
package ghidra.app.plugin.core.compositeeditor;
|
package ghidra.app.plugin.core.compositeeditor;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
|
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import docking.widgets.dialogs.InputDialog;
|
import docking.widgets.dialogs.InputDialog;
|
||||||
import docking.widgets.dialogs.InputDialogListener;
|
import docking.widgets.dialogs.InputDialogListener;
|
||||||
import docking.widgets.fieldpanel.support.FieldRange;
|
import docking.widgets.fieldpanel.support.FieldRange;
|
||||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||||
|
import docking.widgets.table.GTableHeaderRenderer;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.lang.InsufficientBytesException;
|
import ghidra.program.model.lang.InsufficientBytesException;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
@ -39,6 +41,9 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
private static final int DATATYPE = 3;
|
private static final int DATATYPE = 3;
|
||||||
private static final int FIELDNAME = 4;
|
private static final int FIELDNAME = 4;
|
||||||
private static final int COMMENT = 5;
|
private static final int COMMENT = 5;
|
||||||
|
private static final int ORDINAL = 6;
|
||||||
|
|
||||||
|
private List<TableColumn> hiddenColumns;
|
||||||
|
|
||||||
StructureEditorModel(StructureEditorProvider provider, boolean showHexNumbers) {
|
StructureEditorModel(StructureEditorProvider provider, boolean showHexNumbers) {
|
||||||
super(provider);
|
super(provider);
|
||||||
@ -47,6 +52,18 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
columnOffsets = new int[headers.length];
|
columnOffsets = new int[headers.length];
|
||||||
adjustOffsets();
|
adjustOffsets();
|
||||||
this.showHexNumbers = showHexNumbers;
|
this.showHexNumbers = showHexNumbers;
|
||||||
|
|
||||||
|
List<TableColumn> additionalColumns = new ArrayList<>();
|
||||||
|
TableColumn ordinalColumn = new TableColumn(ORDINAL, 75);
|
||||||
|
ordinalColumn.setHeaderRenderer(new GTableHeaderRenderer());
|
||||||
|
ordinalColumn.setHeaderValue("Ordinal");
|
||||||
|
additionalColumns.add(ordinalColumn);
|
||||||
|
hiddenColumns = Collections.unmodifiableList(additionalColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<TableColumn> getHiddenColumns() {
|
||||||
|
return hiddenColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -110,11 +127,7 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
@Override
|
@Override
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
|
||||||
if ((viewComposite == null) || (rowIndex < 0) || (columnIndex < 0) ||
|
if ((viewComposite == null) || (rowIndex < 0) || (columnIndex < 0)) {
|
||||||
(columnIndex >= getColumnCount())) {
|
|
||||||
if (columnIndex == getDataTypeColumn()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +168,10 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
else if (columnIndex == getCommentColumn()) {
|
else if (columnIndex == getCommentColumn()) {
|
||||||
value = dtc.getComment();
|
value = dtc.getComment();
|
||||||
}
|
}
|
||||||
|
else if (columnIndex == ORDINAL) {
|
||||||
|
int ordinal = dtc.getOrdinal();
|
||||||
|
value = showHexNumbers ? getHexString(ordinal, true) : Integer.toString(ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
return (value == null) ? "" : value;
|
return (value == null) ? "" : value;
|
||||||
}
|
}
|
||||||
@ -671,7 +688,6 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
1 == currentRange.getEnd().getIndex().intValue());
|
1 == currentRange.getEnd().getIndex().intValue());
|
||||||
|
|
||||||
if (isOneComponent) {
|
if (isOneComponent) {
|
||||||
// TODO
|
|
||||||
if (!isShowingUndefinedBytes() || isAtEnd(currentIndex) ||
|
if (!isShowingUndefinedBytes() || isAtEnd(currentIndex) ||
|
||||||
onlyUndefinedsUntilEnd(currentIndex + 1)) {
|
onlyUndefinedsUntilEnd(currentIndex + 1)) {
|
||||||
return true; // allow replace of component when aligning.
|
return true; // allow replace of component when aligning.
|
||||||
|
@ -116,7 +116,6 @@ public class GTable extends JTable {
|
|||||||
* Constructs a new GTable
|
* Constructs a new GTable
|
||||||
*/
|
*/
|
||||||
public GTable() {
|
public GTable() {
|
||||||
super();
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,9 +720,6 @@ public class GTable extends JTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see javax.swing.JComponent#getToolTipText(java.awt.event.MouseEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getToolTipText(MouseEvent e) {
|
public String getToolTipText(MouseEvent e) {
|
||||||
String str = super.getToolTipText(e);
|
String str = super.getToolTipText(e);
|
||||||
@ -873,10 +869,10 @@ public class GTable extends JTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs custom work to locate renderers for special table model types. This method
|
* Performs custom work to locate renderers for special table model types. This method allows
|
||||||
* allows clients to bypass the {@link #getCellRenderer(int, int)}, which is sometimes
|
* clients to bypass the {@link #getCellRenderer(int, int)}, which is sometimes overridden by
|
||||||
* overridden by subclasses to return a hard-coded renderer. In that case, some clients
|
* subclasses to return a hard-coded renderer. In that case, some clients still want a way to
|
||||||
* still want a way to perform normal cell renderer lookup.
|
* perform normal cell renderer lookup.
|
||||||
*
|
*
|
||||||
* @param row the row
|
* @param row the row
|
||||||
* @param col the column
|
* @param col the column
|
||||||
@ -895,11 +891,9 @@ public class GTable extends JTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you just begin typing into an editable cell in
|
* If you just begin typing into an editable cell in a JTable, then the cell editor will be
|
||||||
* a JTable, then the cell editor will be displayed. However,
|
* displayed. However, the editor component will not have a focus. This method has been
|
||||||
* the editor component will not have a focus. This
|
* overridden to request focus on the editor component.
|
||||||
* method has been overridden to request
|
|
||||||
* focus on the editor component.
|
|
||||||
*
|
*
|
||||||
* @see javax.swing.JTable#editCellAt(int, int)
|
* @see javax.swing.JTable#editCellAt(int, int)
|
||||||
*/
|
*/
|
||||||
@ -1057,18 +1051,16 @@ public class GTable extends JTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintain a {@link docking.widgets.table.GTableCellRenderingData} object
|
* Maintain a {@link docking.widgets.table.GTableCellRenderingData} object associated with each
|
||||||
* associated with each column that maintains some state and references to
|
* column that maintains some state and references to useful data. These objects are created as
|
||||||
* useful data. These objects are created as needed, stored by the table for
|
* needed, stored by the table for convenient re-use and to prevent per-cell creation, and
|
||||||
* convenient re-use and to prevent per-cell creation, and cleared when columns
|
* cleared when columns are removed from the table.
|
||||||
* are removed from the table.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Row and cell state is cleared before returning to the caller to ensure
|
* Row and cell state is cleared before returning to the caller to ensure consistent state;
|
||||||
* consistent state; when the client is done rendering a cell, row and cell
|
* when the client is done rendering a cell, row and cell state should also be cleared to
|
||||||
* state should also be cleared to minimize references.
|
* minimize references.
|
||||||
*
|
*
|
||||||
* @param viewColumn
|
* @param viewColumn the columns' view index
|
||||||
* The columns' view index
|
|
||||||
* @return Data specific to the column. Row state is cleared before returning.
|
* @return Data specific to the column. Row state is cleared before returning.
|
||||||
*/
|
*/
|
||||||
GTableCellRenderingData getRenderingData(int viewColumn) {
|
GTableCellRenderingData getRenderingData(int viewColumn) {
|
||||||
|
@ -151,10 +151,7 @@ public class GTableColumnModel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addColumn(TableColumn aColumn) {
|
public void addColumn(TableColumn aColumn) {
|
||||||
if (aColumn == null) {
|
Objects.requireNonNull(aColumn);
|
||||||
throw new IllegalArgumentException("Object is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
removeColumnWithModelIndex(aColumn.getModelIndex()); // dedup
|
removeColumnWithModelIndex(aColumn.getModelIndex()); // dedup
|
||||||
|
|
||||||
completeList.add(aColumn);
|
completeList.add(aColumn);
|
||||||
@ -169,6 +166,18 @@ public class GTableColumnModel
|
|||||||
columnModelState.restoreState();
|
columnModelState.restoreState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a table column to this model that is not visible default. This column may be made
|
||||||
|
* visible later by the user or by the system restoring a previously used visible column state.
|
||||||
|
* @param aColumn the column
|
||||||
|
*/
|
||||||
|
public void addHiddenColumn(TableColumn aColumn) {
|
||||||
|
Objects.requireNonNull(aColumn);
|
||||||
|
removeColumnWithModelIndex(aColumn.getModelIndex()); // dedup
|
||||||
|
completeList.add(aColumn);
|
||||||
|
aColumn.addPropertyChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
/** Finds the table's column with the given model index */
|
/** Finds the table's column with the given model index */
|
||||||
private TableColumn getColumnFromModelIndex(int modelIndex) {
|
private TableColumn getColumnFromModelIndex(int modelIndex) {
|
||||||
for (TableColumn tableColumn : completeList) {
|
for (TableColumn tableColumn : completeList) {
|
||||||
|
Loading…
Reference in New Issue
Block a user