• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.gui;
22 
23 import proguard.optimize.Optimizer;
24 import proguard.util.*;
25 
26 import javax.swing.*;
27 import javax.swing.border.*;
28 import java.awt.*;
29 import java.awt.event.*;
30 
31 /**
32  * This <code>JDialog</code> allows the user to enter a String.
33  *
34  * @author Eric Lafortune
35  */
36 final class OptimizationsDialog extends JDialog
37 {
38     /**
39      * Return value if the dialog is canceled (with the Cancel button or by
40      * closing the dialog window).
41      */
42     public static final int CANCEL_OPTION = 1;
43 
44     /**
45      * Return value if the dialog is approved (with the Ok button).
46      */
47     public static final int APPROVE_OPTION = 0;
48 
49 
50     private final JCheckBox[] optimizationCheckBoxes = new JCheckBox[Optimizer.OPTIMIZATION_NAMES.length];
51 
52     private int returnValue;
53 
54 
OptimizationsDialog(JFrame owner)55     public OptimizationsDialog(JFrame owner)
56     {
57         super(owner, msg("selectOptimizations"), true);
58         setResizable(true);
59 
60         // Create some constraints that can be reused.
61         GridBagConstraints constraintsLast = new GridBagConstraints();
62         constraintsLast.gridwidth = GridBagConstraints.REMAINDER;
63         constraintsLast.anchor    = GridBagConstraints.WEST;
64         constraintsLast.insets    = new Insets(1, 2, 1, 2);
65 
66         GridBagConstraints constraintsLastStretch = new GridBagConstraints();
67         constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER;
68         constraintsLastStretch.fill      = GridBagConstraints.HORIZONTAL;
69         constraintsLastStretch.weightx   = 1.0;
70         constraintsLastStretch.anchor    = GridBagConstraints.WEST;
71         constraintsLastStretch.insets    = constraintsLast.insets;
72 
73         GridBagConstraints panelConstraints = new GridBagConstraints();
74         panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
75         panelConstraints.fill      = GridBagConstraints.HORIZONTAL;
76         panelConstraints.weightx   = 1.0;
77         panelConstraints.weighty   = 0.0;
78         panelConstraints.anchor    = GridBagConstraints.NORTHWEST;
79         panelConstraints.insets    = constraintsLast.insets;
80 
81         GridBagConstraints selectButtonConstraints = new GridBagConstraints();
82         selectButtonConstraints.weighty = 1.0;
83         selectButtonConstraints.anchor  = GridBagConstraints.SOUTHWEST;
84         selectButtonConstraints.insets  = new Insets(4, 4, 8, 4);
85 
86         GridBagConstraints okButtonConstraints = new GridBagConstraints();
87         okButtonConstraints.weightx = 1.0;
88         okButtonConstraints.weighty = 1.0;
89         okButtonConstraints.anchor  = GridBagConstraints.SOUTHEAST;
90         okButtonConstraints.insets  = selectButtonConstraints.insets;
91 
92         GridBagConstraints cancelButtonConstraints = new GridBagConstraints();
93         cancelButtonConstraints.gridwidth = GridBagConstraints.REMAINDER;
94         cancelButtonConstraints.weighty   = 1.0;
95         cancelButtonConstraints.anchor    = GridBagConstraints.SOUTHEAST;
96         cancelButtonConstraints.insets    = selectButtonConstraints.insets;
97 
98         GridBagLayout layout = new GridBagLayout();
99 
100         Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
101 
102         // Create the optimizations panel.
103         JPanel optimizationsPanel     = new JPanel(layout);
104         JPanel optimizationSubpanel   = null;
105         String lastOptimizationPrefix = null;
106 
107         for (int index = 0; index < Optimizer.OPTIMIZATION_NAMES.length; index++)
108         {
109             String optimizationName = Optimizer.OPTIMIZATION_NAMES[index];
110 
111             String optimizationPrefix = optimizationName.substring(0, optimizationName.indexOf('/'));
112 
113             if (optimizationSubpanel == null || !optimizationPrefix.equals(lastOptimizationPrefix))
114             {
115                 // Create a new keep subpanel and add it.
116                 optimizationSubpanel = new JPanel(layout);
117                 optimizationSubpanel.setBorder(BorderFactory.createTitledBorder(etchedBorder, msg(optimizationPrefix)));
118                 optimizationsPanel.add(optimizationSubpanel, panelConstraints);
119 
120                 lastOptimizationPrefix = optimizationPrefix;
121             }
122 
123             JCheckBox optimizationCheckBox = new JCheckBox(optimizationName);
124             optimizationCheckBoxes[index] = optimizationCheckBox;
125 
126             optimizationSubpanel.add(tip(optimizationCheckBox, optimizationName.replace('/', '_')+"Tip"), constraintsLastStretch);
127         }
128 
129         // Create the Select All button.
130         JButton selectAllButton = new JButton(msg("selectAll"));
131         selectAllButton.addActionListener(new ActionListener()
132         {
133             public void actionPerformed(ActionEvent e)
134             {
135                 for (int index = 0; index < optimizationCheckBoxes.length; index++)
136                 {
137                     optimizationCheckBoxes[index].setSelected(true);
138                 }
139             }
140         });
141 
142         // Create the Select All button.
143         JButton selectNoneButton = new JButton(msg("selectNone"));
144         selectNoneButton.addActionListener(new ActionListener()
145         {
146             public void actionPerformed(ActionEvent e)
147             {
148                 for (int index = 0; index < optimizationCheckBoxes.length; index++)
149                 {
150                     optimizationCheckBoxes[index].setSelected(false);
151                 }
152             }
153         });
154 
155         // Create the Ok button.
156         JButton okButton = new JButton(msg("ok"));
157         okButton.addActionListener(new ActionListener()
158         {
159             public void actionPerformed(ActionEvent e)
160             {
161                 returnValue = APPROVE_OPTION;
162                 hide();
163             }
164         });
165 
166         // Create the Cancel button.
167         JButton cancelButton = new JButton(msg("cancel"));
168         cancelButton.addActionListener(new ActionListener()
169         {
170             public void actionPerformed(ActionEvent e)
171             {
172                 hide();
173             }
174         });
175 
176         // Add all panels to the main panel.
177         optimizationsPanel.add(selectAllButton,  selectButtonConstraints);
178         optimizationsPanel.add(selectNoneButton, selectButtonConstraints);
179         optimizationsPanel.add(okButton,         okButtonConstraints);
180         optimizationsPanel.add(cancelButton,     cancelButtonConstraints);
181 
182         getContentPane().add(new JScrollPane(optimizationsPanel));
183     }
184 
185 
186     /**
187      * Sets the initial optimization filter to be used by the dialog.
188      */
setFilter(String optimizations)189     public void setFilter(String optimizations)
190     {
191         StringMatcher filter = optimizations != null && optimizations.length() > 0 ?
192             new ListParser(new NameParser()).parse(optimizations) :
193             new FixedStringMatcher("");
194 
195         for (int index = 0; index < Optimizer.OPTIMIZATION_NAMES.length; index++)
196         {
197             optimizationCheckBoxes[index].setSelected(filter.matches(Optimizer.OPTIMIZATION_NAMES[index]));
198         }
199     }
200 
201 
202     /**
203      * Returns the optimization filter composed from the settings in the dialog.
204      */
getFilter()205     public String getFilter()
206     {
207         return new FilterBuilder(optimizationCheckBoxes, '/').buildFilter();
208     }
209 
210 
211     /**
212      * Shows this dialog. This method only returns when the dialog is closed.
213      *
214      * @return <code>CANCEL_OPTION</code> or <code>APPROVE_OPTION</code>,
215      *         depending on the choice of the user.
216      */
showDialog()217     public int showDialog()
218     {
219         returnValue = CANCEL_OPTION;
220 
221         // Open the dialog in the right place, then wait for it to be closed,
222         // one way or another.
223         pack();
224         setLocationRelativeTo(getOwner());
225         show();
226 
227         return returnValue;
228     }
229 
230 
231     /**
232      * Attaches the tool tip from the GUI resources that corresponds to the
233      * given key, to the given component.
234      */
tip(JComponent component, String messageKey)235     private static JComponent tip(JComponent component, String messageKey)
236     {
237         component.setToolTipText(msg(messageKey));
238 
239         return component;
240     }
241 
242 
243     /**
244      * Returns the message from the GUI resources that corresponds to the given
245      * key.
246      */
msg(String messageKey)247     private static String msg(String messageKey)
248     {
249          return GUIResources.getMessage(messageKey);
250     }
251 }