diff options
Diffstat (limited to 'enigma-swing/src/main')
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 @@ | |||
| 1 | package cuchaz.enigma.gui; | ||
| 2 | |||
| 3 | public 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; | |||
| 15 | import java.nio.file.Files; | 15 | import java.nio.file.Files; |
| 16 | import java.nio.file.Path; | 16 | import java.nio.file.Path; |
| 17 | import java.nio.file.Paths; | 17 | import java.nio.file.Paths; |
| 18 | import java.util.EnumSet; | ||
| 19 | import java.util.List; | ||
| 20 | import java.util.Set; | ||
| 18 | 21 | ||
| 19 | import com.google.common.io.MoreFiles; | 22 | import com.google.common.io.MoreFiles; |
| 20 | import joptsimple.*; | 23 | import 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; | |||
| 8 | import javax.swing.KeyStroke; | 8 | import javax.swing.KeyStroke; |
| 9 | 9 | ||
| 10 | import cuchaz.enigma.analysis.EntryReference; | 10 | import cuchaz.enigma.analysis.EntryReference; |
| 11 | import cuchaz.enigma.gui.EditableType; | ||
| 11 | import cuchaz.enigma.gui.Gui; | 12 | import cuchaz.enigma.gui.Gui; |
| 12 | import cuchaz.enigma.gui.GuiController; | 13 | import cuchaz.enigma.gui.GuiController; |
| 13 | import cuchaz.enigma.gui.panels.EditorPanel; | 14 | import cuchaz.enigma.gui.panels.EditorPanel; |
| 14 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 15 | import cuchaz.enigma.translation.representation.entry.*; |
| 15 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 16 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 17 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 18 | import cuchaz.enigma.utils.I18n; | 16 | import cuchaz.enigma.utils.I18n; |
| 19 | 17 | ||
| 20 | public class EditorPopupMenu { | 18 | public 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 | ||
| 17 | import cuchaz.enigma.EnigmaProject; | 17 | import cuchaz.enigma.EnigmaProject; |
| 18 | import cuchaz.enigma.analysis.EntryReference; | 18 | import cuchaz.enigma.analysis.EntryReference; |
| 19 | import cuchaz.enigma.gui.EditableType; | ||
| 19 | import cuchaz.enigma.gui.Gui; | 20 | import cuchaz.enigma.gui.Gui; |
| 20 | import cuchaz.enigma.gui.elements.ConvertingTextField; | 21 | import cuchaz.enigma.gui.elements.ConvertingTextField; |
| 21 | import cuchaz.enigma.gui.events.ConvertingTextFieldListener; | 22 | import 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 | ||