summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui
diff options
context:
space:
mode:
authorGravatar jeff2014-08-21 01:10:37 -0400
committerGravatar jeff2014-08-21 01:10:37 -0400
commit237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375 (patch)
treeebad059c7fa0bc7723858cb25eed0bb6e95fe42a /src/cuchaz/enigma/gui
parentfixed recognition of inner class tokens (diff)
downloadenigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.tar.gz
enigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.tar.xz
enigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.zip
fixed call graph searching
added system to navigate multiple tokens for the same entry in a behavior
Diffstat (limited to 'src/cuchaz/enigma/gui')
-rw-r--r--src/cuchaz/enigma/gui/Gui.java53
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java75
-rw-r--r--src/cuchaz/enigma/gui/ReadableToken.java38
-rw-r--r--src/cuchaz/enigma/gui/TokenListCellRenderer.java40
4 files changed, 167 insertions, 39 deletions
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index 341c149..a5471a7 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -28,6 +28,7 @@ import java.awt.event.WindowAdapter;
28import java.awt.event.WindowEvent; 28import java.awt.event.WindowEvent;
29import java.io.File; 29import java.io.File;
30import java.io.IOException; 30import java.io.IOException;
31import java.util.Collection;
31import java.util.Collections; 32import java.util.Collections;
32import java.util.Comparator; 33import java.util.Comparator;
33import java.util.List; 34import java.util.List;
@@ -145,6 +146,7 @@ public class Gui
145 private BoxHighlightPainter m_deobfuscatedHighlightPainter; 146 private BoxHighlightPainter m_deobfuscatedHighlightPainter;
146 private JTree m_inheritanceTree; 147 private JTree m_inheritanceTree;
147 private JTree m_callsTree; 148 private JTree m_callsTree;
149 private JList<Token> m_tokens;
148 private JTabbedPane m_tabs; 150 private JTabbedPane m_tabs;
149 151
150 // dynamic menu items 152 // dynamic menu items
@@ -457,9 +459,29 @@ public class Gui
457 } 459 }
458 } 460 }
459 } ); 461 } );
460 JPanel callPanel = new JPanel(); 462 m_tokens = new JList<Token>();
461 callPanel.setLayout( new BorderLayout() ); 463 m_tokens.setCellRenderer( new TokenListCellRenderer( m_controller ) );
462 callPanel.add( new JScrollPane( m_callsTree ) ); 464 m_tokens.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
465 m_tokens.setLayoutOrientation( JList.VERTICAL );
466 m_tokens.addMouseListener( new MouseAdapter()
467 {
468 @Override
469 public void mouseClicked( MouseEvent event )
470 {
471 if( event.getClickCount() == 2 )
472 {
473 Token selected = m_tokens.getSelectedValue();
474 if( selected != null )
475 {
476 showToken( selected );
477 }
478 }
479 }
480 } );
481 m_tokens.setPreferredSize( new Dimension( 0, 200 ) );
482 JSplitPane callPanel = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, new JScrollPane( m_callsTree ), new JScrollPane( m_tokens ) );
483 callPanel.setResizeWeight( 1 ); // let the top side take all the slack
484 callPanel.resetToPreferredSizes();
463 485
464 // layout controls 486 // layout controls
465 JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); 487 JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel );
@@ -743,6 +765,21 @@ public class Gui
743 m_editor.grabFocus(); 765 m_editor.grabFocus();
744 } 766 }
745 767
768 public void showTokens( Collection<Token> tokens )
769 {
770 Vector<Token> sortedTokens = new Vector<Token>( tokens );
771 Collections.sort( sortedTokens );
772 if( sortedTokens.size() > 1 )
773 {
774 // sort the tokens and update the tokens panel
775 m_tokens.setListData( sortedTokens );
776 m_tokens.setSelectedIndex( 0 );
777 }
778
779 // show the first token
780 showToken( sortedTokens.get( 0 ) );
781 }
782
746 public void setHighlightedTokens( Iterable<Token> obfuscatedTokens, Iterable<Token> deobfuscatedTokens ) 783 public void setHighlightedTokens( Iterable<Token> obfuscatedTokens, Iterable<Token> deobfuscatedTokens )
747 { 784 {
748 // remove any old highlighters 785 // remove any old highlighters
@@ -900,17 +937,9 @@ public class Gui
900 937
901 private void startRename( ) 938 private void startRename( )
902 { 939 {
903 // get the class name
904 ClassEntry classEntry = m_reference.entry.getClassEntry();
905 String className = classEntry.getName();
906 if( classEntry.isInnerClass() )
907 {
908 className = classEntry.getInnerClassName();
909 }
910
911 // init the text box 940 // init the text box
912 final JTextField text = new JTextField(); 941 final JTextField text = new JTextField();
913 text.setText( className ); 942 text.setText( m_reference.entry.getName() );
914 text.setPreferredSize( new Dimension( 360, text.getPreferredSize().height ) ); 943 text.setPreferredSize( new Dimension( 360, text.getPreferredSize().height ) );
915 text.addKeyListener( new KeyAdapter( ) 944 text.addKeyListener( new KeyAdapter( )
916 { 945 {
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index dfa2557..a35db05 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -14,6 +14,7 @@ import java.io.File;
14import java.io.FileReader; 14import java.io.FileReader;
15import java.io.FileWriter; 15import java.io.FileWriter;
16import java.io.IOException; 16import java.io.IOException;
17import java.util.Collection;
17import java.util.Deque; 18import java.util.Deque;
18import java.util.List; 19import java.util.List;
19 20
@@ -45,7 +46,7 @@ public class GuiController
45 private SourceIndex m_index; 46 private SourceIndex m_index;
46 private ClassEntry m_currentObfClass; 47 private ClassEntry m_currentObfClass;
47 private boolean m_isDirty; 48 private boolean m_isDirty;
48 private Deque<EntryReference<Entry,Entry>> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference 49 private Deque<EntryReference<Entry,Entry>> m_referenceStack;
49 50
50 public GuiController( Gui gui ) 51 public GuiController( Gui gui )
51 { 52 {
@@ -111,7 +112,6 @@ public class GuiController
111 { 112 {
112 return null; 113 return null;
113 } 114 }
114
115 return m_index.getReferenceToken( pos ); 115 return m_index.getReferenceToken( pos );
116 } 116 }
117 117
@@ -124,6 +124,19 @@ public class GuiController
124 return m_index.getDeobfReference( token ); 124 return m_index.getDeobfReference( token );
125 } 125 }
126 126
127 public ReadableToken getReadableToken( Token token )
128 {
129 if( m_index == null )
130 {
131 return null;
132 }
133 return new ReadableToken(
134 m_index.getLineNumber( token.start ),
135 m_index.getColumnNumber( token.start ),
136 m_index.getColumnNumber( token.end )
137 );
138 }
139
127 public boolean entryHasMapping( Entry deobfEntry ) 140 public boolean entryHasMapping( Entry deobfEntry )
128 { 141 {
129 return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) ); 142 return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) );
@@ -134,8 +147,9 @@ public class GuiController
134 return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) ); 147 return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) );
135 } 148 }
136 149
137 public ClassInheritanceTreeNode getClassInheritance( ClassEntry obfClassEntry ) 150 public ClassInheritanceTreeNode getClassInheritance( ClassEntry deobfClassEntry )
138 { 151 {
152 ClassEntry obfClassEntry = m_deobfuscator.obfuscateEntry( deobfClassEntry );
139 ClassInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getClassInheritance( 153 ClassInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getClassInheritance(
140 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), 154 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ),
141 obfClassEntry 155 obfClassEntry
@@ -143,8 +157,9 @@ public class GuiController
143 return ClassInheritanceTreeNode.findNode( rootNode, obfClassEntry ); 157 return ClassInheritanceTreeNode.findNode( rootNode, obfClassEntry );
144 } 158 }
145 159
146 public MethodInheritanceTreeNode getMethodInheritance( MethodEntry obfMethodEntry ) 160 public MethodInheritanceTreeNode getMethodInheritance( MethodEntry deobfMethodEntry )
147 { 161 {
162 MethodEntry obfMethodEntry = m_deobfuscator.obfuscateEntry( deobfMethodEntry );
148 MethodInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getMethodInheritance( 163 MethodInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getMethodInheritance(
149 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), 164 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ),
150 obfMethodEntry 165 obfMethodEntry
@@ -152,8 +167,9 @@ public class GuiController
152 return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry ); 167 return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry );
153 } 168 }
154 169
155 public FieldReferenceTreeNode getFieldReferences( FieldEntry obfFieldEntry ) 170 public FieldReferenceTreeNode getFieldReferences( FieldEntry deobfFieldEntry )
156 { 171 {
172 FieldEntry obfFieldEntry = m_deobfuscator.obfuscateEntry( deobfFieldEntry );
157 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode( 173 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(
158 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), 174 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ),
159 obfFieldEntry 175 obfFieldEntry
@@ -162,11 +178,12 @@ public class GuiController
162 return rootNode; 178 return rootNode;
163 } 179 }
164 180
165 public BehaviorReferenceTreeNode getMethodReferences( BehaviorEntry obfEntry ) 181 public BehaviorReferenceTreeNode getMethodReferences( BehaviorEntry deobfBehaviorEntry )
166 { 182 {
183 BehaviorEntry obfBehaviorEntry = m_deobfuscator.obfuscateEntry( deobfBehaviorEntry );
167 BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode( 184 BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode(
168 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), 185 m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ),
169 obfEntry 186 obfBehaviorEntry
170 ); 187 );
171 rootNode.load( m_deobfuscator.getJarIndex(), true ); 188 rootNode.load( m_deobfuscator.getJarIndex(), true );
172 return rootNode; 189 return rootNode;
@@ -181,13 +198,13 @@ public class GuiController
181 refreshCurrentClass( obfReference ); 198 refreshCurrentClass( obfReference );
182 } 199 }
183 200
184 public void openDeclaration( Entry entry ) 201 public void openDeclaration( Entry deobfEntry )
185 { 202 {
186 if( entry == null ) 203 if( deobfEntry == null )
187 { 204 {
188 throw new IllegalArgumentException( "Entry cannot be null!" ); 205 throw new IllegalArgumentException( "Entry cannot be null!" );
189 } 206 }
190 openReference( new EntryReference<Entry,Entry>( entry ) ); 207 openReference( new EntryReference<Entry,Entry>( deobfEntry ) );
191 } 208 }
192 209
193 public void openReference( EntryReference<Entry,Entry> deobfReference ) 210 public void openReference( EntryReference<Entry,Entry> deobfReference )
@@ -208,8 +225,22 @@ public class GuiController
208 } 225 }
209 else 226 else
210 { 227 {
211 // the class file is already open, just navigate to the reference 228 showReference( obfReference );
212 m_gui.showToken( m_index.getReferenceToken( deobfReference ) ); 229 }
230 }
231
232 private void showReference( EntryReference<Entry,Entry> obfReference )
233 {
234 EntryReference<Entry,Entry> deobfReference = m_deobfuscator.deobfuscateReference( obfReference );
235 Collection<Token> tokens = m_index.getReferenceTokens( deobfReference );
236 if( tokens.isEmpty() )
237 {
238 // DEBUG
239 System.err.println( String.format( "WARNING: no tokens found for %s in %s", deobfReference, m_currentObfClass ) );
240 }
241 else
242 {
243 m_gui.showTokens( tokens );
213 } 244 }
214 } 245 }
215 246
@@ -245,15 +276,15 @@ public class GuiController
245 refreshCurrentClass( null ); 276 refreshCurrentClass( null );
246 } 277 }
247 278
248 private void refreshCurrentClass( EntryReference<Entry,Entry> obfReferenceToShow ) 279 private void refreshCurrentClass( EntryReference<Entry,Entry> obfReference )
249 { 280 {
250 if( m_currentObfClass != null ) 281 if( m_currentObfClass != null )
251 { 282 {
252 deobfuscate( m_currentObfClass, obfReferenceToShow ); 283 deobfuscate( m_currentObfClass, obfReference );
253 } 284 }
254 } 285 }
255 286
256 private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReferenceToShow ) 287 private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReference )
257 { 288 {
258 m_gui.setSource( "(deobfuscating...)" ); 289 m_gui.setSource( "(deobfuscating...)" );
259 290
@@ -266,19 +297,9 @@ public class GuiController
266 // decompile,deobfuscate the bytecode 297 // decompile,deobfuscate the bytecode
267 m_index = m_deobfuscator.getSource( classEntry.getClassName() ); 298 m_index = m_deobfuscator.getSource( classEntry.getClassName() );
268 m_gui.setSource( m_index.getSource() ); 299 m_gui.setSource( m_index.getSource() );
269 if( obfReferenceToShow != null ) 300 if( obfReference != null )
270 { 301 {
271 EntryReference<Entry,Entry> deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow ); 302 showReference( obfReference );
272 Token token = m_index.getReferenceToken( deobfReferenceToShow );
273 if( token == null )
274 {
275 // DEBUG
276 System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow );
277 }
278 else
279 {
280 m_gui.showToken( token );
281 }
282 } 303 }
283 304
284 // set the highlighted tokens 305 // set the highlighted tokens
diff --git a/src/cuchaz/enigma/gui/ReadableToken.java b/src/cuchaz/enigma/gui/ReadableToken.java
new file mode 100644
index 0000000..3f43045
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ReadableToken.java
@@ -0,0 +1,38 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13public class ReadableToken
14{
15 public int line;
16 public int startColumn;
17 public int endColumn;
18
19 public ReadableToken( int line, int startColumn, int endColumn )
20 {
21 this.line = line;
22 this.startColumn = startColumn;
23 this.endColumn = endColumn;
24 }
25
26 @Override
27 public String toString( )
28 {
29 StringBuilder buf = new StringBuilder();
30 buf.append( "line " );
31 buf.append( line );
32 buf.append( " columns " );
33 buf.append( startColumn );
34 buf.append( "-" );
35 buf.append( endColumn );
36 return buf.toString();
37 }
38}
diff --git a/src/cuchaz/enigma/gui/TokenListCellRenderer.java b/src/cuchaz/enigma/gui/TokenListCellRenderer.java
new file mode 100644
index 0000000..9247c06
--- /dev/null
+++ b/src/cuchaz/enigma/gui/TokenListCellRenderer.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.awt.Component;
14
15import javax.swing.DefaultListCellRenderer;
16import javax.swing.JLabel;
17import javax.swing.JList;
18import javax.swing.ListCellRenderer;
19
20import cuchaz.enigma.analysis.Token;
21
22public class TokenListCellRenderer implements ListCellRenderer<Token>
23{
24 private GuiController m_controller;
25 private DefaultListCellRenderer m_defaultRenderer;
26
27 public TokenListCellRenderer( GuiController controller )
28 {
29 m_controller = controller;
30 m_defaultRenderer = new DefaultListCellRenderer();
31 }
32
33 @Override
34 public Component getListCellRendererComponent( JList<? extends Token> list, Token token, int index, boolean isSelected, boolean hasFocus )
35 {
36 JLabel label = (JLabel)m_defaultRenderer.getListCellRendererComponent( list, token, index, isSelected, hasFocus );
37 label.setText( m_controller.getReadableToken( token ).toString() );
38 return label;
39 }
40}