source: josm/trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java@ 12841

Last change on this file since 12841 was 12841, checked in by bastiK, 7 years ago

see #15229 - fix deprecations caused by [12840]

  • Property svn:eol-style set to native
File size: 8.5 KB
RevLine 
[8378]1// License: GPL. For details, see LICENSE file.
[290]2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.io.File;
8import java.io.IOException;
[4371]9import java.util.Collection;
10import java.util.LinkedList;
11import java.util.List;
[5014]12
[1949]13import javax.swing.JFileChooser;
[290]14import javax.swing.JOptionPane;
[1949]15import javax.swing.filechooser.FileFilter;
[290]16
17import org.openstreetmap.josm.Main;
[1397]18import org.openstreetmap.josm.gui.ExtendedDialog;
[12671]19import org.openstreetmap.josm.gui.io.importexport.FileExporter;
[1523]20import org.openstreetmap.josm.gui.layer.Layer;
[290]21import org.openstreetmap.josm.gui.layer.OsmDataLayer;
[7578]22import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
[12620]23import org.openstreetmap.josm.tools.Logging;
[1084]24import org.openstreetmap.josm.tools.Shortcut;
[290]25
[9676]26/**
27 * Abstract superclass of save actions.
28 * @since 290
29 */
[1820]30public abstract class SaveActionBase extends DiskAccessAction {
[290]31
[9676]32 /**
33 * Constructs a new {@code SaveActionBase}.
34 * @param name The action's text as displayed on the menu (if it is added to a menu)
35 * @param iconName The filename of the icon to use
36 * @param tooltip A longer description of the action that will be displayed in the tooltip
37 * @param shortcut A ready-created shortcut object or {@code null} if you don't want a shortcut
38 */
[1808]39 public SaveActionBase(String name, String iconName, String tooltip, Shortcut shortcut) {
[1169]40 super(name, iconName, tooltip, shortcut);
41 }
[1023]42
[4371]43 @Override
[1169]44 public void actionPerformed(ActionEvent e) {
[5014]45 if (!isEnabled())
[1808]46 return;
[9413]47 doSave();
[1373]48 }
49
[9676]50 /**
51 * Saves the active layer.
52 * @return {@code true} if the save operation succeeds
53 */
[1808]54 public boolean doSave() {
[12636]55 Layer layer = getLayerManager().getActiveLayer();
[10318]56 if (layer != null && layer.isSavable()) {
57 return doSave(layer);
[1750]58 }
[5459]59 return false;
[1808]60 }
[290]61
[9676]62 /**
63 * Saves the given layer.
64 * @param layer layer to save
65 * @return {@code true} if the save operation succeeds
66 */
[1808]67 public boolean doSave(Layer layer) {
[8510]68 if (!layer.checkSaveConditions())
[1808]69 return false;
[10007]70 return doInternalSave(layer, getFile(layer));
[4114]71 }
72
[7204]73 /**
74 * Saves a layer to a given file.
75 * @param layer The layer to save
76 * @param file The destination file
77 * @param checkSaveConditions if {@code true}, checks preconditions before saving. Set it to {@code false} to skip it
78 * if preconditions have already been checked (as this check can prompt UI dialog in EDT it may be best in some cases
79 * to do it earlier).
80 * @return {@code true} if the layer has been successfully saved, {@code false} otherwise
81 * @since 7204
82 */
83 public static boolean doSave(Layer layer, File file, boolean checkSaveConditions) {
84 if (checkSaveConditions && !layer.checkSaveConditions())
[1808]85 return false;
[4114]86 return doInternalSave(layer, file);
87 }
[290]88
[5014]89 private static boolean doInternalSave(Layer layer, File file) {
[1169]90 if (file == null)
[1373]91 return false;
[290]92
[1949]93 try {
94 boolean exported = false;
[6815]95 boolean canceled = false;
[10407]96 for (FileExporter exporter : ExtensionFileFilter.getExporters()) {
[1949]97 if (exporter.acceptFile(file, layer)) {
98 exporter.exportData(file, layer);
99 exported = true;
[6815]100 canceled = exporter.isCanceled();
[4463]101 break;
[1949]102 }
103 }
104 if (!exported) {
[2017]105 JOptionPane.showMessageDialog(Main.parent, tr("No Exporter found! Nothing saved."), tr("Warning"),
[1949]106 JOptionPane.WARNING_MESSAGE);
107 return false;
[6815]108 } else if (canceled) {
109 return false;
[1949]110 }
[9510]111 if (!layer.isRenamed()) {
112 layer.setName(file.getName());
113 }
[1949]114 layer.setAssociatedFile(file);
[2025]115 if (layer instanceof OsmDataLayer) {
116 ((OsmDataLayer) layer).onPostSaveToFile();
117 }
[1949]118 Main.parent.repaint();
119 } catch (IOException e) {
[12620]120 Logging.error(e);
[1949]121 return false;
122 }
[9303]123 addToFileOpenHistory(file);
[1373]124 return true;
[1169]125 }
[319]126
[1169]127 protected abstract File getFile(Layer layer);
[290]128
[1169]129 /**
[1808]130 * Refreshes the enabled state
[1949]131 *
[1808]132 */
[1820]133 @Override
134 protected void updateEnabledState() {
[12636]135 Layer activeLayer = getLayerManager().getActiveLayer();
[10318]136 setEnabled(activeLayer != null && activeLayer.isSavable());
[1808]137 }
[1949]138
[5456]139 /**
[6830]140 * Creates a new "Save" dialog for a single {@link ExtensionFileFilter} and makes it visible.<br>
[5456]141 * When the user has chosen a file, checks the file extension, and confirms overwrite if needed.
[6069]142 *
[5456]143 * @param title The dialog title
144 * @param filter The dialog file filter
145 * @return The output {@code File}
[8419]146 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, FileFilter, int, String)
[5456]147 * @since 5456
148 */
149 public static File createAndOpenSaveFileChooser(String title, ExtensionFileFilter filter) {
[7578]150 AbstractFileChooser fc = createAndOpenFileChooser(false, false, title, filter, JFileChooser.FILES_ONLY, null);
[5456]151 return checkFileAndConfirmOverWrite(fc, filter.getDefaultExtension());
152 }
153
154 /**
[6830]155 * Creates a new "Save" dialog for a given file extension and makes it visible.<br>
[5456]156 * When the user has chosen a file, checks the file extension, and confirms overwrite if needed.
[6069]157 *
[5456]158 * @param title The dialog title
159 * @param extension The file extension
160 * @return The output {@code File}
161 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, String)
162 */
[1949]163 public static File createAndOpenSaveFileChooser(String title, String extension) {
[7578]164 AbstractFileChooser fc = createAndOpenFileChooser(false, false, title, extension);
[5456]165 return checkFileAndConfirmOverWrite(fc, extension);
166 }
[6069]167
[9670]168 /**
169 * Checks if selected filename has the given extension. If not, adds the extension and asks for overwrite if filename exists.
170 *
171 * @param fc FileChooser where file was already selected
[9676]172 * @param extension file extension
[9670]173 * @return the {@code File} or {@code null} if the user cancelled the dialog.
174 */
175 public static File checkFileAndConfirmOverWrite(AbstractFileChooser fc, String extension) {
[9676]176 if (fc == null)
177 return null;
[1949]178 File file = fc.getSelectedFile();
[6069]179
[6011]180 FileFilter ff = fc.getFileFilter();
181 if (!ff.accept(file)) {
182 // Extension of another filefilter given ?
183 for (FileFilter cff : fc.getChoosableFileFilters()) {
184 if (cff.accept(file)) {
185 fc.setFileFilter(cff);
186 return file;
187 }
188 }
189 // No filefilter accepts current filename, add default extension
190 String fn = file.getPath();
[9721]191 if (extension != null && ff.accept(new File(fn + '.' + extension))) {
[9466]192 fn += '.' + extension;
193 } else if (ff instanceof ExtensionFileFilter) {
[8846]194 fn += '.' + ((ExtensionFileFilter) ff).getDefaultExtension();
[1949]195 }
[3570]196 file = new File(fn);
[9687]197 if (!fc.getSelectedFile().exists() && !confirmOverwrite(file))
[5457]198 return null;
[1949]199 }
[3863]200 return file;
201 }
202
[9676]203 /**
204 * Asks user to confirm overwiting a file.
205 * @param file file to overwrite
206 * @return {@code true} if the file can be written
207 */
[4911]208 public static boolean confirmOverwrite(File file) {
[9676]209 if (file == null || file.exists()) {
[12279]210 return new ExtendedDialog(
[2070]211 Main.parent,
212 tr("Overwrite"),
[12279]213 tr("Overwrite"), tr("Cancel"))
214 .setContent(tr("File exists. Overwrite?"))
215 .setButtonIcons("save_as", "cancel")
216 .showDialog()
217 .getValue() == 1;
[2070]218 }
[3863]219 return true;
[1949]220 }
[4371]221
[8802]222 static void addToFileOpenHistory(File file) {
223 final String filepath;
[4371]224 try {
225 filepath = file.getCanonicalPath();
226 } catch (IOException ign) {
[12620]227 Logging.warn(ign);
[4371]228 return;
229 }
230
[12841]231 int maxsize = Math.max(0, Main.pref.getInt("file-open.history.max-size", 15));
232 Collection<String> oldHistory = Main.pref.getList("file-open.history");
[7005]233 List<String> history = new LinkedList<>(oldHistory);
[4374]234 history.remove(filepath);
[4371]235 history.add(0, filepath);
236 Main.pref.putCollectionBounded("file-open.history", maxsize, history);
237 }
[290]238}
Note: See TracBrowser for help on using the repository browser.