1 /**
2 * This is a simple mechanism to bind Inkscape to Java, and thence
3 * to all of the nice things that can be layered upon that.
4 *
5 * Authors:
6 * Bob Jamison
7 *
8 * Copyright (C) 2007-2008 Bob Jamison
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 3 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
25 package org.inkscape.script;
28 import java.awt.BorderLayout;
29 import java.security.MessageDigest;
30 import java.security.NoSuchAlgorithmException;
31 import javax.swing.filechooser.FileNameExtensionFilter;
32 import javax.swing.JFileChooser;
33 import javax.swing.JOptionPane;
34 import javax.swing.JPanel;
35 import javax.swing.JTextPane;
37 import java.io.File;
38 import java.io.FileReader;
39 import java.io.FileWriter;
40 import java.io.IOException;
44 /**
45 * A simple script editor for quick fixes.
46 */
47 public class Editor extends JPanel
48 {
49 ScriptConsole parent;
50 JTextPane textPane;
52 //########################################################################
53 //# MESSSAGES
54 //########################################################################
55 void err(String fmt, Object... arguments)
56 {
57 parent.err("Editor err:" + fmt, arguments);
58 }
60 void msg(String fmt, Object... arguments)
61 {
62 parent.msg("Editor:" + fmt, arguments);
63 }
65 void trace(String fmt, Object... arguments)
66 {
67 parent.trace("Editor:" + fmt, arguments);
68 }
71 //########################################################################
72 //# U T I L I T Y
73 //########################################################################
75 private JFileChooser _chooser;
77 JFileChooser getChooser()
78 {
79 if (_chooser == null)
80 {
81 _chooser = new JFileChooser();
82 _chooser.setAcceptAllFileFilterUsed(false);
83 _chooser.setCurrentDirectory(new File("."));
84 FileNameExtensionFilter filter = new FileNameExtensionFilter(
85 "Script Files", "js", "py", "r");
86 _chooser.setFileFilter(filter);
87 }
88 return _chooser;
89 }
92 /**
93 * Returns the current text contained in this editor
94 */
95 public String getText()
96 {
97 return textPane.getText();
98 }
101 String lastHash = null;
103 /**
104 * Sets the text of this editor
105 */
106 public void setText(String txt)
107 {
108 textPane.setText(txt);
109 lastHash = getHash(txt);
110 trace("hash:" + lastHash);
111 }
113 MessageDigest md = null;
115 final String hex = "0123456789abcdef";
117 String toHex(byte arr[])
118 {
119 StringBuffer buf = new StringBuffer();
120 for (byte b : arr)
121 {
122 buf.append(hex.charAt((b>>4) & 15));
123 buf.append(hex.charAt((b ) & 15));
124 }
125 return buf.toString();
126 }
128 String getHash(String text)
129 {
130 if (md == null)
131 {
132 try
133 {
134 md = MessageDigest.getInstance("MD5");
135 }
136 catch (NoSuchAlgorithmException e)
137 {
138 err("getHash: " + e);
139 return "";
140 }
141 }
142 byte hash[] = md.digest(text.getBytes());
143 return toHex(hash);
144 }
147 //########################################################################
148 //# L O A D / S A V E
149 //########################################################################
150 String fileName = "";
152 /**
153 * Gets the name of the current file in the editor
154 */
155 public String getFileName()
156 {
157 return fileName;
158 }
160 /**
161 * Sets the name of the current file in the editor
162 */
163 public void setFileName(String val)
164 {
165 fileName = val;
166 }
168 /**
169 * Selects and opens a file, loading into the editor
170 */
171 public boolean openFile()
172 {
173 JFileChooser chooser = getChooser();
174 int ret = chooser.showOpenDialog(this);
175 if (ret != JFileChooser.APPROVE_OPTION)
176 return false;
177 File f = chooser.getSelectedFile();
178 String fname = f.getName();
179 try
180 {
181 FileReader in = new FileReader(fname);
182 StringBuffer buf = new StringBuffer();
183 while (true)
184 {
185 int ch = in.read();
186 if (ch < 0)
187 break;
188 buf.append((char)ch);
189 }
190 in.close();
191 setText(buf.toString());
192 }
193 catch (IOException e)
194 {
195 err("save file:" + e);
196 return false;
197 }
198 return true;
199 }
202 /**
203 * Saves the file currently in the editor. Uses the Save
204 * selector if there is not current file name.
205 */
206 public boolean saveFile()
207 {
208 if (!isDirty())
209 return true;
211 String fname = getFileName();
212 if (fname == null || fname.length()==0)
213 {
214 JFileChooser chooser = getChooser();
215 int ret = chooser.showSaveDialog(this);
216 if (ret != JFileChooser.APPROVE_OPTION)
217 return false;
218 File f = chooser.getSelectedFile();
219 fname = f.getName();
220 }
221 try
222 {
223 FileWriter out = new FileWriter(fname);
224 out.write(getText());
225 out.close();
226 setFileName(fname);
227 resetDirty();
228 }
229 catch (IOException e)
230 {
231 err("save file:" + e);
232 return false;
233 }
234 return true;
235 }
238 /**
239 * Saves the file currently in the editor under a new name.
240 * Get the new name from the chooser, and see if it already exists.
241 */
242 public boolean saveAsFile()
243 {
244 JFileChooser chooser = getChooser();
245 int ret = chooser.showSaveDialog(this);
246 if (ret != JFileChooser.APPROVE_OPTION)
247 return false;
248 File f = chooser.getSelectedFile();
249 String fname = f.getName();
250 if (f.exists())
251 {
252 ret = JOptionPane.showConfirmDialog(this,
253 "File '" + fname + "' already exists. Overwrite?");
254 if (ret != JOptionPane.YES_OPTION)
255 return false;
256 }
257 try
258 {
259 FileWriter out = new FileWriter(fname);
260 out.write(getText());
261 out.close();
262 setFileName(fname);
263 resetDirty();
264 }
265 catch (IOException e)
266 {
267 err("saveAs file:" + e);
268 return false;
269 }
270 return true;
271 }
274 /**
275 * State that the editor is now 'unedited'
276 */
277 public void resetDirty()
278 {
279 lastHash = getHash(getText());
280 }
282 /**
283 * Determines if the editor has been edited since the last open/save
284 */
285 public boolean isDirty()
286 {
287 String txt = getText();
288 String hash = getHash(txt);
289 if ( (lastHash == null && txt.length()>0) ||
290 (lastHash != null && !lastHash.equals(hash)) )
291 return true;
292 return false;
293 }
296 /**
297 * Creates the editor for the ScriptConsole
298 */
299 public Editor(ScriptConsole par)
300 {
301 super();
302 parent = par;
303 setLayout(new BorderLayout());
304 textPane = new JTextPane();
305 add(textPane, BorderLayout.CENTER);
306 }
310 }