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

Last change on this file since 8178 was 8061, checked in by bastiK, 9 years ago

see #11096 - strip .png

  • Property svn:eol-style set to native
File size: 7.5 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
25public abstract class SaveActionBase extends DiskAccessAction {
26 private File file;
27
28 public SaveActionBase(String name, String iconName, String tooltip, Shortcut shortcut) {
29 super(name, iconName, tooltip, shortcut);
30 }
31
32 @Override
33 public void actionPerformed(ActionEvent e) {
34 if (!isEnabled())
35 return;
36 boolean saved = doSave();
37 if (saved) {
38 addToFileOpenHistory();
39 }
40 }
41
42 public boolean doSave() {
43 if (Main.isDisplayingMapView()) {
44 Layer layer = Main.map.mapView.getActiveLayer();
45 if (layer != null && layer.isSavable()) {
46 return doSave(layer);
47 }
48 }
49 return false;
50 }
51
52 public boolean doSave(Layer layer) {
53 if(!layer.checkSaveConditions())
54 return false;
55 file = getFile(layer);
56 return doInternalSave(layer, file);
57 }
58
59 /**
60 * Saves a layer to a given file.
61 * @param layer The layer to save
62 * @param file The destination file
63 * @param checkSaveConditions if {@code true}, checks preconditions before saving. Set it to {@code false} to skip it
64 * if preconditions have already been checked (as this check can prompt UI dialog in EDT it may be best in some cases
65 * to do it earlier).
66 * @return {@code true} if the layer has been successfully saved, {@code false} otherwise
67 * @since 7204
68 */
69 public static boolean doSave(Layer layer, File file, boolean checkSaveConditions) {
70 if (checkSaveConditions && !layer.checkSaveConditions())
71 return false;
72 return doInternalSave(layer, file);
73 }
74
75 private static boolean doInternalSave(Layer layer, File file) {
76 if (file == null)
77 return false;
78
79 try {
80 boolean exported = false;
81 boolean canceled = false;
82 for (FileExporter exporter : ExtensionFileFilter.exporters) {
83 if (exporter.acceptFile(file, layer)) {
84 exporter.exportData(file, layer);
85 exported = true;
86 canceled = exporter.isCanceled();
87 break;
88 }
89 }
90 if (!exported) {
91 JOptionPane.showMessageDialog(Main.parent, tr("No Exporter found! Nothing saved."), tr("Warning"),
92 JOptionPane.WARNING_MESSAGE);
93 return false;
94 } else if (canceled) {
95 return false;
96 }
97 layer.setName(file.getName());
98 layer.setAssociatedFile(file);
99 if (layer instanceof OsmDataLayer) {
100 ((OsmDataLayer) layer).onPostSaveToFile();
101 }
102 Main.parent.repaint();
103 } catch (IOException e) {
104 Main.error(e);
105 return false;
106 }
107 return true;
108 }
109
110 protected abstract File getFile(Layer layer);
111
112 /**
113 * Refreshes the enabled state
114 *
115 */
116 @Override
117 protected void updateEnabledState() {
118 boolean check = Main.isDisplayingMapView()
119 && Main.map.mapView.getActiveLayer() != null;
120 if(!check) {
121 setEnabled(false);
122 return;
123 }
124 Layer layer = Main.map.mapView.getActiveLayer();
125 setEnabled(layer != null && layer.isSavable());
126 }
127
128 /**
129 * Creates a new "Save" dialog for a single {@link ExtensionFileFilter} and makes it visible.<br>
130 * When the user has chosen a file, checks the file extension, and confirms overwrite if needed.
131 *
132 * @param title The dialog title
133 * @param filter The dialog file filter
134 * @return The output {@code File}
135 * @since 5456
136 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, FileFilter, int, String)
137 */
138 public static File createAndOpenSaveFileChooser(String title, ExtensionFileFilter filter) {
139 AbstractFileChooser fc = createAndOpenFileChooser(false, false, title, filter, JFileChooser.FILES_ONLY, null);
140 return checkFileAndConfirmOverWrite(fc, filter.getDefaultExtension());
141 }
142
143 /**
144 * Creates a new "Save" dialog for a given file extension and makes it visible.<br>
145 * When the user has chosen a file, checks the file extension, and confirms overwrite if needed.
146 *
147 * @param title The dialog title
148 * @param extension The file extension
149 * @return The output {@code File}
150 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, String)
151 */
152 public static File createAndOpenSaveFileChooser(String title, String extension) {
153 AbstractFileChooser fc = createAndOpenFileChooser(false, false, title, extension);
154 return checkFileAndConfirmOverWrite(fc, extension);
155 }
156
157 private static File checkFileAndConfirmOverWrite(AbstractFileChooser fc, String extension) {
158 if (fc == null) return null;
159 File file = fc.getSelectedFile();
160
161 FileFilter ff = fc.getFileFilter();
162 if (!ff.accept(file)) {
163 // Extension of another filefilter given ?
164 for (FileFilter cff : fc.getChoosableFileFilters()) {
165 if (cff.accept(file)) {
166 fc.setFileFilter(cff);
167 return file;
168 }
169 }
170 // No filefilter accepts current filename, add default extension
171 String fn = file.getPath();
172 if (ff instanceof ExtensionFileFilter) {
173 fn += "." + ((ExtensionFileFilter)ff).getDefaultExtension();
174 } else if (extension != null) {
175 fn += "." + extension;
176 }
177 file = new File(fn);
178 if (!confirmOverwrite(file))
179 return null;
180 }
181 return file;
182 }
183
184 public static boolean confirmOverwrite(File file) {
185 if (file == null || (file.exists())) {
186 ExtendedDialog dialog = new ExtendedDialog(
187 Main.parent,
188 tr("Overwrite"),
189 new String[] {tr("Overwrite"), tr("Cancel")}
190 );
191 dialog.setContent(tr("File exists. Overwrite?"));
192 dialog.setButtonIcons(new String[] {"save_as", "cancel"});
193 dialog.showDialog();
194 return (dialog.getValue() == 1);
195 }
196 return true;
197 }
198
199 protected void addToFileOpenHistory() {
200 String filepath;
201 try {
202 filepath = file.getCanonicalPath();
203 } catch (IOException ign) {
204 return;
205 }
206
207 int maxsize = Math.max(0, Main.pref.getInteger("file-open.history.max-size", 15));
208 Collection<String> oldHistory = Main.pref.getCollection("file-open.history");
209 List<String> history = new LinkedList<>(oldHistory);
210 history.remove(filepath);
211 history.add(0, filepath);
212 Main.pref.putCollectionBounded("file-open.history", maxsize, history);
213 }
214}
Note: See TracBrowser for help on using the repository browser.