001/* An action for editing 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.basic; 029 030import java.awt.Frame; 031import java.awt.event.ActionEvent; 032import java.util.Iterator; 033import java.util.List; 034 035import ptolemy.actor.gui.Configuration; 036import ptolemy.actor.gui.EditParametersDialog; 037import ptolemy.data.expr.Parameter; 038import ptolemy.kernel.util.Attribute; 039import ptolemy.kernel.util.ChangeRequest; 040import ptolemy.kernel.util.IllegalActionException; 041import ptolemy.kernel.util.InternalErrorException; 042import ptolemy.kernel.util.NamedObj; 043import ptolemy.moml.MoMLChangeRequest; 044import ptolemy.vergil.actor.DocApplicationSpecializer; 045import ptolemy.vergil.toolbox.FigureAction; 046 047/////////////////////////////////////////////////////////////////// 048//// CustomizeDocumentationAction 049 050/** 051 An action for editing instance-specific documentation. 052 053 @author Edward A. Lee 054 @version $Id$ 055 @since Ptolemy II 5.2 056 @Pt.ProposedRating Red (eal) 057 @Pt.AcceptedRating Red (johnr) 058 */ 059@SuppressWarnings("serial") 060public class CustomizeDocumentationAction extends FigureAction { 061 062 /** Construct an instance of this action. */ 063 public CustomizeDocumentationAction() { 064 super("Customize Documentation"); 065 } 066 067 /////////////////////////////////////////////////////////////////// 068 //// public methods //// 069 070 /** Perform the action by first ensuring that the target has an 071 * instance of DocAttribute, and then opening an edit parameters 072 * dialog on that attribute. 073 */ 074 @Override 075 public void actionPerformed(ActionEvent e) { 076 super.actionPerformed(e); 077 final NamedObj target = getTarget(); 078 boolean done = false; 079 // If the object does not contain an attribute of class 080 // DocAttribute, then create one. Then open a dialog to edit 081 // the parameters of the first such encountered attribute. 082 List docAttributeList = null; 083 084 if (target != null) { 085 Parameter docApplicationSpecializerParameter = null; 086 try { 087 //find the configuration 088 List configsList = Configuration.configurations(); 089 Configuration config = null; 090 for (Iterator it = configsList.iterator(); it.hasNext();) { 091 config = (Configuration) it.next(); 092 if (config != null) { 093 break; 094 } 095 } 096 if (config == null) { 097 throw new InternalErrorException(target, null, 098 "Failed to find configuration"); 099 } 100 101 // Check to see if the configuration has a 102 // _docApplicationSpecializer parameter and if it does, 103 // let it handle the customization 104 105 docApplicationSpecializerParameter = (Parameter) config 106 .getAttribute("_docApplicationSpecializer", 107 Parameter.class); 108 } catch (IllegalActionException iae) { 109 // Ignore. just let the default action happen 110 System.out.println("Error getting the documentation " 111 + "specializer: " + iae.getMessage()); 112 } 113 114 if (docApplicationSpecializerParameter != null) { 115 // If there is a docApplicationSpecializer, use it to 116 // customize the documentation since it knows about 117 // the special doc attribute 118 119 String docApplicationSpecializerClassName = docApplicationSpecializerParameter 120 .getExpression(); 121 try { 122 Class docApplicationSpecializerClass = Class 123 .forName(docApplicationSpecializerClassName); 124 final DocApplicationSpecializer docApplicationSpecializer = (DocApplicationSpecializer) docApplicationSpecializerClass 125 .newInstance(); 126 String docAttributeClassName = docApplicationSpecializer 127 .getDocumentationAttributeClassName(); 128 Class docAttributeClass = Class 129 .forName(docAttributeClassName); 130 if (docApplicationSpecializerClass != null 131 && docAttributeClass != null) { 132 docAttributeList = target 133 .attributeList(docAttributeClass); 134 } 135 136 if (docAttributeList.size() == 0) { 137 docApplicationSpecializer 138 .handleDocumentationAttributeDoesNotExist( 139 getFrame(), target); 140 141 } else { //edit the existing attribute 142 final Attribute docAttribute = (Attribute) docAttributeList 143 .get(docAttributeList.size() - 1); 144 ChangeRequest request = new ChangeRequest(this, 145 "Customize documentation.") { 146 @Override 147 protected void _execute() throws Exception { 148 //_editDocAttribute(getFrame(), docAttribute, target); 149 docApplicationSpecializer.editDocumentation( 150 getFrame(), docAttribute, target); 151 } 152 }; 153 target.requestChange(request); 154 } 155 } catch (Throwable throwable) { 156 System.out.println( 157 "Failed to call doc application specializer " 158 + "class \"" 159 + docApplicationSpecializerClassName 160 + "\" on class \"" 161 + docApplicationSpecializerClassName 162 + "\"."); 163 } 164 done = true; 165 } 166 167 if (!done) { 168 //assign the docAttributeList the default DocAttribute if it 169 //wasn't assigned by the specializer 170 docAttributeList = target.attributeList(DocAttribute.class); 171 if (docAttributeList.size() == 0) { 172 // Create a doc attribute, then edit its parameters. 173 String moml = "<property name=\"" + "DocAttribute" 174 + "\" class=\"ptolemy.vergil.basic.DocAttribute\"/>"; 175 MoMLChangeRequest request = new MoMLChangeRequest(this, 176 target, moml) { 177 @Override 178 protected void _execute() throws Exception { 179 super._execute(); 180 List docAttributes = target 181 .attributeList(DocAttribute.class); 182 183 // There shouldn't be more than one of 184 // these, but if there are, the new one is 185 // the last one. 186 187 DocAttribute attribute = (DocAttribute) docAttributes 188 .get(docAttributes.size() - 1); 189 _editDocAttribute(getFrame(), attribute, target); 190 } 191 }; 192 target.requestChange(request); 193 } else { 194 195 // In case there is more than one such attribute, 196 // get the last one. 197 198 final DocAttribute attribute = (DocAttribute) docAttributeList 199 .get(docAttributeList.size() - 1); 200 201 // Do the update in a change request because it may 202 // modify the DocAttribute parameter. 203 204 ChangeRequest request = new ChangeRequest(this, 205 "Customize documentation.") { 206 @Override 207 protected void _execute() throws Exception { 208 209 // In case parameters or ports have been 210 // added since the DocAttribute was 211 // constructed, refresh it. 212 213 attribute.refreshParametersAndPorts(); 214 _editDocAttribute(getFrame(), attribute, target); 215 } 216 }; 217 target.requestChange(request); 218 } 219 } 220 } 221 } 222 223 /////////////////////////////////////////////////////////////////// 224 //// private methods //// 225 226 /** Edit the specified documentation attribute. 227 * @param owner The owning frame. 228 * @param attribute The attribute to edit. 229 * @param target The target whose documentation is being edited. 230 */ 231 private void _editDocAttribute(Frame owner, DocAttribute attribute, 232 NamedObj target) { 233 new EditParametersDialog(owner, attribute, 234 "Edit Documentation for " + target.getName()); 235 } 236}