diff options
Diffstat (limited to 'src/main/java')
8 files changed, 178 insertions, 78 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 92c68ac..3e85920 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java | |||
| @@ -29,6 +29,7 @@ import cuchaz.enigma.gui.panels.PanelDeobf; | |||
| 29 | import cuchaz.enigma.gui.panels.PanelEditor; | 29 | import cuchaz.enigma.gui.panels.PanelEditor; |
| 30 | import cuchaz.enigma.gui.panels.PanelIdentifier; | 30 | import cuchaz.enigma.gui.panels.PanelIdentifier; |
| 31 | import cuchaz.enigma.gui.panels.PanelObf; | 31 | import cuchaz.enigma.gui.panels.PanelObf; |
| 32 | import cuchaz.enigma.gui.util.History; | ||
| 32 | import cuchaz.enigma.throwables.IllegalNameException; | 33 | import cuchaz.enigma.throwables.IllegalNameException; |
| 33 | import cuchaz.enigma.translation.mapping.AccessModifier; | 34 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 34 | import cuchaz.enigma.translation.representation.entry.*; | 35 | import cuchaz.enigma.translation.representation.entry.*; |
| @@ -54,7 +55,8 @@ public class Gui { | |||
| 54 | 55 | ||
| 55 | private final MenuBar menuBar; | 56 | private final MenuBar menuBar; |
| 56 | // state | 57 | // state |
| 57 | public EntryReference<Entry<?>, Entry<?>> reference; | 58 | public History<EntryReference<Entry<?>, Entry<?>>> referenceHistory; |
| 59 | public EntryReference<Entry<?>, Entry<?>> cursorReference; | ||
| 58 | private boolean shouldNavigateOnClick; | 60 | private boolean shouldNavigateOnClick; |
| 59 | 61 | ||
| 60 | public FileDialog jarFileChooser; | 62 | public FileDialog jarFileChooser; |
| @@ -162,11 +164,11 @@ public class Gui { | |||
| 162 | Object node = path.getLastPathComponent(); | 164 | Object node = path.getLastPathComponent(); |
| 163 | if (node instanceof ClassInheritanceTreeNode) { | 165 | if (node instanceof ClassInheritanceTreeNode) { |
| 164 | ClassInheritanceTreeNode classNode = (ClassInheritanceTreeNode) node; | 166 | ClassInheritanceTreeNode classNode = (ClassInheritanceTreeNode) node; |
| 165 | navigateTo(new ClassEntry(classNode.getObfClassName())); | 167 | controller.navigateTo(new ClassEntry(classNode.getObfClassName())); |
| 166 | } else if (node instanceof MethodInheritanceTreeNode) { | 168 | } else if (node instanceof MethodInheritanceTreeNode) { |
| 167 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode) node; | 169 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode) node; |
| 168 | if (methodNode.isImplemented()) { | 170 | if (methodNode.isImplemented()) { |
| 169 | navigateTo(methodNode.getMethodEntry()); | 171 | controller.navigateTo(methodNode.getMethodEntry()); |
| 170 | } | 172 | } |
| 171 | } | 173 | } |
| 172 | } | 174 | } |
| @@ -195,10 +197,10 @@ public class Gui { | |||
| 195 | Object node = path.getLastPathComponent(); | 197 | Object node = path.getLastPathComponent(); |
| 196 | if (node instanceof ClassImplementationsTreeNode) { | 198 | if (node instanceof ClassImplementationsTreeNode) { |
| 197 | ClassImplementationsTreeNode classNode = (ClassImplementationsTreeNode) node; | 199 | ClassImplementationsTreeNode classNode = (ClassImplementationsTreeNode) node; |
| 198 | navigateTo(classNode.getClassEntry()); | 200 | controller.navigateTo(classNode.getClassEntry()); |
| 199 | } else if (node instanceof MethodImplementationsTreeNode) { | 201 | } else if (node instanceof MethodImplementationsTreeNode) { |
| 200 | MethodImplementationsTreeNode methodNode = (MethodImplementationsTreeNode) node; | 202 | MethodImplementationsTreeNode methodNode = (MethodImplementationsTreeNode) node; |
| 201 | navigateTo(methodNode.getMethodEntry()); | 203 | controller.navigateTo(methodNode.getMethodEntry()); |
| 202 | } | 204 | } |
| 203 | } | 205 | } |
| 204 | } | 206 | } |
| @@ -225,9 +227,9 @@ public class Gui { | |||
| 225 | if (node instanceof ReferenceTreeNode) { | 227 | if (node instanceof ReferenceTreeNode) { |
| 226 | ReferenceTreeNode<Entry<?>, Entry<?>> referenceNode = ((ReferenceTreeNode<Entry<?>, Entry<?>>) node); | 228 | ReferenceTreeNode<Entry<?>, Entry<?>> referenceNode = ((ReferenceTreeNode<Entry<?>, Entry<?>>) node); |
| 227 | if (referenceNode.getReference() != null) { | 229 | if (referenceNode.getReference() != null) { |
| 228 | navigateTo(referenceNode.getReference()); | 230 | controller.navigateTo(referenceNode.getReference()); |
| 229 | } else { | 231 | } else { |
| 230 | navigateTo(referenceNode.getEntry()); | 232 | controller.navigateTo(referenceNode.getEntry()); |
| 231 | } | 233 | } |
| 232 | } | 234 | } |
| 233 | } | 235 | } |
| @@ -433,13 +435,13 @@ public class Gui { | |||
| 433 | } | 435 | } |
| 434 | } | 436 | } |
| 435 | 437 | ||
| 436 | private void showReference(EntryReference<Entry<?>, Entry<?>> reference) { | 438 | private void showCursorReference(EntryReference<Entry<?>, Entry<?>> reference) { |
| 437 | if (reference == null) { | 439 | if (reference == null) { |
| 438 | infoPanel.clearReference(); | 440 | infoPanel.clearReference(); |
| 439 | return; | 441 | return; |
| 440 | } | 442 | } |
| 441 | 443 | ||
| 442 | this.reference = reference; | 444 | this.cursorReference = reference; |
| 443 | 445 | ||
| 444 | EntryReference<Entry<?>, Entry<?>> translatedReference = controller.getDeobfuscator().deobfuscate(reference); | 446 | EntryReference<Entry<?>, Entry<?>> translatedReference = controller.getDeobfuscator().deobfuscate(reference); |
| 445 | 447 | ||
| @@ -526,12 +528,12 @@ public class Gui { | |||
| 526 | Token token = this.controller.getToken(pos); | 528 | Token token = this.controller.getToken(pos); |
| 527 | boolean isToken = token != null; | 529 | boolean isToken = token != null; |
| 528 | 530 | ||
| 529 | reference = this.controller.getReference(token); | 531 | cursorReference = this.controller.getReference(token); |
| 530 | Entry<?> referenceEntry = reference != null ? reference.entry : null; | 532 | Entry<?> referenceEntry = cursorReference != null ? cursorReference.entry : null; |
| 531 | 533 | ||
| 532 | if (referenceEntry != null && shouldNavigateOnClick) { | 534 | if (referenceEntry != null && shouldNavigateOnClick) { |
| 533 | shouldNavigateOnClick = false; | 535 | shouldNavigateOnClick = false; |
| 534 | navigateTo(referenceEntry); | 536 | this.controller.navigateTo(referenceEntry); |
| 535 | return; | 537 | return; |
| 536 | } | 538 | } |
| 537 | 539 | ||
| @@ -540,10 +542,10 @@ public class Gui { | |||
| 540 | boolean isMethodEntry = isToken && referenceEntry instanceof MethodEntry && !((MethodEntry) referenceEntry).isConstructor(); | 542 | boolean isMethodEntry = isToken && referenceEntry instanceof MethodEntry && !((MethodEntry) referenceEntry).isConstructor(); |
| 541 | boolean isConstructorEntry = isToken && referenceEntry instanceof MethodEntry && ((MethodEntry) referenceEntry).isConstructor(); | 543 | boolean isConstructorEntry = isToken && referenceEntry instanceof MethodEntry && ((MethodEntry) referenceEntry).isConstructor(); |
| 542 | boolean isInJar = isToken && this.controller.entryIsInJar(referenceEntry); | 544 | boolean isInJar = isToken && this.controller.entryIsInJar(referenceEntry); |
| 543 | boolean isRenamable = isToken && this.controller.getDeobfuscator().isRenamable(reference); | 545 | boolean isRenamable = isToken && this.controller.getDeobfuscator().isRenamable(cursorReference); |
| 544 | 546 | ||
| 545 | if (isToken) { | 547 | if (isToken) { |
| 546 | showReference(reference); | 548 | showCursorReference(cursorReference); |
| 547 | } else { | 549 | } else { |
| 548 | infoPanel.clearReference(); | 550 | infoPanel.clearReference(); |
| 549 | } | 551 | } |
| @@ -554,7 +556,8 @@ public class Gui { | |||
| 554 | this.popupMenu.showCallsMenu.setEnabled(isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry); | 556 | this.popupMenu.showCallsMenu.setEnabled(isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry); |
| 555 | this.popupMenu.showCallsSpecificMenu.setEnabled(isMethodEntry); | 557 | this.popupMenu.showCallsSpecificMenu.setEnabled(isMethodEntry); |
| 556 | this.popupMenu.openEntryMenu.setEnabled(isInJar && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry)); | 558 | this.popupMenu.openEntryMenu.setEnabled(isInJar && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry)); |
| 557 | this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation()); | 559 | this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousReference()); |
| 560 | this.popupMenu.openNextMenu.setEnabled(this.controller.hasNextReference()); | ||
| 558 | this.popupMenu.toggleMappingMenu.setEnabled(isRenamable); | 561 | this.popupMenu.toggleMappingMenu.setEnabled(isRenamable); |
| 559 | 562 | ||
| 560 | if (isToken && this.controller.getDeobfuscator().isRemapped(referenceEntry)) { | 563 | if (isToken && this.controller.getDeobfuscator().isRemapped(referenceEntry)) { |
| @@ -564,33 +567,12 @@ public class Gui { | |||
| 564 | } | 567 | } |
| 565 | } | 568 | } |
| 566 | 569 | ||
| 567 | public void navigateTo(Entry<?> entry) { | ||
| 568 | if (!this.controller.entryIsInJar(entry)) { | ||
| 569 | // entry is not in the jar. Ignore it | ||
| 570 | return; | ||
| 571 | } | ||
| 572 | if (reference != null) { | ||
| 573 | this.controller.savePreviousReference(reference); | ||
| 574 | } | ||
| 575 | this.controller.openDeclaration(entry); | ||
| 576 | } | ||
| 577 | |||
| 578 | private void navigateTo(EntryReference<Entry<?>, Entry<?>> reference) { | ||
| 579 | if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) { | ||
| 580 | return; | ||
| 581 | } | ||
| 582 | if (this.reference != null) { | ||
| 583 | this.controller.savePreviousReference(this.reference); | ||
| 584 | } | ||
| 585 | this.controller.openReference(reference); | ||
| 586 | } | ||
| 587 | |||
| 588 | public void startRename() { | 570 | public void startRename() { |
| 589 | 571 | ||
| 590 | // init the text box | 572 | // init the text box |
| 591 | final JTextField text = new JTextField(); | 573 | final JTextField text = new JTextField(); |
| 592 | 574 | ||
| 593 | EntryReference<Entry<?>, Entry<?>> translatedReference = controller.getDeobfuscator().deobfuscate(reference); | 575 | EntryReference<Entry<?>, Entry<?>> translatedReference = controller.getDeobfuscator().deobfuscate(cursorReference); |
| 594 | text.setText(translatedReference.getNameableName()); | 576 | text.setText(translatedReference.getNameableName()); |
| 595 | 577 | ||
| 596 | text.setPreferredSize(new Dimension(360, text.getPreferredSize().height)); | 578 | text.setPreferredSize(new Dimension(360, text.getPreferredSize().height)); |
| @@ -631,7 +613,7 @@ public class Gui { | |||
| 631 | String newName = text.getText(); | 613 | String newName = text.getText(); |
| 632 | if (saveName && newName != null && !newName.isEmpty()) { | 614 | if (saveName && newName != null && !newName.isEmpty()) { |
| 633 | try { | 615 | try { |
| 634 | this.controller.rename(reference, newName, true); | 616 | this.controller.rename(cursorReference, newName, true); |
| 635 | } catch (IllegalNameException ex) { | 617 | } catch (IllegalNameException ex) { |
| 636 | text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); | 618 | text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); |
| 637 | text.setToolTipText(ex.getReason()); | 619 | text.setToolTipText(ex.getReason()); |
| @@ -643,7 +625,7 @@ public class Gui { | |||
| 643 | // abort the rename | 625 | // abort the rename |
| 644 | JPanel panel = (JPanel) infoPanel.getComponent(0); | 626 | JPanel panel = (JPanel) infoPanel.getComponent(0); |
| 645 | panel.remove(panel.getComponentCount() - 1); | 627 | panel.remove(panel.getComponentCount() - 1); |
| 646 | panel.add(Utils.unboldLabel(new JLabel(reference.getNameableName(), JLabel.LEFT))); | 628 | panel.add(Utils.unboldLabel(new JLabel(cursorReference.getNameableName(), JLabel.LEFT))); |
| 647 | 629 | ||
| 648 | this.editor.grabFocus(); | 630 | this.editor.grabFocus(); |
| 649 | 631 | ||
| @@ -652,24 +634,24 @@ public class Gui { | |||
| 652 | 634 | ||
| 653 | public void showInheritance() { | 635 | public void showInheritance() { |
| 654 | 636 | ||
| 655 | if (reference == null) { | 637 | if (cursorReference == null) { |
| 656 | return; | 638 | return; |
| 657 | } | 639 | } |
| 658 | 640 | ||
| 659 | inheritanceTree.setModel(null); | 641 | inheritanceTree.setModel(null); |
| 660 | 642 | ||
| 661 | if (reference.entry instanceof ClassEntry) { | 643 | if (cursorReference.entry instanceof ClassEntry) { |
| 662 | // get the class inheritance | 644 | // get the class inheritance |
| 663 | ClassInheritanceTreeNode classNode = this.controller.getClassInheritance((ClassEntry) reference.entry); | 645 | ClassInheritanceTreeNode classNode = this.controller.getClassInheritance((ClassEntry) cursorReference.entry); |
| 664 | 646 | ||
| 665 | // show the tree at the root | 647 | // show the tree at the root |
| 666 | TreePath path = getPathToRoot(classNode); | 648 | TreePath path = getPathToRoot(classNode); |
| 667 | inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); | 649 | inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); |
| 668 | inheritanceTree.expandPath(path); | 650 | inheritanceTree.expandPath(path); |
| 669 | inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path)); | 651 | inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path)); |
| 670 | } else if (reference.entry instanceof MethodEntry) { | 652 | } else if (cursorReference.entry instanceof MethodEntry) { |
| 671 | // get the method inheritance | 653 | // get the method inheritance |
| 672 | MethodInheritanceTreeNode classNode = this.controller.getMethodInheritance((MethodEntry) reference.entry); | 654 | MethodInheritanceTreeNode classNode = this.controller.getMethodInheritance((MethodEntry) cursorReference.entry); |
| 673 | 655 | ||
| 674 | // show the tree at the root | 656 | // show the tree at the root |
| 675 | TreePath path = getPathToRoot(classNode); | 657 | TreePath path = getPathToRoot(classNode); |
| @@ -685,7 +667,7 @@ public class Gui { | |||
| 685 | 667 | ||
| 686 | public void showImplementations() { | 668 | public void showImplementations() { |
| 687 | 669 | ||
| 688 | if (reference == null) { | 670 | if (cursorReference == null) { |
| 689 | return; | 671 | return; |
| 690 | } | 672 | } |
| 691 | 673 | ||
| @@ -694,11 +676,11 @@ public class Gui { | |||
| 694 | DefaultMutableTreeNode node = null; | 676 | DefaultMutableTreeNode node = null; |
| 695 | 677 | ||
| 696 | // get the class implementations | 678 | // get the class implementations |
| 697 | if (reference.entry instanceof ClassEntry) | 679 | if (cursorReference.entry instanceof ClassEntry) |
| 698 | node = this.controller.getClassImplementations((ClassEntry) reference.entry); | 680 | node = this.controller.getClassImplementations((ClassEntry) cursorReference.entry); |
| 699 | else // get the method implementations | 681 | else // get the method implementations |
| 700 | if (reference.entry instanceof MethodEntry) | 682 | if (cursorReference.entry instanceof MethodEntry) |
| 701 | node = this.controller.getMethodImplementations((MethodEntry) reference.entry); | 683 | node = this.controller.getMethodImplementations((MethodEntry) cursorReference.entry); |
| 702 | 684 | ||
| 703 | if (node != null) { | 685 | if (node != null) { |
| 704 | // show the tree at the root | 686 | // show the tree at the root |
| @@ -714,18 +696,18 @@ public class Gui { | |||
| 714 | } | 696 | } |
| 715 | 697 | ||
| 716 | public void showCalls(boolean recurse) { | 698 | public void showCalls(boolean recurse) { |
| 717 | if (reference == null) { | 699 | if (cursorReference == null) { |
| 718 | return; | 700 | return; |
| 719 | } | 701 | } |
| 720 | 702 | ||
| 721 | if (reference.entry instanceof ClassEntry) { | 703 | if (cursorReference.entry instanceof ClassEntry) { |
| 722 | ClassReferenceTreeNode node = this.controller.getClassReferences((ClassEntry) reference.entry); | 704 | ClassReferenceTreeNode node = this.controller.getClassReferences((ClassEntry) cursorReference.entry); |
| 723 | callsTree.setModel(new DefaultTreeModel(node)); | 705 | callsTree.setModel(new DefaultTreeModel(node)); |
| 724 | } else if (reference.entry instanceof FieldEntry) { | 706 | } else if (cursorReference.entry instanceof FieldEntry) { |
| 725 | FieldReferenceTreeNode node = this.controller.getFieldReferences((FieldEntry) reference.entry); | 707 | FieldReferenceTreeNode node = this.controller.getFieldReferences((FieldEntry) cursorReference.entry); |
| 726 | callsTree.setModel(new DefaultTreeModel(node)); | 708 | callsTree.setModel(new DefaultTreeModel(node)); |
| 727 | } else if (reference.entry instanceof MethodEntry) { | 709 | } else if (cursorReference.entry instanceof MethodEntry) { |
| 728 | MethodReferenceTreeNode node = this.controller.getMethodReferences((MethodEntry) reference.entry, recurse); | 710 | MethodReferenceTreeNode node = this.controller.getMethodReferences((MethodEntry) cursorReference.entry, recurse); |
| 729 | callsTree.setModel(new DefaultTreeModel(node)); | 711 | callsTree.setModel(new DefaultTreeModel(node)); |
| 730 | } | 712 | } |
| 731 | 713 | ||
| @@ -735,10 +717,10 @@ public class Gui { | |||
| 735 | } | 717 | } |
| 736 | 718 | ||
| 737 | public void toggleMapping() { | 719 | public void toggleMapping() { |
| 738 | if (this.controller.getDeobfuscator().isRemapped(reference.entry)) { | 720 | if (this.controller.getDeobfuscator().isRemapped(cursorReference.entry)) { |
| 739 | this.controller.removeMapping(reference); | 721 | this.controller.removeMapping(cursorReference); |
| 740 | } else { | 722 | } else { |
| 741 | this.controller.markAsDeobfuscated(reference); | 723 | this.controller.markAsDeobfuscated(cursorReference); |
| 742 | } | 724 | } |
| 743 | } | 725 | } |
| 744 | 726 | ||
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 4155062..5610233 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | import com.google.common.collect.Lists; | 14 | import com.google.common.collect.Lists; |
| 15 | import com.google.common.collect.Queues; | ||
| 16 | import com.google.common.util.concurrent.ThreadFactoryBuilder; | 15 | import com.google.common.util.concurrent.ThreadFactoryBuilder; |
| 17 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; | 16 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; |
| 18 | import cuchaz.enigma.Deobfuscator; | 17 | import cuchaz.enigma.Deobfuscator; |
| @@ -20,6 +19,7 @@ import cuchaz.enigma.SourceProvider; | |||
| 20 | import cuchaz.enigma.analysis.*; | 19 | import cuchaz.enigma.analysis.*; |
| 21 | import cuchaz.enigma.config.Config; | 20 | import cuchaz.enigma.config.Config; |
| 22 | import cuchaz.enigma.gui.dialog.ProgressDialog; | 21 | import cuchaz.enigma.gui.dialog.ProgressDialog; |
| 22 | import cuchaz.enigma.gui.util.History; | ||
| 23 | import cuchaz.enigma.throwables.MappingParseException; | 23 | import cuchaz.enigma.throwables.MappingParseException; |
| 24 | import cuchaz.enigma.translation.Translator; | 24 | import cuchaz.enigma.translation.Translator; |
| 25 | import cuchaz.enigma.translation.mapping.*; | 25 | import cuchaz.enigma.translation.mapping.*; |
| @@ -40,7 +40,6 @@ import java.io.PrintWriter; | |||
| 40 | import java.io.StringWriter; | 40 | import java.io.StringWriter; |
| 41 | import java.nio.file.Path; | 41 | import java.nio.file.Path; |
| 42 | import java.util.Collection; | 42 | import java.util.Collection; |
| 43 | import java.util.Deque; | ||
| 44 | import java.util.List; | 43 | import java.util.List; |
| 45 | import java.util.concurrent.ExecutorService; | 44 | import java.util.concurrent.ExecutorService; |
| 46 | import java.util.concurrent.Executors; | 45 | import java.util.concurrent.Executors; |
| @@ -53,14 +52,13 @@ public class GuiController { | |||
| 53 | private final Gui gui; | 52 | private final Gui gui; |
| 54 | private Deobfuscator deobfuscator; | 53 | private Deobfuscator deobfuscator; |
| 55 | private DecompiledClassSource currentSource; | 54 | private DecompiledClassSource currentSource; |
| 56 | private Deque<EntryReference<Entry<?>, Entry<?>>> referenceStack; | 55 | |
| 57 | 56 | ||
| 58 | private Path loadedMappingPath; | 57 | private Path loadedMappingPath; |
| 59 | private MappingFormat loadedMappingFormat; | 58 | private MappingFormat loadedMappingFormat; |
| 60 | 59 | ||
| 61 | public GuiController(Gui gui) { | 60 | public GuiController(Gui gui) { |
| 62 | this.gui = gui; | 61 | this.gui = gui; |
| 63 | this.referenceStack = Queues.newArrayDeque(); | ||
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | public boolean isDirty() { | 64 | public boolean isDirty() { |
| @@ -246,6 +244,10 @@ public class GuiController { | |||
| 246 | refreshCurrentClass(reference); | 244 | refreshCurrentClass(reference); |
| 247 | } | 245 | } |
| 248 | 246 | ||
| 247 | /** | ||
| 248 | * Navigates to the declaration with respect to navigation history | ||
| 249 | * @param entry the entry whose declaration will be navigated to | ||
| 250 | */ | ||
| 249 | public void openDeclaration(Entry<?> entry) { | 251 | public void openDeclaration(Entry<?> entry) { |
| 250 | if (entry == null) { | 252 | if (entry == null) { |
| 251 | throw new IllegalArgumentException("Entry cannot be null!"); | 253 | throw new IllegalArgumentException("Entry cannot be null!"); |
| @@ -253,11 +255,29 @@ public class GuiController { | |||
| 253 | openReference(new EntryReference<>(entry, entry.getName())); | 255 | openReference(new EntryReference<>(entry, entry.getName())); |
| 254 | } | 256 | } |
| 255 | 257 | ||
| 258 | /** | ||
| 259 | * Navigates to the reference with respect to navigation history | ||
| 260 | * @param reference the reference | ||
| 261 | */ | ||
| 256 | public void openReference(EntryReference<Entry<?>, Entry<?>> reference) { | 262 | public void openReference(EntryReference<Entry<?>, Entry<?>> reference) { |
| 257 | if (reference == null) { | 263 | if (reference == null) { |
| 258 | throw new IllegalArgumentException("Reference cannot be null!"); | 264 | throw new IllegalArgumentException("Reference cannot be null!"); |
| 259 | } | 265 | } |
| 266 | if (this.gui.referenceHistory == null) { | ||
| 267 | this.gui.referenceHistory = new History<>(reference); | ||
| 268 | } else { | ||
| 269 | if (!reference.equals(this.gui.referenceHistory.getCurrent())) { | ||
| 270 | this.gui.referenceHistory.push(reference); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | setReference(reference); | ||
| 274 | } | ||
| 260 | 275 | ||
| 276 | /** | ||
| 277 | * Navigates to the reference without modifying history. If the class is not currently loaded, it will be loaded. | ||
| 278 | * @param reference the reference | ||
| 279 | */ | ||
| 280 | private void setReference(EntryReference<Entry<?>, Entry<?>> reference) { | ||
| 261 | // get the reference target class | 281 | // get the reference target class |
| 262 | ClassEntry classEntry = reference.getLocationClassEntry(); | 282 | ClassEntry classEntry = reference.getLocationClassEntry(); |
| 263 | if (!this.deobfuscator.isRenamable(classEntry)) { | 283 | if (!this.deobfuscator.isRenamable(classEntry)) { |
| @@ -272,6 +292,10 @@ public class GuiController { | |||
| 272 | } | 292 | } |
| 273 | } | 293 | } |
| 274 | 294 | ||
| 295 | /** | ||
| 296 | * Navigates to the reference without modifying history. Assumes the class is loaded. | ||
| 297 | * @param reference | ||
| 298 | */ | ||
| 275 | private void showReference(EntryReference<Entry<?>, Entry<?>> reference) { | 299 | private void showReference(EntryReference<Entry<?>, Entry<?>> reference) { |
| 276 | EntryRemapper mapper = this.deobfuscator.getMapper(); | 300 | EntryRemapper mapper = this.deobfuscator.getMapper(); |
| 277 | 301 | ||
| @@ -289,18 +313,39 @@ public class GuiController { | |||
| 289 | } | 313 | } |
| 290 | } | 314 | } |
| 291 | 315 | ||
| 292 | public void savePreviousReference(EntryReference<Entry<?>, Entry<?>> reference) { | 316 | public void openPreviousReference() { |
| 293 | this.referenceStack.push(reference); | 317 | if (hasPreviousReference()) { |
| 318 | setReference(gui.referenceHistory.goBack()); | ||
| 319 | } | ||
| 294 | } | 320 | } |
| 295 | 321 | ||
| 296 | public void openPreviousReference() { | 322 | public boolean hasPreviousReference() { |
| 297 | if (hasPreviousLocation()) { | 323 | return gui.referenceHistory != null && gui.referenceHistory.canGoBack(); |
| 298 | openReference(this.referenceStack.pop()); | 324 | } |
| 325 | |||
| 326 | public void openNextReference() { | ||
| 327 | if (hasNextReference()) { | ||
| 328 | setReference(gui.referenceHistory.goForward()); | ||
| 299 | } | 329 | } |
| 300 | } | 330 | } |
| 301 | 331 | ||
| 302 | public boolean hasPreviousLocation() { | 332 | public boolean hasNextReference() { |
| 303 | return !this.referenceStack.isEmpty(); | 333 | return gui.referenceHistory != null && gui.referenceHistory.canGoForward(); |
| 334 | } | ||
| 335 | |||
| 336 | public void navigateTo(Entry<?> entry) { | ||
| 337 | if (!entryIsInJar(entry)) { | ||
| 338 | // entry is not in the jar. Ignore it | ||
| 339 | return; | ||
| 340 | } | ||
| 341 | openDeclaration(entry); | ||
| 342 | } | ||
| 343 | |||
| 344 | public void navigateTo(EntryReference<Entry<?>, Entry<?>> reference) { | ||
| 345 | if (!entryIsInJar(reference.getLocationClassEntry())) { | ||
| 346 | return; | ||
| 347 | } | ||
| 348 | openReference(reference); | ||
| 304 | } | 349 | } |
| 305 | 350 | ||
| 306 | private void refreshClasses() { | 351 | private void refreshClasses() { |
| @@ -390,7 +435,7 @@ public class GuiController { | |||
| 390 | 435 | ||
| 391 | public void modifierChange(ItemEvent event) { | 436 | public void modifierChange(ItemEvent event) { |
| 392 | if (event.getStateChange() == ItemEvent.SELECTED) { | 437 | if (event.getStateChange() == ItemEvent.SELECTED) { |
| 393 | deobfuscator.changeModifier(gui.reference.entry, (AccessModifier) event.getItem()); | 438 | deobfuscator.changeModifier(gui.cursorReference.entry, (AccessModifier) event.getItem()); |
| 394 | refreshCurrentClass(); | 439 | refreshCurrentClass(); |
| 395 | } | 440 | } |
| 396 | } | 441 | } |
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java index da09c52..a122bd8 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java | |||
| @@ -125,7 +125,7 @@ public class SearchDialog { | |||
| 125 | .filter(classEntry -> classEntry.getSimpleName().equals(classList.getSelectedValue())). | 125 | .filter(classEntry -> classEntry.getSimpleName().equals(classList.getSelectedValue())). |
| 126 | findFirst() | 126 | findFirst() |
| 127 | .ifPresent(classEntry -> { | 127 | .ifPresent(classEntry -> { |
| 128 | parent.navigateTo(classEntry); | 128 | parent.getController().navigateTo(classEntry); |
| 129 | parent.getDeobfPanel().deobfClasses.setSelectionClass(classEntry); | 129 | parent.getDeobfPanel().deobfClasses.setSelectionClass(classEntry); |
| 130 | }); | 130 | }); |
| 131 | } | 131 | } |
diff --git a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java index 32f9172..fbf39ac 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java | |||
| @@ -15,6 +15,7 @@ public class PopupMenuBar extends JPopupMenu { | |||
| 15 | public final JMenuItem showCallsSpecificMenu; | 15 | public final JMenuItem showCallsSpecificMenu; |
| 16 | public final JMenuItem openEntryMenu; | 16 | public final JMenuItem openEntryMenu; |
| 17 | public final JMenuItem openPreviousMenu; | 17 | public final JMenuItem openPreviousMenu; |
| 18 | public final JMenuItem openNextMenu; | ||
| 18 | public final JMenuItem toggleMappingMenu; | 19 | public final JMenuItem toggleMappingMenu; |
| 19 | 20 | ||
| 20 | public PopupMenuBar(Gui gui) { | 21 | public PopupMenuBar(Gui gui) { |
| @@ -60,14 +61,14 @@ public class PopupMenuBar extends JPopupMenu { | |||
| 60 | } | 61 | } |
| 61 | { | 62 | { |
| 62 | JMenuItem menu = new JMenuItem("Go to Declaration"); | 63 | JMenuItem menu = new JMenuItem("Go to Declaration"); |
| 63 | menu.addActionListener(event -> gui.navigateTo(gui.reference.entry)); | 64 | menu.addActionListener(event -> gui.getController().navigateTo(gui.cursorReference.entry)); |
| 64 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); | 65 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); |
| 65 | menu.setEnabled(false); | 66 | menu.setEnabled(false); |
| 66 | this.add(menu); | 67 | this.add(menu); |
| 67 | this.openEntryMenu = menu; | 68 | this.openEntryMenu = menu; |
| 68 | } | 69 | } |
| 69 | { | 70 | { |
| 70 | JMenuItem menu = new JMenuItem("Go to previous"); | 71 | JMenuItem menu = new JMenuItem("Go back"); |
| 71 | menu.addActionListener(event -> gui.getController().openPreviousReference()); | 72 | menu.addActionListener(event -> gui.getController().openPreviousReference()); |
| 72 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)); | 73 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)); |
| 73 | menu.setEnabled(false); | 74 | menu.setEnabled(false); |
| @@ -75,6 +76,14 @@ public class PopupMenuBar extends JPopupMenu { | |||
| 75 | this.openPreviousMenu = menu; | 76 | this.openPreviousMenu = menu; |
| 76 | } | 77 | } |
| 77 | { | 78 | { |
| 79 | JMenuItem menu = new JMenuItem("Go forward"); | ||
| 80 | menu.addActionListener(event -> gui.getController().openNextReference()); | ||
| 81 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0)); | ||
| 82 | menu.setEnabled(false); | ||
| 83 | this.add(menu); | ||
| 84 | this.openNextMenu = menu; | ||
| 85 | } | ||
| 86 | { | ||
| 78 | JMenuItem menu = new JMenuItem("Mark as deobfuscated"); | 87 | JMenuItem menu = new JMenuItem("Mark as deobfuscated"); |
| 79 | menu.addActionListener(event -> gui.toggleMapping()); | 88 | menu.addActionListener(event -> gui.toggleMapping()); |
| 80 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)); | 89 | menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)); |
diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java index 68cc8e1..2a4e2d7 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java | |||
| @@ -15,7 +15,7 @@ public class PanelDeobf extends JPanel { | |||
| 15 | this.gui = gui; | 15 | this.gui = gui; |
| 16 | 16 | ||
| 17 | this.deobfClasses = new ClassSelector(gui, ClassSelector.DEOBF_CLASS_COMPARATOR, true); | 17 | this.deobfClasses = new ClassSelector(gui, ClassSelector.DEOBF_CLASS_COMPARATOR, true); |
| 18 | this.deobfClasses.setSelectionListener(gui::navigateTo); | 18 | this.deobfClasses.setSelectionListener(gui.getController()::navigateTo); |
| 19 | this.deobfClasses.setRenameSelectionListener(gui::onPanelRename); | 19 | this.deobfClasses.setRenameSelectionListener(gui::onPanelRename); |
| 20 | 20 | ||
| 21 | this.setLayout(new BorderLayout()); | 21 | this.setLayout(new BorderLayout()); |
diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java index f766743..f19d98f 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java | |||
| @@ -21,8 +21,19 @@ public class PanelEditor extends JEditorPane { | |||
| 21 | this.addMouseListener(new MouseAdapter() { | 21 | this.addMouseListener(new MouseAdapter() { |
| 22 | @Override | 22 | @Override |
| 23 | public void mouseReleased(MouseEvent e) { | 23 | public void mouseReleased(MouseEvent e) { |
| 24 | if (e.getButton() == MouseEvent.BUTTON3) | 24 | switch (e.getButton()) { |
| 25 | self.setCaretPosition(self.viewToModel(e.getPoint())); | 25 | case MouseEvent.BUTTON3: // Right click |
| 26 | self.setCaretPosition(self.viewToModel(e.getPoint())); | ||
| 27 | break; | ||
| 28 | |||
| 29 | case 4: // Back navigation | ||
| 30 | gui.getController().openPreviousReference(); | ||
| 31 | break; | ||
| 32 | |||
| 33 | case 5: // Forward navigation | ||
| 34 | gui.getController().openNextReference(); | ||
| 35 | break; | ||
| 36 | } | ||
| 26 | } | 37 | } |
| 27 | }); | 38 | }); |
| 28 | this.addKeyListener(new KeyAdapter() { | 39 | this.addKeyListener(new KeyAdapter() { |
| @@ -49,6 +60,10 @@ public class PanelEditor extends JEditorPane { | |||
| 49 | gui.popupMenu.openPreviousMenu.doClick(); | 60 | gui.popupMenu.openPreviousMenu.doClick(); |
| 50 | break; | 61 | break; |
| 51 | 62 | ||
| 63 | case KeyEvent.VK_E: | ||
| 64 | gui.popupMenu.openNextMenu.doClick(); | ||
| 65 | break; | ||
| 66 | |||
| 52 | case KeyEvent.VK_C: | 67 | case KeyEvent.VK_C: |
| 53 | gui.popupMenu.showCallsMenu.doClick(); | 68 | gui.popupMenu.showCallsMenu.doClick(); |
| 54 | break; | 69 | break; |
diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java index ccdc9f8..8ee564b 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java | |||
| @@ -26,7 +26,7 @@ public class PanelObf extends JPanel { | |||
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | this.obfClasses = new ClassSelector(gui, obfClassComparator, false); | 28 | this.obfClasses = new ClassSelector(gui, obfClassComparator, false); |
| 29 | this.obfClasses.setSelectionListener(gui::navigateTo); | 29 | this.obfClasses.setSelectionListener(gui.getController()::navigateTo); |
| 30 | this.obfClasses.setRenameSelectionListener(gui::onPanelRename); | 30 | this.obfClasses.setRenameSelectionListener(gui::onPanelRename); |
| 31 | 31 | ||
| 32 | this.setLayout(new BorderLayout()); | 32 | this.setLayout(new BorderLayout()); |
diff --git a/src/main/java/cuchaz/enigma/gui/util/History.java b/src/main/java/cuchaz/enigma/gui/util/History.java new file mode 100644 index 0000000..94f3105 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/util/History.java | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | package cuchaz.enigma.gui.util; | ||
| 2 | |||
| 3 | import com.google.common.collect.Queues; | ||
| 4 | |||
| 5 | import java.util.Deque; | ||
| 6 | |||
| 7 | public class History<T> { | ||
| 8 | private final Deque<T> previous = Queues.newArrayDeque(); | ||
| 9 | private final Deque<T> next = Queues.newArrayDeque(); | ||
| 10 | private T current; | ||
| 11 | |||
| 12 | public History(T initial) { | ||
| 13 | current = initial; | ||
| 14 | } | ||
| 15 | |||
| 16 | public T getCurrent() { | ||
| 17 | return current; | ||
| 18 | } | ||
| 19 | |||
| 20 | public void push(T value) { | ||
| 21 | previous.addLast(current); | ||
| 22 | current = value; | ||
| 23 | next.clear(); | ||
| 24 | } | ||
| 25 | |||
| 26 | public void replace(T value) { | ||
| 27 | current = value; | ||
| 28 | } | ||
| 29 | |||
| 30 | public boolean canGoBack() { | ||
| 31 | return !previous.isEmpty(); | ||
| 32 | } | ||
| 33 | |||
| 34 | public T goBack() { | ||
| 35 | next.addFirst(current); | ||
| 36 | current = previous.removeLast(); | ||
| 37 | return current; | ||
| 38 | } | ||
| 39 | |||
| 40 | public boolean canGoForward() { | ||
| 41 | return !next.isEmpty(); | ||
| 42 | } | ||
| 43 | |||
| 44 | public T goForward() { | ||
| 45 | previous.addLast(current); | ||
| 46 | current = next.removeFirst(); | ||
| 47 | return current; | ||
| 48 | } | ||
| 49 | } | ||