From 59e189bef2b5e6d129fb7c2c988ed0b2130e36ac Mon Sep 17 00:00:00 2001 From: lclc98 Date: Mon, 4 Jul 2016 18:14:22 +1000 Subject: Reformat --- .../cuchaz/enigma/gui/BoxHighlightPainter.java | 64 --- src/main/java/cuchaz/enigma/gui/BrowserCaret.java | 2 - .../java/cuchaz/enigma/gui/ClassMatchingGui.java | 521 --------------------- src/main/java/cuchaz/enigma/gui/ClassSelector.java | 143 ++---- .../cuchaz/enigma/gui/ClassSelectorClassNode.java | 47 -- .../enigma/gui/ClassSelectorPackageNode.java | 42 -- src/main/java/cuchaz/enigma/gui/CodeReader.java | 202 -------- .../enigma/gui/DeobfuscatedHighlightPainter.java | 20 - src/main/java/cuchaz/enigma/gui/Gui.java | 20 +- src/main/java/cuchaz/enigma/gui/GuiController.java | 4 +- src/main/java/cuchaz/enigma/gui/GuiTricks.java | 52 -- .../java/cuchaz/enigma/gui/MemberMatchingGui.java | 442 ----------------- .../enigma/gui/ObfuscatedHighlightPainter.java | 20 - .../cuchaz/enigma/gui/OtherHighlightPainter.java | 20 - src/main/java/cuchaz/enigma/gui/ReadableToken.java | 36 -- .../java/cuchaz/enigma/gui/ScoredClassEntry.java | 29 -- .../enigma/gui/SelectionHighlightPainter.java | 29 -- .../java/cuchaz/enigma/gui/dialog/AboutDialog.java | 6 +- .../java/cuchaz/enigma/gui/dialog/CrashDialog.java | 4 +- .../cuchaz/enigma/gui/dialog/ProgressDialog.java | 4 +- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 4 +- .../enigma/gui/filechooser/FileChooserFolder.java | 2 +- .../enigma/gui/highlight/BoxHighlightPainter.java | 64 +++ .../highlight/DeobfuscatedHighlightPainter.java | 20 + .../gui/highlight/ObfuscatedHighlightPainter.java | 20 + .../gui/highlight/OtherHighlightPainter.java | 20 + .../gui/highlight/SelectionHighlightPainter.java | 29 ++ .../enigma/gui/node/ClassSelectorClassNode.java | 42 ++ .../enigma/gui/node/ClassSelectorPackageNode.java | 36 ++ .../java/cuchaz/enigma/gui/panels/PanelDeobf.java | 1 - .../cuchaz/enigma/gui/panels/PanelIdentifier.java | 4 +- .../java/cuchaz/enigma/gui/panels/PanelObf.java | 2 +- 32 files changed, 289 insertions(+), 1662 deletions(-) delete mode 100644 src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java delete mode 100644 src/main/java/cuchaz/enigma/gui/CodeReader.java delete mode 100644 src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java delete mode 100644 src/main/java/cuchaz/enigma/gui/GuiTricks.java delete mode 100644 src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java delete mode 100644 src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ReadableToken.java delete mode 100644 src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java delete mode 100644 src/main/java/cuchaz/enigma/gui/SelectionHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/highlight/DeobfuscatedHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/highlight/ObfuscatedHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/highlight/OtherHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java create mode 100644 src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java create mode 100644 src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java (limited to 'src/main/java/cuchaz/enigma/gui') diff --git a/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java deleted file mode 100644 index b66d13d..0000000 --- a/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.Shape; - -import javax.swing.text.BadLocationException; -import javax.swing.text.Highlighter; -import javax.swing.text.JTextComponent; - -public abstract class BoxHighlightPainter implements Highlighter.HighlightPainter { - - private Color fillColor; - private Color borderColor; - - protected BoxHighlightPainter(Color fillColor, Color borderColor) { - this.fillColor = fillColor; - this.borderColor = borderColor; - } - - @Override - public void paint(Graphics g, int start, int end, Shape shape, JTextComponent text) { - Rectangle bounds = getBounds(text, start, end); - - // fill the area - if (this.fillColor != null) { - g.setColor(this.fillColor); - g.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); - } - - // draw a box around the area - g.setColor(this.borderColor); - g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); - } - - public static Rectangle getBounds(JTextComponent text, int start, int end) { - try { - // determine the bounds of the text - Rectangle bounds = text.modelToView(start).union(text.modelToView(end)); - - // adjust the box so it looks nice - bounds.x -= 2; - bounds.width += 2; - bounds.y += 1; - bounds.height -= 2; - - return bounds; - } catch (BadLocationException ex) { - // don't care... just return something - return new Rectangle(0, 0, 0, 0); - } - } -} diff --git a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java index a75db36..f58d012 100644 --- a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java +++ b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java @@ -15,8 +15,6 @@ import javax.swing.text.Highlighter; public class BrowserCaret extends DefaultCaret { - private static final long serialVersionUID = 1158977422507969940L; - private static final Highlighter.HighlightPainter selectionPainter = (g, p0, p1, bounds, c) -> { }; diff --git a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java deleted file mode 100644 index e813688..0000000 --- a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java +++ /dev/null @@ -1,521 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import com.google.common.collect.BiMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionListener; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import javax.swing.*; - -import cuchaz.enigma.Constants; -import cuchaz.enigma.Deobfuscator; -import cuchaz.enigma.convert.*; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.Mappings; -import cuchaz.enigma.mapping.MappingsChecker; -import de.sciss.syntaxpane.DefaultSyntaxKit; - - -public class ClassMatchingGui { - - private enum SourceType { - Matched { - @Override - public Collection getSourceClasses(ClassMatches matches) { - return matches.getUniqueMatches().keySet(); - } - }, - Unmatched { - @Override - public Collection getSourceClasses(ClassMatches matches) { - return matches.getUnmatchedSourceClasses(); - } - }, - Ambiguous { - @Override - public Collection getSourceClasses(ClassMatches matches) { - return matches.getAmbiguouslyMatchedSourceClasses(); - } - }; - - public JRadioButton newRadio(ActionListener listener, ButtonGroup group) { - JRadioButton button = new JRadioButton(name(), this == getDefault()); - button.setActionCommand(name()); - button.addActionListener(listener); - group.add(button); - return button; - } - - public abstract Collection getSourceClasses(ClassMatches matches); - - public static SourceType getDefault() { - return values()[0]; - } - } - - public interface SaveListener { - void save(ClassMatches matches); - } - - // controls - private JFrame frame; - private ClassSelector sourceClasses; - private ClassSelector destClasses; - private CodeReader sourceReader; - private CodeReader destReader; - private JLabel sourceClassLabel; - private JLabel destClassLabel; - private JButton matchButton; - private Map sourceTypeButtons; - private JCheckBox advanceCheck; - private JCheckBox top10Matches; - - private ClassMatches classMatches; - private Deobfuscator sourceDeobfuscator; - private Deobfuscator destDeobfuscator; - private ClassEntry sourceClass; - private ClassEntry destClass; - private SourceType sourceType; - private SaveListener saveListener; - - public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { - - this.classMatches = matches; - this.sourceDeobfuscator = sourceDeobfuscator; - this.destDeobfuscator = destDeobfuscator; - - // init frame - this.frame = new JFrame(Constants.NAME + " - Class Matcher"); - final Container pane = this.frame.getContentPane(); - pane.setLayout(new BorderLayout()); - - // init source side - JPanel sourcePanel = new JPanel(); - sourcePanel.setLayout(new BoxLayout(sourcePanel, BoxLayout.PAGE_AXIS)); - sourcePanel.setPreferredSize(new Dimension(200, 0)); - pane.add(sourcePanel, BorderLayout.WEST); - sourcePanel.add(new JLabel("Source Classes")); - - // init source type radios - JPanel sourceTypePanel = new JPanel(); - sourcePanel.add(sourceTypePanel); - sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); - ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); - ButtonGroup sourceTypeButtons = new ButtonGroup(); - this.sourceTypeButtons = Maps.newHashMap(); - for (SourceType sourceType : SourceType.values()) { - JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); - this.sourceTypeButtons.put(sourceType, button); - sourceTypePanel.add(button); - } - - this.sourceClasses = new ClassSelector(ClassSelector.DEOBF_CLASS_COMPARATOR); - this.sourceClasses.setListener(this::setSourceClass); - JScrollPane sourceScroller = new JScrollPane(this.sourceClasses); - sourcePanel.add(sourceScroller); - - // init dest side - JPanel destPanel = new JPanel(); - destPanel.setLayout(new BoxLayout(destPanel, BoxLayout.PAGE_AXIS)); - destPanel.setPreferredSize(new Dimension(200, 0)); - pane.add(destPanel, BorderLayout.WEST); - destPanel.add(new JLabel("Destination Classes")); - - this.top10Matches = new JCheckBox("Show only top 10 matches"); - destPanel.add(this.top10Matches); - this.top10Matches.addActionListener(event -> toggleTop10Matches()); - - this.destClasses = new ClassSelector(ClassSelector.DEOBF_CLASS_COMPARATOR); - this.destClasses.setListener(this::setDestClass); - JScrollPane destScroller = new JScrollPane(this.destClasses); - destPanel.add(destScroller); - - JButton autoMatchButton = new JButton("AutoMatch"); - autoMatchButton.addActionListener(event -> autoMatch()); - destPanel.add(autoMatchButton); - - // init source panels - DefaultSyntaxKit.initKit(); - this.sourceReader = new CodeReader(); - this.destReader = new CodeReader(); - - // init all the splits - JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(this.sourceReader)); - splitLeft.setResizeWeight(0); // let the right side take all the slack - JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(this.destReader), destPanel); - splitRight.setResizeWeight(1); // let the left side take all the slack - JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight); - splitCenter.setResizeWeight(0.5); // resize 50:50 - pane.add(splitCenter, BorderLayout.CENTER); - splitCenter.resetToPreferredSizes(); - - // init bottom panel - JPanel bottomPanel = new JPanel(); - bottomPanel.setLayout(new FlowLayout()); - - this.sourceClassLabel = new JLabel(); - this.sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); - this.destClassLabel = new JLabel(); - this.destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); - - this.matchButton = new JButton(); - - this.advanceCheck = new JCheckBox("Advance to next likely match"); - this.advanceCheck.addActionListener(event -> { - if (this.advanceCheck.isSelected()) { - advance(); - } - }); - - bottomPanel.add(this.sourceClassLabel); - bottomPanel.add(this.matchButton); - bottomPanel.add(this.destClassLabel); - bottomPanel.add(this.advanceCheck); - pane.add(bottomPanel, BorderLayout.SOUTH); - - // show the frame - pane.doLayout(); - this.frame.setSize(1024, 576); - this.frame.setMinimumSize(new Dimension(640, 480)); - this.frame.setVisible(true); - this.frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - - // init state - updateDestMappings(); - setSourceType(SourceType.getDefault()); - updateMatchButton(); - this.saveListener = null; - } - - public void setSaveListener(SaveListener val) { - this.saveListener = val; - } - - private void updateDestMappings() { - - Mappings newMappings = MappingsConverter.newMappings(this.classMatches, this.sourceDeobfuscator.getMappings(), this.sourceDeobfuscator, this.destDeobfuscator); - - // look for dropped mappings - MappingsChecker checker = new MappingsChecker(this.destDeobfuscator.getJarIndex()); - checker.dropBrokenMappings(newMappings); - - // count them - int numDroppedFields = checker.getDroppedFieldMappings().size(); - int numDroppedMethods = checker.getDroppedMethodMappings().size(); - System.out.println(String.format("%d mappings from matched classes don't match the dest jar:\n\t%5d fields\n\t%5d methods", - numDroppedFields + numDroppedMethods, - numDroppedFields, - numDroppedMethods - )); - - this.destDeobfuscator.setMappings(newMappings); - } - - protected void setSourceType(SourceType val) { - - // show the source classes - this.sourceType = val; - this.sourceClasses.setClasses(deobfuscateClasses(this.sourceType.getSourceClasses(this.classMatches), this.sourceDeobfuscator)); - - // update counts - for (SourceType sourceType : SourceType.values()) { - this.sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", - sourceType.name(), - sourceType.getSourceClasses(this.classMatches).size() - )); - } - } - - private Collection deobfuscateClasses(Collection in, Deobfuscator deobfuscator) { - List out = Lists.newArrayList(); - for (ClassEntry entry : in) { - - ClassEntry deobf = deobfuscator.deobfuscateEntry(entry); - - // make sure we preserve any scores - if (entry instanceof ScoredClassEntry) { - deobf = new ScoredClassEntry(deobf, ((ScoredClassEntry) entry).getScore()); - } - - out.add(deobf); - } - return out; - } - - protected void setSourceClass(ClassEntry classEntry) { - - Runnable onGetDestClasses = null; - if (this.advanceCheck.isSelected()) { - onGetDestClasses = this::pickBestDestClass; - } - - setSourceClass(classEntry, onGetDestClasses); - } - - protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) { - - // update the current source class - this.sourceClass = classEntry; - this.sourceClassLabel.setText(this.sourceClass != null ? this.sourceClass.getName() : ""); - - if (this.sourceClass != null) { - - // show the dest class(es) - ClassMatch match = this.classMatches.getMatchBySource(this.sourceDeobfuscator.obfuscateEntry(this.sourceClass)); - assert (match != null); - if (match.destClasses.isEmpty()) { - - this.destClasses.setClasses(null); - - // run in a separate thread to keep ui responsive - new Thread() { - @Override - public void run() { - destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator)); - destClasses.expandAll(); - - if (onGetDestClasses != null) { - onGetDestClasses.run(); - } - } - }.start(); - - } else { - - this.destClasses.setClasses(deobfuscateClasses(match.destClasses, this.destDeobfuscator)); - this.destClasses.expandAll(); - - if (onGetDestClasses != null) { - onGetDestClasses.run(); - } - } - } - - setDestClass(null); - this.sourceReader.decompileClass(this.sourceClass, this.sourceDeobfuscator, () -> this.sourceReader.navigateToClassDeclaration(this.sourceClass)); - - updateMatchButton(); - } - - private Collection getLikelyMatches(ClassEntry sourceClass) { - - ClassEntry obfSourceClass = this.sourceDeobfuscator.obfuscateEntry(sourceClass); - - // set up identifiers - ClassNamer namer = new ClassNamer(this.classMatches.getUniqueMatches()); - ClassIdentifier sourceIdentifier = new ClassIdentifier(this.sourceDeobfuscator.getJar(), this.sourceDeobfuscator.getJarIndex(), namer.getSourceNamer(), true); - ClassIdentifier destIdentifier = new ClassIdentifier(this.destDeobfuscator.getJar(), this.destDeobfuscator.getJarIndex(), namer.getDestNamer(), true); - - try { - - // rank all the unmatched dest classes against the source class - ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); - List scoredDestClasses = Lists.newArrayList(); - for (ClassEntry unmatchedDestClass : this.classMatches.getUnmatchedDestClasses()) { - ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); - float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) - / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); - scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score)); - } - - if (this.top10Matches.isSelected() && scoredDestClasses.size() > 10) { - Collections.sort(scoredDestClasses, (a, b) -> { - ScoredClassEntry sa = (ScoredClassEntry) a; - ScoredClassEntry sb = (ScoredClassEntry) b; - return -Float.compare(sa.getScore(), sb.getScore()); - }); - scoredDestClasses = scoredDestClasses.subList(0, 10); - } - - return scoredDestClasses; - - } catch (ClassNotFoundException ex) { - throw new Error("Unable to find class " + ex.getMessage()); - } - } - - protected void setDestClass(ClassEntry classEntry) { - - // update the current source class - this.destClass = classEntry; - this.destClassLabel.setText(this.destClass != null ? this.destClass.getName() : ""); - - this.destReader.decompileClass(this.destClass, this.destDeobfuscator, () -> this.destReader.navigateToClassDeclaration(this.destClass)); - - updateMatchButton(); - } - - private void updateMatchButton() { - - ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass); - ClassEntry obfDest = this.destDeobfuscator.obfuscateEntry(this.destClass); - - BiMap uniqueMatches = this.classMatches.getUniqueMatches(); - boolean twoSelected = this.sourceClass != null && this.destClass != null; - boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); - boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest); - - GuiTricks.deactivateButton(this.matchButton); - if (twoSelected) { - if (isMatched) { - GuiTricks.activateButton(this.matchButton, "Unmatch", event -> onUnmatchClick()); - } else if (canMatch) { - GuiTricks.activateButton(this.matchButton, "Match", event -> onMatchClick()); - } - } - } - - private void onMatchClick() { - // precondition: source and dest classes are set correctly - - ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass); - ClassEntry obfDest = this.destDeobfuscator.obfuscateEntry(this.destClass); - - // remove the classes from their match - this.classMatches.removeSource(obfSource); - this.classMatches.removeDest(obfDest); - - // add them as matched classes - this.classMatches.add(new ClassMatch(obfSource, obfDest)); - - ClassEntry nextClass = null; - if (this.advanceCheck.isSelected()) { - nextClass = this.sourceClasses.getNextClass(this.sourceClass); - } - - save(); - updateMatches(); - - if (nextClass != null) { - advance(nextClass); - } - } - - private void onUnmatchClick() { - // precondition: source and dest classes are set to a unique match - - ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass); - - // remove the source to break the match, then add the source back as unmatched - this.classMatches.removeSource(obfSource); - this.classMatches.add(new ClassMatch(obfSource, null)); - - save(); - updateMatches(); - } - - private void updateMatches() { - updateDestMappings(); - setDestClass(null); - this.destClasses.setClasses(null); - updateMatchButton(); - - // remember where we were in the source tree - String packageName = this.sourceClasses.getSelectedPackage(); - - setSourceType(this.sourceType); - - this.sourceClasses.expandPackage(packageName); - } - - private void save() { - if (this.saveListener != null) { - this.saveListener.save(this.classMatches); - } - } - - private void autoMatch() { - - System.out.println("Automatching..."); - - // compute a new matching - ClassMatching matching = MappingsConverter.computeMatching(this.sourceDeobfuscator.getJar(), this.sourceDeobfuscator.getJarIndex(), - this.destDeobfuscator.getJar(), this.destDeobfuscator.getJarIndex(), this.classMatches.getUniqueMatches()); - ClassMatches newMatches = new ClassMatches(matching.matches()); - System.out.println(String.format("Automatch found %d new matches", newMatches.getUniqueMatches().size() - this.classMatches.getUniqueMatches().size())); - - // update the current matches - this.classMatches = newMatches; - save(); - updateMatches(); - } - - private void advance() { - advance(null); - } - - private void advance(ClassEntry sourceClass) { - - // make sure we have a source class - if (sourceClass == null) { - sourceClass = this.sourceClasses.getSelectedClass(); - if (sourceClass != null) { - sourceClass = this.sourceClasses.getNextClass(sourceClass); - } else { - sourceClass = this.sourceClasses.getFirstClass(); - } - } - - // set the source class - setSourceClass(sourceClass, this::pickBestDestClass); - this.sourceClasses.setSelectionClass(sourceClass); - } - - private void pickBestDestClass() { - - // then, pick the best dest class - ClassEntry firstClass = null; - ScoredClassEntry bestDestClass = null; - for (ClassSelectorPackageNode packageNode : this.destClasses.packageNodes()) { - for (ClassSelectorClassNode classNode : this.destClasses.classNodes(packageNode)) { - if (firstClass == null) { - firstClass = classNode.getClassEntry(); - } - if (classNode.getClassEntry() instanceof ScoredClassEntry) { - ScoredClassEntry scoredClass = (ScoredClassEntry) classNode.getClassEntry(); - if (bestDestClass == null || bestDestClass.getScore() < scoredClass.getScore()) { - bestDestClass = scoredClass; - } - } - } - } - - // pick the entry to show - ClassEntry destClass = null; - if (bestDestClass != null) { - destClass = bestDestClass; - } else if (firstClass != null) { - destClass = firstClass; - } - - setDestClass(destClass); - this.destClasses.setSelectionClass(destClass); - } - - private void toggleTop10Matches() { - if (this.sourceClass != null) { - this.destClasses.clearSelection(); - this.destClasses.setClasses(deobfuscateClasses(getLikelyMatches(this.sourceClass), this.destDeobfuscator)); - this.destClasses.expandAll(); - } - } -} diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelector.java b/src/main/java/cuchaz/enigma/gui/ClassSelector.java index 2ee3b2a..27b4d36 100644 --- a/src/main/java/cuchaz/enigma/gui/ClassSelector.java +++ b/src/main/java/cuchaz/enigma/gui/ClassSelector.java @@ -24,17 +24,13 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; +import cuchaz.enigma.gui.node.ClassSelectorClassNode; +import cuchaz.enigma.gui.node.ClassSelectorPackageNode; import cuchaz.enigma.mapping.ClassEntry; public class ClassSelector extends JTree { - private static final long serialVersionUID = -7632046902384775977L; - public static final Comparator DEOBF_CLASS_COMPARATOR = (a, b) -> { - if (a instanceof ScoredClassEntry && b instanceof ScoredClassEntry) { - return Float.compare(((ScoredClassEntry) b).getScore(), ((ScoredClassEntry) a).getScore()); - } - return a.getName().compareTo(b.getName()); - }; + public static final Comparator DEOBF_CLASS_COMPARATOR = (a, b) -> a.getName().compareTo(b.getName()); public interface ClassSelectionListener { void onSelectClass(ClassEntry classEntry); @@ -75,6 +71,7 @@ public class ClassSelector extends JTree { } public void setClasses(Collection classEntries) { + String state = getExpansionState(this, 0); if (classEntries == null) { setModel(null); return; @@ -137,125 +134,45 @@ public class ClassSelector extends JTree { // finally, update the tree control setModel(new DefaultTreeModel(root)); - } - - public ClassEntry getSelectedClass() { - if (!isSelectionEmpty()) { - Object selectedNode = getSelectionPath().getLastPathComponent(); - if (selectedNode instanceof ClassSelectorClassNode) { - ClassSelectorClassNode classNode = (ClassSelectorClassNode) selectedNode; - return classNode.getClassEntry(); - } - } - return null; - } - - public String getSelectedPackage() { - if (!isSelectionEmpty()) { - Object selectedNode = getSelectionPath().getLastPathComponent(); - if (selectedNode instanceof ClassSelectorPackageNode) { - ClassSelectorPackageNode packageNode = (ClassSelectorPackageNode) selectedNode; - return packageNode.getPackageName(); - } else if (selectedNode instanceof ClassSelectorClassNode) { - ClassSelectorClassNode classNode = (ClassSelectorClassNode) selectedNode; - return classNode.getClassEntry().getPackageName(); - } - } - return null; - } - - public Iterable packageNodes() { - List nodes = Lists.newArrayList(); - DefaultMutableTreeNode root = (DefaultMutableTreeNode) getModel().getRoot(); - Enumeration children = root.children(); - while (children.hasMoreElements()) { - ClassSelectorPackageNode packageNode = (ClassSelectorPackageNode) children.nextElement(); - nodes.add(packageNode); - } - return nodes; - } - public Iterable classNodes(ClassSelectorPackageNode packageNode) { - List nodes = Lists.newArrayList(); - Enumeration children = packageNode.children(); - while (children.hasMoreElements()) { - ClassSelectorClassNode classNode = (ClassSelectorClassNode) children.nextElement(); - nodes.add(classNode); - } - return nodes; + restoreExpanstionState(this, 0, state); } - public void expandPackage(String packageName) { - if (packageName == null) { - return; + public boolean isDescendant(TreePath path1, TreePath path2) { + int count1 = path1.getPathCount(); + int count2 = path2.getPathCount(); + if (count1 <= count2) { + return false; } - for (ClassSelectorPackageNode packageNode : packageNodes()) { - if (packageNode.getPackageName().equals(packageName)) { - expandPath(new TreePath(new Object[]{getModel().getRoot(), packageNode})); - return; - } + while (count1 != count2) { + path1 = path1.getParentPath(); + count1--; } + return path1.equals(path2); } - public void expandAll() { - for (ClassSelectorPackageNode packageNode : packageNodes()) { - expandPath(new TreePath(new Object[]{getModel().getRoot(), packageNode})); - } - } - - public ClassEntry getFirstClass() { - for (ClassSelectorPackageNode packageNode : packageNodes()) { - for (ClassSelectorClassNode classNode : classNodes(packageNode)) { - return classNode.getClassEntry(); - } - } - return null; - } - - public ClassSelectorPackageNode getPackageNode(ClassEntry entry) { - for (ClassSelectorPackageNode packageNode : packageNodes()) { - if (packageNode.getPackageName().equals(entry.getPackageName())) { - return packageNode; - } - } - return null; - } - - public ClassEntry getNextClass(ClassEntry entry) { - boolean foundIt = false; - for (ClassSelectorPackageNode packageNode : packageNodes()) { - if (!foundIt) { - // skip to the package with our target in it - if (packageNode.getPackageName().equals(entry.getPackageName())) { - for (ClassSelectorClassNode classNode : classNodes(packageNode)) { - if (!foundIt) { - if (classNode.getClassEntry().equals(entry)) { - foundIt = true; - } - } else { - // return the next class - return classNode.getClassEntry(); - } - } + public String getExpansionState(JTree tree, int row) { + TreePath rowPath = tree.getPathForRow(row); + StringBuffer buf = new StringBuffer(); + int rowCount = tree.getRowCount(); + for (int i = row; i < rowCount; i++) { + TreePath path = tree.getPathForRow(i); + if (i == row || isDescendant(path, rowPath)) { + if (tree.isExpanded(path)) { + buf.append("," + String.valueOf(i - row)); } } else { - // return the next class - for (ClassSelectorClassNode classNode : classNodes(packageNode)) { - return classNode.getClassEntry(); - } + break; } } - return null; + return buf.toString(); } - public void setSelectionClass(ClassEntry classEntry) { - expandPackage(classEntry.getPackageName()); - for (ClassSelectorPackageNode packageNode : packageNodes()) { - for (ClassSelectorClassNode classNode : classNodes(packageNode)) { - if (classNode.getClassEntry().equals(classEntry)) { - setSelectionPath(new TreePath(new Object[]{getModel().getRoot(), packageNode, classNode})); - } - } + public void restoreExpanstionState(JTree tree, int row, String expansionState) { + StringTokenizer stok = new StringTokenizer(expansionState, ","); + while (stok.hasMoreTokens()) { + int token = row + Integer.parseInt(stok.nextToken()); + tree.expandRow(token); } } } diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java b/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java deleted file mode 100644 index e73340a..0000000 --- a/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import javax.swing.tree.DefaultMutableTreeNode; - -import cuchaz.enigma.mapping.ClassEntry; - -public class ClassSelectorClassNode extends DefaultMutableTreeNode { - - private static final long serialVersionUID = -8956754339813257380L; - - private ClassEntry classEntry; - - public ClassSelectorClassNode(ClassEntry classEntry) { - this.classEntry = classEntry; - } - - public ClassEntry getClassEntry() { - return this.classEntry; - } - - @Override - public String toString() { - if (this.classEntry instanceof ScoredClassEntry) { - return String.format("%d%% %s", (int) ((ScoredClassEntry) this.classEntry).getScore(), this.classEntry.getSimpleName()); - } - return this.classEntry.getSimpleName(); - } - - @Override - public boolean equals(Object other) { - return other instanceof ClassSelectorClassNode && equals((ClassSelectorClassNode) other); - } - - public boolean equals(ClassSelectorClassNode other) { - return this.classEntry.equals(other.classEntry); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java b/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java deleted file mode 100644 index 3b5ba8c..0000000 --- a/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import javax.swing.tree.DefaultMutableTreeNode; - -public class ClassSelectorPackageNode extends DefaultMutableTreeNode { - - private static final long serialVersionUID = -3730868701219548043L; - - private String packageName; - - public ClassSelectorPackageNode(String packageName) { - this.packageName = packageName; - } - - public String getPackageName() { - return this.packageName; - } - - @Override - public String toString() { - return this.packageName; - } - - @Override - public boolean equals(Object other) { - return other instanceof ClassSelectorPackageNode && equals((ClassSelectorPackageNode) other); - } - - public boolean equals(ClassSelectorPackageNode other) { - return this.packageName.equals(other.packageName); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/CodeReader.java b/src/main/java/cuchaz/enigma/gui/CodeReader.java deleted file mode 100644 index a476fa5..0000000 --- a/src/main/java/cuchaz/enigma/gui/CodeReader.java +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import com.strobel.decompiler.languages.java.ast.CompilationUnit; - -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JEditorPane; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.text.BadLocationException; -import javax.swing.text.Highlighter.HighlightPainter; - -import cuchaz.enigma.Deobfuscator; -import cuchaz.enigma.analysis.EntryReference; -import cuchaz.enigma.analysis.SourceIndex; -import cuchaz.enigma.analysis.Token; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.Entry; -import de.sciss.syntaxpane.DefaultSyntaxKit; - - -public class CodeReader extends JEditorPane { - - private static final long serialVersionUID = 3673180950485748810L; - - private static final Object lock = new Object(); - - public interface SelectionListener { - void onSelect(EntryReference reference); - } - - private SelectionHighlightPainter selectionHighlightPainter; - private SourceIndex sourceIndex; - private SelectionListener selectionListener; - - public CodeReader() { - - setEditable(false); - setContentType("text/java"); - - // turn off token highlighting (it's wrong most of the time anyway...) - DefaultSyntaxKit kit = (DefaultSyntaxKit) getEditorKit(); - kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker"); - - // hook events - addCaretListener(event -> { - if (this.selectionListener != null && this.sourceIndex != null) { - Token token = this.sourceIndex.getReferenceToken(event.getDot()); - if (token != null) { - this.selectionListener.onSelect(this.sourceIndex.getDeobfReference(token)); - } else { - this.selectionListener.onSelect(null); - } - } - }); - - this.selectionHighlightPainter = new SelectionHighlightPainter(); - this.sourceIndex = null; - this.selectionListener = null; - } - - public void setSelectionListener(SelectionListener val) { - this.selectionListener = val; - } - - public void setCode(String code) { - // sadly, the java lexer is not thread safe, so we have to serialize all these calls - synchronized (lock) { - setText(code); - } - } - - public SourceIndex getSourceIndex() { - return this.sourceIndex; - } - - public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator, Runnable callback) { - decompileClass(classEntry, deobfuscator, null, callback); - } - - public void decompileClass(final ClassEntry classEntry, final Deobfuscator deobfuscator, final Boolean ignoreBadTokens, final Runnable callback) { - - if (classEntry == null) { - setCode(null); - return; - } - - setCode("(decompiling...)"); - - // run decompilation in a separate thread to keep ui responsive - new Thread() { - @Override - public void run() { - - // decompile it - CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName()); - String source = deobfuscator.getSource(sourceTree); - setCode(source); - sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens); - - if (callback != null) { - callback.run(); - } - } - }.start(); - } - - public void navigateToClassDeclaration(ClassEntry classEntry) { - - // navigate to the class declaration - Token token = this.sourceIndex.getDeclarationToken(classEntry); - if (token == null) { - // couldn't find the class declaration token, might be an anonymous class - // look for any declaration in that class instead - for (Entry entry : this.sourceIndex.declarations()) { - if (entry.getClassEntry().equals(classEntry)) { - token = this.sourceIndex.getDeclarationToken(entry); - break; - } - } - } - - if (token != null) { - navigateToToken(token); - } else { - // couldn't find anything =( - System.out.println("Unable to find declaration in source for " + classEntry); - } - } - - public void navigateToToken(final Token token) { - navigateToToken(this, token, this.selectionHighlightPainter); - } - - // HACKHACK: someday we can update the main GUI to use this code reader - public static void navigateToToken(final JEditorPane editor, final Token token, final HighlightPainter highlightPainter) { - - // set the caret position to the token - editor.setCaretPosition(token.start); - editor.grabFocus(); - - try { - // make sure the token is visible in the scroll window - Rectangle start = editor.modelToView(token.start); - Rectangle end = editor.modelToView(token.end); - final Rectangle show = start.union(end); - show.grow(start.width * 10, start.height * 6); - SwingUtilities.invokeLater(() -> editor.scrollRectToVisible(show)); - } catch (BadLocationException ex) { - throw new Error(ex); - } - - // highlight the token momentarily - final Timer timer = new Timer(200, new ActionListener() { - private int m_counter = 0; - private Object m_highlight = null; - - @Override - public void actionPerformed(ActionEvent event) { - if (m_counter % 2 == 0) { - try { - m_highlight = editor.getHighlighter().addHighlight(token.start, token.end, highlightPainter); - } catch (BadLocationException ex) { - // don't care - } - } else if (m_highlight != null) { - editor.getHighlighter().removeHighlight(m_highlight); - } - - if (m_counter++ > 6) { - Timer timer = (Timer) event.getSource(); - timer.stop(); - } - } - }); - timer.start(); - } - - public void setHighlightedToken(Token token, HighlightPainter painter) { - try { - getHighlighter().addHighlight(token.start, token.end, painter); - } catch (BadLocationException ex) { - throw new IllegalArgumentException(ex); - } - } - - public void clearHighlights() { - getHighlighter().removeAllHighlights(); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java deleted file mode 100644 index d5ad0c8..0000000 --- a/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.Color; - -public class DeobfuscatedHighlightPainter extends BoxHighlightPainter { - - public DeobfuscatedHighlightPainter() { - super(new Color(220, 255, 220), new Color(80, 160, 80)); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 623e12e..d93aa9f 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java @@ -36,11 +36,17 @@ import cuchaz.enigma.gui.elements.MenuBar; import cuchaz.enigma.gui.elements.PopupMenuBar; import cuchaz.enigma.gui.filechooser.FileChooserFile; import cuchaz.enigma.gui.filechooser.FileChooserFolder; +import cuchaz.enigma.gui.highlight.DeobfuscatedHighlightPainter; +import cuchaz.enigma.gui.highlight.ObfuscatedHighlightPainter; +import cuchaz.enigma.gui.highlight.OtherHighlightPainter; +import cuchaz.enigma.gui.highlight.SelectionHighlightPainter; import cuchaz.enigma.gui.panels.PanelDeobf; import cuchaz.enigma.gui.panels.PanelEditor; import cuchaz.enigma.gui.panels.PanelIdentifier; import cuchaz.enigma.gui.panels.PanelObf; import cuchaz.enigma.mapping.*; +import cuchaz.enigma.throwables.IllegalNameException; +import cuchaz.enigma.utils.Utils; import de.sciss.syntaxpane.DefaultSyntaxKit; public class Gui { @@ -363,7 +369,7 @@ public class Gui { if (token == null) { throw new IllegalArgumentException("Token cannot be null!"); } - CodeReader.navigateToToken(this.editor, token, m_selectionHighlightPainter); + Utils.navigateToToken(this.editor, token, m_selectionHighlightPainter); redraw(); } @@ -476,7 +482,7 @@ public class Gui { label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); panel.add(label); - panel.add(GuiTricks.unboldLabel(new JLabel(value, JLabel.LEFT))); + panel.add(Utils.unboldLabel(new JLabel(value, JLabel.LEFT))); } public void onCaretMove(int pos) { @@ -498,13 +504,13 @@ public class Gui { m_infoPanel.clearReference(); } - this.popupMenu.renameMenu.setEnabled(isRenameable && isToken); + this.popupMenu.renameMenu.setEnabled(isRenameable); this.popupMenu.showInheritanceMenu.setEnabled(isClassEntry || isMethodEntry || isConstructorEntry); this.popupMenu.showImplementationsMenu.setEnabled(isClassEntry || isMethodEntry); this.popupMenu.showCallsMenu.setEnabled(isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry); this.popupMenu.openEntryMenu.setEnabled(isInJar && (isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry)); this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation()); - this.popupMenu.toggleMappingMenu.setEnabled(isRenameable && isToken); + this.popupMenu.toggleMappingMenu.setEnabled(isRenameable); if (isToken && this.controller.entryHasDeobfuscatedName(m_reference.entry)) { this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated"); @@ -526,7 +532,6 @@ public class Gui { private void navigateTo(EntryReference reference) { if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) { - // reference is not in the jar. Ignore it return; } if (m_reference != null) { @@ -574,7 +579,7 @@ public class Gui { } catch (IllegalNameException ex) { text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); text.setToolTipText(ex.getReason()); - GuiTricks.showToolTipNow(text); + Utils.showToolTipNow(text); } return; } @@ -582,7 +587,7 @@ public class Gui { // abort the rename JPanel panel = (JPanel) m_infoPanel.getComponent(0); panel.remove(panel.getComponentCount() - 1); - panel.add(GuiTricks.unboldLabel(new JLabel(m_reference.getNamableName(), JLabel.LEFT))); + panel.add(Utils.unboldLabel(new JLabel(m_reference.getNamableName(), JLabel.LEFT))); this.editor.grabFocus(); @@ -704,6 +709,7 @@ public class Gui { if (!this.controller.isDirty()) { // everything is saved, we can exit safely this.frame.dispose(); + System.exit(0); } else { // ask to save before closing String[] options = {"Save and exit", "Discard changes", "Cancel"}; diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 37244ff..c301594 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -27,6 +27,8 @@ import cuchaz.enigma.Deobfuscator; import cuchaz.enigma.analysis.*; import cuchaz.enigma.gui.dialog.ProgressDialog; import cuchaz.enigma.mapping.*; +import cuchaz.enigma.throwables.MappingParseException; +import cuchaz.enigma.utils.ReadableToken; public class GuiController { @@ -72,7 +74,7 @@ public class GuiController { refreshCurrentClass(); } - public void openMappings(File file) throws IOException, MappingParseException { + public void openMappings(File file) throws IOException { this.deobfuscator.setMappings(new MappingsReader().read(file)); this.isDirty = false; this.gui.setMappingsFile(file); diff --git a/src/main/java/cuchaz/enigma/gui/GuiTricks.java b/src/main/java/cuchaz/enigma/gui/GuiTricks.java deleted file mode 100644 index ffacfec..0000000 --- a/src/main/java/cuchaz/enigma/gui/GuiTricks.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.Font; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.util.Arrays; - -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.ToolTipManager; - -public class GuiTricks { - - public static JLabel unboldLabel(JLabel label) { - Font font = label.getFont(); - label.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); - return label; - } - - public static void showToolTipNow(JComponent component) { - // HACKHACK: trick the tooltip manager into showing the tooltip right now - ToolTipManager manager = ToolTipManager.sharedInstance(); - int oldDelay = manager.getInitialDelay(); - manager.setInitialDelay(0); - manager.mouseMoved(new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, 0, 0, 0, false)); - manager.setInitialDelay(oldDelay); - } - - public static void deactivateButton(JButton button) { - button.setEnabled(false); - button.setText(""); - Arrays.asList(button.getActionListeners()).forEach(button::removeActionListener); - } - - public static void activateButton(JButton button, String text, ActionListener newListener) { - button.setText(text); - button.setEnabled(true); - Arrays.asList(button.getActionListeners()).forEach(button::removeActionListener); - button.addActionListener(newListener); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java b/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java deleted file mode 100644 index 0713ad5..0000000 --- a/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java +++ /dev/null @@ -1,442 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import javax.swing.*; -import javax.swing.text.Highlighter.HighlightPainter; - -import cuchaz.enigma.Constants; -import cuchaz.enigma.Deobfuscator; -import cuchaz.enigma.analysis.SourceIndex; -import cuchaz.enigma.analysis.Token; -import cuchaz.enigma.convert.ClassMatches; -import cuchaz.enigma.convert.MemberMatches; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.Entry; -import de.sciss.syntaxpane.DefaultSyntaxKit; - - -public class MemberMatchingGui { - - private enum SourceType { - Matched { - @Override - public Collection getObfSourceClasses(MemberMatches matches) { - return matches.getSourceClassesWithoutUnmatchedEntries(); - } - }, - Unmatched { - @Override - public Collection getObfSourceClasses(MemberMatches matches) { - return matches.getSourceClassesWithUnmatchedEntries(); - } - }; - - public JRadioButton newRadio(ActionListener listener, ButtonGroup group) { - JRadioButton button = new JRadioButton(name(), this == getDefault()); - button.setActionCommand(name()); - button.addActionListener(listener); - group.add(button); - return button; - } - - public abstract Collection getObfSourceClasses(MemberMatches matches); - - public static SourceType getDefault() { - return values()[0]; - } - } - - public interface SaveListener { - void save(MemberMatches matches); - } - - // controls - private JFrame m_frame; - private Map m_sourceTypeButtons; - private ClassSelector m_sourceClasses; - private CodeReader m_sourceReader; - private CodeReader m_destReader; - private JButton m_matchButton; - private JButton m_unmatchableButton; - private JLabel m_sourceLabel; - private JLabel m_destLabel; - private HighlightPainter m_unmatchedHighlightPainter; - private HighlightPainter m_matchedHighlightPainter; - - private ClassMatches m_classMatches; - private MemberMatches m_memberMatches; - private Deobfuscator m_sourceDeobfuscator; - private Deobfuscator m_destDeobfuscator; - private SaveListener m_saveListener; - private SourceType m_sourceType; - private ClassEntry m_obfSourceClass; - private ClassEntry m_obfDestClass; - private T m_obfSourceEntry; - private T m_obfDestEntry; - - public MemberMatchingGui(ClassMatches classMatches, MemberMatches fieldMatches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { - - m_classMatches = classMatches; - m_memberMatches = fieldMatches; - m_sourceDeobfuscator = sourceDeobfuscator; - m_destDeobfuscator = destDeobfuscator; - - // init frame - m_frame = new JFrame(Constants.NAME + " - Member Matcher"); - final Container pane = m_frame.getContentPane(); - pane.setLayout(new BorderLayout()); - - // init classes side - JPanel classesPanel = new JPanel(); - classesPanel.setLayout(new BoxLayout(classesPanel, BoxLayout.PAGE_AXIS)); - classesPanel.setPreferredSize(new Dimension(200, 0)); - pane.add(classesPanel, BorderLayout.WEST); - classesPanel.add(new JLabel("Classes")); - - // init source type radios - JPanel sourceTypePanel = new JPanel(); - classesPanel.add(sourceTypePanel); - sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); - ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); - ButtonGroup sourceTypeButtons = new ButtonGroup(); - m_sourceTypeButtons = Maps.newHashMap(); - for (SourceType sourceType : SourceType.values()) { - JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); - m_sourceTypeButtons.put(sourceType, button); - sourceTypePanel.add(button); - } - - m_sourceClasses = new ClassSelector(ClassSelector.DEOBF_CLASS_COMPARATOR); - m_sourceClasses.setListener(this::setSourceClass); - JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); - classesPanel.add(sourceScroller); - - // init readers - DefaultSyntaxKit.initKit(); - m_sourceReader = new CodeReader(); - m_sourceReader.setSelectionListener(reference -> { - if (reference != null) { - onSelectSource(reference.entry); - } else { - onSelectSource(null); - } - }); - m_destReader = new CodeReader(); - m_destReader.setSelectionListener(reference -> { - if (reference != null) { - onSelectDest(reference.entry); - } else { - onSelectDest(null); - } - }); - - // add key bindings - KeyAdapter keyListener = new KeyAdapter() { - @Override - public void keyPressed(KeyEvent event) { - switch (event.getKeyCode()) { - case KeyEvent.VK_M: - m_matchButton.doClick(); - break; - } - } - }; - m_sourceReader.addKeyListener(keyListener); - m_destReader.addKeyListener(keyListener); - - // init all the splits - JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_sourceReader), new JScrollPane(m_destReader)); - splitRight.setResizeWeight(0.5); // resize 50:50 - JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, classesPanel, splitRight); - splitLeft.setResizeWeight(0); // let the right side take all the slack - pane.add(splitLeft, BorderLayout.CENTER); - splitLeft.resetToPreferredSizes(); - - // init bottom panel - JPanel bottomPanel = new JPanel(); - bottomPanel.setLayout(new FlowLayout()); - pane.add(bottomPanel, BorderLayout.SOUTH); - - m_matchButton = new JButton(); - m_unmatchableButton = new JButton(); - - m_sourceLabel = new JLabel(); - bottomPanel.add(m_sourceLabel); - bottomPanel.add(m_matchButton); - bottomPanel.add(m_unmatchableButton); - m_destLabel = new JLabel(); - bottomPanel.add(m_destLabel); - - // show the frame - pane.doLayout(); - m_frame.setSize(1024, 576); - m_frame.setMinimumSize(new Dimension(640, 480)); - m_frame.setVisible(true); - m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - - m_unmatchedHighlightPainter = new ObfuscatedHighlightPainter(); - m_matchedHighlightPainter = new DeobfuscatedHighlightPainter(); - - // init state - m_saveListener = null; - m_obfSourceClass = null; - m_obfDestClass = null; - m_obfSourceEntry = null; - m_obfDestEntry = null; - setSourceType(SourceType.getDefault()); - updateButtons(); - } - - protected void setSourceType(SourceType val) { - m_sourceType = val; - updateSourceClasses(); - } - - public void setSaveListener(SaveListener val) { - m_saveListener = val; - } - - private void updateSourceClasses() { - - String selectedPackage = m_sourceClasses.getSelectedPackage(); - - List deobfClassEntries = Lists.newArrayList(); - for (ClassEntry entry : m_sourceType.getObfSourceClasses(m_memberMatches)) { - deobfClassEntries.add(m_sourceDeobfuscator.deobfuscateEntry(entry)); - } - m_sourceClasses.setClasses(deobfClassEntries); - - if (selectedPackage != null) { - m_sourceClasses.expandPackage(selectedPackage); - } - - for (SourceType sourceType : SourceType.values()) { - m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", - sourceType.name(), sourceType.getObfSourceClasses(m_memberMatches).size() - )); - } - } - - protected void setSourceClass(ClassEntry sourceClass) { - - m_obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); - m_obfDestClass = m_classMatches.getUniqueMatches().get(m_obfSourceClass); - if (m_obfDestClass == null) { - throw new Error("No matching dest class for source class: " + m_obfSourceClass); - } - - m_sourceReader.decompileClass(m_obfSourceClass, m_sourceDeobfuscator, false, this::updateSourceHighlights); - m_destReader.decompileClass(m_obfDestClass, m_destDeobfuscator, false, this::updateDestHighlights); - } - - protected void updateSourceHighlights() { - highlightEntries(m_sourceReader, m_sourceDeobfuscator, m_memberMatches.matches().keySet(), m_memberMatches.getUnmatchedSourceEntries()); - } - - protected void updateDestHighlights() { - highlightEntries(m_destReader, m_destDeobfuscator, m_memberMatches.matches().values(), m_memberMatches.getUnmatchedDestEntries()); - } - - private void highlightEntries(CodeReader reader, Deobfuscator deobfuscator, Collection obfMatchedEntries, Collection obfUnmatchedEntries) { - reader.clearHighlights(); - SourceIndex index = reader.getSourceIndex(); - - // matched fields - for (T obfT : obfMatchedEntries) { - T deobfT = deobfuscator.deobfuscateEntry(obfT); - Token token = index.getDeclarationToken(deobfT); - if (token != null) { - reader.setHighlightedToken(token, m_matchedHighlightPainter); - } - } - - // unmatched fields - for (T obfT : obfUnmatchedEntries) { - T deobfT = deobfuscator.deobfuscateEntry(obfT); - Token token = index.getDeclarationToken(deobfT); - if (token != null) { - reader.setHighlightedToken(token, m_unmatchedHighlightPainter); - } - } - } - - private boolean isSelectionMatched() { - return m_obfSourceEntry != null && m_obfDestEntry != null - && m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry); - } - - protected void onSelectSource(Entry source) { - - // start with no selection - if (isSelectionMatched()) { - setDest(null); - } - setSource(null); - - // then look for a valid source selection - if (source != null) { - - // this looks really scary, but it's actually ok - // Deobfuscator.obfuscateEntry can handle all implementations of Entry - // and MemberMatches.hasSource() will only pass entries that actually match T - @SuppressWarnings("unchecked") - T sourceEntry = (T) source; - - T obfSourceEntry = m_sourceDeobfuscator.obfuscateEntry(sourceEntry); - if (m_memberMatches.hasSource(obfSourceEntry)) { - setSource(obfSourceEntry); - - // look for a matched dest too - T obfDestEntry = m_memberMatches.matches().get(obfSourceEntry); - if (obfDestEntry != null) { - setDest(obfDestEntry); - } - } - } - - updateButtons(); - } - - protected void onSelectDest(Entry dest) { - - // start with no selection - if (isSelectionMatched()) { - setSource(null); - } - setDest(null); - - // then look for a valid dest selection - if (dest != null) { - - // this looks really scary, but it's actually ok - // Deobfuscator.obfuscateEntry can handle all implementations of Entry - // and MemberMatches.hasSource() will only pass entries that actually match T - @SuppressWarnings("unchecked") - T destEntry = (T) dest; - - T obfDestEntry = m_destDeobfuscator.obfuscateEntry(destEntry); - if (m_memberMatches.hasDest(obfDestEntry)) { - setDest(obfDestEntry); - - // look for a matched source too - T obfSourceEntry = m_memberMatches.matches().inverse().get(obfDestEntry); - if (obfSourceEntry != null) { - setSource(obfSourceEntry); - } - } - } - - updateButtons(); - } - - private void setSource(T obfEntry) { - m_obfSourceEntry = obfEntry; - if (obfEntry == null) { - m_sourceLabel.setText(""); - } else { - m_sourceLabel.setText(getEntryLabel(obfEntry, m_sourceDeobfuscator)); - } - } - - private void setDest(T obfEntry) { - m_obfDestEntry = obfEntry; - if (obfEntry == null) { - m_destLabel.setText(""); - } else { - m_destLabel.setText(getEntryLabel(obfEntry, m_destDeobfuscator)); - } - } - - private String getEntryLabel(T obfEntry, Deobfuscator deobfuscator) { - // show obfuscated and deobfuscated names, but no types/signatures - T deobfEntry = deobfuscator.deobfuscateEntry(obfEntry); - return String.format("%s (%s)", deobfEntry.getName(), obfEntry.getName()); - } - - private void updateButtons() { - - GuiTricks.deactivateButton(m_matchButton); - GuiTricks.deactivateButton(m_unmatchableButton); - - if (m_obfSourceEntry != null && m_obfDestEntry != null) { - if (m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry)) { - GuiTricks.activateButton(m_matchButton, "Unmatch", event -> unmatch()); - } else if (!m_memberMatches.isMatchedSourceEntry(m_obfSourceEntry) && !m_memberMatches.isMatchedDestEntry(m_obfDestEntry)) { - GuiTricks.activateButton(m_matchButton, "Match", event -> match()); - } - } else if (m_obfSourceEntry != null) { - GuiTricks.activateButton(m_unmatchableButton, "Set Unmatchable", event -> unmatchable()); - } - } - - protected void match() { - - // update the field matches - m_memberMatches.makeMatch(m_obfSourceEntry, m_obfDestEntry); - save(); - - // update the ui - onSelectSource(null); - onSelectDest(null); - updateSourceHighlights(); - updateDestHighlights(); - updateSourceClasses(); - } - - protected void unmatch() { - - // update the field matches - m_memberMatches.unmakeMatch(m_obfSourceEntry, m_obfDestEntry); - save(); - - // update the ui - onSelectSource(null); - onSelectDest(null); - updateSourceHighlights(); - updateDestHighlights(); - updateSourceClasses(); - } - - protected void unmatchable() { - - // update the field matches - m_memberMatches.makeSourceUnmatchable(m_obfSourceEntry); - save(); - - // update the ui - onSelectSource(null); - onSelectDest(null); - updateSourceHighlights(); - updateDestHighlights(); - updateSourceClasses(); - } - - private void save() { - if (m_saveListener != null) { - m_saveListener.save(m_memberMatches); - } - } -} diff --git a/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java deleted file mode 100644 index 5afc767..0000000 --- a/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.Color; - -public class ObfuscatedHighlightPainter extends BoxHighlightPainter { - - public ObfuscatedHighlightPainter() { - super(new Color(255, 220, 220), new Color(160, 80, 80)); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java deleted file mode 100644 index 256f69e..0000000 --- a/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.Color; - -public class OtherHighlightPainter extends BoxHighlightPainter { - - public OtherHighlightPainter() { - super(null, new Color(180, 180, 180)); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/ReadableToken.java b/src/main/java/cuchaz/enigma/gui/ReadableToken.java deleted file mode 100644 index feec8c0..0000000 --- a/src/main/java/cuchaz/enigma/gui/ReadableToken.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -public class ReadableToken { - - public int line; - public int startColumn; - public int endColumn; - - public ReadableToken(int line, int startColumn, int endColumn) { - this.line = line; - this.startColumn = startColumn; - this.endColumn = endColumn; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("line "); - buf.append(line); - buf.append(" columns "); - buf.append(startColumn); - buf.append("-"); - buf.append(endColumn); - return buf.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java deleted file mode 100644 index 359ec7a..0000000 --- a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import cuchaz.enigma.mapping.ClassEntry; - -public class ScoredClassEntry extends ClassEntry { - - private static final long serialVersionUID = -8798725308554217105L; - - private float score; - - public ScoredClassEntry(ClassEntry other, float score) { - super(other); - this.score = score; - } - - public float getScore() { - return this.score; - } -} diff --git a/src/main/java/cuchaz/enigma/gui/SelectionHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/SelectionHighlightPainter.java deleted file mode 100644 index fcad07c..0000000 --- a/src/main/java/cuchaz/enigma/gui/SelectionHighlightPainter.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.gui; - -import java.awt.*; - -import javax.swing.text.Highlighter; -import javax.swing.text.JTextComponent; - -public class SelectionHighlightPainter implements Highlighter.HighlightPainter { - - @Override - public void paint(Graphics g, int start, int end, Shape shape, JTextComponent text) { - // draw a thick border - Graphics2D g2d = (Graphics2D) g; - Rectangle bounds = BoxHighlightPainter.getBounds(text, start, end); - g2d.setColor(Color.black); - g2d.setStroke(new BasicStroke(2.0f)); - g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); - } -} diff --git a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java index da4f5fb..f690b15 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java @@ -19,7 +19,7 @@ import java.io.IOException; import javax.swing.*; import cuchaz.enigma.Constants; -import cuchaz.enigma.Util; +import cuchaz.enigma.utils.Utils; public class AboutDialog { @@ -31,7 +31,7 @@ public class AboutDialog { // load the content try { - String html = Util.readResourceToString("/about.html"); + String html = Utils.readResourceToString("/about.html"); html = String.format(html, Constants.NAME, Constants.VERSION); JLabel label = new JLabel(html); label.setHorizontalAlignment(JLabel.CENTER); @@ -44,7 +44,7 @@ public class AboutDialog { String html = "%s"; html = String.format(html, Constants.URL, Constants.URL); JButton link = new JButton(html); - link.addActionListener(event -> Util.openUrl(Constants.URL)); + link.addActionListener(event -> Utils.openUrl(Constants.URL)); link.setBorderPainted(false); link.setOpaque(false); link.setBackground(Color.WHITE); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java index 71aab01..8d3df47 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java @@ -19,7 +19,7 @@ import java.io.StringWriter; import javax.swing.*; import cuchaz.enigma.Constants; -import cuchaz.enigma.gui.GuiTricks; +import cuchaz.enigma.utils.Utils; public class CrashDialog { @@ -48,7 +48,7 @@ public class CrashDialog { FlowLayout buttonsLayout = new FlowLayout(); buttonsLayout.setAlignment(FlowLayout.RIGHT); buttonsPanel.setLayout(buttonsLayout); - buttonsPanel.add(GuiTricks.unboldLabel(new JLabel("If you choose exit, you will lose any unsaved work."))); + buttonsPanel.add(Utils.unboldLabel(new JLabel("If you choose exit, you will lose any unsaved work."))); JButton ignoreButton = new JButton("Ignore"); ignoreButton.addActionListener(event -> { // close (hide) the dialog diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index dc4d91e..c752c86 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java @@ -19,7 +19,7 @@ import javax.swing.*; import cuchaz.enigma.Constants; import cuchaz.enigma.Deobfuscator.ProgressListener; -import cuchaz.enigma.gui.GuiTricks; +import cuchaz.enigma.utils.Utils; public class ProgressDialog implements ProgressListener, AutoCloseable { @@ -44,7 +44,7 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { JPanel panel = new JPanel(); pane.add(panel); panel.setLayout(new BorderLayout()); - this.labelText = GuiTricks.unboldLabel(new JLabel()); + this.labelText = Utils.unboldLabel(new JLabel()); this.progress = new JProgressBar(); this.labelText.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); panel.add(this.labelText, BorderLayout.NORTH); diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 233d55e..e870334 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -9,7 +9,7 @@ import javax.swing.*; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.gui.dialog.AboutDialog; -import cuchaz.enigma.mapping.MappingParseException; +import cuchaz.enigma.throwables.MappingParseException; public class MenuBar extends JMenuBar { @@ -69,8 +69,6 @@ public class MenuBar extends JMenuBar { this.gui.getController().openMappings(this.gui.mappingsFileChooser.getSelectedFile()); } catch (IOException ex) { throw new Error(ex); - } catch (MappingParseException ex) { - JOptionPane.showMessageDialog(this.gui.getFrame(), ex.getMessage()); } } }); diff --git a/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserFolder.java b/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserFolder.java index bd8f0f0..93ca5d6 100644 --- a/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserFolder.java +++ b/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserFolder.java @@ -2,7 +2,7 @@ package cuchaz.enigma.gui.filechooser; import javax.swing.JFileChooser; -public class FileChooserFolder extends JFileChooser{ +public class FileChooserFolder extends JFileChooser { public FileChooserFolder() { this.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); diff --git a/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java new file mode 100644 index 0000000..0a73088 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.highlight; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.text.BadLocationException; +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; + +public abstract class BoxHighlightPainter implements Highlighter.HighlightPainter { + + private Color fillColor; + private Color borderColor; + + protected BoxHighlightPainter(Color fillColor, Color borderColor) { + this.fillColor = fillColor; + this.borderColor = borderColor; + } + + @Override + public void paint(Graphics g, int start, int end, Shape shape, JTextComponent text) { + Rectangle bounds = getBounds(text, start, end); + + // fill the area + if (this.fillColor != null) { + g.setColor(this.fillColor); + g.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); + } + + // draw a box around the area + g.setColor(this.borderColor); + g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); + } + + public static Rectangle getBounds(JTextComponent text, int start, int end) { + try { + // determine the bounds of the text + Rectangle bounds = text.modelToView(start).union(text.modelToView(end)); + + // adjust the box so it looks nice + bounds.x -= 2; + bounds.width += 2; + bounds.y += 1; + bounds.height -= 2; + + return bounds; + } catch (BadLocationException ex) { + // don't care... just return something + return new Rectangle(0, 0, 0, 0); + } + } +} diff --git a/src/main/java/cuchaz/enigma/gui/highlight/DeobfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/highlight/DeobfuscatedHighlightPainter.java new file mode 100644 index 0000000..5d57203 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/highlight/DeobfuscatedHighlightPainter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.highlight; + +import java.awt.Color; + +public class DeobfuscatedHighlightPainter extends BoxHighlightPainter { + + public DeobfuscatedHighlightPainter() { + super(new Color(220, 255, 220), new Color(80, 160, 80)); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/highlight/ObfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/highlight/ObfuscatedHighlightPainter.java new file mode 100644 index 0000000..ee64d86 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/highlight/ObfuscatedHighlightPainter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.highlight; + +import java.awt.Color; + +public class ObfuscatedHighlightPainter extends BoxHighlightPainter { + + public ObfuscatedHighlightPainter() { + super(new Color(255, 220, 220), new Color(160, 80, 80)); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/highlight/OtherHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/highlight/OtherHighlightPainter.java new file mode 100644 index 0000000..43d8352 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/highlight/OtherHighlightPainter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.highlight; + +import java.awt.Color; + +public class OtherHighlightPainter extends BoxHighlightPainter { + + public OtherHighlightPainter() { + super(null, new Color(180, 180, 180)); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java new file mode 100644 index 0000000..f772284 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.highlight; + +import java.awt.*; + +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; + +public class SelectionHighlightPainter implements Highlighter.HighlightPainter { + + @Override + public void paint(Graphics g, int start, int end, Shape shape, JTextComponent text) { + // draw a thick border + Graphics2D g2d = (Graphics2D) g; + Rectangle bounds = BoxHighlightPainter.getBounds(text, start, end); + g2d.setColor(Color.black); + g2d.setStroke(new BasicStroke(2.0f)); + g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java new file mode 100644 index 0000000..e083572 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.node; + +import javax.swing.tree.DefaultMutableTreeNode; + +import cuchaz.enigma.mapping.ClassEntry; + +public class ClassSelectorClassNode extends DefaultMutableTreeNode { + + private ClassEntry classEntry; + + public ClassSelectorClassNode(ClassEntry classEntry) { + this.classEntry = classEntry; + } + + public ClassEntry getClassEntry() { + return this.classEntry; + } + + @Override + public String toString() { + return this.classEntry.getSimpleName(); + } + + @Override + public boolean equals(Object other) { + return other instanceof ClassSelectorClassNode && equals((ClassSelectorClassNode) other); + } + + public boolean equals(ClassSelectorClassNode other) { + return this.classEntry.equals(other.classEntry); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java new file mode 100644 index 0000000..805b3a8 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.gui.node; + +import javax.swing.tree.DefaultMutableTreeNode; + +public class ClassSelectorPackageNode extends DefaultMutableTreeNode { + + private String packageName; + + public ClassSelectorPackageNode(String packageName) { + this.packageName = packageName; + } + + @Override + public String toString() { + return this.packageName; + } + + @Override + public boolean equals(Object other) { + return other instanceof ClassSelectorPackageNode && equals((ClassSelectorPackageNode) other); + } + + public boolean equals(ClassSelectorPackageNode other) { + return this.packageName.equals(other.packageName); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java index 2cc8b76..bba7132 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java @@ -23,6 +23,5 @@ public class PanelDeobf extends JPanel { this.setLayout(new BorderLayout()); this.add(new JLabel("De-obfuscated Classes"), BorderLayout.NORTH); this.add(new JScrollPane(this.deobfClasses), BorderLayout.CENTER); - } } diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java index 4261eb5..faa023b 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java @@ -8,7 +8,7 @@ import javax.swing.JLabel; import javax.swing.JPanel; import cuchaz.enigma.gui.Gui; -import cuchaz.enigma.gui.GuiTricks; +import cuchaz.enigma.utils.Utils; public class PanelIdentifier extends JPanel { @@ -25,7 +25,7 @@ public class PanelIdentifier extends JPanel { public void clearReference() { this.removeAll(); JLabel label = new JLabel("No identifier selected"); - GuiTricks.unboldLabel(label); + Utils.unboldLabel(label); label.setHorizontalAlignment(JLabel.CENTER); this.add(label); diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java index 3e0374e..94b384f 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java @@ -19,7 +19,7 @@ public class PanelObf extends JPanel { public PanelObf(Gui gui) { this.gui = gui; - Comparator obfClassComparator = (a, b) -> { + Comparator obfClassComparator = (a, b) -> { String aname = a.getName(); String bname = b.getName(); if (aname.length() != bname.length()) { -- cgit v1.2.3