001/* An attribute that displays documentation. 002 003 Copyright (c) 2003-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_3 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.vergil.kernel.attributes; 028 029import java.awt.Color; 030import java.awt.Frame; 031import java.io.File; 032import java.net.URL; 033 034import javax.swing.JFileChooser; 035 036import ptolemy.actor.gui.Configuration; 037import ptolemy.actor.gui.ConfigurationApplication; 038import ptolemy.actor.gui.EditorFactory; 039import ptolemy.actor.gui.TableauFrame; 040import ptolemy.data.expr.FileParameter; 041import ptolemy.gui.JFileChooserBugFix; 042import ptolemy.kernel.util.IllegalActionException; 043import ptolemy.kernel.util.InternalErrorException; 044import ptolemy.kernel.util.NameDuplicationException; 045import ptolemy.kernel.util.NamedObj; 046import ptolemy.util.StringUtilities; 047 048/** 049 <p>This attribute is a visible attribute that displays documentation when 050 configured by double clicking on it or by invoking Configure in the context 051 menu. 052 </p><p> 053 The method 054 that causes the documentation to be displayed is createEditor, which 055 is normally used to configure an attribute. This means that the 056 DocumentationAttribute can't be configured. That is, if a 057 double-click occurs or the Configure menu item is selected the 058 documentation will be displayed, and the normal configure dialog 059 will not be offered. Special provisions for "configuring" a 060 DocumentationAttribute are described below. 061 </p><p> 062 The documentation is in a file specified by the FileParameter 063 attribute with the name _documentation. The _documentation FileParameter can 064 be on any object, including this DocumentationAttribute, in the containment 065 hierarchy. (As explained below, the _documentation FileParameter will be 066 found on the container of this DocumentationAttribute.) If a 067 _documentation FileParameter can not be found a JFileChooser is 068 presented. The resulting selection, if there is one, is then used 069 to create a _documentation FileParameter on the <i>container</i>. 070 There are two reasons for this. First, the documentation most likely 071 applies to the container. I.e., this DocumentationAttribute isn't 072 being documented, rather, the thing that this DocumentationAttribute 073 is an attribute of is being documented. Second, the container most 074 likely can be configured in the normal way. Since, the 075 _documentation FileParameter will be on the container the 076 specification for the file containing the documentation can be 077 modified. 078 </p> 079 <p>Note that if a DocumentationAttribute refers to a pdf file, then it 080 may not be possible to view the pdf file in an applet because 081 {@link ptolemy.actor.gui.BrowserLauncher} uses reflection to look up 082 classes. The workaround is to use 083 ptolemy.vergil.pdfrenderer.PDFRenderer 084 085 @deprecated DocumentationAttribute provides no UI way to edit the URL, one must edit the MoML file by hand. Use ptolemy.vergil.basic.DocAttribute or ptolemy.vergil.pdfrenderer.PDFRenderer instead of using DocumentationAttribute. 086 @author Rowland R Johnson 087 @version $Id$ 088 @since Ptolemy II 4.0 089 @see ptolemy.vergil.basic.DocAttribute 090 @Pt.ProposedRating Red (rowland) 091 @Pt.AcceptedRating Red (rowland) 092 */ 093@Deprecated 094public class DocumentationAttribute extends VisibleAttribute { 095 /** Construct an icon with the attached this attached. 096 * @param container The container. 097 * @param name The name of the factory. 098 * @exception IllegalActionException If the factory is not of an 099 * acceptable attribute for the container. 100 * @exception NameDuplicationException If the name coincides with 101 * an attribute already in the container. 102 */ 103 public DocumentationAttribute(NamedObj container, String name) 104 throws IllegalActionException, NameDuplicationException { 105 super(container, name); 106 107 _attachText("_iconDescription", "<svg>\n" 108 + "<rect x=\"-50\" y=\"-20\" width=\"130\" height=\"40\" " 109 + "style=\"fill:yellow\"/>" + "<text x=\"-40\" y=\"-5\" " 110 + "style=\"font-size:12; font-family:SansSerif; fill:black\">" 111 + "Double click to see\ndocumentation.</text></svg>"); 112 new DocumentationAttributeFactory(this, "_editorFactory"); 113 } 114 115 /////////////////////////////////////////////////////////////////// 116 //// inner classes //// 117 private static class DocumentationAttributeFactory extends EditorFactory { 118 // FindBugs suggests making this class static so as to decrease 119 // the size of instances and avoid dangling references. 120 121 public DocumentationAttributeFactory(NamedObj _container, String name) 122 throws IllegalActionException, NameDuplicationException { 123 super(_container, name); 124 } 125 126 /** Display the documentation if there is any. If not, offer a dialog to 127 * let the user specify where the documentation is located. 128 * @param object The object to configure. 129 * @param parent The parent window, or null if there is none. 130 */ 131 @Override 132 public void createEditor(NamedObj object, Frame parent) { 133 try { 134 FileParameter docAttribute = null; 135 if (!(parent instanceof TableauFrame)) { 136 throw new InternalErrorException( 137 "Frame \"" + parent + "\" is not a TableauFrame"); 138 } 139 Configuration configuration = ((TableauFrame) parent) 140 .getConfiguration(); 141 NamedObj documentedObject = object; 142 143 while (documentedObject != null) { 144 docAttribute = (FileParameter) documentedObject 145 .getAttribute("_documentation", 146 FileParameter.class); 147 148 if (docAttribute != null) { 149 break; 150 } 151 152 documentedObject = documentedObject.getContainer(); 153 } 154 155 if (docAttribute != null) { 156 URL doc = ConfigurationApplication 157 .specToURL(docAttribute.getExpression()); 158 configuration.openModel(doc, doc, doc.toExternalForm()); 159 } else { 160 NamedObj container = object.getContainer(); 161 162 if (container == null) { 163 container = object; 164 } 165 166 // Avoid white boxes in file chooser, see 167 // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801 168 JFileChooserBugFix jFileChooserBugFix = new JFileChooserBugFix(); 169 Color background = null; 170 try { 171 background = jFileChooserBugFix.saveBackground(); 172 JFileChooser fileDialog = new JFileChooser(); 173 fileDialog 174 .setDialogTitle("Select a documentation file."); 175 176 //File _directory = null; 177 178 String cwd = StringUtilities.getProperty("user.dir"); 179 180 if (cwd != null) { 181 fileDialog.setCurrentDirectory(new File(cwd)); 182 } 183 184 if (fileDialog.showOpenDialog( 185 parent) == JFileChooser.APPROVE_OPTION) { 186 // FIXME: why is this ignored? 187 //_directory = fileDialog.getCurrentDirectory(); 188 189 String fileName = fileDialog.getSelectedFile() 190 .getAbsolutePath(); 191 192 docAttribute = new FileParameter(container, 193 "_documentation"); 194 docAttribute.setExpression(fileName); 195 } 196 } finally { 197 jFileChooserBugFix.restoreBackground(background); 198 } 199 } 200 } catch (Throwable throwable) { 201 throw new InternalErrorException(object, throwable, 202 "Cannot access Documentation"); 203 } 204 } 205 } 206}