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

Last change on this file since 10138 was 10007, checked in by Don-vip, 8 years ago

remove unused field

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