From a146283291d5529eb9363b2fbc6fd5e643dee85a Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 1 Sep 2014 20:40:11 -0400 Subject: made obfuscated/deobfuscated class selector a bit easier to use --- src/cuchaz/enigma/gui/ClassSelector.java | 181 +++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 src/cuchaz/enigma/gui/ClassSelector.java (limited to 'src/cuchaz/enigma/gui/ClassSelector.java') diff --git a/src/cuchaz/enigma/gui/ClassSelector.java b/src/cuchaz/enigma/gui/ClassSelector.java new file mode 100644 index 0000000..338ad80 --- /dev/null +++ b/src/cuchaz/enigma/gui/ClassSelector.java @@ -0,0 +1,181 @@ +package cuchaz.enigma.gui; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; + +import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Maps; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import cuchaz.enigma.mapping.ClassEntry; + +public class ClassSelector extends JTree +{ + private static final long serialVersionUID = -7632046902384775977L; + + public interface ClassSelectionListener + { + void onSelectClass( ClassEntry classEntry ); + } + + public static Comparator ObfuscatedClassEntryComparator; + public static Comparator DeobfuscatedClassEntryComparator; + + static + { + ObfuscatedClassEntryComparator = new Comparator( ) + { + @Override + public int compare( ClassEntry a, ClassEntry b ) + { + if( a.getName().length() != b.getName().length() ) + { + return a.getName().length() - b.getName().length(); + } + return a.getName().compareTo( b.getName() ); + } + }; + + DeobfuscatedClassEntryComparator = new Comparator( ) + { + @Override + public int compare( ClassEntry a, ClassEntry b ) + { + return a.getName().compareTo( b.getName() ); + } + }; + } + + private ClassSelectionListener m_listener; + private Comparator m_comparator; + + public ClassSelector( Comparator comparator ) + { + m_comparator = comparator; + + // configure the tree control + setRootVisible( false ); + setShowsRootHandles( false ); + setModel( null ); + + // hook events + addMouseListener( new MouseAdapter() + { + @Override + public void mouseClicked( MouseEvent event ) + { + if( m_listener != null && event.getClickCount() == 2 ) + { + // get the selected node + TreePath path = getSelectionPath(); + if( path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode ) + { + ClassSelectorClassNode node = (ClassSelectorClassNode)path.getLastPathComponent(); + m_listener.onSelectClass( node.getClassEntry() ); + } + } + } + } ); + + // init defaults + m_listener = null; + } + + public void setListener( ClassSelectionListener val ) + { + m_listener = val; + } + + public void setClasses( Collection classEntries ) + { + if( classEntries == null ) + { + setModel( null ); + return; + } + + // build the package names + Map packages = Maps.newHashMap(); + for( ClassEntry classEntry : classEntries ) + { + packages.put( classEntry.getPackageName(), null ); + } + + // sort the packages + List sortedPackageNames = Lists.newArrayList( packages.keySet() ); + Collections.sort( sortedPackageNames, new Comparator( ) + { + @Override + public int compare( String a, String b ) + { + // I can never keep this rule straight when writing these damn things... + // a < b => -1, a == b => 0, a > b => +1 + + String[] aparts = a.split( "/" ); + String[] bparts = b.split( "/" ); + for( int i=0; true; i++ ) + { + if( i >= aparts.length ) + { + return -1; + } + else if( i >= bparts.length ) + { + return 1; + } + + int result = aparts[i].compareTo( bparts[i] ); + if( result != 0 ) + { + return result; + } + } + } + } ); + + // create the root node and the package nodes + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + for( String packageName : sortedPackageNames ) + { + ClassSelectorPackageNode node = new ClassSelectorPackageNode( packageName ); + packages.put( packageName, node ); + root.add( node ); + } + + // put the classes into packages + Multimap packagedClassEntries = ArrayListMultimap.create(); + for( ClassEntry classEntry : classEntries ) + { + packagedClassEntries.put( classEntry.getPackageName(), classEntry ); + } + + // build the class nodes + for( String packageName : packagedClassEntries.keySet() ) + { + // sort the class entries + List classEntriesInPackage = Lists.newArrayList( packagedClassEntries.get( packageName ) ); + Collections.sort( classEntriesInPackage, m_comparator ); + + // create the nodes in order + for( ClassEntry classEntry : classEntriesInPackage ) + { + ClassSelectorPackageNode node = packages.get( packageName ); + node.add( new ClassSelectorClassNode( classEntry ) ); + } + } + + // finally, update the tree control + setModel( new DefaultTreeModel( root ) ); + } +} -- cgit v1.2.3