mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-18 00:20:10 +00:00
Merge remote-tracking branch 'origin/patch'
Conflicts: Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java
This commit is contained in:
commit
0e48d6e055
@ -51,7 +51,7 @@ import ghidra.base.widgets.table.DataTypeTableCellEditor;
|
|||||||
import ghidra.dbg.error.DebuggerModelAccessException;
|
import ghidra.dbg.error.DebuggerModelAccessException;
|
||||||
import ghidra.debug.api.target.Target;
|
import ghidra.debug.api.target.Target;
|
||||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.*;
|
||||||
import ghidra.framework.model.DomainObject;
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.framework.model.DomainObjectChangeRecord;
|
import ghidra.framework.model.DomainObjectChangeRecord;
|
||||||
import ghidra.framework.options.AutoOptions;
|
import ghidra.framework.options.AutoOptions;
|
||||||
@ -80,6 +80,7 @@ import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
|||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
import ghidra.util.table.GhidraTableFilterPanel;
|
import ghidra.util.table.GhidraTableFilterPanel;
|
||||||
|
import ghidra.util.table.column.GColumnRenderer;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||||
@ -143,33 +144,53 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
protected enum RegisterTableColumns
|
protected enum RegisterTableColumns
|
||||||
implements EnumeratedTableColumn<RegisterTableColumns, RegisterRow> {
|
implements EnumeratedTableColumn<RegisterTableColumns, RegisterRow> {
|
||||||
FAV("Fav", Boolean.class, RegisterRow::isFavorite, RegisterRow::setFavorite, //
|
FAV("Fav", 1, Boolean.class, RegisterRow::isFavorite, RegisterRow::setFavorite, //
|
||||||
r -> true, SortDirection.DESCENDING),
|
r -> true, SortDirection.DESCENDING),
|
||||||
NUMBER("#", Integer.class, RegisterRow::getNumber),
|
NUMBER("#", 1, Integer.class, RegisterRow::getNumber),
|
||||||
NAME("Name", String.class, RegisterRow::getName),
|
NAME("Name", 40, String.class, RegisterRow::getName),
|
||||||
VALUE("Value", BigInteger.class, RegisterRow::getValue, RegisterRow::setValue, //
|
VALUE("Value", 100, BigInteger.class, RegisterRow::getValue, RegisterRow::setValue, //
|
||||||
RegisterRow::isValueEditable, SortDirection.ASCENDING),
|
RegisterRow::isValueEditable, SortDirection.ASCENDING) {
|
||||||
TYPE("Type", DataType.class, RegisterRow::getDataType, RegisterRow::setDataType, //
|
private static final RegisterValueCellRenderer RENDERER =
|
||||||
|
new RegisterValueCellRenderer();
|
||||||
|
private static final SettingsDefinition[] DEFS = new SettingsDefinition[] {
|
||||||
|
FormatSettingsDefinition.DEF_HEX,
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GColumnRenderer<BigInteger> getRenderer() {
|
||||||
|
return RENDERER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingsDefinition[] getSettingsDefinitions() {
|
||||||
|
return DEFS;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TYPE("Type", 40, DataType.class, RegisterRow::getDataType, RegisterRow::setDataType, //
|
||||||
r -> true, SortDirection.ASCENDING),
|
r -> true, SortDirection.ASCENDING),
|
||||||
REPR("Repr", String.class, RegisterRow::getRepresentation, RegisterRow::setRepresentation, //
|
REPR("Repr", 100, String.class, RegisterRow::getRepresentation, RegisterRow::setRepresentation, //
|
||||||
RegisterRow::isRepresentationEditable, SortDirection.ASCENDING);
|
RegisterRow::isRepresentationEditable, SortDirection.ASCENDING);
|
||||||
|
|
||||||
private final String header;
|
private final String header;
|
||||||
|
private final int width;
|
||||||
private final Function<RegisterRow, ?> getter;
|
private final Function<RegisterRow, ?> getter;
|
||||||
private final BiConsumer<RegisterRow, Object> setter;
|
private final BiConsumer<RegisterRow, Object> setter;
|
||||||
private final Predicate<RegisterRow> editable;
|
private final Predicate<RegisterRow> editable;
|
||||||
private final Class<?> cls;
|
private final Class<?> cls;
|
||||||
private final SortDirection direction;
|
private final SortDirection direction;
|
||||||
|
|
||||||
<T> RegisterTableColumns(String header, Class<T> cls, Function<RegisterRow, T> getter) {
|
<T> RegisterTableColumns(String header, int width, Class<T> cls,
|
||||||
this(header, cls, getter, null, null, SortDirection.ASCENDING);
|
Function<RegisterRow, T> getter) {
|
||||||
|
this(header, width, cls, getter, null, null, SortDirection.ASCENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
<T> RegisterTableColumns(String header, Class<T> cls, Function<RegisterRow, T> getter,
|
<T> RegisterTableColumns(String header, int width, Class<T> cls,
|
||||||
|
Function<RegisterRow, T> getter,
|
||||||
BiConsumer<RegisterRow, T> setter, Predicate<RegisterRow> editable,
|
BiConsumer<RegisterRow, T> setter, Predicate<RegisterRow> editable,
|
||||||
SortDirection direction) {
|
SortDirection direction) {
|
||||||
this.header = header;
|
this.header = header;
|
||||||
|
this.width = width;
|
||||||
this.cls = cls;
|
this.cls = cls;
|
||||||
this.getter = getter;
|
this.getter = getter;
|
||||||
this.setter = (BiConsumer<RegisterRow, Object>) setter;
|
this.setter = (BiConsumer<RegisterRow, Object>) setter;
|
||||||
@ -206,6 +227,11 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
public SortDirection defaultSortDirection() {
|
public SortDirection defaultSortDirection() {
|
||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPreferredWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class RegistersTableModel
|
protected static class RegistersTableModel
|
||||||
@ -387,7 +413,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegisterValueCellRenderer extends HexBigIntegerTableCellRenderer {
|
static class RegisterValueCellRenderer extends HexDefaultGColumnRenderer<BigInteger> {
|
||||||
@Override
|
@Override
|
||||||
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||||
super.getTableCellRendererComponent(data);
|
super.getTableCellRendererComponent(data);
|
||||||
@ -574,21 +600,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
});
|
});
|
||||||
|
|
||||||
TableColumnModel columnModel = regsTable.getColumnModel();
|
TableColumnModel columnModel = regsTable.getColumnModel();
|
||||||
TableColumn favCol = columnModel.getColumn(RegisterTableColumns.FAV.ordinal());
|
|
||||||
favCol.setPreferredWidth(1);
|
|
||||||
TableColumn numCol = columnModel.getColumn(RegisterTableColumns.NUMBER.ordinal());
|
|
||||||
numCol.setPreferredWidth(1);
|
|
||||||
TableColumn nameCol = columnModel.getColumn(RegisterTableColumns.NAME.ordinal());
|
|
||||||
nameCol.setPreferredWidth(40);
|
|
||||||
TableColumn valCol = columnModel.getColumn(RegisterTableColumns.VALUE.ordinal());
|
TableColumn valCol = columnModel.getColumn(RegisterTableColumns.VALUE.ordinal());
|
||||||
valCol.setCellRenderer(new RegisterValueCellRenderer());
|
|
||||||
valCol.setCellEditor(new HexBigIntegerTableCellEditor());
|
valCol.setCellEditor(new HexBigIntegerTableCellEditor());
|
||||||
valCol.setPreferredWidth(100);
|
|
||||||
TableColumn typeCol = columnModel.getColumn(RegisterTableColumns.TYPE.ordinal());
|
TableColumn typeCol = columnModel.getColumn(RegisterTableColumns.TYPE.ordinal());
|
||||||
typeCol.setCellEditor(new RegisterDataTypeEditor());
|
typeCol.setCellEditor(new RegisterDataTypeEditor());
|
||||||
typeCol.setPreferredWidth(50);
|
|
||||||
TableColumn reprCol = columnModel.getColumn(RegisterTableColumns.REPR.ordinal());
|
|
||||||
reprCol.setPreferredWidth(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,8 +21,10 @@ import java.util.function.Predicate;
|
|||||||
import docking.widgets.table.ColumnSortState.SortDirection;
|
import docking.widgets.table.ColumnSortState.SortDirection;
|
||||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
|
import ghidra.docking.settings.SettingsDefinition;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
|
import ghidra.util.table.column.GColumnRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A table model whose columns are described using an {@link Enum}.
|
* A table model whose columns are described using an {@link Enum}.
|
||||||
@ -106,6 +108,26 @@ public class DefaultEnumeratedColumnTableModel<C extends Enum<C> & EnumeratedTab
|
|||||||
default public SortDirection defaultSortDirection() {
|
default public SortDirection defaultSortDirection() {
|
||||||
return SortDirection.ASCENDING;
|
return SortDirection.ASCENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default public int getPreferredWidth() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because of limitations with Java generics and Enumerations, type checking cannot be
|
||||||
|
* guaranteed here. The user must ensure that any returned by {@link #getValueOf(Object)}
|
||||||
|
* can be accepted by the renderer returned here. The framework will perform an unchecked
|
||||||
|
* cast of the renderer.
|
||||||
|
*
|
||||||
|
* @return the renderer
|
||||||
|
*/
|
||||||
|
default public GColumnRenderer<?> getRenderer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default public SettingsDefinition[] getSettingsDefinitions() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<R> modelData = new ArrayList<>();
|
private final List<R> modelData = new ArrayList<>();
|
||||||
@ -167,6 +189,26 @@ public class DefaultEnumeratedColumnTableModel<C extends Enum<C> & EnumeratedTab
|
|||||||
ServiceProvider serviceProvider) {
|
ServiceProvider serviceProvider) {
|
||||||
col.setValueOf(row, value);
|
col.setValueOf(row, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public GColumnRenderer<Object> getColumnRenderer() {
|
||||||
|
return (GColumnRenderer<Object>) col.getRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnPreferredWidth() {
|
||||||
|
return col.getPreferredWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingsDefinition[] getSettingsDefinitions() {
|
||||||
|
SettingsDefinition[] defs = col.getSettingsDefinitions();
|
||||||
|
if (defs != null) {
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
return super.getSettingsDefinitions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,6 +52,7 @@ public class HexBigIntegerTableCellEditor extends AbstractCellEditor implements
|
|||||||
input.setHexMode();
|
input.setHexMode();
|
||||||
input.setAllowsHexPrefix(false);
|
input.setAllowsHexPrefix(false);
|
||||||
input.setShowNumberMode(true);
|
input.setShowNumberMode(true);
|
||||||
|
input.setHorizontalAlignment(JTextField.RIGHT);
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
input.setValue((BigInteger) value);
|
input.setValue((BigInteger) value);
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/* ###
|
|
||||||
* 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 docking.widgets.table;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
|
|
||||||
import ghidra.docking.settings.Settings;
|
|
||||||
import ghidra.util.table.column.AbstractGColumnRenderer;
|
|
||||||
|
|
||||||
public class HexBigIntegerTableCellRenderer extends AbstractGColumnRenderer<BigInteger> {
|
|
||||||
@Override
|
|
||||||
protected void configureFont(JTable table, TableModel model, int column) {
|
|
||||||
setFont(fixedWidthFont);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String formatBigInteger(BigInteger value) {
|
|
||||||
return value == null ? "??" : value.toString(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
|
||||||
super.getTableCellRendererComponent(data);
|
|
||||||
setText(formatBigInteger((BigInteger) data.getValue()));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Seems the filter model does not heed this....
|
|
||||||
@Override
|
|
||||||
public String getFilterString(BigInteger t, Settings settings) {
|
|
||||||
return formatBigInteger(t);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,35 @@
|
|||||||
|
/* ###
|
||||||
|
* 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 docking.widgets.table;
|
||||||
|
|
||||||
|
import ghidra.docking.settings.FormatSettingsDefinition;
|
||||||
|
import ghidra.docking.settings.Settings;
|
||||||
|
import ghidra.util.table.column.AbstractGColumnRenderer;
|
||||||
|
|
||||||
|
public class HexDefaultGColumnRenderer<T extends Number> extends AbstractGColumnRenderer<T> {
|
||||||
|
private final static FormatSettingsDefinition INTEGER_RADIX_SETTING =
|
||||||
|
FormatSettingsDefinition.DEF_HEX;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getRadix(Settings settings) {
|
||||||
|
return INTEGER_RADIX_SETTING.getRadix(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilterString(Number t, Settings settings) {
|
||||||
|
return formatNumber(t, settings);
|
||||||
|
}
|
||||||
|
}
|
@ -50,10 +50,10 @@ public abstract class AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOU
|
|||||||
protected static final FloatingPointPrecisionSettingsDefinition FLOATING_POINT_PRECISION_SETTING =
|
protected static final FloatingPointPrecisionSettingsDefinition FLOATING_POINT_PRECISION_SETTING =
|
||||||
FloatingPointPrecisionSettingsDefinition.DEF;
|
FloatingPointPrecisionSettingsDefinition.DEF;
|
||||||
|
|
||||||
protected static SettingsDefinition[] INTEGER_SETTINGS_DEFINITIONS =
|
protected static final SettingsDefinition[] INTEGER_SETTINGS_DEFINITIONS =
|
||||||
new SettingsDefinition[] { INTEGER_RADIX_SETTING, INTEGER_SIGNEDNESS_MODE_SETTING };
|
new SettingsDefinition[] { INTEGER_RADIX_SETTING, INTEGER_SIGNEDNESS_MODE_SETTING };
|
||||||
|
|
||||||
protected static SettingsDefinition[] FLOATING_POINT_SETTINGS_DEFINITIONS =
|
protected static final SettingsDefinition[] FLOATING_POINT_SETTINGS_DEFINITIONS =
|
||||||
new SettingsDefinition[] { FLOATING_POINT_PRECISION_SETTING };
|
new SettingsDefinition[] { FLOATING_POINT_PRECISION_SETTING };
|
||||||
|
|
||||||
private boolean hasConfiguredDefaultSettings = false;
|
private boolean hasConfiguredDefaultSettings = false;
|
||||||
|
@ -34,8 +34,8 @@ import ghidra.util.*;
|
|||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default table cell renderer that relies on the <code>toString()</code> method
|
* A default table cell renderer that relies on the <code>toString()</code> method when rendering
|
||||||
* when rendering the cells of the table.
|
* the cells of the table.
|
||||||
*/
|
*/
|
||||||
public class GTableCellRenderer extends AbstractGCellRenderer implements TableCellRenderer {
|
public class GTableCellRenderer extends AbstractGCellRenderer implements TableCellRenderer {
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new GTableCellRenderer using the specified font.
|
* Constructs a new GTableCellRenderer using the specified font.
|
||||||
|
*
|
||||||
* @param f the font to use when rendering text in the table cells
|
* @param f the font to use when rendering text in the table cells
|
||||||
*/
|
*/
|
||||||
public GTableCellRenderer(Font f) {
|
public GTableCellRenderer(Font f) {
|
||||||
@ -93,6 +94,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the cell renderer text
|
* Return the cell renderer text
|
||||||
|
*
|
||||||
* @param value Cell object value
|
* @param value Cell object value
|
||||||
* @return A string interpretation of value; generated by calling value.toString()
|
* @return A string interpretation of value; generated by calling value.toString()
|
||||||
*/
|
*/
|
||||||
@ -101,8 +103,8 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Satisfies the Java {@link javax.swing.table.TableCellRenderer} interface; retrieves
|
* Satisfies the Java {@link javax.swing.table.TableCellRenderer} interface; retrieves column
|
||||||
* column data via a GTableCellRenderingData object, and defers painting to
|
* data via a GTableCellRenderingData object, and defers painting to
|
||||||
* {@link #getTableCellRendererComponent(GTableCellRenderingData)}.
|
* {@link #getTableCellRendererComponent(GTableCellRenderingData)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is marked <code>final</code> to redirect subclasses to the enhanced method,
|
* This is marked <code>final</code> to redirect subclasses to the enhanced method,
|
||||||
@ -111,7 +113,8 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
* Throws an AssertException if the table this renderer is used with is not a
|
* Throws an AssertException if the table this renderer is used with is not a
|
||||||
* {@link docking.widgets.table.GTable} instance.
|
* {@link docking.widgets.table.GTable} instance.
|
||||||
*
|
*
|
||||||
* @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
|
* @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable,
|
||||||
|
* java.lang.Object, boolean, boolean, int, int)
|
||||||
* @see #getTableCellRendererComponent(GTableCellRenderingData)
|
* @see #getTableCellRendererComponent(GTableCellRenderingData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -144,8 +147,9 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide basic cell rendering -- setting foreground and background colors, font, text,
|
* Provide basic cell rendering -- setting foreground and background colors, font, text,
|
||||||
* alignment, drop color, and border. Additional data that may be of use to the renderer
|
* alignment, drop color, and border. Additional data that may be of use to the renderer is
|
||||||
* is passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
|
* passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
|
||||||
|
*
|
||||||
* @param data Context data used in the rendering of a data cell.
|
* @param data Context data used in the rendering of a data cell.
|
||||||
* @return The component used for drawing the table cell.
|
* @return The component used for drawing the table cell.
|
||||||
*/
|
*/
|
||||||
@ -199,8 +203,21 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
setFont(defaultFont);
|
setFont(defaultFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getRadix(Settings settings) {
|
||||||
|
return INTEGER_RADIX_SETTING.getRadix(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SignednessFormatMode getSignMode(Settings settings) {
|
||||||
|
return INTEGER_SIGNEDNESS_MODE_SETTING.getFormatMode(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getPrecision(Settings settings) {
|
||||||
|
return FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a Number per the Settings parameters.
|
* Format a Number per the Settings parameters.
|
||||||
|
*
|
||||||
* @param value the number to format
|
* @param value the number to format
|
||||||
* @param settings settings controlling the display of the Number parameter
|
* @param settings settings controlling the display of the Number parameter
|
||||||
* @return a formatted representation of the Number value
|
* @return a formatted representation of the Number value
|
||||||
@ -208,8 +225,8 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
protected String formatNumber(Number value, Settings settings) {
|
protected String formatNumber(Number value, Settings settings) {
|
||||||
|
|
||||||
if (NumericUtilities.isIntegerType(value)) {
|
if (NumericUtilities.isIntegerType(value)) {
|
||||||
int radix = INTEGER_RADIX_SETTING.getRadix(settings);
|
int radix = getRadix(settings);
|
||||||
SignednessFormatMode signMode = INTEGER_SIGNEDNESS_MODE_SETTING.getFormatMode(settings);
|
SignednessFormatMode signMode = getSignMode(settings);
|
||||||
long number = value.longValue();
|
long number = value.longValue();
|
||||||
return NumericUtilities.formatNumber(number, radix, signMode);
|
return NumericUtilities.formatNumber(number, radix, signMode);
|
||||||
}
|
}
|
||||||
@ -219,18 +236,18 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||||||
if (number.isNaN() || number.isInfinite()) {
|
if (number.isNaN() || number.isInfinite()) {
|
||||||
return Character.toString('\u221e'); // infinity symbol
|
return Character.toString('\u221e'); // infinity symbol
|
||||||
}
|
}
|
||||||
int precision = FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
|
int precision = getPrecision(settings);
|
||||||
return getFormatter(precision).format(number);
|
return getFormatter(precision).format(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof BigInteger) {
|
if (value instanceof BigInteger) {
|
||||||
int radix = INTEGER_RADIX_SETTING.getRadix(settings);
|
int radix = getRadix(settings);
|
||||||
return ((BigInteger) value).toString(radix);
|
return ((BigInteger) value).toString(radix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof BigDecimal) {
|
if (value instanceof BigDecimal) {
|
||||||
|
|
||||||
int precision = FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
|
int precision = getPrecision(settings);
|
||||||
DecimalFormat formatter = getFormatter(precision);
|
DecimalFormat formatter = getFormatter(precision);
|
||||||
formatter.format(value);
|
formatter.format(value);
|
||||||
|
|
||||||
|
@ -34,26 +34,28 @@ import ghidra.util.SystemUtilities;
|
|||||||
/**
|
/**
|
||||||
* TextField for entering integer numbers, either in decimal or hex.
|
* TextField for entering integer numbers, either in decimal or hex.
|
||||||
*
|
*
|
||||||
* <P> This field does continuous checking, so
|
* <P>
|
||||||
* you can't enter a bad value.
|
* This field does continuous checking, so you can't enter a bad value.
|
||||||
*
|
*
|
||||||
* <P> Internally, values are maintained using BigIntegers so this field can
|
* <P>
|
||||||
* contain numbers as large as desired. There are convenience methods for getting the value as
|
* Internally, values are maintained using BigIntegers so this field can contain numbers as large as
|
||||||
* either an int or long. If using these convenience methods, you should also set the max allowed
|
* desired. There are convenience methods for getting the value as either an int or long. If using
|
||||||
* value so that users can't enter a value larger than can be represented by the {@link #getIntValue()}
|
* these convenience methods, you should also set the max allowed value so that users can't enter a
|
||||||
* or {@link #getLongValue()} methods as appropriate.
|
* value larger than can be represented by the {@link #getIntValue()} or {@link #getLongValue()}
|
||||||
|
* methods as appropriate.
|
||||||
*
|
*
|
||||||
* <P> There are several configuration options as follows:
|
* <P>
|
||||||
|
* There are several configuration options as follows:
|
||||||
* <UL>
|
* <UL>
|
||||||
* <LI> Allows negative numbers - either support all integer numbers or just non-negative
|
* <LI>Allows negative numbers - either support all integer numbers or just non-negative numbers.
|
||||||
* numbers. See {@link #setAllowNegativeValues(boolean)} </LI>
|
* See {@link #setAllowNegativeValues(boolean)}</LI>
|
||||||
* <LI>Allows hex prefix - If this mode is on, then hex mode is turned on and off automatically
|
* <LI>Allows hex prefix - If this mode is on, then hex mode is turned on and off automatically
|
||||||
* depending whether or not the text starts with 0x. Otherwise, the hex/decimal mode is set externally
|
* depending whether or not the text starts with 0x. Otherwise, the hex/decimal mode is set
|
||||||
* (either programmatically or pressing <CTRL> M) and the user is restricted to the numbers/letters
|
* externally (either programmatically or pressing <CTRL> M) and the user is restricted to the
|
||||||
* appropriate for that mode. See {@link #setAllowsHexPrefix(boolean)}</LI>
|
* numbers/letters appropriate for that mode. See {@link #setAllowsHexPrefix(boolean)}</LI>
|
||||||
* <LI> Have a max value - a max value can be set (must be positive) such that the user can not type a
|
* <LI>Have a max value - a max value can be set (must be positive) such that the user can not type
|
||||||
* number whose absolute value is greater than the max. Otherwise, the value is unlimited if max is
|
* a number whose absolute value is greater than the max. Otherwise, the value is unlimited if max
|
||||||
* null/unspecified. See {@link #setMaxValue(BigInteger)}</LI>
|
* is null/unspecified. See {@link #setMaxValue(BigInteger)}</LI>
|
||||||
* <LI>Show the number mode as hint text - If on either "Hex" or "Dec" is displayed lightly in the
|
* <LI>Show the number mode as hint text - If on either "Hex" or "Dec" is displayed lightly in the
|
||||||
* bottom right portion of the text field. See {@link #setShowNumberMode(boolean)}</LI>
|
* bottom right portion of the text field. See {@link #setShowNumberMode(boolean)}</LI>
|
||||||
* </UL>
|
* </UL>
|
||||||
@ -93,8 +95,8 @@ public class IntegerTextField {
|
|||||||
*
|
*
|
||||||
* @param columns the number of columns to display in the JTextField.
|
* @param columns the number of columns to display in the JTextField.
|
||||||
* @param initialValue the initial value. This constructor takes an initialValue as a long. If
|
* @param initialValue the initial value. This constructor takes an initialValue as a long. If
|
||||||
* you need a value that is bigger (or smaller) than can be specified as a long, then use
|
* you need a value that is bigger (or smaller) than can be specified as a long, then
|
||||||
* the constructor that takes a BigInteger as an initial value.
|
* use the constructor that takes a BigInteger as an initial value.
|
||||||
*/
|
*/
|
||||||
public IntegerTextField(int columns, long initialValue) {
|
public IntegerTextField(int columns, long initialValue) {
|
||||||
this(columns, BigInteger.valueOf(initialValue));
|
this(columns, BigInteger.valueOf(initialValue));
|
||||||
@ -159,11 +161,13 @@ public class IntegerTextField {
|
|||||||
/**
|
/**
|
||||||
* Returns the current value as an int.
|
* Returns the current value as an int.
|
||||||
*
|
*
|
||||||
* <P> If the field has no current value, 0 will be returned. If
|
* <P>
|
||||||
* the value is bigger (or smaller) than an int, it will be cast to an int.
|
* If the field has no current value, 0 will be returned. If the value is bigger (or smaller)
|
||||||
|
* than an int, it will be cast to an int.
|
||||||
*
|
*
|
||||||
* <P> If using this method, it is highly recommended that you set the max value to {@link Integer#MAX_VALUE}
|
* <P>
|
||||||
* or lower.
|
* If using this method, it is highly recommended that you set the max value to
|
||||||
|
* {@link Integer#MAX_VALUE} or lower.
|
||||||
*
|
*
|
||||||
* @return the current value as an int. Or 0 if there is no value
|
* @return the current value as an int. Or 0 if there is no value
|
||||||
* @throws ArithmeticException if the value in this field will not fit into an int
|
* @throws ArithmeticException if the value in this field will not fit into an int
|
||||||
@ -179,11 +183,13 @@ public class IntegerTextField {
|
|||||||
/**
|
/**
|
||||||
* Returns the current value as a long.
|
* Returns the current value as a long.
|
||||||
*
|
*
|
||||||
* <P> If the field has no current value, 0 will be returned. If
|
* <P>
|
||||||
* the value is bigger (or smaller) than an long, it will be cast to a long.
|
* If the field has no current value, 0 will be returned. If the value is bigger (or smaller)
|
||||||
|
* than an long, it will be cast to a long.
|
||||||
*
|
*
|
||||||
* <P> If using this method, it is highly recommended that you set the max value to {@link Long#MAX_VALUE}
|
* <P>
|
||||||
* or lower.
|
* If using this method, it is highly recommended that you set the max value to
|
||||||
|
* {@link Long#MAX_VALUE} or lower.
|
||||||
*
|
*
|
||||||
* @return the current value as a long. Or 0 if there is no value
|
* @return the current value as a long. Or 0 if there is no value
|
||||||
* @throws ArithmeticException if the value in this field will not fit into a long
|
* @throws ArithmeticException if the value in this field will not fit into a long
|
||||||
@ -215,13 +221,13 @@ public class IntegerTextField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the field to the given text. The text must be a properly formated string that is
|
* Sets the field to the given text. The text must be a properly formated string that is a value
|
||||||
* a value that is valid for this field. If the field is set to not allow "0x" prefixes, then
|
* that is valid for this field. If the field is set to not allow "0x" prefixes, then the input
|
||||||
* the input string cannot start with 0x and furthermore, if the field is in decimal mode, then
|
* string cannot start with 0x and furthermore, if the field is in decimal mode, then input
|
||||||
* input string cannot take in hex digits a-f. On the other hand, if "0x" prefixes are allowed,
|
* string cannot take in hex digits a-f. On the other hand, if "0x" prefixes are allowed, then
|
||||||
* then the input string can be either a decimal number or a hex number depending on if the
|
* the input string can be either a decimal number or a hex number depending on if the input
|
||||||
* input string starts with "0x". In this case, the field's hex mode will be set to match
|
* string starts with "0x". In this case, the field's hex mode will be set to match the input
|
||||||
* the input text. If the text is not valid, the field will not change.
|
* text. If the text is not valid, the field will not change.
|
||||||
*
|
*
|
||||||
* @param text the value as text to set on this field
|
* @param text the value as text to set on this field
|
||||||
* @return true if the set was successful
|
* @return true if the set was successful
|
||||||
@ -259,8 +265,9 @@ public class IntegerTextField {
|
|||||||
/**
|
/**
|
||||||
* Sets the radix mode to Hex.
|
* Sets the radix mode to Hex.
|
||||||
*
|
*
|
||||||
* <P> If the field is currently in decimal mode, the current text will be
|
* <P>
|
||||||
* change from displaying the current value from decimal to hex.
|
* If the field is currently in decimal mode, the current text will be change from displaying
|
||||||
|
* the current value from decimal to hex.
|
||||||
*/
|
*/
|
||||||
public void setHexMode() {
|
public void setHexMode() {
|
||||||
BigInteger currentValue = getValue();
|
BigInteger currentValue = getValue();
|
||||||
@ -271,8 +278,9 @@ public class IntegerTextField {
|
|||||||
/**
|
/**
|
||||||
* Sets the mode to Decimal.
|
* Sets the mode to Decimal.
|
||||||
*
|
*
|
||||||
* <P> If the field is currently in hex mode, the current text will be
|
* <P>
|
||||||
* change from displaying the current value from hex to decimal.
|
* If the field is currently in hex mode, the current text will be change from displaying the
|
||||||
|
* current value from hex to decimal.
|
||||||
*/
|
*/
|
||||||
public void setDecimalMode() {
|
public void setDecimalMode() {
|
||||||
BigInteger currentValue = getValue();
|
BigInteger currentValue = getValue();
|
||||||
@ -283,12 +291,12 @@ public class IntegerTextField {
|
|||||||
/**
|
/**
|
||||||
* Sets whether on not the field supports the 0x prefix.
|
* Sets whether on not the field supports the 0x prefix.
|
||||||
*
|
*
|
||||||
* <P> If 0x is supported, hex numbers
|
* <P>
|
||||||
* will be displayed with the 0x prefix. Also, when typing, you must type 0x first to enter
|
* If 0x is supported, hex numbers will be displayed with the 0x prefix. Also, when typing, you
|
||||||
* a hex number, otherwise it will only allow digits 0-9. If the 0x prefix option is turned
|
* must type 0x first to enter a hex number, otherwise it will only allow digits 0-9. If the 0x
|
||||||
* off, then hex numbers are displayed without the 0x prefix and you can't change the decimal/hex
|
* prefix option is turned off, then hex numbers are displayed without the 0x prefix and you
|
||||||
* mode by typing 0x. The field will either be in decimal or hex mode and the typed text
|
* can't change the decimal/hex mode by typing 0x. The field will either be in decimal or hex
|
||||||
* will be interpreted appropriately for the mode.
|
* mode and the typed text will be interpreted appropriately for the mode.
|
||||||
*
|
*
|
||||||
* @param allowsHexPrefix true to use the 0x convention for hex.
|
* @param allowsHexPrefix true to use the 0x convention for hex.
|
||||||
*/
|
*/
|
||||||
@ -333,9 +341,10 @@ public class IntegerTextField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current maximum allowed value. Null indicates that there is no maximum value.
|
* Returns the current maximum allowed value. Null indicates that there is no maximum value. If
|
||||||
* If negative values are permitted (see {@link #setAllowNegativeValues(boolean)}) this value
|
* negative values are permitted (see {@link #setAllowNegativeValues(boolean)}) this value will
|
||||||
* will establish the upper and lower limit of the absolute value.
|
* establish the upper and lower limit of the absolute value.
|
||||||
|
*
|
||||||
* @return the current maximum value allowed.
|
* @return the current maximum value allowed.
|
||||||
*/
|
*/
|
||||||
public BigInteger getMaxValue() {
|
public BigInteger getMaxValue() {
|
||||||
@ -451,6 +460,15 @@ public class IntegerTextField {
|
|||||||
textField.selectAll();
|
textField.selectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the horizontal alignment of the JTextField
|
||||||
|
*
|
||||||
|
* @param alignment the alignment as in {@link JTextField#setHorizontalAlignment(int)}
|
||||||
|
*/
|
||||||
|
public void setHorizontalAlignment(int alignment) {
|
||||||
|
textField.setHorizontalAlignment(alignment);
|
||||||
|
}
|
||||||
|
|
||||||
private String computeTextForValue(BigInteger value) {
|
private String computeTextForValue(BigInteger value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return "";
|
return "";
|
||||||
@ -724,7 +742,13 @@ public class IntegerTextField {
|
|||||||
|
|
||||||
Dimension size = getSize();
|
Dimension size = getSize();
|
||||||
Insets insets = getInsets();
|
Insets insets = getInsets();
|
||||||
int x = size.width - insets.right - hintWidth;
|
int x;
|
||||||
|
if (getHorizontalAlignment() == RIGHT) {
|
||||||
|
x = insets.left;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = size.width - insets.right - hintWidth;
|
||||||
|
}
|
||||||
int y = size.height - insets.bottom - 1;
|
int y = size.height - insets.bottom - 1;
|
||||||
String mode = isHexMode ? "Hex" : "Dec";
|
String mode = isHexMode ? "Hex" : "Dec";
|
||||||
GraphicsUtils.drawString(this, g, mode, x, y);
|
GraphicsUtils.drawString(this, g, mode, x, y);
|
||||||
|
Loading…
Reference in New Issue
Block a user