diff options
| author | 2021-04-02 21:43:58 +0200 | |
|---|---|---|
| committer | 2021-04-02 21:43:58 +0200 | |
| commit | 9b5141471a42be0a105e27eb97ca8f972c958ca1 (patch) | |
| tree | 00f9fb2a5ffcceeb3df1b2ab3a95cb1b7c53fdce | |
| parent | Bump version (diff) | |
| download | enigma-9b5141471a42be0a105e27eb97ca8f972c958ca1.tar.gz enigma-9b5141471a42be0a105e27eb97ca8f972c958ca1.tar.xz enigma-9b5141471a42be0a105e27eb97ca8f972c958ca1.zip | |
Copy method/field descriptor on click
4 files changed, 46 insertions, 2 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java index 255fe81d..a4914678 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java | |||
| @@ -5,6 +5,8 @@ import java.awt.Container; | |||
| 5 | import java.awt.GridBagConstraints; | 5 | import java.awt.GridBagConstraints; |
| 6 | import java.awt.GridBagLayout; | 6 | import java.awt.GridBagLayout; |
| 7 | import java.awt.event.ItemEvent; | 7 | import java.awt.event.ItemEvent; |
| 8 | import java.awt.event.MouseAdapter; | ||
| 9 | import java.awt.event.MouseEvent; | ||
| 8 | import java.util.function.Consumer; | 10 | import java.util.function.Consumer; |
| 9 | 11 | ||
| 10 | import javax.swing.BorderFactory; | 12 | import javax.swing.BorderFactory; |
| @@ -97,7 +99,7 @@ public class IdentifierPanel { | |||
| 97 | FieldEntry fe = (FieldEntry) deobfEntry; | 99 | FieldEntry fe = (FieldEntry) deobfEntry; |
| 98 | this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.field"), fe.getName()); | 100 | this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.field"), fe.getName()); |
| 99 | th.addStringRow(I18n.translate("info_panel.identifier.class"), fe.getParent().getFullName()); | 101 | th.addStringRow(I18n.translate("info_panel.identifier.class"), fe.getParent().getFullName()); |
| 100 | th.addStringRow(I18n.translate("info_panel.identifier.type_descriptor"), fe.getDesc().toString()); | 102 | th.addCopiableStringRow(I18n.translate("info_panel.identifier.type_descriptor"), fe.getDesc().toString()); |
| 101 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); | 103 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); |
| 102 | } else if (deobfEntry instanceof MethodEntry) { | 104 | } else if (deobfEntry instanceof MethodEntry) { |
| 103 | MethodEntry me = (MethodEntry) deobfEntry; | 105 | MethodEntry me = (MethodEntry) deobfEntry; |
| @@ -107,7 +109,7 @@ public class IdentifierPanel { | |||
| 107 | this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.method"), me.getName()); | 109 | this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.method"), me.getName()); |
| 108 | th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName()); | 110 | th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName()); |
| 109 | } | 111 | } |
| 110 | th.addStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString()); | 112 | th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString()); |
| 111 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); | 113 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); |
| 112 | } else if (deobfEntry instanceof LocalVariableEntry) { | 114 | } else if (deobfEntry instanceof LocalVariableEntry) { |
| 113 | LocalVariableEntry lve = (LocalVariableEntry) deobfEntry; | 115 | LocalVariableEntry lve = (LocalVariableEntry) deobfEntry; |
| @@ -207,6 +209,19 @@ public class IdentifierPanel { | |||
| 207 | this.row += 1; | 209 | this.row += 1; |
| 208 | } | 210 | } |
| 209 | 211 | ||
| 212 | public void addCopiableRow(JLabel c1, JLabel c2) { | ||
| 213 | c2.addMouseListener(new MouseAdapter() { | ||
| 214 | @Override | ||
| 215 | public void mouseClicked(MouseEvent e) { | ||
| 216 | if (e.getButton() == MouseEvent.BUTTON1) { | ||
| 217 | GuiUtil.copyToClipboard(c2.getText()); | ||
| 218 | GuiUtil.showPopup(c2, I18n.translate("popup.copied"), e.getXOnScreen(), e.getYOnScreen()); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | }); | ||
| 222 | addRow(c1, c2); | ||
| 223 | } | ||
| 224 | |||
| 210 | public ConvertingTextField addConvertingTextField(String c1, String c2) { | 225 | public ConvertingTextField addConvertingTextField(String c1, String c2) { |
| 211 | ConvertingTextField textField = new ConvertingTextField(c2); | 226 | ConvertingTextField textField = new ConvertingTextField(c2); |
| 212 | addRow(new JLabel(c1), textField.getUi()); | 227 | addRow(new JLabel(c1), textField.getUi()); |
| @@ -226,6 +241,10 @@ public class IdentifierPanel { | |||
| 226 | addRow(new JLabel(c1), GuiUtil.unboldLabel(new JLabel(c2))); | 241 | addRow(new JLabel(c1), GuiUtil.unboldLabel(new JLabel(c2))); |
| 227 | } | 242 | } |
| 228 | 243 | ||
| 244 | public void addCopiableStringRow(String c1, String c2) { | ||
| 245 | addCopiableRow(new JLabel(c1), GuiUtil.unboldLabel(new JLabel(c2))); | ||
| 246 | } | ||
| 247 | |||
| 229 | public JComboBox<AccessModifier> addModifierRow(String c1, Consumer<AccessModifier> changeListener) { | 248 | public JComboBox<AccessModifier> addModifierRow(String c1, Consumer<AccessModifier> changeListener) { |
| 230 | if (!project.isRenamable(e)) | 249 | if (!project.isRenamable(e)) |
| 231 | return null; | 250 | return null; |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java index 7f08fc25..e26c29b3 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java | |||
| @@ -9,6 +9,7 @@ import cuchaz.enigma.utils.Os; | |||
| 9 | 9 | ||
| 10 | import javax.swing.*; | 10 | import javax.swing.*; |
| 11 | import java.awt.*; | 11 | import java.awt.*; |
| 12 | import java.awt.datatransfer.StringSelection; | ||
| 12 | import java.awt.event.MouseAdapter; | 13 | import java.awt.event.MouseAdapter; |
| 13 | import java.awt.event.MouseEvent; | 14 | import java.awt.event.MouseEvent; |
| 14 | import java.awt.font.TextAttribute; | 15 | import java.awt.font.TextAttribute; |
| @@ -53,6 +54,24 @@ public class GuiUtil { | |||
| 53 | return label; | 54 | return label; |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 57 | /** | ||
| 58 | * Puts the provided {@code text} in the system clipboard. | ||
| 59 | */ | ||
| 60 | public static void copyToClipboard(String text) { | ||
| 61 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); | ||
| 62 | } | ||
| 63 | |||
| 64 | public static void showPopup(JComponent component, String text, int x, int y) { | ||
| 65 | // from https://stackoverflow.com/questions/39955015/java-swing-show-tooltip-as-a-message-dialog | ||
| 66 | JToolTip tooltip = new JToolTip(); | ||
| 67 | tooltip.setTipText(text); | ||
| 68 | Popup p = PopupFactory.getSharedInstance().getPopup(component, tooltip, x + 10, y); | ||
| 69 | p.show(); | ||
| 70 | Timer t = new Timer(1000, e -> p.hide()); | ||
| 71 | t.setRepeats(false); | ||
| 72 | t.start(); | ||
| 73 | } | ||
| 74 | |||
| 56 | public static void showToolTipNow(JComponent component) { | 75 | public static void showToolTipNow(JComponent component) { |
| 57 | // HACKHACK: trick the tooltip manager into showing the tooltip right now | 76 | // HACKHACK: trick the tooltip manager into showing the tooltip right now |
| 58 | ToolTipManager manager = ToolTipManager.sharedInstance(); | 77 | ToolTipManager manager = ToolTipManager.sharedInstance(); |
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index fd21faac..903faa76 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json | |||
| @@ -108,6 +108,8 @@ | |||
| 108 | "info_panel.tree.implementations": "Implementations", | 108 | "info_panel.tree.implementations": "Implementations", |
| 109 | "info_panel.tree.calls": "Call Graph", | 109 | "info_panel.tree.calls": "Call Graph", |
| 110 | 110 | ||
| 111 | "popup.copied": "Copied!", | ||
| 112 | |||
| 111 | "log_panel.messages": "Messages", | 113 | "log_panel.messages": "Messages", |
| 112 | "log_panel.users": "Users", | 114 | "log_panel.users": "Users", |
| 113 | 115 | ||
diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json index 43bea4de..42edd6bb 100644 --- a/enigma/src/main/resources/lang/fr_fr.json +++ b/enigma/src/main/resources/lang/fr_fr.json | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | "menu.view.themes": "Thèmes", | 36 | "menu.view.themes": "Thèmes", |
| 37 | "menu.view.themes.default": "Par défaut", | 37 | "menu.view.themes.default": "Par défaut", |
| 38 | "menu.view.themes.darcula": "Darcula", | 38 | "menu.view.themes.darcula": "Darcula", |
| 39 | "menu.view.themes.metal": "Métal", | ||
| 39 | "menu.view.themes.system": "Système", | 40 | "menu.view.themes.system": "Système", |
| 40 | "menu.view.themes.none": "Aucun (JVM par défaut)", | 41 | "menu.view.themes.none": "Aucun (JVM par défaut)", |
| 41 | "menu.view.languages": "Langues", | 42 | "menu.view.languages": "Langues", |
| @@ -107,6 +108,8 @@ | |||
| 107 | "info_panel.tree.implementations": "Implémentations", | 108 | "info_panel.tree.implementations": "Implémentations", |
| 108 | "info_panel.tree.calls": "Graphique des appels", | 109 | "info_panel.tree.calls": "Graphique des appels", |
| 109 | 110 | ||
| 111 | "popup.copied": "Copié !", | ||
| 112 | |||
| 110 | "log_panel.messages": "Messages", | 113 | "log_panel.messages": "Messages", |
| 111 | "log_panel.users": "Utilisateurs", | 114 | "log_panel.users": "Utilisateurs", |
| 112 | 115 | ||
| @@ -191,6 +194,7 @@ | |||
| 191 | "validation.message.illegal_identifier.long": "Caractère '%2$s' invalide à la position %3$d.", | 194 | "validation.message.illegal_identifier.long": "Caractère '%2$s' invalide à la position %3$d.", |
| 192 | "validation.message.illegal_doc_comment_end": "Un commentaire de Javadoc ne peut pas contenir la séquence de caractères '*/'.", | 195 | "validation.message.illegal_doc_comment_end": "Un commentaire de Javadoc ne peut pas contenir la séquence de caractères '*/'.", |
| 193 | "validation.message.reserved_identifier": "'%s' est un identifiant réservé.", | 196 | "validation.message.reserved_identifier": "'%s' est un identifiant réservé.", |
| 197 | "validation.message.unknown_record_getter": "Impossible de trouver un accesseur de composant de record correspondant pour %s", | ||
| 194 | 198 | ||
| 195 | "crash.title": "%s - Rapport de plantage", | 199 | "crash.title": "%s - Rapport de plantage", |
| 196 | "crash.summary": "%s a planté ! =(", | 200 | "crash.summary": "%s a planté ! =(", |