001    /*  Copyright 2004, David R. Cok 
002        Originally generated as part of a GUI interface to the
003        Esc/Java2 application.
004    */
005    
006    package escjava.gui;
007    
008    import java.lang.reflect.Field;
009    import javax.swing.*;
010    import java.awt.*;
011    import java.awt.event.FocusAdapter;
012    import java.awt.event.FocusEvent;
013    import java.awt.event.ActionEvent;
014    import java.awt.event.ActionListener;
015    
016    import escjava.translate.NoWarn;
017    import escjava.ast.TagConstants;
018    
019    /** This class creates and maintains a JPanel containing components for
020        controlling the various options that affect the running of the Esc/Java2
021        tool.
022    */
023    public class EscOptions extends JPanel implements ActionListener {
024    
025        /** A reference to the Options structure in the ESC tool,
026            which serves as the document for this GUI. 
027         */
028        protected escjava.Options doc;
029    
030        /** A reference to the Class object of escjava.Options.
031         */
032        static final public /*@non_null*/ Class escoptions = escjava.Options.class;
033    
034        /** These are the options that are actually portrayed in the
035            GUI.  The array contains the text string, field name and the tooltip.
036         */
037        static /*@non_null*/ String[][] optionsShown = {
038            {"Control of Input:", null, null},
039            {"source 1.4", "assertIsKeyword",       
040                    "When enabled, Java 1.4 source (including assert statements)\n"+
041                    "is parsed; when disabled 'assert' is treated as a nomal identifier" },
042    
043            {"enableassertions", "assertionsEnabled",
044                    "When enabled, Java assert statements are enabled;\n"+
045                    "when disabled, Java assert statements are ignored." },
046            //{"jmlAssertions",     
047            //      "When enabled, Java assert statements are\n"+
048            //      "treated like JML assert statements." },
049            {"parsePlus", "parsePlus",
050                    "When enabled, JML annotations in '//@' and\n"+
051                    "/*@' comments are parsed by the ESC/Java2 tool" },
052            {"Control of Output:",null,null},
053            {"noCautions",  "noCautions",
054                    "When enabled, no Caution messages are output" },
055            {"noSemicolonWarnings", "noSemicolonWarnings",
056                    "When enabled, no warnings about missing semicolons\n"+
057                    "are issued (JML requires terminating semicolons)" },
058            {"noNotCheckedWarnings", "noNotCheckedWarnings",
059                    "When enabled, no warnings about JML features that\n"+
060                    "are not implemented in ESC/Java2 are issued" },
061    
062            {"Debugging:", null, null},
063            {"verbose", "v",        "Shows lots of tracing output" },
064            {"showErrorLocation", "showErrorLocation",      "TBD description" },
065            {"showDesugaredSpecs", "desugaredSpecs",        "TBD description" },
066            //{"pxLog log",                 "TBD description" },
067            {"pgc", "pgc",          "TBD description" },
068            {"pdsa", "pdsa",                "TBD description" },
069            {"pvc", "pvc",          "TBD description" },
070            //{"testMode", "testMode",              "TBD description" },
071            };
072    
073        public EscOptions(escjava.Options doc) {
074            build(doc);
075        }
076    
077        public void init(escjava.Options doc) {
078            // FIXME - change this so it does not rebuild the GUI every time
079            build(doc);
080        }
081    
082        public void build(escjava.Options doc) {
083            this.doc = doc;
084            removeAll();
085            JButton jb;
086            setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS));
087    
088            JPanel misc = new JPanel();
089            misc.setLayout(new BoxLayout(misc,BoxLayout.PAGE_AXIS));
090            add(misc);
091            JPanel warningsB = new JPanel();
092            warningsB.setLayout(new BoxLayout(warningsB,BoxLayout.PAGE_AXIS));
093            add(warningsB);
094    
095            JPanel warningsHeader = new JPanel();
096            warningsHeader.setLayout(new BoxLayout(warningsHeader,BoxLayout.LINE_AXIS));
097            warningsHeader.setAlignmentX(Component.LEFT_ALIGNMENT);
098            warningsB.add(warningsHeader);
099    
100            JPanel warnings = new JPanel(new GridLayout(0,2));
101            warnings.setAlignmentX(Component.LEFT_ALIGNMENT);
102            warningsB.add(warnings);
103    
104            warningsB.add(Box.createVerticalGlue());
105            
106            warningsHeader.add(new JLabel(" Warning Types:  "));
107            //warningsHeader.add(Box.createHorizontalGlue());
108            warningsHeader.add(jb = new JButton("Disable All"));
109            jb.addActionListener( new ActionListener() {
110                public void actionPerformed(ActionEvent e) {
111                    NoWarn.setAllChkStatus(TagConstants.CHK_AS_ASSUME);
112                    init(GUI.gui.options());
113                }
114            });
115            warningsHeader.add(jb = new JButton("Enable All"));
116            jb.addActionListener( new ActionListener() {
117                public void actionPerformed(ActionEvent e) {
118                    NoWarn.setAllChkStatus(TagConstants.CHK_AS_ASSERT);
119                    init(GUI.gui.options());
120                }
121            });
122    
123            final JTextField simplify = new JTextField(System.getProperty("simplify"));
124            JPanel simplifyHeader = new JPanel();
125            simplifyHeader.setLayout(new BoxLayout(simplifyHeader,BoxLayout.LINE_AXIS));
126            simplifyHeader.add(new JLabel("Path to SIMPLIFY executable:  "));
127            //simplifyHeader.add(Box.createHorizontalGlue());
128            simplifyHeader.add(jb = new JButton("Browse"));
129            jb.addActionListener( new ActionListener() {
130                public void actionPerformed(ActionEvent e) {
131                    JFileChooser fc = new JFileChooser();
132                    fc.setApproveButtonText("Select");
133                    int returnVal = fc.showOpenDialog(EscOptions.this);
134                    if (returnVal == JFileChooser.APPROVE_OPTION) {
135                        java.io.File file = fc.getSelectedFile();
136                        String name = file.getAbsolutePath();
137                        simplify.setText(name);
138                        System.setProperty("simplify",name);
139                    }
140                }
141            });
142            simplifyHeader.setAlignmentX(Component.LEFT_ALIGNMENT);
143    
144            misc.add(simplifyHeader);
145    
146            // For some reason the maximum height of a JTextField is very large,
147            // so it does not behave well in a Boxlayout.
148            simplify.setColumns(30);
149            simplify.setMaximumSize(simplify.getPreferredSize());
150            misc.add(simplify);
151            simplify.addActionListener(
152                new ActionListener() {
153                    public void actionPerformed(ActionEvent e) {
154                        System.setProperty("simplify",simplify.getText());
155                    }
156                });
157            simplify.addFocusListener(
158                new FocusAdapter() {
159                    public void focusLost(FocusEvent e) {
160                        System.setProperty("simplify",simplify.getText());
161                    }
162                });
163            simplify.setAlignmentX(Component.LEFT_ALIGNMENT);
164            
165            JCheckBox cb;
166            for (int i = 0; i<optionsShown.length; ++i) {
167                String[] opttext = optionsShown[i];
168                if (opttext[1] == null) {
169                    misc.add(new JLabel(opttext[0]));
170                } else {
171                    try {
172                        boolean b = false;
173                        try {
174                            Field f = escoptions.getField(opttext[1]);
175                            b = f.getBoolean(escjava.Main.options());
176                        } catch (Exception e) {
177                            // Some options do not have fields.  These are special
178                            // cases and are ok.  We presume they are false by
179                            // default.
180                        }
181                        cb = new JCheckBox(opttext[0],b);
182                        cb.setAlignmentX(Component.LEFT_ALIGNMENT);
183                        cb.setToolTipText(opttext[2]);
184                        cb.addActionListener(this);
185                        misc.add(cb);
186                    } catch (Exception e) {
187                        JOptionPane.showMessageDialog(this,
188                            "Please report an INTERNAL ERROR: " + Project.eol +
189                            "An exception occurred while building the GUI " +
190                            "component with label " + opttext[0] + Project.eol +
191                            e);
192                    }
193                }
194            }
195            misc.add(Box.createVerticalGlue());
196    
197            ActionListener a = new MListener();
198            String[] wnames = escjava.ast.TagConstants.escchecks;
199            int n = wnames.length-4;
200            int nn = n/2;
201            int np =n-nn;
202            for (int i=0; i<nn; ++i) {
203                makeWarningOpt(wnames[i],warnings,a);
204                makeWarningOpt(wnames[i+np],warnings,a);
205            }
206            if (n%2 == 1) {
207                makeWarningOpt(wnames[nn],warnings,a);
208            }
209        }
210    
211        public void makeWarningOpt(/*@non_null*/ String name, 
212                                   /*@non_null*/ JPanel warnings, 
213                                   /*@non_null*/ ActionListener a) {
214            int tag = NoWarn.toNoWarnTag(name);
215            boolean b = NoWarn.getChkStatus(tag) != TagConstants.CHK_AS_ASSUME;
216            JCheckBox cb = new JCheckBox(name,b);
217            warnings.add(cb);
218            cb.addActionListener(a);
219            //cb.setToolTipText(opttext[2]);
220        }
221    
222            //@ also
223            //@   requires e != null;
224        public void actionPerformed(ActionEvent e) {
225            // write back out to the Options structure
226    
227            Object source = e.getSource();
228            String name = null;
229            if (source instanceof JCheckBox) {
230                String fname = null;
231                name = ((JCheckBox)source).getText();
232                for (int i=0; i<optionsShown.length; ++i) {
233                    if (name.equals(optionsShown[i][0])) {
234                        fname = optionsShown[i][1];
235                        break;
236                    }
237                }
238                boolean value = ((JCheckBox)source).isSelected();
239                if (fname == null) {
240                    JOptionPane.showMessageDialog(this,
241                        "Please report an INTERNAL ERROR: " + Project.eol +
242                        "GUI references an unlisted option - " + name);
243                } else if (fname.equals("v")) {
244                    javafe.util.Info.on = value;
245                } else try {
246                    Field f = escoptions.getField(fname);
247                    f.setBoolean(escjava.Main.options(),value);
248                } catch (Exception ee) {
249                    JOptionPane.showMessageDialog(this,
250                        "Please report an INTERNAL ERROR: " + Project.eol +
251                        "GUI failed to find an option " + fname +
252                        " for checkbox labeled " + name);
253                }
254            } else {
255                JOptionPane.showMessageDialog(this,
256                    "Please report an INTERNAL ERROR: " + Project.eol +
257                    "GUI named " + name +
258                    " is an unsupported component of type " + source.getClass());
259            }
260        }
261    
262        static public class MListener implements ActionListener {
263            static private /*@non_null*/ String[] temp = new String[1];
264            //@ also
265            //@   requires e != null;
266            public void actionPerformed(ActionEvent e) {
267                Object o = e.getSource();
268                if (o instanceof JCheckBox) {
269                    JCheckBox cb = (JCheckBox)o;
270                    boolean b = cb.isSelected();
271                    temp[0] = cb.getText();
272                    try {
273                        GUI.gui.options.processOption(
274                            b ? "-warn" : "-nowarn", temp, 0);
275                    } catch (javafe.util.UsageError ee) {
276                        // FIXME - internal error if this happens
277                    }
278                }
279            }
280        }
281    
282    }