001/* A GUI that builds the Java and Actor documentation.
002
003 Copyright (c) 2006-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.actor;
029
030import java.awt.BorderLayout;
031import java.awt.Dimension;
032import java.awt.GridLayout;
033import java.awt.event.ActionEvent;
034import java.awt.event.ActionListener;
035import java.net.URL;
036
037import javax.swing.BorderFactory;
038import javax.swing.BoxLayout;
039import javax.swing.JButton;
040import javax.swing.JPanel;
041import javax.swing.JScrollPane;
042import javax.swing.JSplitPane;
043import javax.swing.JTextArea;
044
045import ptolemy.actor.gui.Configuration;
046import ptolemy.actor.gui.Configurer;
047import ptolemy.actor.gui.PtolemyFrame;
048import ptolemy.actor.gui.Tableau;
049import ptolemy.gui.JTextAreaExec;
050import ptolemy.kernel.util.IllegalActionException;
051import ptolemy.kernel.util.InternalErrorException;
052import ptolemy.kernel.util.NameDuplicationException;
053import ptolemy.kernel.util.StringAttribute;
054import ptolemy.util.ClassUtilities;
055import ptolemy.util.MessageHandler;
056
057//////////////////////////////////////////////////////////////////////////
058//// DocBuilderGUI
059
060/**
061 A PtolemyFrame that builds the Java and Actor documentation.
062
063 @author Christopher Brooks
064 @version $Id$
065 @since Ptolemy II 5.2
066 @Pt.ProposedRating Green (cxh)
067 @Pt.AcceptedRating Red (eal)
068 */
069@SuppressWarnings("serial")
070public class DocBuilderGUI extends PtolemyFrame {
071
072    /** Construct a frame to build the Java and Actor documentation.
073     *  After constructing this, it is necessary to
074     *  call setVisible(true) to make the frame appear.  This is
075     *  typically accomplished by calling show() on enclosing tableau.
076     *
077     *  @param docBuilder The doc builder object associated with this builder.
078     *  @param tableau The tableau responsible for this frame.
079     *  @exception IllegalActionException If the model rejects the
080     *   configuration attribute.
081     *  @exception NameDuplicationException If a name collision occurs.
082     */
083    public DocBuilderGUI(final DocBuilder docBuilder, Tableau tableau)
084            throws IllegalActionException, NameDuplicationException {
085        super(docBuilder, tableau);
086
087        setTitle("Ptolemy II Java and Actor Documentation Builder");
088
089        if (getEffigy() == null) {
090            throw new InternalErrorException("Cannot get an effigy!");
091        }
092
093        // Caveats panel.
094        JPanel caveatsPanel = new JPanel();
095        caveatsPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
096        caveatsPanel.setLayout(new BoxLayout(caveatsPanel, BoxLayout.X_AXIS));
097
098        // We handle the applicationName specially so that we create
099        // only the docs for the app we are running.
100        Configuration configuration = getConfiguration();
101
102        try {
103            StringAttribute applicationNameAttribute = (StringAttribute) configuration
104                    .getAttribute("_applicationName", StringAttribute.class);
105
106            if (applicationNameAttribute != null) {
107                _applicationName = applicationNameAttribute.getExpression();
108            }
109        } catch (Throwable throwable) {
110            // Ignore and use the default applicationName
111        }
112
113        JTextArea messageArea = new JTextArea(
114                "NOTE: Use this tool to build the Java"
115                        + " and Actor Documentation"
116                        + (_applicationName != null ? "for " + _applicationName
117                                : "")
118                        + ".");
119        messageArea.setEditable(false);
120        messageArea.setBorder(BorderFactory.createEtchedBorder());
121        messageArea.setLineWrap(true);
122        messageArea.setWrapStyleWord(true);
123        caveatsPanel.add(messageArea);
124
125        JButton moreInfoButton = new JButton("More Info");
126        moreInfoButton.addActionListener(new ActionListener() {
127            @Override
128            public void actionPerformed(ActionEvent evt) {
129                String infoFile = "ptolemy/vergil/actor/docViewerHelp.htm";
130                try {
131                    Configuration configuration = getConfiguration();
132
133                    // FIXME: Help should bring this up as well.
134                    URL infoURL = ClassUtilities.getResource(infoFile);
135                    configuration.openModel(null, infoURL,
136                            infoURL.toExternalForm());
137                } catch (Exception ex) {
138                    throw new InternalErrorException(docBuilder, ex,
139                            "Failed to open " + infoFile);
140                }
141            }
142        });
143        caveatsPanel.add(moreInfoButton);
144
145        JPanel left = new JPanel();
146        left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
147        caveatsPanel.setMaximumSize(new Dimension(500, 100));
148        left.add(caveatsPanel);
149
150        // Panel for push buttons.
151        JPanel buttonPanel = new JPanel();
152        buttonPanel.setLayout(new GridLayout(1, 4));
153
154        JButton goButton = new JButton("Generate");
155        goButton.setToolTipText("Generate documentation");
156        buttonPanel.add(goButton);
157
158        JButton stopButton = new JButton("Cancel");
159        stopButton.setToolTipText("Terminate executing processes");
160        buttonPanel.add(stopButton);
161
162        JButton clearButton = new JButton("Clear");
163        clearButton.setToolTipText("Clear Log");
164        buttonPanel.add(clearButton);
165
166        buttonPanel.setMaximumSize(new Dimension(500, 50));
167        left.add(buttonPanel);
168
169        Configurer configurer = new Configurer(docBuilder);
170        JPanel controlPanel = new JPanel();
171        controlPanel.add(configurer);
172
173        JScrollPane scrollPane = new JScrollPane(controlPanel);
174
175        left.add(scrollPane, BorderLayout.CENTER);
176
177        // Create a JTextAreaExec without Start and Cancel buttons.
178        final JTextAreaExec exec = new JTextAreaExec(
179                "Documentation Builder" + " Commands", false);
180
181        exec.setPreferredSize(new Dimension(500, 300));
182
183        docBuilder.setConfiguration(configuration);
184
185        // If we execute any commands, print the output in the text area.
186        docBuilder.setExecuteCommands(exec);
187
188        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left,
189                exec);
190        splitPane.setOneTouchExpandable(true);
191
192        // Adjust the divider so that the control panel does not
193        // have a horizontal scrollbar.
194        Dimension preferred = left.getPreferredSize();
195        splitPane.setDividerLocation(preferred.width + 20);
196
197        getContentPane().add(splitPane, BorderLayout.CENTER);
198
199        stopButton.addActionListener(new ActionListener() {
200            @Override
201            public void actionPerformed(ActionEvent evt) {
202                exec.cancel();
203            }
204        });
205
206        clearButton.addActionListener(new ActionListener() {
207            @Override
208            public void actionPerformed(ActionEvent evt) {
209                exec.clear();
210            }
211        });
212
213        goButton.addActionListener(new ActionListener() {
214            @Override
215            public void actionPerformed(ActionEvent evt) {
216                try {
217                    exec.updateStatusBar("// Starting Doc Building"
218                            + (_applicationName != null
219                                    ? " for " + _applicationName
220                                    : ""));
221
222                    docBuilder.buildDocs();
223
224                    exec.updateStatusBar(" ");
225                } catch (Exception ex) {
226                    MessageHandler.error("Doc Building failed.", ex);
227                }
228            }
229        });
230    }
231
232    /** The name of the application, usually from the _applicationName
233     *  StringAttribute in configuration.xml.
234     *  If null, then use the default documentation in doc/codeDoc.
235     */
236    private String _applicationName;
237}