Merge remote-tracking branch 'origin/GT-3560_rev308_delayed_column_initialization'

This commit is contained in:
ghidorahrex 2020-02-26 13:11:35 -05:00
commit 2cadf691b2
4 changed files with 82 additions and 81 deletions

View File

@ -139,7 +139,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
@Override
public boolean isCellEditable(int row, int col) {
DynamicTableColumn<ResourceFile, ?, ?> column = tableColumns.get(col);
DynamicTableColumn<ResourceFile, ?, ?> column = getColumn(col);
String columnName = column.getColumnName();
if (SCRIPT_ACTION_COLUMN_NAME.equals(columnName)) {
return true;
@ -149,7 +149,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
@Override
public void setValueAt(Object value, int row, int col) {
DynamicTableColumn<ResourceFile, ?, ?> column = tableColumns.get(col);
DynamicTableColumn<ResourceFile, ?, ?> column = getColumn(col);
String columnName = column.getColumnName();
if (SCRIPT_ACTION_COLUMN_NAME.equals(columnName)) {
ResourceFile script = getScriptAt(row);
@ -190,7 +190,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
}
private class ScriptActionColumn
extends AbstractDynamicTableColumn<ResourceFile, Boolean, Object> {
extends AbstractDynamicTableColumn<ResourceFile, Boolean, Object> {
@Override
public String getColumnDescription() {
@ -231,7 +231,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
return SystemUtilities.compareTo(d1, d2);
};
private GColumnRenderer<ImageIcon> renderer = new AbstractGColumnRenderer<ImageIcon>() {
private GColumnRenderer<ImageIcon> renderer = new AbstractGColumnRenderer<>() {
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
JLabel label = (JLabel) super.getTableCellRendererComponent(data);
@ -318,7 +318,7 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
}
private class DescriptionColumn
extends AbstractDynamicTableColumn<ResourceFile, String, Object> {
extends AbstractDynamicTableColumn<ResourceFile, String, Object> {
@Override
public String getColumnName() {
@ -339,55 +339,55 @@ class GhidraScriptTableModel extends GDynamicColumnTableModel<ResourceFile, Obje
}
private class KeyBindingColumn
extends AbstractDynamicTableColumn<ResourceFile, KeyBindingsInfo, Object> {
extends AbstractDynamicTableColumn<ResourceFile, KeyBindingsInfo, Object> {
private GColumnRenderer<KeyBindingsInfo> renderer =
new AbstractGColumnRenderer<KeyBindingsInfo>() {
new AbstractGColumnRenderer<>() {
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
JComponent component = (JComponent) super.getTableCellRendererComponent(data);
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
JComponent component = (JComponent) super.getTableCellRendererComponent(data);
Object value = data.getValue();
boolean isSelected = data.isSelected();
Object value = data.getValue();
boolean isSelected = data.isSelected();
KeyBindingsInfo info = (KeyBindingsInfo) value;
KeyBindingsInfo info = (KeyBindingsInfo) value;
if (info.errorMessage != null) {
component.setForeground(Color.RED);
component.setToolTipText(info.errorMessage);
if (info.errorMessage != null) {
component.setForeground(Color.RED);
component.setToolTipText(info.errorMessage);
}
else {
String keybindingText = "";
if (!info.keystroke.isEmpty()) {
keybindingText = ": " + info.toString();
}
if (info.hasAction) {
component.setForeground(Color.BLACK);
component.setToolTipText(
"Keybinding for action in tool" + keybindingText);
}
else {
String keybindingText = "";
if (!info.keystroke.isEmpty()) {
keybindingText = ": " + info.toString();
}
if (info.hasAction) {
component.setForeground(Color.BLACK);
component.setToolTipText(
"Keybinding for action in tool" + keybindingText);
}
else {
component.setForeground(Color.LIGHT_GRAY);
component.setToolTipText("Keybinding for script" + keybindingText);
}
component.setForeground(Color.LIGHT_GRAY);
component.setToolTipText("Keybinding for script" + keybindingText);
}
}
if (isSelected) {
Color selectedForegroundColor =
if (isSelected) {
Color selectedForegroundColor =
(info.errorMessage != null) ? Color.PINK : Color.WHITE;
component.setForeground(selectedForegroundColor);
}
return component;
component.setForeground(selectedForegroundColor);
}
return component;
@Override
public String getFilterString(KeyBindingsInfo t, Settings settings) {
return t.toString();
}
};
}
@Override
public String getFilterString(KeyBindingsInfo t, Settings settings) {
return t.toString();
}
};
@Override
public GColumnRenderer<KeyBindingsInfo> getColumnRenderer() {

View File

@ -29,47 +29,41 @@ import ghidra.docking.settings.SettingsDefinition;
public interface ConfigurableColumnTableModel extends TableModel {
/**
* Returns settings for the specified column index.
* Returns settings for the specified column index
* @param index column index
* @return column settings.
*/
public Settings getColumnSettings(int index);
/**
* Returns settings definitions for the specified column index.
* Returns settings definitions for the specified column index
* @param index column index
* @return column settings definitions.
*/
public SettingsDefinition[] getColumnSettingsDefinitions(int index);
/**
* A convenience method to set bulk column setting information for a group of columns at one
* time (this saves repeated rebuilding when settings are changing for multiple columns at
* once).
* @param index the column index
* @param newSettings A list of pair objects that contain the column index of the column to
* which the new settings apply and the new settings object.
*/
public void setColumnSettings(int index, Settings newSettings);
/**
* Allows for the bulk setting of Settings. This prevents excessive event
* notification when all settings need to be changed.
*
* @param settings An array of Settings that contains Settings for each column
* where the index of the Settings in the array is the index of the column
* in the model.
* @see #setColumnSettings(int, Settings)
* in the model
*/
public void setAllColumnSettings(Settings[] settings);
/**
* Gets the maximum number of text display lines needed for any given cell within the
* specified column.
* specified column
* @param index column field index
* @return maximum number of lines needed for specified column
*/
public int getMaxLines(int index);
/**
* Returns the table cell renderer for the given column
* @param columnIndex the index of the column
* @return the renderer
*/
public TableCellRenderer getRenderer(int columnIndex);
}

View File

@ -64,9 +64,9 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
protected ServiceProvider serviceProvider;
private TableColumnDescriptor<ROW_TYPE> columnDescriptor;
protected List<DynamicTableColumn<ROW_TYPE, ?, ?>> tableColumns;
private List<DynamicTableColumn<ROW_TYPE, ?, ?>> defaultTableColumns;
protected Map<DynamicTableColumn<ROW_TYPE, ?, ?>, Settings> columnSettings;
protected List<DynamicTableColumn<ROW_TYPE, ?, ?>> tableColumns = new ArrayList<>();
private List<DynamicTableColumn<ROW_TYPE, ?, ?>> defaultTableColumns = new ArrayList<>();
protected Map<DynamicTableColumn<ROW_TYPE, ?, ?>, Settings> columnSettings = new HashMap<>();
private boolean ignoreSettingChanges = false;
@ -75,16 +75,8 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
SystemUtilities.assertTrue((serviceProvider != null), "ServiceProvider cannot be null");
this.serviceProvider = serviceProvider;
this.tableColumns = new ArrayList<>();
this.defaultTableColumns = new ArrayList<>();
loadDefaultTableColumns();
loadDiscoveredTableColumns();
this.columnSettings = new HashMap<>();
for (DynamicTableColumn<ROW_TYPE, ?, ?> column : tableColumns) {
columnSettings.put(column, new SettingsImpl(this, column));
}
reloadColumns();
}
protected abstract TableColumnDescriptor<ROW_TYPE> createTableColumnDescriptor();
@ -129,6 +121,29 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
setDefaultTableSortState(sortState);
}
/**
* Allows clients to defer column creation until after this parent class's constructor has
* been called. This method will not restore any column settings that have been changed
* after construction. Thus, this method is intended only to be called during the
* construction process.
*/
protected void reloadColumns() {
// note: since we should only be called during construction, there is no need to
// fire an event to signal the table structure has changed
columnDescriptor = null;
tableColumns.clear();
defaultTableColumns.clear();
loadDefaultTableColumns();
loadDiscoveredTableColumns();
columnSettings.clear();
for (DynamicTableColumn<ROW_TYPE, ?, ?> column : tableColumns) {
columnSettings.put(column, new SettingsImpl(this, column));
}
}
private TableColumnDescriptor<ROW_TYPE> getTableColumnDescriptor() {
if (columnDescriptor == null) {
columnDescriptor = createTableColumnDescriptor();
@ -489,14 +504,6 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
return columnSettings.get(column);
}
@Override
public synchronized void setColumnSettings(int index, Settings newSettings) {
ignoreSettingChanges = true;
applySettings(index, newSettings);
ignoreSettingChanges = false;
stateChanged(new ChangeEvent(tableColumns.get(index)));
}
private void applySettings(int index, Settings newSettings) {
DynamicTableColumn<ROW_TYPE, ?, ?> column = tableColumns.get(index);
Settings settings = columnSettings.get(column);

View File

@ -128,7 +128,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (editingOn) {
DynamicTableColumn<DomainFileInfo, ?, ?> column = tableColumns.get(columnIndex);
DynamicTableColumn<DomainFileInfo, ?, ?> column = getColumn(columnIndex);
return column instanceof DomainFileNameColumn;
}
return false;
@ -162,7 +162,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
//==================================================================================================
private class DomainFileTypeColumn
extends AbstractDynamicTableColumn<DomainFileInfo, DomainFileType, ProjectData> {
extends AbstractDynamicTableColumn<DomainFileInfo, DomainFileType, ProjectData> {
@Override
public String getColumnName() {
@ -182,7 +182,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
}
private class DomainFileNameColumn
extends AbstractDynamicTableColumn<DomainFileInfo, String, ProjectData> {
extends AbstractDynamicTableColumn<DomainFileInfo, String, ProjectData> {
@Override
public String getColumnName() {
@ -203,7 +203,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
}
private class ModificationDateColumn
extends AbstractDynamicTableColumn<DomainFileInfo, Date, ProjectData> {
extends AbstractDynamicTableColumn<DomainFileInfo, Date, ProjectData> {
@Override
public String getColumnName() {
@ -224,7 +224,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
}
private class DomainFilePathColumn
extends AbstractDynamicTableColumn<DomainFileInfo, String, ProjectData> {
extends AbstractDynamicTableColumn<DomainFileInfo, String, ProjectData> {
@Override
public String getColumnName() {