001/* A tableau representing a Doc window.
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 */
027package ptolemy.vergil.actor;
028
029import java.net.MalformedURLException;
030import java.net.URL;
031
032import ptolemy.actor.gui.Configuration;
033import ptolemy.actor.gui.Effigy;
034import ptolemy.actor.gui.MoMLApplication;
035import ptolemy.actor.gui.Tableau;
036import ptolemy.actor.gui.TableauFactory;
037import ptolemy.kernel.util.IllegalActionException;
038import ptolemy.kernel.util.NameDuplicationException;
039import ptolemy.kernel.util.NamedObj;
040import ptolemy.vergil.basic.DocAttribute;
041
042///////////////////////////////////////////////////////////////////
043//// DocTableau
044
045/**
046 A tableau representing a documentation view in a toplevel window.
047 The URL that is viewed is given by the <i>url</i> parameter, and
048 can be either an absolute URL, a system fileName, or a resource that
049 can be loaded relative to the classpath.  For more information about how
050 the URL is specified, see MoMLApplication.specToURL().
051 <p>
052 The constructor of this
053 class creates the window. The text window itself is an instance
054 of DocViewer, and can be accessed using the getFrame() method.
055 As with other tableaux, this is an entity that is contained by
056 an effigy of a model.
057 There can be any number of instances of this class in an effigy.
058
059 @author  Edward A. Lee
060 @version $Id$
061 @since Ptolemy II 5.2
062 @Pt.ProposedRating Yellow (eal)
063 @Pt.AcceptedRating Red (cxh)
064 @see Effigy
065 @see DocViewer
066 @see MoMLApplication#specToURL(String)
067 */
068public class DocTableau extends Tableau {
069
070    /** Construct a new tableau for the model represented by the given effigy.
071     *  This creates an instance of DocViewer.  It does not make the frame
072     *  visible.  To do that, call show().
073     *  @param container The container.
074     *  @param name The name.
075     *  @exception IllegalActionException If the container does not accept
076     *   this entity (this should not occur).
077     *  @exception NameDuplicationException If the name coincides with an
078     *   attribute already in the container.
079     */
080    public DocTableau(Effigy container, String name)
081            throws IllegalActionException, NameDuplicationException {
082        super(container, name);
083        if (!(container instanceof DocEffigy)) {
084            throw new IllegalActionException(container,
085                    "Needs to be an instance of DocEffigy to contain a DocTableau.");
086        }
087        DocAttribute docAttribute = ((DocEffigy) container).getDocAttribute();
088        if (docAttribute != null) {
089            // Have a doc attribute.
090            DocViewer frame = new DocViewer(docAttribute.getContainer(),
091                    (Configuration) container.toplevel());
092            setFrame(frame);
093            frame.setTableau(this);
094        } else {
095            // No doc attribute. Find the URL of the enclosing effigy.
096            try {
097                URL effigyURL = container.uri.getURL();
098                DocViewer frame = new DocViewer(effigyURL,
099                        (Configuration) container.toplevel());
100                setFrame(frame);
101                frame.setTableau(this);
102            } catch (MalformedURLException e) {
103                throw new IllegalActionException(this, container, e,
104                        "Malformed URL");
105            }
106        }
107    }
108
109    ///////////////////////////////////////////////////////////////////
110    ////                         inner classes                     ////
111
112    /** A factory that creates Doc viewer tableaux for Ptolemy models.
113     */
114    public static class Factory extends TableauFactory {
115        /** Create a factory with the given name and container.
116         *  @param container The container.
117         *  @param name The name.
118         *  @exception IllegalActionException If the container is incompatible
119         *   with this attribute.
120         *  @exception NameDuplicationException If the name coincides with
121         *   an attribute already in the container.
122         */
123        public Factory(NamedObj container, String name)
124                throws IllegalActionException, NameDuplicationException {
125            super(container, name);
126        }
127
128        ///////////////////////////////////////////////////////////////////
129        ////                         public methods                    ////
130
131        /** If the specified effigy already contains a tableau named
132         *  "DocTableau", then return that tableau; otherwise, create
133         *  a new instance of DocTableau in the specified
134         *  effigy, and name it "DocTableau".  If the specified
135         *  effigy is not an instance of DocEffigy, then do not
136         *  create a tableau and return null.  It is the
137         *  responsibility of callers of this method to check the
138         *  return value and call show().
139         *
140         *  @param effigy The effigy.
141         *  @return A Doc viewer tableau, or null if one cannot be
142         *    found or created.
143         *  @exception Exception If the factory should be able to create a
144         *   tableau for the effigy, but something goes wrong.
145         */
146        @Override
147        public Tableau createTableau(Effigy effigy) throws Exception {
148            if (effigy instanceof DocEffigy) {
149                // Indicate to the effigy that this factory contains effigies
150                // offering multiple views of the effigy data.
151                effigy.setTableauFactory(this);
152
153                // First see whether the effigy already contains an
154                // DocTableau.
155                DocTableau tableau = (DocTableau) effigy
156                        .getEntity("DocTableau");
157
158                if (tableau == null) {
159                    tableau = new DocTableau(effigy, "DocTableau");
160                }
161                // Don't call show() here.  If show() is called here,
162                // then you can't set the size of the window after
163                // createTableau() returns.  This will affect how
164                // centering works.
165                return tableau;
166            } else {
167                return null;
168            }
169        }
170    }
171}