Project

General

Profile

Feature #6833 ยป TextEditorConfigureFactory.java

Daniel Crawl, 08/23/2015 02:34 PM

 
1
/* An attribute that creates a text editor to edit a string attribute.
2

    
3
 Copyright (c) 2003-2014 The Regents of the University of California.
4
 All rights reserved.
5
 Permission is hereby granted, without written agreement and without
6
 license or royalty fees, to use, copy, modify, and distribute this
7
 software and its documentation for any purpose, provided that the above
8
 copyright notice and the following two paragraphs appear in all copies
9
 of this software.
10

    
11
 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
12
 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
13
 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
14
 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
15
 SUCH DAMAGE.
16

    
17
 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
18
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
20
 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
21
 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
22
 ENHANCEMENTS, OR MODIFICATIONS.
23

    
24
 PT_COPYRIGHT_VERSION_2
25
 COPYRIGHTENDKEY
26

    
27
 */
28
package ptolemy.vergil.toolbox;
29

    
30
import java.awt.Frame;
31
import java.lang.reflect.Constructor;
32

    
33
import javax.swing.text.Document;
34

    
35
import ptolemy.actor.gui.EditorFactory;
36
import ptolemy.data.IntToken;
37
import ptolemy.data.expr.Parameter;
38
import ptolemy.data.type.BaseType;
39
import ptolemy.kernel.util.Attribute;
40
import ptolemy.kernel.util.IllegalActionException;
41
import ptolemy.kernel.util.NameDuplicationException;
42
import ptolemy.kernel.util.NamedObj;
43
import ptolemy.kernel.util.StringAttribute;
44
import ptolemy.util.MessageHandler;
45

    
46
///////////////////////////////////////////////////////////////////
47
//// TextEditorConfigureFactory
48

    
49
/**
50
 If this class is contained by a actor, then double clicking on that
51
 actor will invoke a text editor that edits the value of a specified
52
 string attribute.  The string attribute must be contained by the
53
 same container as this factory; its name is given by the
54
 <i>attributeName</i> attribute of this factory. The number of
55
 rows and columns displayed are given by the <i>rowsDisplayed</i>
56
 and <i>columnsDisplayed</i> parameters. The default is 80 columns
57
 and 40 rows.
58
 <p>
59
 This attribute is similar to TextEditorTableauFactory, except that
60
 it opens the text editor when the containing actor is configured
61
 (edit parameters), whereas TextEditorTableauFactory opens the text
62
 editor when the user looks inside.
63
 @see TextEditorTableauFactory
64

    
65
 @author Edward A. Lee
66
 @version $Id: TextEditorConfigureFactory.java 70402 2014-10-23 00:52:20Z cxh $
67
 @since Ptolemy II 4.0
68
 @Pt.ProposedRating Yellow (eal)
69
 @Pt.AcceptedRating Red (ptolemy)
70
 */
