001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.actions.SaveActionBase.createAndOpenSaveFileChooser;
005import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
006import static org.openstreetmap.josm.tools.I18n.tr;
007
008import java.awt.event.ActionEvent;
009import java.awt.event.KeyEvent;
010import java.io.File;
011import java.io.IOException;
012import java.text.MessageFormat;
013
014import javax.swing.JOptionPane;
015
016import org.openstreetmap.josm.Main;
017import org.openstreetmap.josm.gui.layer.GpxLayer;
018import org.openstreetmap.josm.gui.layer.Layer;
019import org.openstreetmap.josm.gui.layer.OsmDataLayer;
020import org.openstreetmap.josm.io.FileExporter;
021import org.openstreetmap.josm.io.GpxImporter;
022import org.openstreetmap.josm.tools.CheckParameterUtil;
023import org.openstreetmap.josm.tools.Shortcut;
024
025/**
026 * Exports data to gpx.
027 * @since 78
028 */
029public class GpxExportAction extends DiskAccessAction {
030
031    /**
032     * Constructs a new {@code GpxExportAction}.
033     */
034    public GpxExportAction() {
035        super(tr("Export to GPX..."), "exportgpx", tr("Export the data to GPX file."),
036                Shortcut.registerShortcut("file:exportgpx", tr("Export to GPX..."), KeyEvent.VK_E, Shortcut.CTRL));
037        putValue("help", ht("/Action/GpxExport"));
038    }
039
040    /**
041     * Get the layer to export.
042     * @return The layer to export, either a {@link GpxLayer} or {@link OsmDataLayer}.
043     */
044    protected Layer getLayer() {
045        if (!Main.isDisplayingMapView())
046            return null;
047        Layer layer = Main.map.mapView.getActiveLayer();
048        return (layer instanceof GpxLayer || layer instanceof OsmDataLayer) ? layer : null;
049    }
050
051    @Override
052    public void actionPerformed(ActionEvent e) {
053        if (!isEnabled())
054            return;
055        Layer layer = getLayer();
056        if (layer == null) {
057            JOptionPane.showMessageDialog(
058                    Main.parent,
059                    tr("Nothing to export. Get some data first."),
060                    tr("Information"),
061                    JOptionPane.INFORMATION_MESSAGE
062            );
063            return;
064        }
065        export(layer);
066    }
067
068    /**
069     * Exports a layer to a file. Launches a file chooser to request the user to enter a file name.
070     *
071     * <code>layer</code> must not be null. <code>layer</code> must be an instance of
072     * {@link OsmDataLayer} or {@link GpxLayer}.
073     *
074     * @param layer the layer
075     * @throws IllegalArgumentException if layer is null
076     * @throws IllegalArgumentException if layer is neither an instance of {@link OsmDataLayer}
077     *  nor of {@link GpxLayer}
078     */
079    public void export(Layer layer) {
080        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
081        if (!(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
082            throw new IllegalArgumentException(MessageFormat.format("Expected instance of OsmDataLayer or GpxLayer. Got ''{0}''.",
083                    layer.getClass().getName()));
084
085        File file = createAndOpenSaveFileChooser(tr("Export GPX file"), GpxImporter.FILE_FILTER);
086        if (file == null)
087            return;
088
089        for (FileExporter exporter : ExtensionFileFilter.exporters) {
090            if (exporter.acceptFile(file, layer)) {
091                try {
092                    exporter.exportData(file, layer);
093                } catch (IOException e) {
094                    Main.error(e);
095                }
096            }
097        }
098    }
099
100    /**
101     * Refreshes the enabled state
102     */
103    @Override
104    protected void updateEnabledState() {
105        setEnabled(getLayer() != null);
106    }
107}