// $Id: ActionSaveAllGraphics.java 16011 2008-11-10 20:25:22Z tfmorris $ // Copyright (c) 1996-2008 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.uml.ui; import java.awt.event.ActionEvent; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import org.apache.log4j.Logger; import org.argouml.application.events.ArgoEventPump; import org.argouml.application.events.ArgoEventTypes; import org.argouml.application.events.ArgoStatusEvent; import org.argouml.configuration.Configuration; import org.argouml.i18n.Translator; import org.argouml.kernel.Project; import org.argouml.kernel.ProjectManager; import org.argouml.ui.targetmanager.TargetManager; import org.argouml.uml.diagram.ArgoDiagram; import org.argouml.uml.diagram.DiagramUtils; import org.argouml.util.ArgoFrame; import org.tigris.gef.base.Diagram; import org.tigris.gef.base.SaveGraphicsAction; import org.tigris.gef.util.Util; /** * Wraps a SaveGraphicsAction allow selection of an output directory to which * all diagrams will be written. Introduced thanks to issue 2126. Saves diagrams * only using the default format. * <p> * * TODO: Add a user choice for other formats (PNG, SVG,...) <p> * * @author Leonardo Souza Mario Bueno (lsbueno@tigris.org) */ public class ActionSaveAllGraphics extends AbstractAction { private static final Logger LOG = Logger.getLogger(ActionSaveAllGraphics.class); private boolean overwrite; /** * The constructor. * */ public ActionSaveAllGraphics() { super(Translator.localize("action.save-all-graphics"), null); // Set the tooltip string: putValue(Action.SHORT_DESCRIPTION, Translator.localize("action.save-all-graphics")); } public void actionPerformed( ActionEvent ae ) { trySave( false ); } /** * @param canOverwrite true if we can overwrite without asking * @return success */ public boolean trySave(boolean canOverwrite) { return trySave(canOverwrite, null); } /** * @param canOverwrite * true if we can overwrite without asking * @param directory * directory to save to. If null, user will be prompted to * choose. * @return success save status */ public boolean trySave(boolean canOverwrite, File directory) { overwrite = canOverwrite; Project p = ProjectManager.getManager().getCurrentProject(); TargetManager tm = TargetManager.getInstance(); File saveDir = (directory != null) ? directory : getSaveDir(p); if (saveDir == null) { /* The user cancelled! */ return false; } boolean okSoFar = true; ArgoDiagram activeDiagram = DiagramUtils.getActiveDiagram(); for (ArgoDiagram d : p.getDiagramList()) { tm.setTarget(d); okSoFar = trySaveDiagram(d, saveDir); if (!okSoFar) { break; } } tm.setTarget(activeDiagram); return okSoFar; } /** * @param target the diagram * @param saveDir the directory to save to * @return continue exporting diagrams if true */ protected boolean trySaveDiagram(Object target, File saveDir) { if ( target instanceof Diagram ) { String defaultName = ((Diagram) target).getName(); defaultName = Util.stripJunk(defaultName); // TODO: It's probably worthwhile to abstract and factor // this chooser and directory stuff. More file handling is // coming, I'm sure. try { File theFile = new File(saveDir, defaultName + "." + SaveGraphicsManager.getInstance().getDefaultSuffix()); String name = theFile.getName(); String path = theFile.getParent(); SaveGraphicsAction cmd = SaveGraphicsManager.getInstance() .getSaveActionBySuffix( SaveGraphicsManager.getInstance().getDefaultSuffix()); if (cmd == null) { showStatus("Unknown graphics file type with extension " + SaveGraphicsManager.getInstance() .getDefaultSuffix()); return false; } showStatus( "Writing " + path + name + "..." ); boolean result = saveGraphicsToFile(theFile, cmd); showStatus( "Wrote " + path + name ); return result; } catch ( FileNotFoundException ignore ) { LOG.error("got a FileNotFoundException", ignore); } catch ( IOException ignore ) { LOG.error("got an IOException", ignore); } } return false; } /** * @param p the current project * @return returns null if the user did not approve his choice */ protected File getSaveDir(Project p) { JFileChooser chooser = getFileChooser(p); String fn = Configuration.getString( SaveGraphicsManager.KEY_SAVEALL_GRAPHICS_PATH); if (fn.length() > 0) { chooser.setSelectedFile(new File(fn)); } int retval = chooser.showSaveDialog(ArgoFrame.getInstance()); if ( retval == JFileChooser.APPROVE_OPTION ) { File theFile = chooser.getSelectedFile(); String path = theFile.getPath(); Configuration.setString( SaveGraphicsManager.KEY_SAVEALL_GRAPHICS_PATH, path); return theFile; } return null; } /** * @param theFile the file to write * @param cmd the action to execute to save the graphics * @return continue exporting diagrams if true * @throws IOException */ private boolean saveGraphicsToFile(File theFile, SaveGraphicsAction cmd) throws IOException { if ( theFile.exists() && !overwrite ) { String message = Translator.messageFormat( "optionpane.confirm-overwrite", new Object[] {theFile}); String title = Translator.localize( "optionpane.confirm-overwrite-title"); //Custom button text: Object[] options = {Translator.localize( "optionpane.confirm-overwrite.overwrite"), // 0 Translator.localize( "optionpane.confirm-overwrite.overwrite-all"), // 1 Translator.localize( "optionpane.confirm-overwrite.skip-this-one"), // 2 Translator.localize( "optionpane.confirm-overwrite.cancel")}; // 3 int response = JOptionPane.showOptionDialog(ArgoFrame.getInstance(), message, title, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, //do not use a custom Icon options, //the titles of buttons options[0]); //default button title if (response == 1) { overwrite = true; } if (response == 2) { return true; } if (response == 3) { return false; } if (response == JOptionPane.CLOSED_OPTION) { return false; } } FileOutputStream fo = null; try { fo = new FileOutputStream( theFile ); cmd.setStream(fo); cmd.setScale(Configuration.getInteger( SaveGraphicsManager.KEY_GRAPHICS_RESOLUTION, 1)); cmd.actionPerformed(null); } finally { if (fo != null) { fo.close(); } } return true; } private JFileChooser getFileChooser(Project p) { JFileChooser chooser = null; try { if ( p != null && p.getURI() != null && p.getURI().toURL().getFile().length() > 0 ) { chooser = new JFileChooser(p.getURI().toURL().getFile()); } } catch ( MalformedURLException ex ) { LOG.error("exception in opening JFileChooser", ex); } if ( chooser == null ) chooser = new JFileChooser(); chooser.setDialogTitle( Translator.localize("filechooser.save-all-graphics")); chooser.setDialogType(JFileChooser.OPEN_DIALOG); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setMultiSelectionEnabled(false); return chooser; } private void showStatus(String text) { ArgoEventPump.fireEvent(new ArgoStatusEvent( ArgoEventTypes.STATUS_TEXT, this, text)); } }