Merge remote-tracking branch 'origin/GP-4321-dragonmacher-table-copy-fix--SQUASHED'

This commit is contained in:
Ryan Kurtz 2024-03-12 13:41:36 -04:00
commit 8746542a86
2 changed files with 52 additions and 15 deletions

View file

@ -35,7 +35,6 @@ public class GTableTest extends AbstractGhidraHeadedIntegrationTest {
private GhidraTable table;
private JFrame frame;
private long testKeyTimeout = 100;
private boolean timeoutTriggered;
@Before
@ -56,7 +55,7 @@ public class GTableTest extends AbstractGhidraHeadedIntegrationTest {
}
private void installTestAutoLookupTimeout() {
// note: this call will not work due to the unpredictable timing of event
// note: this call will not work due to the unpredictable timing of event
// processing in the various test environments
// table.setAutoLookupTimeout(testKeyTimeout);

View file

@ -18,6 +18,7 @@ package docking.widgets.table;
import static docking.DockingUtils.*;
import static docking.action.MenuData.*;
import static java.awt.event.InputEvent.*;
import static javax.swing.ListSelectionModel.*;
import java.awt.*;
import java.awt.event.*;
@ -1176,30 +1177,31 @@ public class GTable extends JTable {
private void copyColumns(int... copyColumns) {
int[] originalColumns = new int[0];
boolean wasAllowed = getColumnSelectionAllowed();
if (wasAllowed) {
originalColumns = getSelectedColumns();
}
setColumnSelectionAllowed(true);
setSelectedColumns(copyColumns);
//
// We have to change the column model's selection settings to ensure that the copy works
// correctly. For example, if the model only allows single column selection, then we have
// to change that to allow for multiple column selection. We will put the original state
// back when finished.
//
ColumnSelectionState originalState = ColumnSelectionState.copy(this);
ColumnSelectionState newState = ColumnSelectionState.withColumns(this, copyColumns);
newState.apply();
copying = true;
try {
Action builtinCopyAction = TransferHandler.getCopyAction();
builtinCopyAction.actionPerformed(new ActionEvent(GTable.this, 0, "copy"));
}
finally {
copying = false;
// put back whatever selection existed before this action was executed
setSelectedColumns(originalColumns);
setColumnSelectionAllowed(wasAllowed);
originalState.apply(); // put back column model's original selection state
}
}
private int getColumnSelectionMode() {
return getColumnModel().getSelectionModel().getSelectionMode();
}
private void setSelectedColumns(int[] columns) {
columnModel.getSelectionModel().clearSelection();
for (int column : columns) {
@ -1460,6 +1462,42 @@ public class GTable extends JTable {
// Inner Classes
//==================================================================================================
/**
* A class that captures attribute of the table's column model so that we can change and then
* restore those values.
*/
private static class ColumnSelectionState {
private GTable table;
private boolean selectionAllowed;
private int[] selectedColumns;
private int selectionMode;
ColumnSelectionState(GTable table, boolean selectionAllowed, int selectionMode,
int[] selectedColumns) {
this.table = table;
this.selectionAllowed = selectionAllowed;
this.selectedColumns = selectedColumns;
this.selectionMode = selectionMode;
}
void apply() {
table.getColumnModel().getSelectionModel().setSelectionMode(selectionMode);
table.setColumnSelectionAllowed(selectionAllowed);
table.setSelectedColumns(selectedColumns);
}
static ColumnSelectionState withColumns(GTable table, int[] columns) {
return new ColumnSelectionState(table, true, MULTIPLE_INTERVAL_SELECTION, columns);
}
static ColumnSelectionState copy(GTable table) {
int[] columns = table.getSelectedColumns();
boolean allowed = table.getColumnSelectionAllowed();
int mode = table.getColumnSelectionMode();
return new ColumnSelectionState(table, allowed, mode, columns);
}
}
private class MyTableColumnModelListener implements TableColumnModelListener {
@Override
public void columnSelectionChanged(ListSelectionEvent e) {