001/*
002 * SVG Salamander
003 * Copyright (c) 2004, Mark McKay
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or 
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 *   - Redistributions of source code must retain the above 
011 *     copyright notice, this list of conditions and the following
012 *     disclaimer.
013 *   - Redistributions in binary form must reproduce the above
014 *     copyright notice, this list of conditions and the following
015 *     disclaimer in the documentation and/or other materials 
016 *     provided with the distribution.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
029 * OF THE POSSIBILITY OF SUCH DAMAGE. 
030 * 
031 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
032 * projects can be found at http://www.kitfox.com
033 *
034 * Created on April 3, 2004, 5:28 PM
035 */
036
037package com.kitfox.svg.app;
038
039import com.kitfox.svg.SVGCache;
040import com.kitfox.svg.SVGConst;
041import com.kitfox.svg.SVGDiagram;
042import com.kitfox.svg.SVGDisplayPanel;
043import com.kitfox.svg.SVGElement;
044import com.kitfox.svg.SVGException;
045import com.kitfox.svg.SVGUniverse;
046import java.awt.BorderLayout;
047import java.awt.Color;
048import java.awt.Point;
049import java.io.File;
050import java.io.InputStream;
051import java.net.URI;
052import java.net.URL;
053import java.net.URLEncoder;
054import java.security.AccessControlException;
055import java.util.ArrayList;
056import java.util.Iterator;
057import java.util.List;
058import java.util.logging.Level;
059import java.util.logging.Logger;
060import java.util.regex.Matcher;
061import java.util.regex.Pattern;
062import javax.swing.JFileChooser;
063import javax.swing.JOptionPane;
064
065
066/**
067 * @author Mark McKay
068 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
069 */
070public class SVGViewer extends javax.swing.JFrame 
071{
072    public static final long serialVersionUID = 1;
073
074    SVGDisplayPanel svgDisplayPanel = new SVGDisplayPanel();
075
076    /** FileChooser for running in trusted environments */
077    final JFileChooser fileChooser;
078    {
079//        fileChooser = new JFileChooser(new File("."));
080        JFileChooser fc = null;
081        try
082        {
083            fc = new JFileChooser();
084            fc.setFileFilter(
085                new javax.swing.filechooser.FileFilter() {
086                    final Matcher matchLevelFile = Pattern.compile(".*\\.svg[z]?").matcher("");
087
088                    public boolean accept(File file)
089                    {
090                        if (file.isDirectory()) return true;
091
092                        matchLevelFile.reset(file.getName());
093                        return matchLevelFile.matches();
094                    }
095
096                    public String getDescription() { return "SVG file (*.svg, *.svgz)"; }
097                }
098            );
099        }
100        catch (AccessControlException ex)
101        {
102            //Do not create file chooser if webstart refuses permissions
103        }
104        fileChooser = fc;
105    }
106
107    /** Backup file service for opening files in WebStart situations */
108    /*
109    final FileOpenService fileOpenService;
110    {
111        try 
112        { 
113            fileOpenService = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService"); 
114        } 
115        catch (UnavailableServiceException e) 
116        { 
117            fileOpenService = null; 
118        } 
119    }
120     */
121    
122    /** Creates new form SVGViewer */
123    public SVGViewer() {
124        initComponents();
125
126        setSize(800, 600);
127
128        svgDisplayPanel.setBgColor(Color.white);
129
130        svgDisplayPanel.setPreferredSize(getSize());
131        panel_svgArea.add(svgDisplayPanel, BorderLayout.CENTER);
132//        scrollPane_svgArea.setViewportView(svgDisplayPanel);
133    }
134
135    private void loadURL(URL url)
136    {
137        boolean verbose = cmCheck_verbose.isSelected();
138        
139//                SVGUniverse universe = new SVGUniverse();
140        SVGUniverse universe = SVGCache.getSVGUniverse();
141        SVGDiagram diagram = null;
142        URI uri;
143
144        if (!CheckBoxMenuItem_anonInputStream.isSelected())
145        {
146            //Load from a disk with a valid URL
147            uri = universe.loadSVG(url);
148
149            if (verbose) System.err.println("Loading document " + uri.toString());
150
151            diagram = universe.getDiagram(uri);
152        }
153        else
154        {
155            //Load from a stream with no particular valid URL
156            try
157            {
158                InputStream is = url.openStream();
159                uri = universe.loadSVG(is, "defaultName");
160
161                if (verbose) System.err.println("Loading document " + uri.toString());
162            }
163            catch (Exception e)
164            {
165                Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
166                return;
167            }
168        }
169/*
170ByteArrayOutputStream bs = new ByteArrayOutputStream();
171ObjectOutputStream os = new ObjectOutputStream(bs);
172os.writeObject(universe);
173os.close();
174
175ByteArrayInputStream bin = new ByteArrayInputStream(bs.toByteArray());
176ObjectInputStream is = new ObjectInputStream(bin);
177universe = (SVGUniverse)is.readObject();
178is.close();
179*/
180
181        diagram = universe.getDiagram(uri);
182
183        svgDisplayPanel.setDiagram(diagram);
184        repaint();
185    }
186    
187    /** This method is called from within the constructor to
188     * initialize the form.
189     * WARNING: Do NOT modify this code. The content of this method is
190     * always regenerated by the Form Editor.
191     */
192    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
193    private void initComponents()
194    {
195        scrollPane_svgArea = new javax.swing.JScrollPane();
196        panel_svgArea = new javax.swing.JPanel();
197        jMenuBar1 = new javax.swing.JMenuBar();
198        menu_file = new javax.swing.JMenu();
199        cm_loadFile = new javax.swing.JMenuItem();
200        cm_loadUrl = new javax.swing.JMenuItem();
201        menu_window = new javax.swing.JMenu();
202        cm_800x600 = new javax.swing.JMenuItem();
203        CheckBoxMenuItem_anonInputStream = new javax.swing.JCheckBoxMenuItem();
204        cmCheck_verbose = new javax.swing.JCheckBoxMenuItem();
205        menu_help = new javax.swing.JMenu();
206        cm_about = new javax.swing.JMenuItem();
207
208        setTitle("SVG Viewer - Salamander Project");
209        addWindowListener(new java.awt.event.WindowAdapter()
210        {
211            public void windowClosing(java.awt.event.WindowEvent evt)
212            {
213                exitForm(evt);
214            }
215        });
216
217        panel_svgArea.setLayout(new java.awt.BorderLayout());
218
219        panel_svgArea.addMouseListener(new java.awt.event.MouseAdapter()
220        {
221            public void mousePressed(java.awt.event.MouseEvent evt)
222            {
223                panel_svgAreaMousePressed(evt);
224            }
225            public void mouseReleased(java.awt.event.MouseEvent evt)
226            {
227                panel_svgAreaMouseReleased(evt);
228            }
229        });
230
231        scrollPane_svgArea.setViewportView(panel_svgArea);
232
233        getContentPane().add(scrollPane_svgArea, java.awt.BorderLayout.CENTER);
234
235        menu_file.setMnemonic('f');
236        menu_file.setText("File");
237        cm_loadFile.setMnemonic('l');
238        cm_loadFile.setText("Load File...");
239        cm_loadFile.addActionListener(new java.awt.event.ActionListener()
240        {
241            public void actionPerformed(java.awt.event.ActionEvent evt)
242            {
243                cm_loadFileActionPerformed(evt);
244            }
245        });
246
247        menu_file.add(cm_loadFile);
248
249        cm_loadUrl.setText("Load URL...");
250        cm_loadUrl.addActionListener(new java.awt.event.ActionListener()
251        {
252            public void actionPerformed(java.awt.event.ActionEvent evt)
253            {
254                cm_loadUrlActionPerformed(evt);
255            }
256        });
257
258        menu_file.add(cm_loadUrl);
259
260        jMenuBar1.add(menu_file);
261
262        menu_window.setText("Window");
263        cm_800x600.setText("800 x 600");
264        cm_800x600.addActionListener(new java.awt.event.ActionListener()
265        {
266            public void actionPerformed(java.awt.event.ActionEvent evt)
267            {
268                cm_800x600ActionPerformed(evt);
269            }
270        });
271
272        menu_window.add(cm_800x600);
273
274        CheckBoxMenuItem_anonInputStream.setText("Anonymous Input Stream");
275        menu_window.add(CheckBoxMenuItem_anonInputStream);
276
277        cmCheck_verbose.setText("Verbose");
278        cmCheck_verbose.addActionListener(new java.awt.event.ActionListener()
279        {
280            public void actionPerformed(java.awt.event.ActionEvent evt)
281            {
282                cmCheck_verboseActionPerformed(evt);
283            }
284        });
285
286        menu_window.add(cmCheck_verbose);
287
288        jMenuBar1.add(menu_window);
289
290        menu_help.setText("Help");
291        cm_about.setText("About...");
292        cm_about.addActionListener(new java.awt.event.ActionListener()
293        {
294            public void actionPerformed(java.awt.event.ActionEvent evt)
295            {
296                cm_aboutActionPerformed(evt);
297            }
298        });
299
300        menu_help.add(cm_about);
301
302        jMenuBar1.add(menu_help);
303
304        setJMenuBar(jMenuBar1);
305
306        pack();
307    }// </editor-fold>//GEN-END:initComponents
308
309    private void cm_loadUrlActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadUrlActionPerformed
310    {//GEN-HEADEREND:event_cm_loadUrlActionPerformed
311        String urlStrn = JOptionPane.showInputDialog(this, "Enter URL of SVG file");
312        if (urlStrn == null) return;
313        
314        try
315        {
316            URL url = new URL(URLEncoder.encode(urlStrn, "UTF-8"));
317            loadURL(url);
318        }
319        catch (Exception e)
320        {
321            Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
322        }
323
324    }//GEN-LAST:event_cm_loadUrlActionPerformed
325
326    private void panel_svgAreaMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMouseReleased
327    {//GEN-HEADEREND:event_panel_svgAreaMouseReleased
328        SVGDiagram diagram = svgDisplayPanel.getDiagram();
329        List pickedElements;
330        try
331        {
332            pickedElements = diagram.pick(new Point(evt.getX(), evt.getY()), null);
333        } 
334        catch (SVGException e)
335        {
336            Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
337            return;
338        }
339        
340        System.out.println("Pick results:");
341        for (Iterator it = pickedElements.iterator(); it.hasNext();)
342        {
343            ArrayList path = (ArrayList)it.next();
344            
345            System.out.print("  Path: ");
346            
347            for (Iterator it2 = path.iterator(); it2.hasNext();)
348            {
349                SVGElement ele = (SVGElement)it2.next();
350
351                System.out.print("" + ele.getId() + "(" + ele.getClass().getName() + ") ");
352            }
353            System.out.println();
354        }
355    }//GEN-LAST:event_panel_svgAreaMouseReleased
356
357    private void panel_svgAreaMousePressed(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMousePressed
358    {//GEN-HEADEREND:event_panel_svgAreaMousePressed
359
360    }//GEN-LAST:event_panel_svgAreaMousePressed
361
362    private void cmCheck_verboseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmCheck_verboseActionPerformed
363    {//GEN-HEADEREND:event_cmCheck_verboseActionPerformed
364        SVGCache.getSVGUniverse().setVerbose(cmCheck_verbose.isSelected());
365    }//GEN-LAST:event_cmCheck_verboseActionPerformed
366
367    private void cm_aboutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_aboutActionPerformed
368    {//GEN-HEADEREND:event_cm_aboutActionPerformed
369        //JOptionPane.showMessageDialog(this, "Salamander SVG - Created by Mark McKay\nhttp://www.kitfox.com");
370        VersionDialog dlg = new VersionDialog(this, true, cmCheck_verbose.isSelected());
371        dlg.setVisible(true);
372    }//GEN-LAST:event_cm_aboutActionPerformed
373
374    private void cm_800x600ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cm_800x600ActionPerformed
375        setSize(800, 600);
376    }//GEN-LAST:event_cm_800x600ActionPerformed
377    
378    private void cm_loadFileActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadFileActionPerformed
379    {//GEN-HEADEREND:event_cm_loadFileActionPerformed
380        try
381        {
382            int retVal = fileChooser.showOpenDialog(this);
383            if (retVal == JFileChooser.APPROVE_OPTION)
384            {
385                File chosenFile = fileChooser.getSelectedFile();
386
387                URL url = chosenFile.toURI().toURL();
388
389                loadURL(url);
390            }
391        }
392        catch (Exception e)
393        {
394            Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
395        }
396
397    }//GEN-LAST:event_cm_loadFileActionPerformed
398
399    /** Exit the Application */
400    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
401//        setVisible(false);
402//        dispose();
403        System.exit(0);
404    }//GEN-LAST:event_exitForm
405
406    /**
407     * @param args the command line arguments
408     */
409    public static void main(String args[]) {
410        new SVGViewer().setVisible(true);
411    }
412
413    // Variables declaration - do not modify//GEN-BEGIN:variables
414    private javax.swing.JCheckBoxMenuItem CheckBoxMenuItem_anonInputStream;
415    private javax.swing.JCheckBoxMenuItem cmCheck_verbose;
416    private javax.swing.JMenuItem cm_800x600;
417    private javax.swing.JMenuItem cm_about;
418    private javax.swing.JMenuItem cm_loadFile;
419    private javax.swing.JMenuItem cm_loadUrl;
420    private javax.swing.JMenuBar jMenuBar1;
421    private javax.swing.JMenu menu_file;
422    private javax.swing.JMenu menu_help;
423    private javax.swing.JMenu menu_window;
424    private javax.swing.JPanel panel_svgArea;
425    private javax.swing.JScrollPane scrollPane_svgArea;
426    // End of variables declaration//GEN-END:variables
427
428}