summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui/Gui.java
diff options
context:
space:
mode:
authorGravatar jeff2014-08-04 00:26:48 -0400
committerGravatar jeff2014-08-04 00:26:48 -0400
commit57f45b0409d5363782052183bb090175c469f89a (patch)
tree672b32876b420445630e58e16b67d671e45c07b6 /src/cuchaz/enigma/gui/Gui.java
parentfixed bugs with saving mappings (diff)
downloadenigma-fork-57f45b0409d5363782052183bb090175c469f89a.tar.gz
enigma-fork-57f45b0409d5363782052183bb090175c469f89a.tar.xz
enigma-fork-57f45b0409d5363782052183bb090175c469f89a.zip
added stable save order for mappings to hopefully help with merging
added color-coding for source identifiers redesigned rename GUI customized editor pane, added popup menu finished name validation added last-chance save on window close
Diffstat (limited to 'src/cuchaz/enigma/gui/Gui.java')
-rw-r--r--src/cuchaz/enigma/gui/Gui.java354
1 files changed, 267 insertions, 87 deletions
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index 3f46b6e..87b9308 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -11,6 +11,7 @@
11package cuchaz.enigma.gui; 11package cuchaz.enigma.gui;
12 12
13import java.awt.BorderLayout; 13import java.awt.BorderLayout;
14import java.awt.Color;
14import java.awt.Container; 15import java.awt.Container;
15import java.awt.Dimension; 16import java.awt.Dimension;
16import java.awt.FlowLayout; 17import java.awt.FlowLayout;
@@ -18,18 +19,21 @@ import java.awt.Font;
18import java.awt.GridLayout; 19import java.awt.GridLayout;
19import java.awt.event.ActionEvent; 20import java.awt.event.ActionEvent;
20import java.awt.event.ActionListener; 21import java.awt.event.ActionListener;
22import java.awt.event.KeyAdapter;
23import java.awt.event.KeyEvent;
21import java.awt.event.MouseAdapter; 24import java.awt.event.MouseAdapter;
22import java.awt.event.MouseEvent; 25import java.awt.event.MouseEvent;
26import java.awt.event.WindowAdapter;
27import java.awt.event.WindowEvent;
23import java.io.File; 28import java.io.File;
24import java.io.IOException; 29import java.io.IOException;
25import java.util.Collections; 30import java.util.Collections;
26import java.util.Comparator; 31import java.util.Comparator;
27import java.util.List; 32import java.util.List;
33import java.util.Map;
28import java.util.Vector; 34import java.util.Vector;
29 35
30import javax.swing.BorderFactory; 36import javax.swing.BorderFactory;
31import javax.swing.BoxLayout;
32import javax.swing.JButton;
33import javax.swing.JEditorPane; 37import javax.swing.JEditorPane;
34import javax.swing.JFileChooser; 38import javax.swing.JFileChooser;
35import javax.swing.JFrame; 39import javax.swing.JFrame;
@@ -38,7 +42,9 @@ import javax.swing.JList;
38import javax.swing.JMenu; 42import javax.swing.JMenu;
39import javax.swing.JMenuBar; 43import javax.swing.JMenuBar;
40import javax.swing.JMenuItem; 44import javax.swing.JMenuItem;
45import javax.swing.JOptionPane;
41import javax.swing.JPanel; 46import javax.swing.JPanel;
47import javax.swing.JPopupMenu;
42import javax.swing.JScrollPane; 48import javax.swing.JScrollPane;
43import javax.swing.JSplitPane; 49import javax.swing.JSplitPane;
44import javax.swing.JTextField; 50import javax.swing.JTextField;
@@ -47,17 +53,19 @@ import javax.swing.WindowConstants;
47import javax.swing.event.CaretEvent; 53import javax.swing.event.CaretEvent;
48import javax.swing.event.CaretListener; 54import javax.swing.event.CaretListener;
49import javax.swing.text.BadLocationException; 55import javax.swing.text.BadLocationException;
56import javax.swing.text.Highlighter;
50 57
51import jsyntaxpane.DefaultSyntaxKit; 58import jsyntaxpane.DefaultSyntaxKit;
59import jsyntaxpane.SyntaxDocument;
52import jsyntaxpane.Token; 60import jsyntaxpane.Token;
53import cuchaz.enigma.ClassFile; 61import cuchaz.enigma.ClassFile;
54import cuchaz.enigma.Constants; 62import cuchaz.enigma.Constants;
55import cuchaz.enigma.analysis.SourceIndex;
56import cuchaz.enigma.mapping.ArgumentEntry; 63import cuchaz.enigma.mapping.ArgumentEntry;
57import cuchaz.enigma.mapping.ClassEntry; 64import cuchaz.enigma.mapping.ClassEntry;
58import cuchaz.enigma.mapping.Entry; 65import cuchaz.enigma.mapping.Entry;
59import cuchaz.enigma.mapping.EntryPair; 66import cuchaz.enigma.mapping.EntryPair;
60import cuchaz.enigma.mapping.FieldEntry; 67import cuchaz.enigma.mapping.FieldEntry;
68import cuchaz.enigma.mapping.IllegalNameException;
61import cuchaz.enigma.mapping.MethodEntry; 69import cuchaz.enigma.mapping.MethodEntry;
62 70
63public class Gui 71public class Gui
@@ -86,14 +94,11 @@ public class Gui
86 // controls 94 // controls
87 private JFrame m_frame; 95 private JFrame m_frame;
88 private JList<ClassFile> m_obfClasses; 96 private JList<ClassFile> m_obfClasses;
89 private JList<ClassFile> m_deobfClasses; 97 private JList<Map.Entry<ClassFile,String>> m_deobfClasses;
90 private JEditorPane m_editor; 98 private JEditorPane m_editor;
91 private JPanel m_actionPanel; 99 private JPanel m_infoPanel;
92 private JPanel m_renamePanel; 100 private BoxHighlightPainter m_obfuscatedHighlightPainter;
93 private JLabel m_typeLabel; 101 private BoxHighlightPainter m_deobfuscatedHighlightPainter;
94 private JTextField m_nameField;
95 private JButton m_renameButton;
96 private BoxHighlightPainter m_highlightPainter;
97 102
98 // dynamic menu items 103 // dynamic menu items
99 private JMenuItem m_closeJarMenu; 104 private JMenuItem m_closeJarMenu;
@@ -101,6 +106,7 @@ public class Gui
101 private JMenuItem m_saveMappingsMenu; 106 private JMenuItem m_saveMappingsMenu;
102 private JMenuItem m_saveMappingsAsMenu; 107 private JMenuItem m_saveMappingsAsMenu;
103 private JMenuItem m_closeMappingsMenu; 108 private JMenuItem m_closeMappingsMenu;
109 private JMenuItem m_renameMenu;
104 110
105 // state 111 // state
106 private EntryPair<Entry> m_selectedEntryPair; 112 private EntryPair<Entry> m_selectedEntryPair;
@@ -124,7 +130,7 @@ public class Gui
124 m_obfClasses = new JList<ClassFile>(); 130 m_obfClasses = new JList<ClassFile>();
125 m_obfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 131 m_obfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
126 m_obfClasses.setLayoutOrientation( JList.VERTICAL ); 132 m_obfClasses.setLayoutOrientation( JList.VERTICAL );
127 m_obfClasses.setCellRenderer( new ClassListCellRenderer() ); 133 m_obfClasses.setCellRenderer( new ObfuscatedClassListCellRenderer() );
128 m_obfClasses.addMouseListener( new MouseAdapter() 134 m_obfClasses.addMouseListener( new MouseAdapter()
129 { 135 {
130 public void mouseClicked( MouseEvent event ) 136 public void mouseClicked( MouseEvent event )
@@ -146,20 +152,20 @@ public class Gui
146 obfPanel.add( obfScroller, BorderLayout.CENTER ); 152 obfPanel.add( obfScroller, BorderLayout.CENTER );
147 153
148 // init deobfuscated classes list 154 // init deobfuscated classes list
149 m_deobfClasses = new JList<ClassFile>(); 155 m_deobfClasses = new JList<Map.Entry<ClassFile,String>>();
150 m_deobfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 156 m_deobfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
151 m_deobfClasses.setLayoutOrientation( JList.VERTICAL ); 157 m_deobfClasses.setLayoutOrientation( JList.VERTICAL );
152 m_deobfClasses.setCellRenderer( new ClassListCellRenderer() ); 158 m_deobfClasses.setCellRenderer( new DeobfuscatedClassListCellRenderer() );
153 m_deobfClasses.addMouseListener( new MouseAdapter() 159 m_deobfClasses.addMouseListener( new MouseAdapter()
154 { 160 {
155 public void mouseClicked( MouseEvent event ) 161 public void mouseClicked( MouseEvent event )
156 { 162 {
157 if( event.getClickCount() == 2 ) 163 if( event.getClickCount() == 2 )
158 { 164 {
159 ClassFile selected = m_deobfClasses.getSelectedValue(); 165 Map.Entry<ClassFile,String> selected = m_deobfClasses.getSelectedValue();
160 if( selected != null ) 166 if( selected != null )
161 { 167 {
162 m_controller.deobfuscateClass( selected ); 168 m_controller.deobfuscateClass( selected.getKey() );
163 } 169 }
164 } 170 }
165 } 171 }
@@ -170,39 +176,20 @@ public class Gui
170 deobfPanel.add( new JLabel( "De-obfuscated Classes" ), BorderLayout.NORTH ); 176 deobfPanel.add( new JLabel( "De-obfuscated Classes" ), BorderLayout.NORTH );
171 deobfPanel.add( deobfScroller, BorderLayout.CENTER ); 177 deobfPanel.add( deobfScroller, BorderLayout.CENTER );
172 178
173 // init action panel 179 // init info panel
174 m_actionPanel = new JPanel(); 180 m_infoPanel = new JPanel();
175 m_actionPanel.setLayout( new BoxLayout( m_actionPanel, BoxLayout.Y_AXIS ) ); 181 m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) );
176 m_actionPanel.setPreferredSize( new Dimension( 0, 120 ) ); 182 m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) );
177 m_actionPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) ); 183 m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) );
178 m_nameField = new JTextField( 26 );
179 m_renameButton = new JButton( "Rename" );
180 m_renameButton.addActionListener( new ActionListener( )
181 {
182 @Override
183 public void actionPerformed( ActionEvent event )
184 {
185 if( m_selectedEntryPair != null )
186 {
187 m_controller.rename( m_selectedEntryPair.obf, m_nameField.getText() );
188 }
189 }
190 } );
191 m_renamePanel = new JPanel();
192 m_renamePanel.setLayout( new FlowLayout( FlowLayout.LEFT, 6, 0 ) );
193 m_typeLabel = new JLabel( "LongName:", JLabel.RIGHT );
194 // NOTE: this looks ridiculous, but it fixes the label size to the size of current text
195 m_typeLabel.setPreferredSize( m_typeLabel.getPreferredSize() );
196 m_renamePanel.add( m_typeLabel );
197 m_renamePanel.add( m_nameField );
198 m_renamePanel.add( m_renameButton );
199 clearEntryPair(); 184 clearEntryPair();
200 185
201 // init editor 186 // init editor
202 DefaultSyntaxKit.initKit(); 187 DefaultSyntaxKit.initKit();
203 m_highlightPainter = new BoxHighlightPainter(); 188 m_obfuscatedHighlightPainter = new ObfuscatedHighlightPainter();
189 m_deobfuscatedHighlightPainter = new DeobfuscatedHighlightPainter();
204 m_editor = new JEditorPane(); 190 m_editor = new JEditorPane();
205 m_editor.setEditable( false ); 191 m_editor.setEditable( false );
192 m_editor.setCaret( new BrowserCaret() );
206 JScrollPane sourceScroller = new JScrollPane( m_editor ); 193 JScrollPane sourceScroller = new JScrollPane( m_editor );
207 m_editor.setContentType( "text/java" ); 194 m_editor.setContentType( "text/java" );
208 m_editor.addCaretListener( new CaretListener( ) 195 m_editor.addCaretListener( new CaretListener( )
@@ -214,19 +201,55 @@ public class Gui
214 if( m_selectedEntryPair != null ) 201 if( m_selectedEntryPair != null )
215 { 202 {
216 showEntryPair( m_selectedEntryPair ); 203 showEntryPair( m_selectedEntryPair );
204 m_renameMenu.setEnabled( true );
217 } 205 }
218 else 206 else
219 { 207 {
220 clearEntryPair(); 208 clearEntryPair();
209 m_renameMenu.setEnabled( false );
221 } 210 }
222 } 211 }
223 } ); 212 } );
213 m_editor.addKeyListener( new KeyAdapter( )
214 {
215 @Override
216 public void keyPressed( KeyEvent event )
217 {
218 switch( event.getKeyCode() )
219 {
220 case KeyEvent.VK_R:
221 startRename();
222 break;
223 }
224 }
225 } );
226
227 // turn off token highlighting (it's wrong most of the time anyway...)
228 DefaultSyntaxKit kit = (DefaultSyntaxKit)m_editor.getEditorKit();
229 kit.toggleComponent( m_editor, "jsyntaxpane.components.TokenMarker" );
230
231 // init editor popup menu
232 JPopupMenu popupMenu = new JPopupMenu();
233 m_editor.setComponentPopupMenu( popupMenu );
234 {
235 JMenuItem menu = new JMenuItem( "Rename" );
236 menu.addActionListener( new ActionListener( )
237 {
238 @Override
239 public void actionPerformed( ActionEvent event )
240 {
241 startRename();
242 }
243 } );
244 popupMenu.add( menu );
245 m_renameMenu = menu;
246 }
224 247
225 // layout controls 248 // layout controls
226 JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); 249 JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel );
227 JPanel rightPanel = new JPanel(); 250 JPanel rightPanel = new JPanel();
228 rightPanel.setLayout( new BorderLayout() ); 251 rightPanel.setLayout( new BorderLayout() );
229 rightPanel.add( m_actionPanel, BorderLayout.NORTH ); 252 rightPanel.add( m_infoPanel, BorderLayout.NORTH );
230 rightPanel.add( sourceScroller, BorderLayout.CENTER ); 253 rightPanel.add( sourceScroller, BorderLayout.CENTER );
231 JSplitPane splitMain = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, rightPanel ); 254 JSplitPane splitMain = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, rightPanel );
232 pane.add( splitMain, BorderLayout.CENTER ); 255 pane.add( splitMain, BorderLayout.CENTER );
@@ -353,6 +376,19 @@ public class Gui
353 } ); 376 } );
354 m_closeMappingsMenu = item; 377 m_closeMappingsMenu = item;
355 } 378 }
379 menu.addSeparator();
380 {
381 JMenuItem item = new JMenuItem( "Exit" );
382 menu.add( item );
383 item.addActionListener( new ActionListener( )
384 {
385 @Override
386 public void actionPerformed( ActionEvent event )
387 {
388 close();
389 }
390 } );
391 }
356 } 392 }
357 { 393 {
358 JMenu menu = new JMenu( "Help" ); 394 JMenu menu = new JMenu( "Help" );
@@ -374,12 +410,21 @@ public class Gui
374 // init state 410 // init state
375 onCloseJar(); 411 onCloseJar();
376 412
413 m_frame.addWindowListener( new WindowAdapter( )
414 {
415 @Override
416 public void windowClosing( WindowEvent event )
417 {
418 close();
419 }
420 } );
421
377 // show the frame 422 // show the frame
378 pane.doLayout(); 423 pane.doLayout();
379 m_frame.setSize( 800, 600 ); 424 m_frame.setSize( 800, 600 );
380 m_frame.setMinimumSize( new Dimension( 640, 480 ) ); 425 m_frame.setMinimumSize( new Dimension( 640, 480 ) );
381 m_frame.setVisible( true ); 426 m_frame.setVisible( true );
382 m_frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE ); 427 m_frame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
383 } 428 }
384 429
385 public GuiController getController( ) 430 public GuiController getController( )
@@ -430,15 +475,15 @@ public class Gui
430 } 475 }
431 } 476 }
432 477
433 public void setDeobfClasses( List<ClassFile> classes ) 478 public void setDeobfClasses( Map<ClassFile,String> deobfClasses )
434 { 479 {
435 if( classes != null ) 480 if( deobfClasses != null )
436 { 481 {
437 m_deobfClasses.setListData( new Vector<ClassFile>( classes ) ); 482 m_deobfClasses.setListData( new Vector<Map.Entry<ClassFile,String>>( deobfClasses.entrySet() ) );
438 } 483 }
439 else 484 else
440 { 485 {
441 m_deobfClasses.setListData( new Vector<ClassFile>() ); 486 m_deobfClasses.setListData( new Vector<Map.Entry<ClassFile,String>>() );
442 } 487 }
443 } 488 }
444 489
@@ -450,48 +495,77 @@ public class Gui
450 495
451 public void setSource( String source ) 496 public void setSource( String source )
452 { 497 {
453 setSource( source, null ); 498 setSource( source, 0 );
454 } 499 }
455 500
456 public void setSource( String source, SourceIndex index ) 501 public void setSource( String source, int lineNum )
457 { 502 {
503 // remove any old highlighters
504 m_editor.getHighlighter().removeAllHighlights();
505
458 m_editor.setText( source ); 506 m_editor.setText( source );
459 setHighlightedTokens( null ); 507
508 // count the offset of the target line
509 String text = m_editor.getText();
510 int pos = 0;
511 int numLines = 0;
512 for( ; pos < text.length(); pos++ )
513 {
514 if( numLines == lineNum )
515 {
516 break;
517 }
518 if( text.charAt( pos ) == '\n' )
519 {
520 numLines++;
521 }
522 }
523
524 // put the caret at the line number
525 m_editor.setCaretPosition( pos );
526 m_editor.grabFocus();
460 } 527 }
461 528
462 public void setHighlightedTokens( Iterable<Token> tokens ) 529 public void setHighlightedTokens( Iterable<Token> obfuscatedTokens, Iterable<Token> deobfuscatedTokens )
463 { 530 {
464 // remove any old highlighters 531 // remove any old highlighters
465 m_editor.getHighlighter().removeAllHighlights(); 532 m_editor.getHighlighter().removeAllHighlights();
466 533
467 if( tokens == null ) 534 // color things based on the index
535 if( obfuscatedTokens != null )
468 { 536 {
469 return; 537 setHighlightedTokens( obfuscatedTokens, m_obfuscatedHighlightPainter );
538 }
539 if( deobfuscatedTokens != null )
540 {
541 setHighlightedTokens( deobfuscatedTokens, m_deobfuscatedHighlightPainter );
470 } 542 }
471 543
472 // color things based on the index 544 redraw();
545 }
546
547 private void setHighlightedTokens( Iterable<Token> tokens, Highlighter.HighlightPainter painter )
548 {
473 for( Token token : tokens ) 549 for( Token token : tokens )
474 { 550 {
475 try 551 try
476 { 552 {
477 m_editor.getHighlighter().addHighlight( token.start, token.end(), m_highlightPainter ); 553 m_editor.getHighlighter().addHighlight( token.start, token.end(), painter );
478 } 554 }
479 catch( BadLocationException ex ) 555 catch( BadLocationException ex )
480 { 556 {
481 throw new IllegalArgumentException( ex ); 557 throw new IllegalArgumentException( ex );
482 } 558 }
483 } 559 }
484
485 redraw();
486 } 560 }
487 561
488 private void clearEntryPair( ) 562 private void clearEntryPair( )
489 { 563 {
490 m_actionPanel.removeAll(); 564 m_infoPanel.removeAll();
491 JLabel label = new JLabel( "No identifier selected" ); 565 JLabel label = new JLabel( "No identifier selected" );
492 unboldLabel( label ); 566 unboldLabel( label );
493 label.setHorizontalAlignment( JLabel.CENTER ); 567 label.setHorizontalAlignment( JLabel.CENTER );
494 m_actionPanel.add( label ); 568 m_infoPanel.add( label );
495 569
496 redraw(); 570 redraw();
497 } 571 }
@@ -507,30 +581,22 @@ public class Gui
507 581
508 m_selectedEntryPair = pair; 582 m_selectedEntryPair = pair;
509 583
510 // layout the action panel 584 m_infoPanel.removeAll();
511 m_actionPanel.removeAll();
512 m_actionPanel.add( m_renamePanel );
513 m_nameField.setText( pair.deobf.getName() );
514
515 // layout the dynamic section
516 JPanel dynamicPanel = new JPanel();
517 dynamicPanel.setLayout( new GridLayout( 3, 1, 0, 0 ) );
518 m_actionPanel.add( dynamicPanel );
519 if( pair.deobf instanceof ClassEntry ) 585 if( pair.deobf instanceof ClassEntry )
520 { 586 {
521 showClassEntryPair( (EntryPair<? extends ClassEntry>)pair, dynamicPanel ); 587 showClassEntryPair( (EntryPair<? extends ClassEntry>)pair );
522 } 588 }
523 else if( pair.deobf instanceof FieldEntry ) 589 else if( pair.deobf instanceof FieldEntry )
524 { 590 {
525 showFieldEntryPair( (EntryPair<? extends FieldEntry>)pair, dynamicPanel ); 591 showFieldEntryPair( (EntryPair<? extends FieldEntry>)pair );
526 } 592 }
527 else if( pair.deobf instanceof MethodEntry ) 593 else if( pair.deobf instanceof MethodEntry )
528 { 594 {
529 showMethodEntryPair( (EntryPair<? extends MethodEntry>)pair, dynamicPanel ); 595 showMethodEntryPair( (EntryPair<? extends MethodEntry>)pair );
530 } 596 }
531 else if( pair.deobf instanceof ArgumentEntry ) 597 else if( pair.deobf instanceof ArgumentEntry )
532 { 598 {
533 showArgumentEntryPair( (EntryPair<? extends ArgumentEntry>)pair, dynamicPanel ); 599 showArgumentEntryPair( (EntryPair<? extends ArgumentEntry>)pair );
534 } 600 }
535 else 601 else
536 { 602 {
@@ -540,30 +606,30 @@ public class Gui
540 redraw(); 606 redraw();
541 } 607 }
542 608
543 private void showClassEntryPair( EntryPair<? extends ClassEntry> pair, JPanel panel ) 609 private void showClassEntryPair( EntryPair<? extends ClassEntry> pair )
544 { 610 {
545 m_typeLabel.setText( "Class: " ); 611 addNameValue( m_infoPanel, "Class", pair.deobf.getName() );
546 } 612 }
547 613
548 private void showFieldEntryPair( EntryPair<? extends FieldEntry> pair, JPanel panel ) 614 private void showFieldEntryPair( EntryPair<? extends FieldEntry> pair )
549 { 615 {
550 m_typeLabel.setText( "Field: " ); 616 addNameValue( m_infoPanel, "Field", pair.deobf.getName() );
551 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() ); 617 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() );
552 } 618 }
553 619
554 private void showMethodEntryPair( EntryPair<? extends MethodEntry> pair, JPanel panel ) 620 private void showMethodEntryPair( EntryPair<? extends MethodEntry> pair )
555 { 621 {
556 m_typeLabel.setText( "Method: " ); 622 addNameValue( m_infoPanel, "Method", pair.deobf.getName() );
557 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() ); 623 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() );
558 addNameValue( panel, "Signature", pair.obf.getSignature() + " <-> " + pair.deobf.getSignature() ); 624 addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() );
559 } 625 }
560 626
561 private void showArgumentEntryPair( EntryPair<? extends ArgumentEntry> pair, JPanel panel ) 627 private void showArgumentEntryPair( EntryPair<? extends ArgumentEntry> pair )
562 { 628 {
563 m_typeLabel.setText( "Argument: " ); 629 addNameValue( m_infoPanel, "Argument", pair.deobf.getName() );
564 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() ); 630 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() );
565 addNameValue( panel, "Method", pair.obf.getMethodEntry().getName() + " <-> " + pair.deobf.getMethodEntry().getName() ); 631 addNameValue( m_infoPanel, "Method", pair.deobf.getMethodEntry().getName() );
566 addNameValue( panel, "Index", Integer.toString( pair.obf.getIndex() ) ); 632 addNameValue( m_infoPanel, "Index", Integer.toString( pair.deobf.getIndex() ) );
567 } 633 }
568 634
569 private void addNameValue( JPanel container, String name, String value ) 635 private void addNameValue( JPanel container, String name, String value )
@@ -578,6 +644,120 @@ public class Gui
578 644
579 panel.add( unboldLabel( new JLabel( value, JLabel.LEFT ) ) ); 645 panel.add( unboldLabel( new JLabel( value, JLabel.LEFT ) ) );
580 } 646 }
647
648 private void startRename( )
649 {
650 // init the text box
651 final JTextField text = new JTextField();
652 text.setText( m_selectedEntryPair.deobf.getName() );
653 text.setPreferredSize( new Dimension( 360, text.getPreferredSize().height ) );
654 text.addKeyListener( new KeyAdapter( )
655 {
656 @Override
657 public void keyPressed( KeyEvent event )
658 {
659 switch( event.getKeyCode() )
660 {
661 case KeyEvent.VK_ENTER:
662 finishRename( text, true );
663 break;
664
665 case KeyEvent.VK_ESCAPE:
666 finishRename( text, false );
667 break;
668 }
669 }
670 } );
671
672 // find the label with the name and replace it with the text box
673 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 );
674 panel.remove( panel.getComponentCount() - 1 );
675 panel.add( text );
676 text.grabFocus();
677 text.selectAll();
678
679 redraw();
680 }
681
682 private void finishRename( JTextField text, boolean saveName )
683 {
684 String newName = text.getText();
685 if( saveName && newName != null && newName.length() > 0 )
686 {
687 SyntaxDocument doc = (SyntaxDocument)m_editor.getDocument();
688 int lineNum = doc.getLineNumberAt( m_editor.getCaretPosition() );
689 try
690 {
691 m_controller.rename( m_selectedEntryPair.obf, newName, lineNum );
692 }
693 catch( IllegalNameException ex )
694 {
695 text.setBorder( BorderFactory.createLineBorder( Color.red, 1 ) );
696 }
697 return;
698 }
699
700 // abort the rename
701 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 );
702 panel.remove( panel.getComponentCount() - 1 );
703 panel.add( unboldLabel( new JLabel( m_selectedEntryPair.deobf.getName(), JLabel.LEFT ) ) );
704
705 m_editor.grabFocus();
706
707 redraw();
708 }
709
710 private void close( )
711 {
712 if( !m_controller.isDirty() )
713 {
714 // everything is saved, we can exit safely
715 m_frame.dispose();
716 }
717 else
718 {
719 // ask to save before closing
720 String[] options = {
721 "Save and exit",
722 "Discard changes",
723 "Cancel"
724 };
725 int response = JOptionPane.showOptionDialog(
726 m_frame,
727 "Your mappings have not been saved yet. Do you want to save?",
728 "Save your changes?",
729 JOptionPane.YES_NO_CANCEL_OPTION,
730 JOptionPane.QUESTION_MESSAGE,
731 null,
732 options,
733 options[2]
734 );
735 switch( response )
736 {
737 case JOptionPane.YES_OPTION: // save and exit
738 if( m_mappingsFileChooser.getSelectedFile() != null || m_mappingsFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION )
739 {
740 try
741 {
742 m_controller.saveMappings( m_mappingsFileChooser.getSelectedFile() );
743 m_frame.dispose();
744 }
745 catch( IOException ex )
746 {
747 throw new Error( ex );
748 }
749 }
750 break;
751
752 case JOptionPane.NO_OPTION:
753 // don't save, exit
754 m_frame.dispose();
755 break;
756
757 // cancel means do nothing
758 }
759 }
760 }
581 761
582 private JLabel unboldLabel( JLabel label ) 762 private JLabel unboldLabel( JLabel label )
583 { 763 {