1 /*
2  * $Id$
3  * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer
4  *
5  * Permission is hereby granted, free of charge, to any person
6  * obtaining a copy of this software and associated documentation
7  * files (the "Software"), to deal in the Software without
8  * restriction, including without limitation the rights to use,
9  * copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following
12  * conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 /*
28  * This class was originally published under the MPL by Bruno Lowagie
29  * and Carsten Hammer.
30  * It was a part of iText, a Java-PDF library. You can now use it under
31  * the MIT License; for backward compatibility you can also use it under
32  * the MPL version 1.1: http://www.mozilla.org/MPL/
33  * A copy of the MPL license is bundled with the source code FYI.
34  */
35 
36 package com.lowagie.toolbox;
37 
38 import java.awt.*;
39 import java.awt.event.*;
40 import java.beans.*;
41 import java.io.*;
42 import java.util.*;
43 
44 import javax.swing.*;
45 import javax.swing.text.*;
46 
47 import com.lowagie.tools.Executable;
48 
49 /**
50  * This is a utility that allows you to use a number of iText tools.
51  * @since 2.1.1 (imported from itexttoolbox project)
52  */
53 public class Toolbox extends JFrame implements ActionListener {
54     /** A serial version ID */
55     private static final long serialVersionUID = -3766198389452935073L;
56     /** The DesktopPane of the toolbox. */
57     private JDesktopPane desktop;
58     /** The ConsolePane of the toolbox. */
59     private JScrollPane console;
60 
61     /** The list of tools in the toolbox. */
62     private Properties toolmap = new Properties();
63 
64     /** x-coordinate of the location of a new internal frame. */
65     private int locationX = 0;
66 
67     /** y-coordinate of the location of a new internal frame. */
68     private int locationY = 0;
69     /**
70      * toolarray
71      */
72     private ArrayList<AbstractTool> toolarray = new ArrayList<AbstractTool>();
73 
74     private Vector<String> menulist=new Vector<String>();
75     private Vector<String> menuitemlist=new Vector<String>();
76     /**
77      * Constructs the Toolbox object.
78      */
Toolbox()79     public Toolbox() {
80         super();
81         setSize(600, 500);
82         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
83         setResizable(true);
84         setTitle("iText Toolbox");
85         desktop = new JDesktopPane();
86         setJMenuBar(getMenubar());
87         setIconImage(new ImageIcon(com.lowagie.toolbox.Toolbox.class.getResource(
88                 "1t3xt.gif")).getImage());
89         Console c;
90         try {
91             c = new Console();
92             console = new JScrollPane(c.textArea);
93         } catch (IOException e) {
94             e.printStackTrace();
95         }
96         JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
97                                               desktop,
98                                               console);
99         splitPane.setContinuousLayout(true);
100         splitPane.setOneTouchExpandable(true);
101         splitPane.setDividerLocation(300);
102         setContentPane(splitPane);
103         centerFrame(this);
104         setVisible(true);
105     }
106 
107     /**
108      * Starts the Toolbox utility.
109      *
110      * use as first argument the name of the plugin,
111      * then the arguments of the plugin used.
112      *
113      * e.g.
114      *
115      * java -jar itext.jar Burst inputfile.pdf
116      *
117      * That way you can call plugins by name directly.
118      *
119      * @param args
120      *            no arguments needed
121      */
main(String[] args)122     public static void main(String[] args) {
123         try {
124             Class.forName("com.lowagie.text.Document");
125         } catch (ClassNotFoundException e) {
126             JOptionPane.showMessageDialog(null,
127                                           "You need the iText.jar in your CLASSPATH!",
128                                           e.getClass().getName(),
129                                           JOptionPane.ERROR_MESSAGE);
130             System.exit(1);
131         }
132         Toolbox toolbox = new Toolbox();
133         if (args.length > 0) {
134             try {
135                 AbstractTool tool = toolbox.createFrame(args[0]);
136                 String[] nargs = new String[args.length - 1];
137                 System.arraycopy(args, 1, nargs, 0, args.length - 1);
138                 tool.setMainArguments(nargs);
139                 tool.execute();
140             } catch (PropertyVetoException ex) {
141             } catch (ClassNotFoundException ex) {
142             } catch (IllegalAccessException ex) {
143             } catch (InstantiationException ex) {
144             }
145         }
146     }
147 
148     /**
149      * Gets the menubar.
150      *
151      * @return a menubar
152      */
getMenubar()153     private JMenuBar getMenubar() {
154         Properties p = new Properties();
155         try {
156             p.load(Toolbox.class.getClassLoader().getResourceAsStream(
157                     "com/lowagie/toolbox/tools.txt"));
158             String usertoolstxt = System.getProperty("user.home") +
159                                   System.getProperty("file.separator") +
160                                   "tools.txt";
161             File uttf = new File(usertoolstxt);
162             if (uttf.isFile() && uttf.exists()) {
163                 p.load(new FileInputStream(usertoolstxt));
164             }
165         } catch (IOException e) {
166             e.printStackTrace();
167         }
168         toolmap = new Properties();
169         JMenuBar menubar = new JMenuBar();
170         JMenu file = new JMenu(ToolMenuItems.FILE);
171         file.setMnemonic(KeyEvent.VK_T);
172         JMenuItem close = new JMenuItem(ToolMenuItems.CLOSE);
173         close.setMnemonic(KeyEvent.VK_C);
174         close.addActionListener(this);
175         file.add(close);
176         JMenu view = new JMenu(ToolMenuItems.VIEW);
177         JMenuItem reset = new JMenuItem(ToolMenuItems.RESET);
178         reset.addActionListener(this);
179         view.add(reset);
180 //        JMenuItem filelist = new JMenuItem(FILELIST);
181 //        filelist.addActionListener(this);
182 //        view.add(filelist);
183         JMenu tools = new JMenu(ToolMenuItems.TOOLS);
184 // Here one day should be the wizard to help you create a new beanshell script
185 //        JMenuItem create = new JMenuItem(CREATE);
186 //        create.addActionListener(this);
187 //        tools.add(create);
188         buildPluginMenuItems(new TreeMap<Object, Object>(p), tools);
189         JMenu help = new JMenu(ToolMenuItems.HELP);
190         JMenuItem about = new JMenuItem(ToolMenuItems.ABOUT);
191 //        about.setIcon(new ImageIcon(Toolbox.class.getResource(
192 //                "Help24.gif")));
193         about.setMnemonic(KeyEvent.VK_A);
194         about.addActionListener(this);
195         help.add(about);
196         JMenuItem versions = new JMenuItem(ToolMenuItems.VERSION);
197 //        versions.setIcon(new ImageIcon(Toolbox.class.getResource(
198 //                "About24.gif")));
199         versions.addActionListener(this);
200         help.add(versions);
201         menubar.add(file);
202         menubar.add(tools);
203         menubar.add(view);
204         menubar.add(Box.createGlue());
205         menubar.add(help);
206         return menubar;
207     }
208 
209     /**
210      * BuildPluginMenuItems
211      *
212      * @param tmp Map
213      * @param tools JMenu
214      */
buildPluginMenuItems(Map<Object, Object> tmp, JMenu tools)215     private void buildPluginMenuItems(Map<Object, Object> tmp, JMenu tools) {
216         String name, tool;
217         JMenu current = null;
218         JMenuItem item;
219 
220         for (Map.Entry<Object, Object> entry: tmp.entrySet()) {
221             name = (String) entry.getKey();
222             if (current == null || !name.startsWith(current.getText())) {
223                 String menu = name.substring(0, name.indexOf('.'));
224                 menulist.add(menu);
225                 current = new JMenu(menu);
226                 tools.add(current);
227             }
228             String menuitem = name.substring(current.getText().length() + 1);
229             menuitemlist.add(menuitem);
230             item = new JMenuItem(menuitem);
231             item.addActionListener(this);
232             tool = (String) entry.getValue();
233             try {
234                 if (Class.forName(tool) != null) {
235                     toolmap.put(item.getText(), tool);
236                     current.add(item);
237                 }
238             } catch (ClassNotFoundException e) {
239                 System.err.println("Plugin " + name
240                                    + " was not found in your CLASSPATH.");
241             }
242         }
243     }
244 
245     /**
246      * Creates an Internal Frame.
247      *
248      * @param name the name of the application
249      * @throws InstantiationException
250      * @throws IllegalAccessException
251      * @throws ClassNotFoundException
252      * @throws PropertyVetoException
253      * @return AbstractTool
254      */
createFrame(String name)255     public AbstractTool createFrame(String name) throws InstantiationException,
256             IllegalAccessException, ClassNotFoundException,
257             PropertyVetoException {
258         AbstractTool ti = null;
259         String classname = (String) toolmap.get(name);
260         ti = (AbstractTool) Class.forName(classname).newInstance();
261         toolarray.add(ti);
262         JInternalFrame f = ti.getInternalFrame();
263         f.setLocation(locationX, locationY);
264         locationX += 25;
265         if (locationX > this.getWidth() + 50) {
266             locationX = 0;
267         }
268         locationY += 25;
269         if (locationY > this.getHeight() + 50) {
270             locationY = 0;
271         }
272         f.setVisible(true);
273         desktop.add(f);
274         f.setSelected(true);
275         return ti;
276     }
277 
278     /**
279      * Centers a JFrame.
280      *
281      * @param f JFrame
282      */
centerFrame(Frame f)283     public static void centerFrame(Frame f) {
284         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
285         Dimension frameSize = f.getSize();
286         if (frameSize.height > screenSize.height) {
287             frameSize.height = screenSize.height;
288         }
289         if (frameSize.width > screenSize.width) {
290             frameSize.width = screenSize.width;
291         }
292         f.setLocation((screenSize.width - frameSize.width) / 2,
293                       (screenSize.height - frameSize.height) / 2);
294     }
295 
296     /**
297      *
298      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
299      * @param evt ActionEvent
300      */
actionPerformed(ActionEvent evt)301     public void actionPerformed(ActionEvent evt) {
302         if (ToolMenuItems.CLOSE.equals(evt.getActionCommand())) {
303             System.out.println("The Toolbox is closed.");
304             System.exit(0);
305         } else if (ToolMenuItems.ABOUT.equals(evt.getActionCommand())) {
306             System.out
307                     .println("The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info.");
308             try {
309                 Executable
310                         .launchBrowser("http://itexttoolbox.sourceforge.net/");
311             } catch (IOException ioe) {
312                 JOptionPane
313                         .showMessageDialog(
314                                 this,
315                                 "The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info.");
316             }
317         } else if (ToolMenuItems.RESET.equals(evt.getActionCommand())) {
318             JInternalFrame[] framearray = desktop.getAllFrames();
319             int xx = 0, yy = 0;
320             for (int i = 0; i < framearray.length; i++) {
321                 if (!framearray[i].isIcon()) {
322                     try {
323                         int frameDistance = framearray[i].getHeight() -
324                                             framearray[i].getContentPane().
325                                             getHeight();
326                         framearray[i].setMaximum(false);
327                         int fwidth = framearray[i].getWidth();
328                         int fheight = framearray[i].getHeight();
329                         framearray[i].reshape(xx, yy, fwidth, fheight);
330                         xx += frameDistance;
331                         yy += frameDistance;
332                         if (xx + fwidth > desktop.getWidth()) {
333                             xx = 0;
334                         }
335                         if (yy + fheight > desktop.getHeight()) {
336                             yy = 0;
337                         }
338                     } catch (PropertyVetoException e) {
339                     }
340                 }
341             }
342         } else if (ToolMenuItems.VERSION.equals(evt.getActionCommand())) {
343             JFrame f = new Versions();
344             centerFrame(f);
345             f.setVisible(true);
346         } else {
347             try {
348                 createFrame(evt.getActionCommand());
349             } catch (Exception e) {
350                 e.printStackTrace();
351             }
352         }
353     }
354 
355     /**
356      * A Class that redirects output to System.out and System.err.
357      */
358     public class Console {
359         class ErrorContext extends StyleContext {
360             private static final long serialVersionUID = 7766294638325167438L;
361             public static final String STDERROR = "Error";
362             public static final String STDOUT = "StdOut";
363 
ErrorContext()364             public ErrorContext() {
365                 super();
366                 Style root = getStyle(DEFAULT_STYLE);
367                 Style s = addStyle(STDERROR, root);
368                 StyleConstants.setForeground(s, Color.RED);
369                 s = addStyle(STDOUT, root);
370                 StyleConstants.setForeground(s, Color.BLACK);
371             }
372         }
373 
374 
375         PipedInputStream piOut;
376         PipedInputStream piErr;
377         PipedOutputStream poOut;
378         PipedOutputStream poErr;
379         ErrorContext errorcontext = new ErrorContext();
380         JTextPane textArea = new JTextPane(new DefaultStyledDocument(
381                 errorcontext));
382         PrintStream oriout;
383         PrintStream orierr;
384 
385         /**
386          * Creates a new Console object.
387          * @throws IOException
388          */
Console()389         public Console() throws IOException {
390             // Set up System.out
391             piOut = new PipedInputStream();
392             poOut = new PipedOutputStream(piOut);
393             oriout = System.out;
394             System.setOut(new PrintStream(poOut, true));
395 
396             // Set up System.err
397             piErr = new PipedInputStream();
398             poErr = new PipedOutputStream(piErr);
399             orierr = System.err;
400             System.setErr(new PrintStream(poErr, true));
401 
402             // Add a scrolling text area
403             textArea.setEditable(false);
404 
405             // Create reader threads
406             new ReaderThread(piOut, ErrorContext.STDOUT).start();
407             new ReaderThread(piErr, ErrorContext.STDERROR).start();
408         }
409 
410         class ReaderThread extends Thread {
411             PipedInputStream pi;
412             String type;
413 
ReaderThread(PipedInputStream pi, String type)414             ReaderThread(PipedInputStream pi, String type) {
415                 this.pi = pi;
416                 this.type = type;
417             }
418 
419             /**
420              * @see java.lang.Thread#run()
421              */
run()422             public void run() {
423                 final byte[] buf = new byte[1024];
424 
425                 while (true) {
426                     try {
427                         final int len = pi.read(buf);
428                         if (len == -1) {
429                             break;
430                         }
431                         javax.swing.text.Document doc = textArea.getDocument();
432                         AttributeSet attset = errorcontext.getStyle(type);
433                         String snippet = new String(buf, 0, len);
434                         doc.insertString(doc.getLength(),
435                                          snippet, attset);
436                         oriout.print(snippet);
437                         textArea.setCaretPosition(textArea.getDocument().
438                                                   getLength());
439                     } catch (BadLocationException ex) {
440                     } catch (IOException e) {
441                     }
442                 }
443             }
444         }
445     }
446 
447 
getMenulist()448     public Vector<String> getMenulist() {
449         return menulist;
450     }
451 }
452