diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerOptionsDialog.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerOptionsDialog.java index 3a53335d29..71fd8a2006 100644 --- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerOptionsDialog.java +++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerOptionsDialog.java @@ -87,6 +87,7 @@ public class ByteViewerOptionsDialog extends DialogComponentProvider addressInputField.setAddress(getAlignmentAddress()); panel.add(addressInputField); addressInputField.addChangeListener(this); + addressInputField.setAccessibleName("Alignment Address"); } } @@ -97,6 +98,7 @@ public class ByteViewerOptionsDialog extends DialogComponentProvider bytesPerLineField.setValue(BigInteger.valueOf(provider.getBytesPerLine())); panel.add(bytesPerLineField); bytesPerLineField.addChangeListener(this); + bytesPerLineField.getAccessibleContext().setAccessibleName("Bytes Per Line"); panel.add(new GLabel("Group size (Hex View Only):")); groupSizeField = new FixedBitSizeValueField(8, false, true); @@ -105,6 +107,7 @@ public class ByteViewerOptionsDialog extends DialogComponentProvider groupSizeField.setValue(BigInteger.valueOf(provider.getGroupSize())); panel.add(groupSizeField); groupSizeField.addChangeListener(this); + groupSizeField.getAccessibleContext().setAccessibleName("Group Size"); return panel; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/ListPanel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/ListPanel.java index 9f1b29df30..39abfff466 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/ListPanel.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/ListPanel.java @@ -33,6 +33,7 @@ public class ListPanel extends JPanel { private ListSelectionListener listSelectionListener; private ActionListener doubleClickActionListener; private MouseListener mouseListener; + private KeyListener keyListener; private JScrollPane scrollpane; private JList list; @@ -258,6 +259,14 @@ public class ListPanel extends JPanel { mouseListener = l; } + public void setKeyListener(KeyListener l) { + if (keyListener != null) { + list.removeKeyListener(keyListener); + } + list.addKeyListener(l); + keyListener = l; + } + /** * Displays a standard warning message about no selected objects * in the list. diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java index 29952b28f1..f3c6152651 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java @@ -16,8 +16,7 @@ package ghidra.framework.main; import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.*; import java.util.ArrayList; import java.util.List; @@ -159,6 +158,7 @@ public class SaveDataDialog extends DialogComponentProvider { listPanel = new ListPanel<>(); listPanel.setCellRenderer(new DataCellRenderer()); listPanel.setMouseListener(new ListMouseListener()); + listPanel.setKeyListener(new ListKeyListener()); parentPanel.add(myButtonPanel, BorderLayout.EAST); parentPanel.add(listPanel, BorderLayout.CENTER); @@ -255,11 +255,15 @@ public class SaveDataDialog extends DialogComponentProvider { boldFont = font.deriveFont(font.getStyle() | Font.BOLD); } + Color fg = isSelected ? list.getSelectionForeground() : list.getForeground(); + Color bg = isSelected ? list.getSelectionBackground() : list.getBackground(); // set color to red if file cannot be saved 'as is' if (!saveable[index]) { - checkboxes[index].setForeground(Colors.ERROR); + fg = Colors.ERROR; checkboxes[index].setFont(boldFont); } + checkboxes[index].setForeground(fg); + checkboxes[index].setBackground(bg); return checkboxes[index]; } } @@ -290,6 +294,23 @@ public class SaveDataDialog extends DialogComponentProvider { } } + private class ListKeyListener extends KeyAdapter { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + e.consume(); + JList list = (JList) e.getSource(); + int index = list.getSelectedIndex(); + if (index < 0) { + return; + } + boolean selected = checkboxes[index].isSelected(); + checkboxes[index].setSelected(!selected); + listPanel.repaint(); + } + } + } + private class SaveTask extends Task { private DomainFile[] domainFiles; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DomainFilesPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DomainFilesPanel.java index bfbd46ead4..763d68de17 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DomainFilesPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DomainFilesPanel.java @@ -16,8 +16,7 @@ package ghidra.framework.main.datatree; import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.*; import java.util.ArrayList; import java.util.List; @@ -63,6 +62,7 @@ class DomainFilesPanel extends JPanel { listPanel = new ListPanel<>(); listPanel.setCellRenderer(new DataCellRenderer()); listPanel.setMouseListener(new ListMouseListener()); + listPanel.setKeyListener(new ListKeyListener()); if (listTitle != null) { listPanel.setListTitle(listTitle); } @@ -107,6 +107,10 @@ class DomainFilesPanel extends JPanel { } index = selected; } + Color fg = isSelected ? list.getSelectionForeground() : list.getForeground(); + Color bg = isSelected ? list.getSelectionBackground() : list.getBackground(); + checkboxes[index].setForeground(fg); + checkboxes[index].setBackground(bg); return checkboxes[index]; } } @@ -137,4 +141,20 @@ class DomainFilesPanel extends JPanel { } } + private class ListKeyListener extends KeyAdapter { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + e.consume(); + JList list = (JList) e.getSource(); + int index = list.getSelectedIndex(); + if (index < 0) { + return; + } + boolean selected = checkboxes[index].isSelected(); + checkboxes[index].setSelected(!selected); + listPanel.repaint(); + } + } + } }