mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 03:08:27 +08:00
Merge remote-tracking branch
'origin/GP-3173-dragonmacher-function-editor-focus-issue' (Closes #3561)
This commit is contained in:
+10
-8
@@ -26,6 +26,7 @@ import javax.swing.table.TableCellEditor;
|
|||||||
|
|
||||||
import docking.widgets.DropDownSelectionTextField;
|
import docking.widgets.DropDownSelectionTextField;
|
||||||
import docking.widgets.table.CellEditorUtils;
|
import docking.widgets.table.CellEditorUtils;
|
||||||
|
import docking.widgets.table.FocusableEditor;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
@@ -34,13 +35,14 @@ import ghidra.util.Swing;
|
|||||||
import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
||||||
|
|
||||||
public class DataTypeTableCellEditor extends AbstractCellEditor
|
public class DataTypeTableCellEditor extends AbstractCellEditor
|
||||||
implements TableCellEditor {
|
implements TableCellEditor, FocusableEditor {
|
||||||
private final PluginTool tool;
|
private final PluginTool tool;
|
||||||
private DataTypeManagerService service;
|
private DataTypeManagerService service;
|
||||||
private JTable table;
|
private JTable table;
|
||||||
|
|
||||||
private JPanel editorPanel;
|
private JPanel editorPanel;
|
||||||
private DataTypeSelectionEditor editor;
|
private DataTypeSelectionEditor editor;
|
||||||
|
private DropDownSelectionTextField<DataType> textField;
|
||||||
|
|
||||||
private DataType dt;
|
private DataType dt;
|
||||||
|
|
||||||
@@ -119,6 +121,11 @@ public class DataTypeTableCellEditor extends AbstractCellEditor
|
|||||||
return editorPanel;
|
return editorPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusEditor() {
|
||||||
|
textField.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
protected void init(int row, int column) {
|
protected void init(int row, int column) {
|
||||||
updateService();
|
updateService();
|
||||||
editor = new DataTypeSelectionEditor(service, getAllowed(row, column));
|
editor = new DataTypeSelectionEditor(service, getAllowed(row, column));
|
||||||
@@ -126,17 +133,12 @@ public class DataTypeTableCellEditor extends AbstractCellEditor
|
|||||||
editor.setTabCommitsEdit(true);
|
editor.setTabCommitsEdit(true);
|
||||||
editor.setConsumeEnterKeyPress(false);
|
editor.setConsumeEnterKeyPress(false);
|
||||||
|
|
||||||
final DropDownSelectionTextField<DataType> textField = editor.getDropDownTextField();
|
textField = editor.getDropDownTextField();
|
||||||
textField.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
|
textField.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
|
||||||
CellEditorUtils.onOneFocus(textField, () -> textField.selectAll());
|
CellEditorUtils.onOneFocus(textField, () -> textField.selectAll());
|
||||||
|
|
||||||
editor.addCellEditorListener(cellEditorListener);
|
editor.addCellEditorListener(cellEditorListener);
|
||||||
editorPanel = new JPanel(new BorderLayout()) {
|
editorPanel = new JPanel(new BorderLayout());
|
||||||
@Override
|
|
||||||
public void requestFocus() {
|
|
||||||
textField.requestFocus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
editorPanel.add(textField, BorderLayout.CENTER);
|
editorPanel.add(textField, BorderLayout.CENTER);
|
||||||
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-8
@@ -1235,9 +1235,10 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ComponentDataTypeCellEditor extends AbstractCellEditor
|
private class ComponentDataTypeCellEditor extends AbstractCellEditor
|
||||||
implements TableCellEditor {
|
implements TableCellEditor, FocusableEditor {
|
||||||
|
|
||||||
private DataTypeSelectionEditor editor;
|
private DataTypeSelectionEditor editor;
|
||||||
|
private DropDownSelectionTextField<DataType> textField;
|
||||||
private DataType dt;
|
private DataType dt;
|
||||||
private int maxLength;
|
private int maxLength;
|
||||||
private boolean bitfieldAllowed;
|
private boolean bitfieldAllowed;
|
||||||
@@ -1277,7 +1278,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||||||
editor.setPreferredDataTypeManager(originalDataTypeManager);
|
editor.setPreferredDataTypeManager(originalDataTypeManager);
|
||||||
editor.setConsumeEnterKeyPress(false); // we want the table to handle Enter key presses
|
editor.setConsumeEnterKeyPress(false); // we want the table to handle Enter key presses
|
||||||
|
|
||||||
final DropDownSelectionTextField<DataType> textField = editor.getDropDownTextField();
|
textField = editor.getDropDownTextField();
|
||||||
textField.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
|
textField.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
|
||||||
editor.addCellEditorListener(new CellEditorListener() {
|
editor.addCellEditorListener(new CellEditorListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -1311,12 +1312,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
editorPanel = new JPanel() {
|
editorPanel = new JPanel();
|
||||||
@Override
|
|
||||||
public void requestFocus() {
|
|
||||||
textField.requestFocus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
editorPanel.setLayout(new BorderLayout());
|
editorPanel.setLayout(new BorderLayout());
|
||||||
editorPanel.add(textField, BorderLayout.CENTER);
|
editorPanel.add(textField, BorderLayout.CENTER);
|
||||||
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
||||||
@@ -1334,6 +1330,11 @@ public abstract class CompositeEditorPanel extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusEditor() {
|
||||||
|
textField.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getCellEditorValue() {
|
public Object getCellEditorValue() {
|
||||||
return dt;
|
return dt;
|
||||||
|
|||||||
+8
-1
@@ -26,13 +26,15 @@ import javax.swing.table.TableCellEditor;
|
|||||||
|
|
||||||
import docking.DialogComponentProvider;
|
import docking.DialogComponentProvider;
|
||||||
import docking.widgets.DropDownSelectionTextField;
|
import docking.widgets.DropDownSelectionTextField;
|
||||||
|
import docking.widgets.table.FocusableEditor;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.util.MessageType;
|
import ghidra.util.MessageType;
|
||||||
import ghidra.util.data.DataTypeParser;
|
import ghidra.util.data.DataTypeParser;
|
||||||
|
|
||||||
class ParameterDataTypeCellEditor extends AbstractCellEditor implements TableCellEditor {
|
class ParameterDataTypeCellEditor extends AbstractCellEditor
|
||||||
|
implements TableCellEditor, FocusableEditor {
|
||||||
private DataTypeSelectionEditor editor;
|
private DataTypeSelectionEditor editor;
|
||||||
private DropDownSelectionTextField<DataType> textField;
|
private DropDownSelectionTextField<DataType> textField;
|
||||||
private JButton dataTypeChooserButton;
|
private JButton dataTypeChooserButton;
|
||||||
@@ -113,6 +115,11 @@ class ParameterDataTypeCellEditor extends AbstractCellEditor implements TableCel
|
|||||||
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
editorPanel.add(dataTypeChooserButton, BorderLayout.EAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusEditor() {
|
||||||
|
textField.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return text field associated with the generated component. Null will
|
* @return text field associated with the generated component. Null will
|
||||||
* be returned if getTableCellEditorComponent method has not yet been invoked.
|
* be returned if getTableCellEditorComponent method has not yet been invoked.
|
||||||
|
|||||||
+16
-3
@@ -16,7 +16,7 @@
|
|||||||
package ghidra.app.plugin.core.function.editor;
|
package ghidra.app.plugin.core.function.editor;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.event.*;
|
import java.awt.event.MouseEvent;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ import javax.swing.event.PopupMenuListener;
|
|||||||
import javax.swing.table.TableCellEditor;
|
import javax.swing.table.TableCellEditor;
|
||||||
|
|
||||||
import docking.widgets.combobox.GhidraComboBox;
|
import docking.widgets.combobox.GhidraComboBox;
|
||||||
|
import docking.widgets.table.FocusableEditor;
|
||||||
import docking.widgets.textfield.IntegerTextField;
|
import docking.widgets.textfield.IntegerTextField;
|
||||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||||
import ghidra.app.util.AddressInput;
|
import ghidra.app.util.AddressInput;
|
||||||
@@ -36,7 +37,8 @@ import ghidra.program.model.listing.Program;
|
|||||||
import ghidra.program.model.listing.ProgramContext;
|
import ghidra.program.model.listing.ProgramContext;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
class VarnodeLocationCellEditor extends AbstractCellEditor implements TableCellEditor {
|
class VarnodeLocationCellEditor extends AbstractCellEditor
|
||||||
|
implements TableCellEditor, FocusableEditor {
|
||||||
private Program program;
|
private Program program;
|
||||||
private VarnodeType type;
|
private VarnodeType type;
|
||||||
private Component editorComponent;
|
private Component editorComponent;
|
||||||
@@ -44,7 +46,8 @@ class VarnodeLocationCellEditor extends AbstractCellEditor implements TableCellE
|
|||||||
private AddressInput addressInput;
|
private AddressInput addressInput;
|
||||||
private IntegerTextField offsetInput;
|
private IntegerTextField offsetInput;
|
||||||
|
|
||||||
private Comparator<Register> registerWrapperComparator = (r1, r2) -> r1.toString().compareToIgnoreCase(r2.toString());
|
private Comparator<Register> registerWrapperComparator =
|
||||||
|
(r1, r2) -> r1.toString().compareToIgnoreCase(r2.toString());
|
||||||
private VarnodeInfo currentVarnode;
|
private VarnodeInfo currentVarnode;
|
||||||
private int maxRegisterSize;
|
private int maxRegisterSize;
|
||||||
|
|
||||||
@@ -134,6 +137,16 @@ class VarnodeLocationCellEditor extends AbstractCellEditor implements TableCellE
|
|||||||
return editorComponent;
|
return editorComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusEditor() {
|
||||||
|
if (editorComponent instanceof AddressInput input) {
|
||||||
|
input.focusEditor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editorComponent.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Component createAddressEditor(VarnodeInfo varnode) {
|
private Component createAddressEditor(VarnodeInfo varnode) {
|
||||||
addressInput = new AddressInput(BorderFactory.createEmptyBorder());
|
addressInput = new AddressInput(BorderFactory.createEmptyBorder());
|
||||||
addressInput.setAddressFactory(program.getAddressFactory());
|
addressInput.setAddressFactory(program.getAddressFactory());
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ package ghidra.app.util;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -27,13 +26,14 @@ import javax.swing.border.Border;
|
|||||||
import javax.swing.event.*;
|
import javax.swing.event.*;
|
||||||
|
|
||||||
import docking.widgets.combobox.GComboBox;
|
import docking.widgets.combobox.GComboBox;
|
||||||
|
import docking.widgets.table.FocusableEditor;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel for user input of addresses. Handles case with multiple address
|
* Panel for user input of addresses. Handles case with multiple address
|
||||||
* spaces.
|
* spaces.
|
||||||
*/
|
*/
|
||||||
public class AddressInput extends JPanel {
|
public class AddressInput extends JPanel implements FocusableEditor {
|
||||||
private JTextField textField;
|
private JTextField textField;
|
||||||
private JComboBox<AddressSpace> combo;
|
private JComboBox<AddressSpace> combo;
|
||||||
private boolean comboAdded;
|
private boolean comboAdded;
|
||||||
@@ -45,19 +45,16 @@ public class AddressInput extends JPanel {
|
|||||||
private JTextField spaceField;
|
private JTextField spaceField;
|
||||||
|
|
||||||
private static final Comparator<AddressSpace> ADDRESS_SPACE_SORT_COMPARATOR =
|
private static final Comparator<AddressSpace> ADDRESS_SPACE_SORT_COMPARATOR =
|
||||||
new Comparator<>() {
|
(s1, s2) -> {
|
||||||
@Override
|
if (s1.isOverlaySpace()) {
|
||||||
public int compare(AddressSpace s1, AddressSpace s2) {
|
if (!s2.isOverlaySpace()) {
|
||||||
if (s1.isOverlaySpace()) {
|
return 1;
|
||||||
if (!s2.isOverlaySpace()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (s2.isOverlaySpace()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return s1.getName().compareTo(s2.getName());
|
|
||||||
}
|
}
|
||||||
|
else if (s2.isOverlaySpace()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return s1.getName().compareTo(s2.getName());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,12 +98,7 @@ public class AddressInput extends JPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
combo.addActionListener(new ActionListener() {
|
combo.addActionListener(ev -> stateChanged());
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent ev) {
|
|
||||||
stateChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -353,6 +345,16 @@ public class AddressInput extends JPanel {
|
|||||||
return textField.isEditable();
|
return textField.isEditable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusEditor() {
|
||||||
|
if (comboAdded) {
|
||||||
|
combo.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
textField.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void stateChanged() {
|
private void stateChanged() {
|
||||||
if (changeListener != null && !updatingAddress && !stateChanging) {
|
if (changeListener != null && !updatingAddress && !stateChanging) {
|
||||||
stateChanging = true;
|
stateChanging = true;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/* ###
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that the implementing cell editor desires to be notified when editing begins so that the
|
||||||
|
* editor can request focus on the right widget.
|
||||||
|
*/
|
||||||
|
public interface FocusableEditor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called with the editor should take focus.
|
||||||
|
*/
|
||||||
|
public void focusEditor();
|
||||||
|
}
|
||||||
@@ -940,9 +940,16 @@ public class GTable extends JTable {
|
|||||||
public boolean editCellAt(int row, int column, EventObject e) {
|
public boolean editCellAt(int row, int column, EventObject e) {
|
||||||
boolean editAtCell = super.editCellAt(row, column, e);
|
boolean editAtCell = super.editCellAt(row, column, e);
|
||||||
if (editAtCell) {
|
if (editAtCell) {
|
||||||
Component editor = getEditorComponent();
|
TableCellEditor currentEditor = getCellEditor();
|
||||||
editor.requestFocusInWindow();
|
Component editorComponent = getEditorComponent();
|
||||||
if (editor instanceof JTextComponent textComponent) {
|
if (currentEditor instanceof FocusableEditor focusable) {
|
||||||
|
focusable.focusEditor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editorComponent.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editorComponent instanceof JTextComponent textComponent) {
|
||||||
textComponent.selectAll();
|
textComponent.selectAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user