| 1 | // License: GPL. For details, see LICENSE file.
|
|---|
| 2 | package org.openstreetmap.josm.actions;
|
|---|
| 3 |
|
|---|
| 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
|---|
| 5 | import static org.openstreetmap.josm.tools.I18n.tr;
|
|---|
| 6 |
|
|---|
| 7 | import java.awt.GridBagLayout;
|
|---|
| 8 | import java.awt.event.KeyEvent;
|
|---|
| 9 | import java.beans.PropertyChangeListener;
|
|---|
| 10 | import java.io.File;
|
|---|
| 11 |
|
|---|
| 12 | import javax.swing.JCheckBox;
|
|---|
| 13 | import javax.swing.JLabel;
|
|---|
| 14 | import javax.swing.JPanel;
|
|---|
| 15 | import javax.swing.SwingConstants;
|
|---|
| 16 |
|
|---|
| 17 | import org.openstreetmap.josm.data.gpx.GpxConstants;
|
|---|
| 18 | import org.openstreetmap.josm.gui.ExtendedDialog;
|
|---|
| 19 | import org.openstreetmap.josm.gui.MainApplication;
|
|---|
| 20 | import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
|
|---|
| 21 | import org.openstreetmap.josm.gui.layer.GpxLayer;
|
|---|
| 22 | import org.openstreetmap.josm.gui.layer.Layer;
|
|---|
| 23 | import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
|
|---|
| 24 | import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
|
|---|
| 25 | import org.openstreetmap.josm.spi.preferences.Config;
|
|---|
| 26 | import org.openstreetmap.josm.tools.GBC;
|
|---|
| 27 | import org.openstreetmap.josm.tools.Shortcut;
|
|---|
| 28 |
|
|---|
| 29 | /**
|
|---|
| 30 | * Export the data as an OSM xml file.
|
|---|
| 31 | *
|
|---|
| 32 | * @author imi
|
|---|
| 33 | */
|
|---|
| 34 | public final class SaveAction extends SaveActionBase {
|
|---|
| 35 | private static final SaveAction instance = new SaveAction();
|
|---|
| 36 |
|
|---|
| 37 | private final PropertyChangeListener updateOnRequireSaveChange = evt -> {
|
|---|
| 38 | if (AbstractModifiableLayer.REQUIRES_SAVE_TO_DISK_PROP.equals(evt.getPropertyName())) {
|
|---|
| 39 | updateEnabledState();
|
|---|
| 40 | }
|
|---|
| 41 | };
|
|---|
| 42 |
|
|---|
| 43 | /**
|
|---|
| 44 | * Construct the action with "Save" as label.
|
|---|
| 45 | */
|
|---|
| 46 | private SaveAction() {
|
|---|
| 47 | super(tr("Save"), "save", tr("Save the current data."),
|
|---|
| 48 | Shortcut.registerShortcut("system:save", tr("File: {0}", tr("Save")), KeyEvent.VK_S, Shortcut.CTRL),
|
|---|
| 49 | true);
|
|---|
| 50 | setHelpId(ht("/Action/Save"));
|
|---|
| 51 | }
|
|---|
| 52 |
|
|---|
| 53 | /**
|
|---|
| 54 | * Returns the unique instance.
|
|---|
| 55 | * @return the unique instance
|
|---|
| 56 | */
|
|---|
| 57 | public static SaveAction getInstance() {
|
|---|
| 58 | return instance;
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | @Override
|
|---|
| 62 | protected LayerChangeAdapter buildLayerChangeAdapter() {
|
|---|
| 63 | return new LayerChangeAdapter() {
|
|---|
| 64 | @Override
|
|---|
| 65 | public void layerAdded(LayerAddEvent e) {
|
|---|
| 66 | Layer l = e.getAddedLayer();
|
|---|
| 67 | if (l instanceof AbstractModifiableLayer) {
|
|---|
| 68 | l.addPropertyChangeListener(updateOnRequireSaveChange);
|
|---|
| 69 | }
|
|---|
| 70 | super.layerAdded(e);
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | @Override
|
|---|
| 74 | public void layerRemoving(LayerRemoveEvent e) {
|
|---|
| 75 | Layer l = e.getRemovedLayer();
|
|---|
| 76 | if (l instanceof AbstractModifiableLayer) {
|
|---|
| 77 | l.removePropertyChangeListener(updateOnRequireSaveChange);
|
|---|
| 78 | }
|
|---|
| 79 | super.layerRemoving(e);
|
|---|
| 80 | }
|
|---|
| 81 | };
|
|---|
| 82 | }
|
|---|
| 83 |
|
|---|
| 84 | @Override
|
|---|
| 85 | protected boolean listenToSelectionChange() {
|
|---|
| 86 | return false;
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | @Override
|
|---|
| 90 | public File getFile(Layer layer) {
|
|---|
| 91 | File f = layer.getAssociatedFile();
|
|---|
| 92 | if (f != null && !f.exists()) {
|
|---|
| 93 | f = null;
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | // Ask for overwrite in case of GpxLayer
|
|---|
| 97 | if (f != null
|
|---|
| 98 | && layer instanceof GpxLayer
|
|---|
| 99 | && (((GpxLayer) layer).data == null
|
|---|
| 100 | || !GpxConstants.JOSM_CREATOR_NAME.equals(((GpxLayer) layer).data.creator))
|
|---|
| 101 | && !Config.getPref().getBoolean("gpx.export.overwrite", false)) {
|
|---|
| 102 |
|
|---|
| 103 | JPanel p = new JPanel(new GridBagLayout());
|
|---|
| 104 | JLabel label = new JLabel("<html>"
|
|---|
| 105 | + tr("The file \"{0}\" will be modified.<br>Would you like to overwrite the existing file?", f.getName())
|
|---|
| 106 | + "</html>");
|
|---|
| 107 | label.setHorizontalAlignment(SwingConstants.CENTER);
|
|---|
| 108 | JCheckBox remember = new JCheckBox(tr("Always overwrite GPX files without asking"));
|
|---|
| 109 | remember.setHorizontalAlignment(SwingConstants.CENTER);
|
|---|
| 110 | p.add(label, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 10));
|
|---|
| 111 | p.add(remember, GBC.eop().fill(GBC.HORIZONTAL));
|
|---|
| 112 | ExtendedDialog dialog = new ExtendedDialog(
|
|---|
| 113 | MainApplication.getMainFrame(),
|
|---|
| 114 | tr("Overwrite"),
|
|---|
| 115 | tr("Overwrite"), tr("Save As..."), tr("Cancel"))
|
|---|
| 116 | .setButtonIcons("save", "save_as", "cancel")
|
|---|
| 117 | .setContent(p);
|
|---|
| 118 | int val = dialog.showDialog().getValue();
|
|---|
| 119 | if (val == 1) {
|
|---|
| 120 | Config.getPref().putBoolean("gpx.export.overwrite", remember.isSelected());
|
|---|
| 121 | } else if (val == 2) {
|
|---|
| 122 | f = null;
|
|---|
| 123 | } else {
|
|---|
| 124 | return null;
|
|---|
| 125 | }
|
|---|
| 126 | }
|
|---|
| 127 | return f == null ? layer.createAndOpenSaveFileChooser() : f;
|
|---|
| 128 | }
|
|---|
| 129 | }
|
|---|