From 9ff21db4c73cf1fad541f5360bc31f8ab5389a3d Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Mon, 20 May 2024 17:20:50 -0400 Subject: [PATCH] GP-4605 - Allow Ctrl-a to select all in the Python window --- .../core/interpreter/InterpreterPanel.java | 200 ++++++++++-------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java index 7825d4483f..48b73d53f3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java @@ -195,101 +195,9 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener { } }); - outputTextPane.addKeyListener(new KeyListener() { - private void handleEvent(KeyEvent e) { + outputTextPane.addKeyListener(new OutputTextPaneKeyListener()); - // Ignore the copy event, as the output text pane knows how to copy its text - KeyStroke copyKeyStroke = - KeyStroke.getKeyStroke(KeyEvent.VK_C, DockingUtils.CONTROL_KEY_MODIFIER_MASK); - if (copyKeyStroke.equals(KeyStroke.getKeyStrokeForEvent(e))) { - return; - } - - // Send everything else down to the inputTextPane. - KeyBindingUtils.retargetEvent(inputTextPane, e); - } - - @Override - public void keyTyped(KeyEvent e) { - handleEvent(e); - } - - @Override - public void keyReleased(KeyEvent e) { - handleEvent(e); - } - - @Override - public void keyPressed(KeyEvent e) { - handleEvent(e); - } - }); - - inputTextPane.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - CodeCompletionWindow completionWindow = getCodeCompletionWindow(); - - switch (e.getKeyCode()) { - case KeyEvent.VK_ENTER: - if (completionWindow.isVisible()) { - /* As opposed to TAB, ENTER inserts the selected - * completion (if there is one selected) then - * *closes* the completionWindow - */ - insertCompletion(completionWindow.getCompletion()); - completionWindow.setVisible(false); - e.consume(); - } - else { - inputTextPane.setCaretPosition(inputTextPane.getDocument().getLength()); - } - break; - case KeyEvent.VK_UP: - if (completionWindow.isVisible()) { - /* scroll up in the completion window */ - completionWindow.selectPrevious(); - } - else { - String historyUp = history.getHistoryUp(); - if (historyUp != null) { - setInputTextPaneText(historyUp); - } - } - e.consume(); - break; - case KeyEvent.VK_DOWN: - if (completionWindow.isVisible()) { - /* scroll down in the completion window */ - completionWindow.selectNext(); - } - else { - String historyDown = history.getHistoryDown(); - if (historyDown != null) { - setInputTextPaneText(historyDown); - } - } - e.consume(); - break; - case KeyEvent.VK_ESCAPE: - completionWindow.setVisible(false); - e.consume(); - break; - default: - - // Check for the completion window trigger on input that contains text - if (completionWindowTrigger.isTrigger(e) && - !inputTextPane.getText().trim().isEmpty()) { - completionWindowTriggered(completionWindow); - e.consume(); - break; - } - - updateCompletionList(); - // and let the key go through to the text input field - } - } - }); + inputTextPane.addKeyListener(new InputTextPaneKeyListener()); outputTextPane.addCaretListener(e -> { Caret caret = inputTextPane.getCaret(); @@ -772,4 +680,108 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener { queuedBytes.offer(EMPTY_BYTES); } } + + private class OutputTextPaneKeyListener implements KeyListener { + + private final KeyStroke COPY_KEY_STROKE = + KeyStroke.getKeyStroke(KeyEvent.VK_C, DockingUtils.CONTROL_KEY_MODIFIER_MASK); + KeyStroke SELECT_ALL_KEY_STROKE = + KeyStroke.getKeyStroke(KeyEvent.VK_A, DockingUtils.CONTROL_KEY_MODIFIER_MASK); + + private void handleEvent(KeyEvent e) { + + // Ignore the events we wish for the output text pane to process + if (COPY_KEY_STROKE.equals(KeyStroke.getKeyStrokeForEvent(e))) { + return; + } + + if (SELECT_ALL_KEY_STROKE.equals(KeyStroke.getKeyStrokeForEvent(e))) { + return; + } + + // Send everything else down to the inputTextPane. + KeyBindingUtils.retargetEvent(inputTextPane, e); + } + + @Override + public void keyTyped(KeyEvent e) { + handleEvent(e); + } + + @Override + public void keyReleased(KeyEvent e) { + handleEvent(e); + } + + @Override + public void keyPressed(KeyEvent e) { + handleEvent(e); + } + } + + private class InputTextPaneKeyListener extends KeyAdapter { + @Override + public void keyPressed(KeyEvent e) { + CodeCompletionWindow completionWindow = getCodeCompletionWindow(); + + switch (e.getKeyCode()) { + case KeyEvent.VK_ENTER: + if (completionWindow.isVisible()) { + /* As opposed to TAB, ENTER inserts the selected + * completion (if there is one selected) then + * *closes* the completionWindow + */ + insertCompletion(completionWindow.getCompletion()); + completionWindow.setVisible(false); + e.consume(); + } + else { + inputTextPane.setCaretPosition(inputTextPane.getDocument().getLength()); + } + break; + case KeyEvent.VK_UP: + if (completionWindow.isVisible()) { + /* scroll up in the completion window */ + completionWindow.selectPrevious(); + } + else { + String historyUp = history.getHistoryUp(); + if (historyUp != null) { + setInputTextPaneText(historyUp); + } + } + e.consume(); + break; + case KeyEvent.VK_DOWN: + if (completionWindow.isVisible()) { + /* scroll down in the completion window */ + completionWindow.selectNext(); + } + else { + String historyDown = history.getHistoryDown(); + if (historyDown != null) { + setInputTextPaneText(historyDown); + } + } + e.consume(); + break; + case KeyEvent.VK_ESCAPE: + completionWindow.setVisible(false); + e.consume(); + break; + default: + + // Check for the completion window trigger on input that contains text + if (completionWindowTrigger.isTrigger(e) && + !inputTextPane.getText().trim().isEmpty()) { + completionWindowTriggered(completionWindow); + e.consume(); + break; + } + + updateCompletionList(); + // and let the key go through to the text input field + } + } + } }