feat(gui): ctrl+c copy highlighted word in code view (#1292)
This commit is contained in:
@@ -110,6 +110,7 @@ import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.JPackage;
|
||||
import jadx.gui.treemodel.JResource;
|
||||
import jadx.gui.treemodel.JRoot;
|
||||
import jadx.gui.ui.codearea.AbstractCodeArea;
|
||||
import jadx.gui.ui.codearea.AbstractCodeContentPanel;
|
||||
import jadx.gui.ui.codearea.EditorViewState;
|
||||
import jadx.gui.ui.dialog.ADBDialog;
|
||||
@@ -936,7 +937,11 @@ public class MainWindow extends JFrame {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ContentPanel panel = tabbedPane.getSelectedCodePanel();
|
||||
if (panel instanceof AbstractCodeContentPanel) {
|
||||
String preferText = ((AbstractCodeContentPanel) panel).getCodeArea().getSelectedText();
|
||||
AbstractCodeArea codeArea = ((AbstractCodeContentPanel) panel).getCodeArea();
|
||||
String preferText = codeArea.getSelectedText();
|
||||
if (StringUtils.isEmpty(preferText)) {
|
||||
preferText = codeArea.getWordUnderCaret();
|
||||
}
|
||||
if (!StringUtils.isEmpty(preferText)) {
|
||||
SearchDialog.searchText(MainWindow.this, preferText);
|
||||
return;
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
@@ -37,6 +39,7 @@ import jadx.gui.ui.panel.ContentPanel;
|
||||
import jadx.gui.utils.DefaultPopupMenuListener;
|
||||
import jadx.gui.utils.JumpPosition;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
private static final long serialVersionUID = -3980354865216031972L;
|
||||
@@ -57,9 +60,16 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
setCloseCurlyBraces(true);
|
||||
setAntiAliasingEnabled(true);
|
||||
loadSettings();
|
||||
|
||||
JadxSettings settings = contentPanel.getTabbedPane().getMainWindow().getSettings();
|
||||
setLineWrap(settings.isCodeAreaLineWrap());
|
||||
addWrapLineMenuAction(settings);
|
||||
|
||||
addCaretActions();
|
||||
addFastCopyAction();
|
||||
}
|
||||
|
||||
private void addWrapLineMenuAction(JadxSettings settings) {
|
||||
JPopupMenu popupMenu = getPopupMenu();
|
||||
popupMenu.addSeparator();
|
||||
JCheckBoxMenuItem wrapItem = new JCheckBoxMenuItem(NLS.str("popup.line_wrap"), getLineWrap());
|
||||
@@ -88,7 +98,16 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
wrapItem.setState(getLineWrap());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setCodeAreaLineWrap(AbstractCodeArea codeArea, boolean wrap) {
|
||||
codeArea.setLineWrap(wrap);
|
||||
if (codeArea.isVisible()) {
|
||||
codeArea.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void addCaretActions() {
|
||||
Caret caret = getCaret();
|
||||
if (caret instanceof DefaultCaret) {
|
||||
((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
|
||||
@@ -123,11 +142,20 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
});
|
||||
}
|
||||
|
||||
private void setCodeAreaLineWrap(AbstractCodeArea codeArea, boolean wrap) {
|
||||
codeArea.setLineWrap(wrap);
|
||||
if (codeArea.isVisible()) {
|
||||
codeArea.repaint();
|
||||
}
|
||||
/**
|
||||
* Ctrl+C will copy highlighted word
|
||||
*/
|
||||
private void addFastCopyAction() {
|
||||
addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_C && UiUtils.isCtrlDown(e)) {
|
||||
if (StringUtils.isEmpty(getSelectedText())) {
|
||||
UiUtils.copyToClipboard(getWordUnderCaret());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String highlightCaretWord(String lastText, int pos) {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package jadx.gui.ui.codearea;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.*;
|
||||
@@ -29,6 +26,7 @@ import jadx.gui.treemodel.JField;
|
||||
import jadx.gui.treemodel.JMethod;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
import static javax.swing.KeyStroke.getKeyStroke;
|
||||
|
||||
@@ -62,9 +60,7 @@ public final class FridaAction extends JNodeMenuAction<JNode> {
|
||||
try {
|
||||
String fridaSnippet = generateFridaSnippet();
|
||||
LOG.info("Frida snippet:\n{}", fridaSnippet);
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
StringSelection selection = new StringSelection(fridaSnippet);
|
||||
clipboard.setContents(selection, selection);
|
||||
UiUtils.copyToClipboard(fridaSnippet);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to generate Frida code snippet", e);
|
||||
JOptionPane.showMessageDialog(codeArea.getMainWindow(), e.getLocalizedMessage(), NLS.str("error_dialog.title"),
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package jadx.gui.ui.codearea;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
@@ -25,6 +22,7 @@ import jadx.gui.treemodel.JClass;
|
||||
import jadx.gui.treemodel.JMethod;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
import static javax.swing.KeyStroke.getKeyStroke;
|
||||
|
||||
@@ -55,9 +53,7 @@ public class XposedAction extends JNodeMenuAction<JNode> {
|
||||
try {
|
||||
String xposedSnippet = generateXposedSnippet();
|
||||
LOG.info("Xposed snippet:\n{}", xposedSnippet);
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
StringSelection selection = new StringSelection(xposedSnippet);
|
||||
clipboard.setContents(selection, selection);
|
||||
UiUtils.copyToClipboard(xposedSnippet);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to generate Xposed code snippet", e);
|
||||
JOptionPane.showMessageDialog(codeArea.getMainWindow(), e.getLocalizedMessage(), NLS.str("error_dialog.title"),
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.gui.ui.codearea.AbstractCodeArea;
|
||||
@@ -253,6 +254,10 @@ public class UiUtils {
|
||||
return CTRL_BNT_KEY;
|
||||
}
|
||||
|
||||
public static boolean isCtrlDown(KeyEvent keyEvent) {
|
||||
return keyEvent.getModifiersEx() == CTRL_BNT_KEY;
|
||||
}
|
||||
|
||||
public static <T extends Window & RootPaneContainer> void addEscapeShortCutToDispose(T window) {
|
||||
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
||||
window.getRootPane().registerKeyboardAction(e -> window.dispose(), stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
@@ -296,4 +301,17 @@ public class UiUtils {
|
||||
JOptionPane.showMessageDialog(parent, message,
|
||||
NLS.str("message.errorTitle"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public static void copyToClipboard(String text) {
|
||||
if (StringUtils.isEmpty(text)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
StringSelection selection = new StringSelection(text);
|
||||
clipboard.setContents(selection, selection);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed copy text to clipboard", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user