71
public class TextEditorConfigureFactory extends EditorFactory implements
72
TextEditorFactory {
73
    /** Construct a factory with the specified container and name.
74
     *  @param container The container.
75
     *  @param name The name of the factory.
76
     *  @exception IllegalActionException If the factory is not of an
77
     *   acceptable attribute for the container.
78
     *  @exception NameDuplicationException If the name coincides with
79
     *   an attribute already in the container.
80
     */
81
    public TextEditorConfigureFactory(NamedObj container, String name)
82
            throws IllegalActionException, NameDuplicationException {
83
        super(container, name);
84

    
85
        attributeName = new StringAttribute(this, "attributeName");
86

    
87
        columnsDisplayed = new Parameter(this, "columnsDisplayed");
88
        columnsDisplayed.setTypeEquals(BaseType.INT);
89
        columnsDisplayed.setExpression("80");
90

    
91
        rowsDisplayed = new Parameter(this, "rowsDisplayed");
92
        rowsDisplayed.setTypeEquals(BaseType.INT);
93
        rowsDisplayed.setExpression("40");
94
        
95
        syntaxStyle = new StringAttribute(this, "syntaxStyle");
96

    
97
    }
98

    
99
    ///////////////////////////////////////////////////////////////////
100
    ////                         parameters                        ////
101

    
102
    /** The name of the string attribute that is to be edited. */
103
    public StringAttribute attributeName;
104

    
105
    /** The horizontal size of the display, in columns. This contains
106
     *  an integer, and defaults to 40.
107
     */
108
    public Parameter columnsDisplayed;
109

    
110
    /** The vertical size of the display, in rows. This contains an
111
     *  integer, and defaults to 10.
112
     */
113
    public Parameter rowsDisplayed;
114
    
115
    /** The style of the text to be edited. This may or may not be
116
     *  supported. If the package "org.fife.ui.rsyntaxtextarea" is found in
117
     *  the classpath, then the supported styles include
118
     *  "text/plain", "text/c", "text/clojure", "text/cpp", "text/cs",
119
     *  "text/css", "text/dtd", "text/fortran", 
120
     *  "text/groovy", "text/html", "text/java", 
121
     *  "text/javascript", "text/json", "text/jsp", 
122
     *  "text/latex", "text/makefile", 
123
     *  "text/perl", "text/php", 
124
     *  "text/properties", "text/python", "text/ruby", "text/sas", 
125
     *  "text/scala", "text/sql", "text/tcl", "text/unix", "text/vb", 
126
     *  "text/bat", and "text/xml".
127
     */
128
    public StringAttribute syntaxStyle;
129

    
130
    ///////////////////////////////////////////////////////////////////
131
    ////                         public methods                    ////
132

    
133
    /** Remove any editor that may have been associated with this object
134
     *  by a previous call to createEditor().
135
     */
136
    @Override
137
    public void clear() {
138
        _editor = null;
139
    }
140

    
141
    /** Create an editor for editing the string attribute specified
142
     *  by the <i>attributeName</i> parameter.
143
     *  @param object The object to configure (which is expected to
144
     *   be the same as the container of this attribute).
145
     *  @param parent The frame with respect to which to define the
146
     *   editor.
147
     */
148
    @Override
149
    public void createEditor(NamedObj object, Frame parent) {
150
        if (_editor == null) {
151
            try {
152
                StringAttribute attributeToEdit = (StringAttribute) getContainer()
153
                        .getAttribute(attributeName.getExpression(),
154
                                StringAttribute.class);
155
                int numberOfRows = ((IntToken) rowsDisplayed.getToken())
156
                        .intValue();
157
                int numberOfColumns = ((IntToken) columnsDisplayed.getToken())
158
                        .intValue();
159
                
160
                String style = syntaxStyle.getExpression();
161
                if (style != null && !style.trim().equals("")) {
162
                    // Attempt to specify a syntax-aware text editor.
163
                    try {
164
                        
165
                        Document doc = null;
166
                        try {
167
                            // Attempt to create a styled document.
168
                            // Use reflection here to avoid a hard dependency on an external package.
169
                            Class<?> docClass = Class.forName("org.fife.ui.rsyntaxtextarea.RSyntaxDocument");
170
                            Constructor<?> docClassConstructor = docClass.getConstructor(String.class);
171
                            doc = (Document) docClassConstructor.newInstance(new Object[] {style});
172
                        } catch (Throwable ex) {
173
                            // Ignore and use default text editor.
174
                            System.out.println("Note: failed to open syntax-directed editor: " + ex.getMessage());
175
                        }
176

    
177
                        if(doc != null) {
178
                            Class<?> editorClass = Class.forName(
179
                                    "ptolemy.actor.gui.syntax.SyntaxTextEditorForStringAttributes");
180
                            Constructor<?> constructor = editorClass.getConstructor(
181
                                    new Class[] {
182
                                            TextEditorFactory.class, Attribute.class,
183
                                            Integer.TYPE, Integer.TYPE,
184
                                            String.class, Document.class
185
                                            });
186
                            _editor = (TextEditorForStringAttributes) constructor.newInstance(
187
                                    new Object[] {
188
                                            this, attributeToEdit,
189
                                            numberOfRows, numberOfColumns,
190
                                            "Editor for " + attributeName.getExpression() + " of "
191
                                                    + getContainer().getFullName(), doc});
192
                            
193
                            _editor.text.append(TextEditorTableauFactory.getTextToEdit(attributeToEdit));
194
                            // The above will mark the text object modified. Reverse this.
195
                            _editor.setModified(false);
196

    
197
                        }
198
                    } catch (Throwable ex) {
199
                        // Ignore and use default text editor.
200
                        System.out.println("Note: failed to open syntax-directed editor: " + ex.getMessage());
201
                    }
202
                }
203
                if(_editor == null) {
204
                    _editor = new TextEditorForStringAttributes(this,
205
                            attributeToEdit, numberOfRows, numberOfColumns,
206
                            "Editor for " + attributeName.getExpression() + " of "
207
                                    + getContainer().getFullName());
208
                }
209
            } catch (IllegalActionException ex) {
210
                MessageHandler.error(
211
                        "Cannot get specified string attribute to edit.", ex);
212
            }
213
            if (_editor == null) {
214
                throw new NullPointerException("Could not create editor for "
215
                        + object.getFullName() + " in frame " + parent);
216
            } else {
217
                // Can't just call show() here because after calling pack() and
218
                // before making visible we need to call adjustFileMenu().
219
                // Also, can't do this if the editor has already been created.
220
                _editor.pack();
221
                _editor.adjustFileMenu();
222
                _editor.centerOnScreen();
223
            }
224
        }
225
        _editor.setVisible(true);
226
    }
227

    
228
    /** Return the current text of the text editor.
229
     *  @return The current text of the text editor, or null if there
230
     *   is none.
231
     */
232
    @Override
233
    public String getText() {
234
        if (_editor != null) {
235
            return _editor.text.getText();
236
        }
237

    
238
        return null;
239
    }
240

    
241
    ///////////////////////////////////////////////////////////////////
242
    ////                         private members                   ////
243
    // Keep track of an open editor so that it isn't opened more than
244
    // once.
245
    private TextEditorForStringAttributes _editor;
246
}
    (1-1/1)