/* * Freeplane - mind map editor * Copyright (C) 2009 Eric Lavarde, Freeplane admins * * 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, see <http://www.gnu.org/licenses/>. */ package org.freeplane.features.export.mindmapmode; import java.awt.Component; import java.awt.EventQueue; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.text.MessageFormat; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import org.freeplane.core.ui.ExampleFileFilter; import org.freeplane.core.ui.components.UITools; import org.freeplane.core.util.FileUtils; import org.freeplane.core.util.TextUtils; import org.freeplane.features.map.MapModel; /** * This class uses the JFileChooser dialog to allow users to choose a file name to * export to. The filter selection is created by gathering all the *.xsl files * present in the user-specific and system-specific Export-directories of Freeplane. * Those files are recognised by their extension (.xsl) but also by the fact that they * contain within the 5 first lines a string of the form: * <pre>MINDMAPEXPORT <i>extensions</i> <i>description</i></pre> * where the fields in italic are relative to the file format to which the mindmap will * be exported to using this specific XSLT sheet: * <ul> * <li><i>extensions</i> is a semi-column separated list of acceptable file extensions * without asterisk or dot, e.g. "jpg;jpeg".</li> * <li><i>description</i> is a description of the file format, e.g. "JPEG image".</li> * </ul> * Only the first unique combination of extensions and description will be kept, in such * a way that users can "overwrite" an already existing XSLT sheet with their own * version. * @author Eric Lavarde * @see javax.swing.JFileChooser * */ public class ExportDialog { /** the JFileChooser dialog used to choose filter and the file to export to. */ final private JFileChooser fileChooser = new JFileChooser(); /** * This constructor does <i>not</i> the export per itself. * It populates the {@link #fileChooser} field * (especially the {@link JFileChooser#getChoosableFileFilters() choosable * file filters}). */ public ExportDialog() { super(); fileChooser.setAcceptAllFileFilterUsed(false); // the user can't select an "All Files filter" fileChooser.setDialogTitle(TextUtils.getText("export_using_xslt")); fileChooser.setToolTipText(TextUtils.getText("select_file_export_to")); final ExportController exportEngineRegistry = ExportController.getContoller(); for (FileFilter filter : exportEngineRegistry.getFileFilters()) { fileChooser.addChoosableFileFilter(filter); } final FileFilter fileFilter = fileChooser.getChoosableFileFilters()[0]; fileChooser.setFileFilter(fileFilter); } /** * A function to call again and again in order to export the same XML source file. * @see #export(Component) */ /** * A function to call again and again in order to export the same XML source file. * @param parentframe a parent component for the dialogs to appear (can be null). * @param streamSource */ void export(final Component parentframe, final MapModel map) { final ExportController exportEngineRegistry = ExportController.getContoller(); if (exportEngineRegistry.getFilterMap().isEmpty()) { JOptionPane.showMessageDialog(parentframe, TextUtils.getText("xslt_export_not_possible")); return; } // Finish to setup the File Chooser... // And then use it final String absolutePathWithoutExtension; final File xmlSourceFile = map.getFile(); if (xmlSourceFile != null) { absolutePathWithoutExtension = FileUtils.removeExtension(xmlSourceFile.getAbsolutePath()); } else { absolutePathWithoutExtension = null; } final PropertyChangeListener filterChangeListener = new PropertyChangeListener() { final private File selectedFile = absolutePathWithoutExtension == null ? null : new File( absolutePathWithoutExtension); public void propertyChange(final PropertyChangeEvent evt) { if (evt.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { final FileFilter filter = fileChooser.getFileFilter(); if(! (filter instanceof ExampleFileFilter)){ return; } final File acceptableFile = getAcceptableFile(selectedFile, (ExampleFileFilter) filter); EventQueue.invokeLater(new Runnable() { public void run() { fileChooser.setSelectedFile(acceptableFile); } }); return; } if (selectedFile != null && evt.getPropertyName().equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) { final FileFilter filter = fileChooser.getFileFilter(); if(! (filter instanceof ExampleFileFilter)){ return; } final File acceptableFile = getAcceptableFile(selectedFile, (ExampleFileFilter) filter); final File currentDirectory = fileChooser.getCurrentDirectory(); if(currentDirectory != null){ final File file = new File (currentDirectory, acceptableFile.getName()); fileChooser.setSelectedFile(file); } else fileChooser.setSelectedFile(acceptableFile); return; } } }; filterChangeListener.propertyChange(new PropertyChangeEvent(fileChooser, JFileChooser.FILE_FILTER_CHANGED_PROPERTY, null, fileChooser.getFileFilter())); try { fileChooser.addPropertyChangeListener(filterChangeListener); final int returnVal = fileChooser.showSaveDialog(parentframe); if (returnVal == JFileChooser.APPROVE_OPTION) { // we check which filter has been selected by the user and use its // description as key for the map to get the corresponding XSLT file if(! (fileChooser.getFileFilter() instanceof ExampleFileFilter)){ UITools.errorMessage(TextUtils.getText("invalid_export_file")); return; } final ExampleFileFilter fileFilter = (ExampleFileFilter) fileChooser.getFileFilter(); final File selectedFile = getAcceptableFile(fileChooser.getSelectedFile(), fileFilter); if (selectedFile == null) { return; } if (selectedFile.isDirectory()) { return; } if (selectedFile.exists()) { final String overwriteText = MessageFormat.format(TextUtils.getText("file_already_exists"), new Object[] { selectedFile.toString() }); final int overwriteMap = JOptionPane.showConfirmDialog(UITools.getFrame(), overwriteText, overwriteText, JOptionPane.YES_NO_OPTION); if (overwriteMap != JOptionPane.YES_OPTION) { return; } } final IExportEngine exportEngine = exportEngineRegistry.getFilterMap().get(fileFilter); exportEngine.export(map, selectedFile); } } finally { fileChooser.removePropertyChangeListener(filterChangeListener); } } private File getAcceptableFile(File selectedFile, final ExampleFileFilter fileFilter) { if (selectedFile == null) { return null; } if (!fileFilter.accept(selectedFile)) { selectedFile = new File(selectedFile.getAbsolutePath() + '.' + fileFilter.getExtensionProposal()); } return selectedFile; } }