summaryrefslogtreecommitdiff
path: root/enigma-swing/src/main/java/cuchaz
diff options
context:
space:
mode:
authorGravatar Yanis482020-12-14 21:15:53 +0100
committerGravatar Yanis482020-12-14 21:15:53 +0100
commite16f81dba9edadb3fc02492bfeff06266890e754 (patch)
treefbc2389fbea75c110712c9ae982cfa5d5b957fee /enigma-swing/src/main/java/cuchaz
parentBump version (diff)
downloadenigma-e16f81dba9edadb3fc02492bfeff06266890e754.tar.gz
enigma-e16f81dba9edadb3fc02492bfeff06266890e754.tar.xz
enigma-e16f81dba9edadb3fc02492bfeff06266890e754.zip
Structure panel!
Diffstat (limited to 'enigma-swing/src/main/java/cuchaz')
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java56
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java12
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java102
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java31
4 files changed, 177 insertions, 24 deletions
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 c56731dc..a3a438ee 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -51,10 +51,7 @@ import cuchaz.enigma.network.packet.RemoveMappingC2SPacket;
51import cuchaz.enigma.network.packet.RenameC2SPacket; 51import cuchaz.enigma.network.packet.RenameC2SPacket;
52import cuchaz.enigma.source.Token; 52import cuchaz.enigma.source.Token;
53import cuchaz.enigma.translation.mapping.EntryRemapper; 53import cuchaz.enigma.translation.mapping.EntryRemapper;
54import cuchaz.enigma.translation.representation.entry.ClassEntry; 54import cuchaz.enigma.translation.representation.entry.*;
55import cuchaz.enigma.translation.representation.entry.Entry;
56import cuchaz.enigma.translation.representation.entry.FieldEntry;
57import cuchaz.enigma.translation.representation.entry.MethodEntry;
58import cuchaz.enigma.utils.I18n; 55import cuchaz.enigma.utils.I18n;
59import cuchaz.enigma.utils.validation.ParameterizedMessage; 56import cuchaz.enigma.utils.validation.ParameterizedMessage;
60import cuchaz.enigma.utils.validation.ValidationContext; 57import cuchaz.enigma.utils.validation.ValidationContext;
@@ -82,6 +79,7 @@ public class Gui implements LanguageChangeListener {
82 private JPanel classesPanel; 79 private JPanel classesPanel;
83 private JSplitPane splitClasses; 80 private JSplitPane splitClasses;
84 private IdentifierPanel infoPanel; 81 private IdentifierPanel infoPanel;
82 private StructurePanel structurePanel;
85 private JTree inheritanceTree; 83 private JTree inheritanceTree;
86 private JTree implementationsTree; 84 private JTree implementationsTree;
87 private JTree callsTree; 85 private JTree callsTree;
@@ -163,6 +161,9 @@ public class Gui implements LanguageChangeListener {
163 // init info panel 161 // init info panel
164 infoPanel = new IdentifierPanel(this); 162 infoPanel = new IdentifierPanel(this);
165 163
164 // init structure panel
165 this.structurePanel = new StructurePanel(this);
166
166 // init inheritance panel 167 // init inheritance panel
167 inheritanceTree = new JTree(); 168 inheritanceTree = new JTree();
168 inheritanceTree.setModel(null); 169 inheritanceTree.setModel(null);
@@ -287,6 +288,8 @@ public class Gui implements LanguageChangeListener {
287 editorTabPopupMenu.show(openFiles, e.getX(), e.getY(), EditorPanel.byUi(openFiles.getComponentAt(i))); 288 editorTabPopupMenu.show(openFiles, e.getX(), e.getY(), EditorPanel.byUi(openFiles.getComponentAt(i)));
288 } 289 }
289 } 290 }
291
292 showStructure(getActiveEditor());
290 } 293 }
291 }); 294 });
292 295
@@ -311,6 +314,7 @@ public class Gui implements LanguageChangeListener {
311 centerPanel.add(openFiles, BorderLayout.CENTER); 314 centerPanel.add(openFiles, BorderLayout.CENTER);
312 tabs = new JTabbedPane(); 315 tabs = new JTabbedPane();
313 tabs.setPreferredSize(ScaleUtil.getDimension(250, 0)); 316 tabs.setPreferredSize(ScaleUtil.getDimension(250, 0));
317 tabs.addTab(I18n.translate("info_panel.tree.structure"), structurePanel);
314 tabs.addTab(I18n.translate("info_panel.tree.inheritance"), inheritancePanel); 318 tabs.addTab(I18n.translate("info_panel.tree.inheritance"), inheritancePanel);
315 tabs.addTab(I18n.translate("info_panel.tree.implementations"), implementationsPanel); 319 tabs.addTab(I18n.translate("info_panel.tree.implementations"), implementationsPanel);
316 tabs.addTab(I18n.translate("info_panel.tree.calls"), callPanel); 320 tabs.addTab(I18n.translate("info_panel.tree.calls"), callPanel);
@@ -482,11 +486,14 @@ public class Gui implements LanguageChangeListener {
482 } 486 }
483 }); 487 });
484 488
489 showStructure(ed);
490
485 return ed; 491 return ed;
486 }); 492 });
487 if (editorPanel != null) { 493 if (editorPanel != null) {
488 openFiles.setSelectedComponent(editors.get(entry).getUi()); 494 openFiles.setSelectedComponent(editors.get(entry).getUi());
489 } 495 }
496
490 return editorPanel; 497 return editorPanel;
491 } 498 }
492 499
@@ -506,6 +513,7 @@ public class Gui implements LanguageChangeListener {
506 public void closeEditor(EditorPanel ed) { 513 public void closeEditor(EditorPanel ed) {
507 openFiles.remove(ed.getUi()); 514 openFiles.remove(ed.getUi());
508 editors.inverse().remove(ed); 515 editors.inverse().remove(ed);
516 showStructure(getActiveEditor());
509 ed.destroy(); 517 ed.destroy();
510 } 518 }
511 519
@@ -595,6 +603,32 @@ public class Gui implements LanguageChangeListener {
595 infoPanel.startRenaming(); 603 infoPanel.startRenaming();
596 } 604 }
597 605
606 public void showStructure(EditorPanel editor) {
607 JTree structureTree = this.structurePanel.getStructureTree();
608 structureTree.setModel(null);
609
610 if (editor == null) {
611 this.structurePanel.getSortingPanel().setVisible(false);
612 return;
613 }
614
615 ClassEntry classEntry = editor.getClassHandle().getRef();
616 if (classEntry == null) return;
617
618 this.structurePanel.getSortingPanel().setVisible(true);
619
620 // get the class structure
621 StructureTreeNode node = this.controller.getClassStructure(classEntry, this.structurePanel.shouldHideDeobfuscated());
622
623 // show the tree at the root
624 TreePath path = getPathToRoot(node);
625 structureTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0)));
626 structureTree.expandPath(path);
627 structureTree.setSelectionRow(structureTree.getRowForPath(path));
628
629 redraw();
630 }
631
598 public void showInheritance(EditorPanel editor) { 632 public void showInheritance(EditorPanel editor) {
599 EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); 633 EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference();
600 if (cursorReference == null) return; 634 if (cursorReference == null) return;
@@ -621,7 +655,7 @@ public class Gui implements LanguageChangeListener {
621 inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path)); 655 inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path));
622 } 656 }
623 657
624 tabs.setSelectedIndex(0); 658 tabs.setSelectedIndex(1);
625 659
626 redraw(); 660 redraw();
627 } 661 }
@@ -649,7 +683,7 @@ public class Gui implements LanguageChangeListener {
649 implementationsTree.setSelectionRow(implementationsTree.getRowForPath(path)); 683 implementationsTree.setSelectionRow(implementationsTree.getRowForPath(path));
650 } 684 }
651 685
652 tabs.setSelectedIndex(1); 686 tabs.setSelectedIndex(2);
653 687
654 redraw(); 688 redraw();
655 } 689 }
@@ -669,7 +703,7 @@ public class Gui implements LanguageChangeListener {
669 callsTree.setModel(new DefaultTreeModel(node)); 703 callsTree.setModel(new DefaultTreeModel(node));
670 } 704 }
671 705
672 tabs.setSelectedIndex(2); 706 tabs.setSelectedIndex(3);
673 707
674 redraw(); 708 redraw();
675 } 709 }
@@ -893,9 +927,10 @@ public class Gui implements LanguageChangeListener {
893 public void retranslateUi() { 927 public void retranslateUi() {
894 this.jarFileChooser.setTitle(I18n.translate("menu.file.jar.open")); 928 this.jarFileChooser.setTitle(I18n.translate("menu.file.jar.open"));
895 this.exportJarFileChooser.setTitle(I18n.translate("menu.file.export.jar")); 929 this.exportJarFileChooser.setTitle(I18n.translate("menu.file.export.jar"));
896 this.tabs.setTitleAt(0, I18n.translate("info_panel.tree.inheritance")); 930 this.tabs.setTitleAt(0, I18n.translate("info_panel.tree.structure"));
897 this.tabs.setTitleAt(1, I18n.translate("info_panel.tree.implementations")); 931 this.tabs.setTitleAt(1, I18n.translate("info_panel.tree.inheritance"));
898 this.tabs.setTitleAt(2, I18n.translate("info_panel.tree.calls")); 932 this.tabs.setTitleAt(2, I18n.translate("info_panel.tree.implementations"));
933 this.tabs.setTitleAt(3, I18n.translate("info_panel.tree.calls"));
899 this.logTabs.setTitleAt(0, I18n.translate("log_panel.users")); 934 this.logTabs.setTitleAt(0, I18n.translate("log_panel.users"));
900 this.logTabs.setTitleAt(1, I18n.translate("log_panel.messages")); 935 this.logTabs.setTitleAt(1, I18n.translate("log_panel.messages"));
901 this.connectionStatusLabel.setText(I18n.translate(connectionState == ConnectionState.NOT_CONNECTED ? "status.disconnected" : "status.connected")); 936 this.connectionStatusLabel.setText(I18n.translate(connectionState == ConnectionState.NOT_CONNECTED ? "status.disconnected" : "status.connected"));
@@ -907,6 +942,7 @@ public class Gui implements LanguageChangeListener {
907 this.deobfPanel.retranslateUi(); 942 this.deobfPanel.retranslateUi();
908 this.deobfPanelPopupMenu.retranslateUi(); 943 this.deobfPanelPopupMenu.retranslateUi();
909 this.infoPanel.retranslateUi(); 944 this.infoPanel.retranslateUi();
945 this.structurePanel.retranslateUi();
910 this.editors.values().forEach(EditorPanel::retranslateUi); 946 this.editors.values().forEach(EditorPanel::retranslateUi);
911 } 947 }
912 948
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
index 4f7819e4..4e964dae 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -57,10 +57,7 @@ import cuchaz.enigma.translation.mapping.serde.MappingParseException;
57import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 57import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
58import cuchaz.enigma.translation.mapping.tree.EntryTree; 58import cuchaz.enigma.translation.mapping.tree.EntryTree;
59import cuchaz.enigma.translation.mapping.tree.HashEntryTree; 59import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
60import cuchaz.enigma.translation.representation.entry.ClassEntry; 60import cuchaz.enigma.translation.representation.entry.*;
61import cuchaz.enigma.translation.representation.entry.Entry;
62import cuchaz.enigma.translation.representation.entry.FieldEntry;
63import cuchaz.enigma.translation.representation.entry.MethodEntry;
64import cuchaz.enigma.utils.I18n; 61import cuchaz.enigma.utils.I18n;
65import cuchaz.enigma.utils.Utils; 62import cuchaz.enigma.utils.Utils;
66import cuchaz.enigma.utils.validation.ValidationContext; 63import cuchaz.enigma.utils.validation.ValidationContext;
@@ -395,6 +392,13 @@ public class GuiController implements ClientPacketHandler {
395 chp.invalidateMapped(); 392 chp.invalidateMapped();
396 } 393 }
397 394
395 public StructureTreeNode getClassStructure(ClassEntry entry, boolean hideDeobfuscated) {
396 Translator translator = this.project.getMapper().getDeobfuscator();
397 StructureTreeNode rootNode = new StructureTreeNode(translator, entry, entry);
398 rootNode.load(this.project.getJarIndex(), hideDeobfuscated);
399 return rootNode;
400 }
401
398 public ClassInheritanceTreeNode getClassInheritance(ClassEntry entry) { 402 public ClassInheritanceTreeNode getClassInheritance(ClassEntry entry) {
399 Translator translator = project.getMapper().getDeobfuscator(); 403 Translator translator = project.getMapper().getDeobfuscator();
400 ClassInheritanceTreeNode rootNode = indexTreeBuilder.buildClassInheritance(translator, entry); 404 ClassInheritanceTreeNode rootNode = indexTreeBuilder.buildClassInheritance(translator, entry);
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java
new file mode 100644
index 00000000..32f803f8
--- /dev/null
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java
@@ -0,0 +1,102 @@
1package cuchaz.enigma.gui.panels;
2
3import cuchaz.enigma.analysis.StructureTreeNode;
4import cuchaz.enigma.gui.Gui;
5import cuchaz.enigma.gui.util.GuiUtil;
6import cuchaz.enigma.translation.representation.entry.ClassEntry;
7import cuchaz.enigma.translation.representation.entry.FieldEntry;
8import cuchaz.enigma.translation.representation.entry.MethodEntry;
9import cuchaz.enigma.translation.representation.entry.ParentedEntry;
10import cuchaz.enigma.utils.I18n;
11
12import javax.swing.*;
13import javax.swing.tree.TreeCellRenderer;
14import javax.swing.tree.TreePath;
15import java.awt.*;
16import java.awt.event.MouseAdapter;
17import java.awt.event.MouseEvent;
18
19public class StructurePanel extends JPanel {
20 private final Gui gui;
21
22 private JPanel sortingPanel;
23 private JCheckBox hideDeobfuscated;
24
25 private JTree structureTree;
26
27 public StructurePanel(Gui gui) {
28 this.gui = gui;
29
30 this.sortingPanel = new JPanel();
31 this.hideDeobfuscated = new JCheckBox(I18n.translate("info_panel.tree.structure.hide_deobfuscated"));
32 this.hideDeobfuscated.addActionListener(event -> gui.showStructure(gui.getActiveEditor()));
33 this.sortingPanel.add(this.hideDeobfuscated);
34 this.sortingPanel.setVisible(false);
35
36 this.structureTree = new JTree();
37 this.structureTree.setModel(null);
38 this.structureTree.setCellRenderer(new StructureTreeCellRenderer());
39 this.structureTree.addMouseListener(new MouseAdapter() {
40 @Override
41 public void mouseClicked(MouseEvent event) {
42 if (event.getClickCount() >= 2) {
43 // get the selected node
44 TreePath path = structureTree.getSelectionPath();
45 if (path == null) {
46 return;
47 }
48
49 Object node = path.getLastPathComponent();
50 if (node instanceof StructureTreeNode) {
51 gui.getController().navigateTo(((StructureTreeNode) node).getEntry());
52 }
53 }
54 }
55 });
56
57 this.setLayout(new BorderLayout());
58 this.add(this.sortingPanel, BorderLayout.NORTH);
59 this.add(new JScrollPane(this.structureTree));
60 }
61
62 public JPanel getSortingPanel() {
63 return this.sortingPanel;
64 }
65
66 public boolean shouldHideDeobfuscated() {
67 return this.hideDeobfuscated.isSelected();
68 }
69
70 public JTree getStructureTree() {
71 return this.structureTree;
72 }
73
74 public void retranslateUi() {
75 this.hideDeobfuscated.setText(I18n.translate("info_panel.tree.structure.hide_deobfuscated"));
76 }
77
78 class StructureTreeCellRenderer implements TreeCellRenderer {
79 private JLabel label;
80
81 public StructureTreeCellRenderer() {
82 this.label = new JLabel();
83 }
84
85 @Override
86 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
87 ParentedEntry entry = ((StructureTreeNode) value).getEntry();
88
89 if (entry instanceof ClassEntry) {
90 this.label.setIcon(GuiUtil.CLASS_ICON);
91 } else if (entry instanceof MethodEntry) {
92 this.label.setIcon(GuiUtil.METHOD_ICON);
93 } else if (entry instanceof FieldEntry) {
94 this.label.setIcon(GuiUtil.FIELD_ICON);
95 }
96
97 this.label.setText(value.toString());
98
99 return this.label;
100 }
101 }
102}
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java
index 7fe942d0..666fc0aa 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java
@@ -1,24 +1,24 @@
1package cuchaz.enigma.gui.util; 1package cuchaz.enigma.gui.util;
2 2
3import java.awt.Color; 3import cuchaz.enigma.utils.Os;
4import java.awt.Cursor; 4
5import java.awt.Desktop; 5import javax.imageio.ImageIO;
6import java.awt.Font; 6import javax.swing.*;
7import java.awt.*;
7import java.awt.event.MouseAdapter; 8import java.awt.event.MouseAdapter;
8import java.awt.event.MouseEvent; 9import java.awt.event.MouseEvent;
9import java.awt.font.TextAttribute; 10import java.awt.font.TextAttribute;
10import java.io.IOException; 11import java.io.IOException;
12import java.io.InputStream;
11import java.net.URI; 13import java.net.URI;
12import java.net.URISyntaxException; 14import java.net.URISyntaxException;
13import java.util.Map; 15import java.util.Map;
14 16
15import javax.swing.JComponent;
16import javax.swing.JLabel;
17import javax.swing.ToolTipManager;
18
19import cuchaz.enigma.utils.Os;
20
21public class GuiUtil { 17public class GuiUtil {
18 public static final Icon CLASS_ICON = loadIcon("class");
19 public static final Icon METHOD_ICON = loadIcon("method");
20 public static final Icon FIELD_ICON = loadIcon("field");
21
22 public static void openUrl(String url) { 22 public static void openUrl(String url) {
23 try { 23 try {
24 switch (Os.getOs()) { 24 switch (Os.getOs()) {
@@ -70,4 +70,15 @@ public class GuiUtil {
70 return link; 70 return link;
71 } 71 }
72 72
73 public static Icon loadIcon(String name) {
74 try {
75 InputStream inputStream = GuiUtil.class.getResourceAsStream("/icons/" + name + ".png");
76 Image image = ImageIO.read(inputStream).getScaledInstance(ScaleUtil.scale(16), ScaleUtil.scale(16), Image.SCALE_DEFAULT);
77 return new ImageIcon(image);
78 } catch (IOException e) {
79 e.printStackTrace();
80 }
81
82 return null;
83 }
73} 84}