summaryrefslogtreecommitdiff
path: root/enigma-swing/src/main
diff options
context:
space:
mode:
authorGravatar Marco Rebhan2021-06-20 11:48:37 +0200
committerGravatar Marco Rebhan2021-06-21 10:37:21 +0200
commit045a44a9ae2a70087e0d960a7196d1564c4c7ab1 (patch)
treeabddbd4e8999a0ed9d73a8ab53d1e9e8b715b197 /enigma-swing/src/main
parentBump version (diff)
downloadenigma-045a44a9ae2a70087e0d960a7196d1564c4c7ab1.tar.gz
enigma-045a44a9ae2a70087e0d960a7196d1564c4c7ab1.tar.xz
enigma-045a44a9ae2a70087e0d960a7196d1564c4c7ab1.zip
Allow disabling editing part of the mappings
For now, this is done over CLI options, it cannot be changed through the GUI. The new CLI options are: -C, --no-edit-classes Disable editing class names -D, --no-edit-javadocs Disable editing Javadocs -E, --no-edit-all Disable editing everything -F, --no-edit-fields Disable editing field names -M, --no-edit-methods Disable editing method names -P, --no-edit-parameters Disable editing parameter names -c, --edit-classes Enable editing class names -d, --edit-javadocs Enable editing Javadocs -e, --edit-all Enable editing everything --edit-locals Enable editing local variable names -f, --edit-fields Enable editing field names -m, --edit-methods Enable editing method names --no-edit-locals Disable editing local variable names -p, --edit-parameters Enable editing parameter names They can be combined together and are applied in order of appearance in the argument list from left to right, and everything is editable by default, as before. For example, --no-edit-all --edit-javadocs --edit-parameters (or -Edp for short) will allow you to edit only Javadocs and parameter names. --(no-)edit-locals is only provided for completeness and has no effect right now because Enigma does not allow for editing locals other than parameters.
Diffstat (limited to 'enigma-swing/src/main')
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java10
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java11
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java49
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java33
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java39
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java81
6 files changed, 176 insertions, 47 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java
new file mode 100644
index 00000000..3dfa35ce
--- /dev/null
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java
@@ -0,0 +1,10 @@
1package cuchaz.enigma.gui;
2
3public enum EditableType {
4 CLASS,
5 METHOD,
6 FIELD,
7 PARAMETER,
8 LOCAL_VARIABLE,
9 JAVADOC,
10}
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
index 52bd93ee..c46bda2e 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -73,6 +73,7 @@ public class Gui implements LanguageChangeListener {
73 public History<EntryReference<Entry<?>, Entry<?>>> referenceHistory; 73 public History<EntryReference<Entry<?>, Entry<?>>> referenceHistory;
74 private ConnectionState connectionState; 74 private ConnectionState connectionState;
75 private boolean isJarOpen; 75 private boolean isJarOpen;
76 private final Set<EditableType> editableTypes;
76 77
77 public JFileChooser jarFileChooser; 78 public JFileChooser jarFileChooser;
78 public JFileChooser tinyMappingsFileChooser; 79 public JFileChooser tinyMappingsFileChooser;
@@ -112,7 +113,9 @@ public class Gui implements LanguageChangeListener {
112 private final JTabbedPane openFiles; 113 private final JTabbedPane openFiles;
113 private final HashBiMap<ClassEntry, EditorPanel> editors = HashBiMap.create(); 114 private final HashBiMap<ClassEntry, EditorPanel> editors = HashBiMap.create();
114 115
115 public Gui(EnigmaProfile profile) { 116 public Gui(EnigmaProfile profile, Set<EditableType> editableTypes) {
117 this.editableTypes = editableTypes;
118
116 // init frame 119 // init frame
117 this.frame = new JFrame(Enigma.NAME); 120 this.frame = new JFrame(Enigma.NAME);
118 final Container pane = this.frame.getContentPane(); 121 final Container pane = this.frame.getContentPane();
@@ -596,7 +599,7 @@ public class Gui implements LanguageChangeListener {
596 599
597 public void startDocChange(EditorPanel editor) { 600 public void startDocChange(EditorPanel editor) {
598 EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); 601 EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference();
599 if (cursorReference == null) return; 602 if (cursorReference == null || !this.isEditable(EditableType.JAVADOC)) return;
600 JavadocDialog.show(frame, getController(), cursorReference); 603 JavadocDialog.show(frame, getController(), cursorReference);
601 } 604 }
602 605
@@ -987,4 +990,8 @@ public class Gui implements LanguageChangeListener {
987 return vc.canProceed(); 990 return vc.canProceed();
988 } 991 }
989 992
993 public boolean isEditable(EditableType t) {
994 return this.editableTypes.contains(t);
995 }
996
990} 997}
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
index b655bd4e..cd968fce 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
@@ -15,6 +15,9 @@ import java.io.IOException;
15import java.nio.file.Files; 15import java.nio.file.Files;
16import java.nio.file.Path; 16import java.nio.file.Path;
17import java.nio.file.Paths; 17import java.nio.file.Paths;
18import java.util.EnumSet;
19import java.util.List;
20import java.util.Set;
18 21
19import com.google.common.io.MoreFiles; 22import com.google.common.io.MoreFiles;
20import joptsimple.*; 23import joptsimple.*;
@@ -42,6 +45,21 @@ public class Main {
42 .withRequiredArg() 45 .withRequiredArg()
43 .withValuesConvertedBy(PathConverter.INSTANCE); 46 .withValuesConvertedBy(PathConverter.INSTANCE);
44 47
48 parser.acceptsAll(List.of("edit-all", "e"), "Enable editing everything");
49 parser.acceptsAll(List.of("no-edit-all", "E"), "Disable editing everything");
50 parser.acceptsAll(List.of("edit-classes", "c"), "Enable editing class names");
51 parser.acceptsAll(List.of("no-edit-classes", "C"), "Disable editing class names");
52 parser.acceptsAll(List.of("edit-methods", "m"), "Enable editing method names");
53 parser.acceptsAll(List.of("no-edit-methods", "M"), "Disable editing method names");
54 parser.acceptsAll(List.of("edit-fields", "f"), "Enable editing field names");
55 parser.acceptsAll(List.of("no-edit-fields", "F"), "Disable editing field names");
56 parser.acceptsAll(List.of("edit-parameters", "p"), "Enable editing parameter names");
57 parser.acceptsAll(List.of("no-edit-parameters", "P"), "Disable editing parameter names");
58 parser.acceptsAll(List.of("edit-locals"), "Enable editing local variable names");
59 parser.acceptsAll(List.of("no-edit-locals"), "Disable editing local variable names");
60 parser.acceptsAll(List.of("edit-javadocs", "d"), "Enable editing Javadocs");
61 parser.acceptsAll(List.of("no-edit-javadocs", "D"), "Disable editing Javadocs");
62
45 parser.accepts("help", "Displays help information"); 63 parser.accepts("help", "Displays help information");
46 64
47 try { 65 try {
@@ -52,13 +70,42 @@ public class Main {
52 return; 70 return;
53 } 71 }
54 72
73 Set<EditableType> editables = EnumSet.allOf(EditableType.class);
74
75 for (OptionSpec<?> spec : options.specs()) {
76 for (String s : spec.options()) {
77 switch (s) {
78 case "edit-all" -> editables.addAll(List.of(EditableType.values()));
79 case "no-edit-all" -> editables.clear();
80 case "edit-classes" -> editables.add(EditableType.CLASS);
81 case "no-edit-classes" -> editables.remove(EditableType.CLASS);
82 case "edit-methods" -> editables.add(EditableType.METHOD);
83 case "no-edit-methods" -> editables.remove(EditableType.METHOD);
84 case "edit-fields" -> editables.add(EditableType.FIELD);
85 case "no-edit-fields" -> editables.remove(EditableType.FIELD);
86 case "edit-parameters" -> editables.add(EditableType.PARAMETER);
87 case "no-edit-parameters" -> editables.remove(EditableType.PARAMETER);
88 case "edit-locals" -> {
89 editables.add(EditableType.LOCAL_VARIABLE);
90 System.err.println("warning: --edit-locals has no effect as local variables are currently not editable");
91 }
92 case "no-edit-locals" -> {
93 editables.remove(EditableType.LOCAL_VARIABLE);
94 System.err.println("warning: --no-edit-locals has no effect as local variables are currently not editable");
95 }
96 case "edit-javadocs" -> editables.add(EditableType.JAVADOC);
97 case "no-edit-javadocs" -> editables.remove(EditableType.JAVADOC);
98 }
99 }
100 }
101
55 EnigmaProfile parsedProfile = EnigmaProfile.read(options.valueOf(profile)); 102 EnigmaProfile parsedProfile = EnigmaProfile.read(options.valueOf(profile));
56 103
57 I18n.setLanguage(UiConfig.getLanguage()); 104 I18n.setLanguage(UiConfig.getLanguage());
58 System.setProperty("apple.laf.useScreenMenuBar", "true"); 105 System.setProperty("apple.laf.useScreenMenuBar", "true");
59 Themes.setupTheme(); 106 Themes.setupTheme();
60 107
61 Gui gui = new Gui(parsedProfile); 108 Gui gui = new Gui(parsedProfile, editables);
62 GuiController controller = gui.getController(); 109 GuiController controller = gui.getController();
63 110
64 if (options.has(jar)) { 111 if (options.has(jar)) {
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java
index 7eb1edba..9a6ea098 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java
@@ -25,7 +25,8 @@ public class ConvertingTextField implements Validatable {
25 private final JPanel ui; 25 private final JPanel ui;
26 private final ValidatableTextField textField; 26 private final ValidatableTextField textField;
27 private final JLabel label; 27 private final JLabel label;
28 private boolean isEditing = false; 28 private boolean editing = false;
29 private boolean editable = true;
29 30
30 private final Set<ConvertingTextFieldListener> listeners = new HashSet<>(); 31 private final Set<ConvertingTextFieldListener> listeners = new HashSet<>();
31 32
@@ -68,10 +69,11 @@ public class ConvertingTextField implements Validatable {
68 } 69 }
69 70
70 public void startEditing() { 71 public void startEditing() {
71 if (isEditing) return; 72 if (this.editing || !this.editable) return;
73
72 this.ui.removeAll(); 74 this.ui.removeAll();
73 this.ui.add(this.textField); 75 this.ui.add(this.textField);
74 this.isEditing = true; 76 this.editing = true;
75 this.ui.validate(); 77 this.ui.validate();
76 this.ui.repaint(); 78 this.ui.repaint();
77 this.textField.requestFocusInWindow(); 79 this.textField.requestFocusInWindow();
@@ -80,7 +82,7 @@ public class ConvertingTextField implements Validatable {
80 } 82 }
81 83
82 public void stopEditing(boolean abort) { 84 public void stopEditing(boolean abort) {
83 if (!isEditing) return; 85 if (!editing) return;
84 86
85 if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, abort))) return; 87 if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, abort))) return;
86 88
@@ -92,7 +94,7 @@ public class ConvertingTextField implements Validatable {
92 94
93 this.ui.removeAll(); 95 this.ui.removeAll();
94 this.ui.add(this.label); 96 this.ui.add(this.label);
95 this.isEditing = false; 97 this.editing = false;
96 this.ui.validate(); 98 this.ui.validate();
97 this.ui.repaint(); 99 this.ui.repaint();
98 this.listeners.forEach(l -> l.onStopEditing(this, abort)); 100 this.listeners.forEach(l -> l.onStopEditing(this, abort));
@@ -105,19 +107,28 @@ public class ConvertingTextField implements Validatable {
105 } 107 }
106 108
107 public void setEditText(String text) { 109 public void setEditText(String text) {
108 if (!isEditing) return; 110 if (!editing) return;
109 111
110 this.textField.setText(text); 112 this.textField.setText(text);
111 } 113 }
112 114
115 public void setEditable(boolean editable) {
116 if (!editable) {
117 this.stopEditing(true);
118 }
119
120 this.label.setEnabled(editable);
121 this.editable = editable;
122 }
123
113 public void selectAll() { 124 public void selectAll() {
114 if (!isEditing) return; 125 if (!editing) return;
115 126
116 this.textField.selectAll(); 127 this.textField.selectAll();
117 } 128 }
118 129
119 public void selectSubstring(int startIndex) { 130 public void selectSubstring(int startIndex) {
120 if (!isEditing) return; 131 if (!editing) return;
121 132
122 Document doc = this.textField.getDocument(); 133 Document doc = this.textField.getDocument();
123 if (doc != null) { 134 if (doc != null) {
@@ -126,13 +137,13 @@ public class ConvertingTextField implements Validatable {
126 } 137 }
127 138
128 public void selectSubstring(int startIndex, int endIndex) { 139 public void selectSubstring(int startIndex, int endIndex) {
129 if (!isEditing) return; 140 if (!editing) return;
130 141
131 this.textField.select(startIndex, endIndex); 142 this.textField.select(startIndex, endIndex);
132 } 143 }
133 144
134 public String getText() { 145 public String getText() {
135 if (isEditing) { 146 if (editing) {
136 return this.textField.getText(); 147 return this.textField.getText();
137 } else { 148 } else {
138 return this.label.getText(); 149 return this.label.getText();
@@ -144,7 +155,7 @@ public class ConvertingTextField implements Validatable {
144 } 155 }
145 156
146 public boolean hasChanges() { 157 public boolean hasChanges() {
147 if (!isEditing) return false; 158 if (!editing) return false;
148 return !this.textField.getText().equals(this.label.getText()); 159 return !this.textField.getText().equals(this.label.getText());
149 } 160 }
150 161
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
index dbe8948c..637f6a48 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
@@ -8,13 +8,11 @@ import javax.swing.JPopupMenu;
8import javax.swing.KeyStroke; 8import javax.swing.KeyStroke;
9 9
10import cuchaz.enigma.analysis.EntryReference; 10import cuchaz.enigma.analysis.EntryReference;
11import cuchaz.enigma.gui.EditableType;
11import cuchaz.enigma.gui.Gui; 12import cuchaz.enigma.gui.Gui;
12import cuchaz.enigma.gui.GuiController; 13import cuchaz.enigma.gui.GuiController;
13import cuchaz.enigma.gui.panels.EditorPanel; 14import cuchaz.enigma.gui.panels.EditorPanel;
14import cuchaz.enigma.translation.representation.entry.ClassEntry; 15import cuchaz.enigma.translation.representation.entry.*;
15import cuchaz.enigma.translation.representation.entry.Entry;
16import cuchaz.enigma.translation.representation.entry.FieldEntry;
17import cuchaz.enigma.translation.representation.entry.MethodEntry;
18import cuchaz.enigma.utils.I18n; 16import cuchaz.enigma.utils.I18n;
19 17
20public class EditorPopupMenu { 18public class EditorPopupMenu {
@@ -147,12 +145,35 @@ public class EditorPopupMenu {
147 145
148 boolean isClassEntry = referenceEntry instanceof ClassEntry; 146 boolean isClassEntry = referenceEntry instanceof ClassEntry;
149 boolean isFieldEntry = referenceEntry instanceof FieldEntry; 147 boolean isFieldEntry = referenceEntry instanceof FieldEntry;
150 boolean isMethodEntry = referenceEntry instanceof MethodEntry && !((MethodEntry) referenceEntry).isConstructor(); 148 boolean isMethodEntry = referenceEntry instanceof MethodEntry me && !me.isConstructor();
151 boolean isConstructorEntry = referenceEntry instanceof MethodEntry && ((MethodEntry) referenceEntry).isConstructor(); 149 boolean isConstructorEntry = referenceEntry instanceof MethodEntry me && me.isConstructor();
152 boolean isRenamable = ref != null && controller.project.isRenamable(ref); 150 boolean isRenamable = ref != null && controller.project.isRenamable(ref);
153 151
154 this.renameItem.setEnabled(isRenamable); 152 // TODO get rid of this with Entry rework
155 this.editJavadocItem.setEnabled(isRenamable); 153 EditableType type = null;
154
155 if (referenceEntry instanceof ClassEntry) {
156 type = EditableType.CLASS;
157 } else if (referenceEntry instanceof MethodEntry me) {
158 if (me.isConstructor()) {
159 // treat constructors as classes because renaming one renames
160 // the class
161 type = EditableType.CLASS;
162 } else {
163 type = EditableType.METHOD;
164 }
165 } else if (referenceEntry instanceof FieldEntry) {
166 type = EditableType.FIELD;
167 } else if (referenceEntry instanceof LocalVariableEntry lve) {
168 if (lve.isArgument()) {
169 type = EditableType.PARAMETER;
170 } else {
171 type = EditableType.LOCAL_VARIABLE;
172 }
173 }
174
175 this.renameItem.setEnabled(isRenamable && (type != null && this.gui.isEditable(type)));
176 this.editJavadocItem.setEnabled(isRenamable && this.gui.isEditable(EditableType.JAVADOC));
156 this.showInheritanceItem.setEnabled(isClassEntry || isMethodEntry || isConstructorEntry); 177 this.showInheritanceItem.setEnabled(isClassEntry || isMethodEntry || isConstructorEntry);
157 this.showImplementationsItem.setEnabled(isClassEntry || isMethodEntry); 178 this.showImplementationsItem.setEnabled(isClassEntry || isMethodEntry);
158 this.showCallsItem.setEnabled(isRenamable && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry)); 179 this.showCallsItem.setEnabled(isRenamable && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry));
@@ -160,7 +181,7 @@ public class EditorPopupMenu {
160 this.openEntryItem.setEnabled(isRenamable && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry)); 181 this.openEntryItem.setEnabled(isRenamable && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry));
161 this.openPreviousItem.setEnabled(controller.hasPreviousReference()); 182 this.openPreviousItem.setEnabled(controller.hasPreviousReference());
162 this.openNextItem.setEnabled(controller.hasNextReference()); 183 this.openNextItem.setEnabled(controller.hasNextReference());
163 this.toggleMappingItem.setEnabled(isRenamable); 184 this.toggleMappingItem.setEnabled(isRenamable && (type != null && this.gui.isEditable(type)));
164 185
165 if (referenceEntry != null && this.gui.getController().project.getMapper().extendedDeobfuscate(referenceEntry).isDeobfuscated()) { 186 if (referenceEntry != null && this.gui.getController().project.getMapper().extendedDeobfuscate(referenceEntry).isDeobfuscated()) {
166 this.toggleMappingItem.setText(I18n.translate("popup_menu.reset_obfuscated")); 187 this.toggleMappingItem.setText(I18n.translate("popup_menu.reset_obfuscated"));
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 a4914678..3bae94c3 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
@@ -16,6 +16,7 @@ import javax.swing.JPanel;
16 16
17import cuchaz.enigma.EnigmaProject; 17import cuchaz.enigma.EnigmaProject;
18import cuchaz.enigma.analysis.EntryReference; 18import cuchaz.enigma.analysis.EntryReference;
19import cuchaz.enigma.gui.EditableType;
19import cuchaz.enigma.gui.Gui; 20import cuchaz.enigma.gui.Gui;
20import cuchaz.enigma.gui.elements.ConvertingTextField; 21import cuchaz.enigma.gui.elements.ConvertingTextField;
21import cuchaz.enigma.gui.events.ConvertingTextFieldListener; 22import cuchaz.enigma.gui.events.ConvertingTextFieldListener;
@@ -83,7 +84,7 @@ public class IdentifierPanel {
83 84
84 this.nameField = null; 85 this.nameField = null;
85 86
86 TableHelper th = new TableHelper(this.ui, this.entry, this.gui.getController().project); 87 TableHelper th = new TableHelper(this.ui, this.entry, this.gui);
87 th.begin(); 88 th.begin();
88 if (this.entry == null) { 89 if (this.entry == null) {
89 this.ui.setEnabled(false); 90 this.ui.setEnabled(false);
@@ -93,27 +94,39 @@ public class IdentifierPanel {
93 if (deobfEntry instanceof ClassEntry) { 94 if (deobfEntry instanceof ClassEntry) {
94 ClassEntry ce = (ClassEntry) deobfEntry; 95 ClassEntry ce = (ClassEntry) deobfEntry;
95 String name = ce.isInnerClass() ? ce.getName() : ce.getFullName(); 96 String name = ce.isInnerClass() ? ce.getName() : ce.getFullName();
96 this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.class"), name); 97 this.nameField = th.addRenameTextField(EditableType.CLASS, name);
97 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); 98 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.CLASS, this::onModifierChanged);
98 } else if (deobfEntry instanceof FieldEntry) { 99 } else if (deobfEntry instanceof FieldEntry) {
99 FieldEntry fe = (FieldEntry) deobfEntry; 100 FieldEntry fe = (FieldEntry) deobfEntry;
100 this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.field"), fe.getName()); 101 this.nameField = th.addRenameTextField(EditableType.FIELD, fe.getName());
101 th.addStringRow(I18n.translate("info_panel.identifier.class"), fe.getParent().getFullName()); 102 th.addStringRow(I18n.translate("info_panel.identifier.class"), fe.getParent().getFullName());
102 th.addCopiableStringRow(I18n.translate("info_panel.identifier.type_descriptor"), fe.getDesc().toString()); 103 th.addCopiableStringRow(I18n.translate("info_panel.identifier.type_descriptor"), fe.getDesc().toString());
103 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); 104 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.FIELD, this::onModifierChanged);
104 } else if (deobfEntry instanceof MethodEntry) { 105 } else if (deobfEntry instanceof MethodEntry) {
105 MethodEntry me = (MethodEntry) deobfEntry; 106 MethodEntry me = (MethodEntry) deobfEntry;
106 if (me.isConstructor()) { 107 if (me.isConstructor()) {
107 th.addStringRow(I18n.translate("info_panel.identifier.constructor"), me.getParent().getFullName()); 108 ClassEntry ce = me.getParent();
109 if (ce != null) {
110 String name = ce.isInnerClass() ? ce.getName() : ce.getFullName();
111 this.nameField = th.addRenameTextField(EditableType.CLASS, name);
112 }
108 } else { 113 } else {
109 this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.method"), me.getName()); 114 this.nameField = th.addRenameTextField(EditableType.METHOD, me.getName());
110 th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName()); 115 th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName());
111 } 116 }
112 th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString()); 117 th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString());
113 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), this::onModifierChanged); 118 th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.METHOD, this::onModifierChanged);
114 } else if (deobfEntry instanceof LocalVariableEntry) { 119 } else if (deobfEntry instanceof LocalVariableEntry) {
115 LocalVariableEntry lve = (LocalVariableEntry) deobfEntry; 120 LocalVariableEntry lve = (LocalVariableEntry) deobfEntry;
116 this.nameField = th.addRenameTextField(I18n.translate("info_panel.identifier.variable"), lve.getName()); 121 EditableType type;
122
123 if (lve.isArgument()) {
124 type = EditableType.PARAMETER;
125 } else {
126 type = EditableType.LOCAL_VARIABLE;
127 }
128
129 this.nameField = th.addRenameTextField(type, lve.getName());
117 th.addStringRow(I18n.translate("info_panel.identifier.class"), lve.getContainingClass().getFullName()); 130 th.addStringRow(I18n.translate("info_panel.identifier.class"), lve.getContainingClass().getFullName());
118 th.addStringRow(I18n.translate("info_panel.identifier.method"), lve.getParent().getName()); 131 th.addStringRow(I18n.translate("info_panel.identifier.method"), lve.getParent().getName());
119 th.addStringRow(I18n.translate("info_panel.identifier.index"), Integer.toString(lve.getIndex())); 132 th.addStringRow(I18n.translate("info_panel.identifier.index"), Integer.toString(lve.getIndex()));
@@ -185,13 +198,13 @@ public class IdentifierPanel {
185 198
186 private final Container c; 199 private final Container c;
187 private final Entry<?> e; 200 private final Entry<?> e;
188 private final EnigmaProject project; 201 private final Gui gui;
189 private int row; 202 private int row;
190 203
191 public TableHelper(Container c, Entry<?> e, EnigmaProject project) { 204 public TableHelper(Container c, Entry<?> e, Gui gui) {
192 this.c = c; 205 this.c = c;
193 this.e = e; 206 this.e = e;
194 this.project = project; 207 this.gui = gui;
195 } 208 }
196 209
197 public void begin() { 210 public void begin() {
@@ -228,11 +241,21 @@ public class IdentifierPanel {
228 return textField; 241 return textField;
229 } 242 }
230 243
231 public ConvertingTextField addRenameTextField(String c1, String c2) { 244 public ConvertingTextField addRenameTextField(EditableType type, String c2) {
232 if (project.isRenamable(e)) { 245 String description = switch(type) {
233 return addConvertingTextField(c1, c2); 246 case CLASS -> I18n.translate("info_panel.identifier.class");
247 case METHOD -> I18n.translate("info_panel.identifier.method");
248 case FIELD -> I18n.translate("info_panel.identifier.field");
249 case PARAMETER, LOCAL_VARIABLE -> I18n.translate("info_panel.identifier.variable");
250 default -> throw new IllegalStateException("Unexpected value: " + type);
251 };
252
253 if (this.gui.getController().project.isRenamable(e)) {
254 ConvertingTextField field = addConvertingTextField(description, c2);
255 field.setEditable(this.gui.isEditable(type));
256 return field;
234 } else { 257 } else {
235 addStringRow(c1, c2); 258 addStringRow(description, c2);
236 return null; 259 return null;
237 } 260 }
238 } 261 }
@@ -245,22 +268,32 @@ public class IdentifierPanel {
245 addCopiableRow(new JLabel(c1), GuiUtil.unboldLabel(new JLabel(c2))); 268 addCopiableRow(new JLabel(c1), GuiUtil.unboldLabel(new JLabel(c2)));
246 } 269 }
247 270
248 public JComboBox<AccessModifier> addModifierRow(String c1, Consumer<AccessModifier> changeListener) { 271 public JComboBox<AccessModifier> addModifierRow(String c1, EditableType type, Consumer<AccessModifier> changeListener) {
249 if (!project.isRenamable(e)) 272 EnigmaProject project = this.gui.getController().project;
273
274 if (!project.isRenamable(e)) {
250 return null; 275 return null;
276 }
277
251 JComboBox<AccessModifier> combo = new JComboBox<>(AccessModifier.values()); 278 JComboBox<AccessModifier> combo = new JComboBox<>(AccessModifier.values());
252 EntryMapping mapping = project.getMapper().getDeobfMapping(e); 279 EntryMapping mapping = project.getMapper().getDeobfMapping(e);
280
253 if (mapping != null) { 281 if (mapping != null) {
254 combo.setSelectedIndex(mapping.getAccessModifier().ordinal()); 282 combo.setSelectedIndex(mapping.getAccessModifier().ordinal());
255 } else { 283 } else {
256 combo.setSelectedIndex(AccessModifier.UNCHANGED.ordinal()); 284 combo.setSelectedIndex(AccessModifier.UNCHANGED.ordinal());
257 } 285 }
258 combo.addItemListener(event -> { 286
259 if (event.getStateChange() == ItemEvent.SELECTED) { 287 if (this.gui.isEditable(type)) {
260 AccessModifier modifier = (AccessModifier) event.getItem(); 288 combo.addItemListener(event -> {
261 changeListener.accept(modifier); 289 if (event.getStateChange() == ItemEvent.SELECTED) {
262 } 290 AccessModifier modifier = (AccessModifier) event.getItem();
263 }); 291 changeListener.accept(modifier);
292 }
293 });
294 } else {
295 combo.setEnabled(false);
296 }
264 297
265 addRow(new JLabel(c1), combo); 298 addRow(new JLabel(c1), combo);
266 299