// // @(#)MapPanelSVGAction.java 4/2002 // // Copyright 2002 Zachary DelProposto. All rights reserved. // Use is subject to license terms. // // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Or from http://www.gnu.org/ // package dip.gui.map; import dip.gui.dialog.ErrorDialog; import dip.gui.dialog.prefs.ExportPreferencePanel; import dip.gui.dialog.prefs.GeneralPreferencePanel; import dip.misc.SimpleFileFilter; import dip.gui.swing.XJFileChooser; import dip.gui.ClientFrame; import dip.misc.Utils; import java.awt.Component; import java.awt.Color; import java.io.*; import java.awt.event.ActionEvent; import javax.swing.Action; import java.awt.event.ActionListener; import org.w3c.dom.Document; import org.apache.batik.transcoder.*; import org.apache.batik.transcoder.print.PrintTranscoder; import org.apache.batik.transcoder.image.JPEGTranscoder; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.batik.transcoder.svg2svg.SVGTranscoder; import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.fop.svg.PDFTranscoder; /** * * Actions for SVG, including: * <ol> * <li>Print * <li>Exporting: JPG * <li>Exporting: PNG * <li>Exporting: SVG * <li>Exporting: PDF * </ol> * Takes care of error handling--errors go to a popup dialog. <p> * All events are executed in a separate thread. * */ public class MapPanelSVGAction { /** Constructor */ private MapPanelSVGAction() {} /** Error handler for Transcoding */ private static class TranscoderErrorHandler implements org.apache.batik.transcoder.ErrorHandler { public TranscoderErrorHandler() {} public void error(TranscoderException ex) { showErrorDialog(ex); } public void fatalError(TranscoderException ex) { showErrorDialog(ex); } public void warning(TranscoderException ex) { showErrorDialog(ex); } private void showErrorDialog(TranscoderException ex) { ErrorDialog.displayGeneral(null, ex); }// showErrorDialog() }// inner class TranscoderErrorHandler() /** Implements Print */ public static class Print implements ActionListener { private final MapPanel mp; public Print(MapPanel mp) { this.mp = mp; }// Print() public void actionPerformed(ActionEvent e) { final Document document = mp.getSVGDocument(); if(document == null) { return; } new Thread(getPMTG(mp), "jdipPrintThread") { public void run() { PrintTranscoder pt = new PrintTranscoder(); pt.addTranscodingHint(PrintTranscoder.KEY_SHOW_PAGE_DIALOG, Boolean.TRUE); pt.addTranscodingHint(PrintTranscoder.KEY_SHOW_PRINTER_DIALOG, Boolean.TRUE); pt.addTranscodingHint(PrintTranscoder.KEY_SCALE_TO_PAGE, Boolean.TRUE); pt.addTranscodingHint(PrintTranscoder.KEY_PAGE_ORIENTATION, PrintTranscoder.VALUE_PAGE_ORIENTATION_LANDSCAPE); // clone document Document cloneDoc = (Document) document.cloneNode(true); TranscoderInput input = new TranscoderInput(cloneDoc); pt.transcode(input, null); try { pt.print(); } catch(java.awt.print.PrinterException ex) { ErrorDialog.displayGeneral(null, ex); } }// run() }.start(); // Thread() }// actionPerformed() }// inner class Print /** Implements exporting as JPG */ public static class ExportJPG extends Export { /** JPG export: default quality of 0.8 (80%) **/ public ExportJPG(MapPanel mp) { super(mp, new JPEGTranscoder(), SimpleFileFilter.JPG_FILTER); }// ExportJPG() /** Set JPEG-specific options */ public void setOptions(Transcoder t) { super.setOptions(t); //t.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, Color.WHITE); }// ExportJPG() }// nested class ExportJPG /** Implements exporting as PNG */ public static class ExportPNG extends Export { /** Create a PNG Export object */ public ExportPNG(MapPanel mp) { super(mp, new PNGTranscoder(), SimpleFileFilter.PNG_FILTER); }// ExportPNG() /** Set PNG options */ public void setOptions(Transcoder t) { super.setOptions(t); //t.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, Color.WHITE); }// ExportJPG() }// nested class ExportPNG /** Implements exporting as PDF */ public static class ExportPDF extends Export { public ExportPDF(MapPanel mp) { super(mp, new PDFTranscoder(), SimpleFileFilter.PDF_FILTER); }// ExportPDF() /** DO NOT apply Image export settings for PDF. */ public void setOptions(Transcoder t) { }// ExportJPG() }// nested class ExportPDF /* we need a new class, because SVG transcoder expects a Writer not an OutputStream */ /** Implements exporting as SVG */ public static class ExportSVG implements ActionListener { private final MapPanel mp; public ExportSVG(MapPanel mp) { this.mp = mp; }// ExportJPG() public void actionPerformed(ActionEvent e) { final Document document = mp.getSVGDocument(); if(document == null) { return; } new Thread(getPMTG(mp), "jdipExportSVGThread") { public void run() { // get the file File file = getSaveFile(mp.getClientFrame(), SimpleFileFilter.SVG_FILTER); if(file == null) { return; } // create a transcoder, set error handler SVGTranscoder transcoder = new SVGTranscoder(); transcoder.setErrorHandler(new TranscoderErrorHandler()); ExportPreferencePanel.applyTranscodingHints(transcoder); // clone document final Document cloneDoc = (Document) document.cloneNode(true); // create the transcoder input TranscoderInput input = new TranscoderInput(cloneDoc); Writer writer = null; try { // create the transcoder output -- it must be a Writer! writer = new BufferedWriter(new FileWriter(file)); TranscoderOutput output = new TranscoderOutput(writer); // save image transcoder.transcode(input, output); writer.flush(); } catch(Exception ex) { ErrorDialog.displayFileIO(null, ex, file.getName()); } finally { if(writer != null) { try { writer.close(); } catch(IOException e) { ErrorDialog.displayFileIO(null, e, file.getName()); } } } }// run() }.start(); // Thread() }// actionPerformed() }// nested class ExportSVG /** Implements basic exporting */ public static class Export implements ActionListener { private final MapPanel mp; private final SimpleFileFilter simpleFileFilter; private final Transcoder transcoder; /** Export */ public Export(MapPanel mp, Transcoder t, SimpleFileFilter simpleFileFilter) { if(mp == null || t == null || simpleFileFilter == null) { throw new IllegalArgumentException(); } this.mp = mp; this.simpleFileFilter = simpleFileFilter; this.transcoder = t; }// ExportJPG() /** * Set any transcoding options. * By default, uses ExportPreferencePanel to set options; * thus, subclasses should call their super() constructor unless * they wish to override the preference settings. */ public void setOptions(Transcoder t) { ExportPreferencePanel.applyTranscodingHints(t); }// setOptions() /** Perform the Export */ public void actionPerformed(ActionEvent e) { final Document document = mp.getSVGDocument(); if(document == null) { return; } new Thread(getPMTG(mp), "jdipExportThread") { public void run() { // get the file File file = getSaveFile(mp.getClientFrame(), simpleFileFilter); if(file == null) { return; } // set error handler transcoder.setErrorHandler(new TranscoderErrorHandler()); // set options setOptions(transcoder); // create the transcoder input, after cloning the document. final Document cloneDoc = (Document) document.cloneNode(true); TranscoderInput input = new TranscoderInput(cloneDoc); OutputStream ostream = null; try { // create the transcoder output ostream = new BufferedOutputStream(new FileOutputStream(file)); TranscoderOutput output = new TranscoderOutput(ostream); // save image transcoder.transcode(input, output); ostream.flush(); } catch(Exception ex) { ErrorDialog.displayFileIO(null, ex, file.getName()); } finally { if(ostream != null) { try { ostream.close(); } catch(IOException e) { ErrorDialog.displayFileIO(null, e, file.getName()); } } } }// run() }.start(); // Thread() }// actionPerformed() }// nested class Export /** Popup a "save as" file requester */ private static synchronized File getSaveFile(ClientFrame cf, SimpleFileFilter simpleFileFilter) { XJFileChooser chooser = XJFileChooser.getXJFileChooser(); chooser.addFileFilter(simpleFileFilter); chooser.setFileFilter(simpleFileFilter); chooser.setCurrentDirectory( GeneralPreferencePanel.getDefaultGameDir() ); chooser.setSelectedFile( new File(cf.getPM().getSuggestedExportName()) ); File file = chooser.displaySave(cf, Utils.getLocalString("MapPanel.export.title")); chooser.dispose(); return file; }// getSaveFile() /** Get the PM thread group from a MapPanel */ private static ThreadGroup getPMTG(MapPanel mp) { return mp.getClientFrame().getPM().getPMThreadGroup(); }// getPMTG() }// class MapSVGAction