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

Last change on this file since 1222 was 1180, checked in by stoecker, 15 years ago

fixed bug #1871, removed all deprecations

  • Property svn:eol-style set to native
File size: 8.8 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
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.FileOutputStream;
9import java.io.FileInputStream;
10import java.io.FileNotFoundException;
11import java.io.IOException;
12
13import javax.swing.JFileChooser;
14import javax.swing.JOptionPane;
15import javax.swing.filechooser.FileFilter;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.gui.layer.OsmDataLayer;
20import org.openstreetmap.josm.gui.layer.Layer;
21import org.openstreetmap.josm.gui.layer.GpxLayer;
22import org.openstreetmap.josm.io.OsmWriter;
23import org.openstreetmap.josm.io.GpxWriter;
24import org.openstreetmap.josm.tools.Shortcut;
25
26public abstract class SaveActionBase extends DiskAccessAction {
27
28 private Layer layer;
29
30 public SaveActionBase(String name, String iconName, String tooltip, Shortcut shortcut, Layer layer) {
31 super(name, iconName, tooltip, shortcut);
32 this.layer = layer;
33 }
34
35 public void actionPerformed(ActionEvent e) {
36 Layer layer = this.layer;
37 if (layer == null && Main.map != null && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
38 || Main.map.mapView.getActiveLayer() instanceof GpxLayer))
39 layer = Main.map.mapView.getActiveLayer();
40 if (layer == null)
41 layer = Main.main.editLayer();
42
43 if (!checkSaveConditions(layer))
44 return;
45
46
47 File file = getFile(layer);
48 if (file == null)
49 return;
50
51 save(file, layer);
52
53 layer.name = file.getName();
54 layer.associatedFile = file;
55 Main.parent.repaint();
56 }
57
58 protected abstract File getFile(Layer layer);
59
60 /**
61 * Checks whether it is ok to launch a save (whether we have data,
62 * there is no conflict etc.)
63 * @return <code>true</code>, if it is safe to save.
64 */
65 public boolean checkSaveConditions(Layer layer) {
66 if (layer == null) {
67 JOptionPane.showMessageDialog(Main.parent, tr("Internal Error: cannot check conditions for no layer. Please report this as a bug."));
68 return false;
69 }
70 if (Main.map == null) {
71 JOptionPane.showMessageDialog(Main.parent, tr("No document open so nothing to save."));
72 return false;
73 }
74
75 if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.parent,tr("The document contains no data. Save anyway?"), tr("Empty document"), JOptionPane.YES_NO_OPTION)) {
76 return false;
77 }
78 if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null) {
79 return false;
80 }
81 if (!Main.map.conflictDialog.conflicts.isEmpty()) {
82 int answer = JOptionPane.showConfirmDialog(Main.parent,
83 tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"),tr("Conflicts"), JOptionPane.YES_NO_OPTION);
84 if (answer != JOptionPane.YES_OPTION)
85 return false;
86 }
87 return true;
88 }
89
90 public static File openFileDialog(Layer layer) {
91 JFileChooser fc = createAndOpenFileChooser(false, false, layer instanceof GpxLayer ? tr("Save GPX file") : tr("Save OSM file"));
92 if (fc == null)
93 return null;
94
95 File file = fc.getSelectedFile();
96
97 String fn = file.getPath();
98 if (fn.indexOf('.') == -1) {
99 FileFilter ff = fc.getFileFilter();
100 if (ff instanceof ExtensionFileFilter)
101 fn += "." + ((ExtensionFileFilter)ff).defaultExtension;
102 else if (layer instanceof GpxLayer)
103 fn += ".gpx";
104 else
105 fn += ".osm";
106 file = new File(fn);
107 }
108 return file;
109 }
110
111 private static void copy(File src, File dst) throws IOException {
112 FileInputStream srcStream;
113 FileOutputStream dstStream;
114 try {
115 srcStream = new FileInputStream(src);
116 dstStream = new FileOutputStream(dst);
117 } catch (FileNotFoundException e) {
118 JOptionPane.showMessageDialog(Main.parent, tr("Could not back up file.")+"\n"+e.getMessage());
119 return;
120 }
121 byte buf[] = new byte[1<<16];
122 int len;
123 while ((len = srcStream.read(buf)) != -1) {
124 dstStream.write(buf, 0, len);
125 }
126 srcStream.close();
127 dstStream.close();
128 }
129
130 public static void save(File file, Layer layer) {
131 if (layer instanceof GpxLayer) {
132 save(file, (GpxLayer)layer);
133 ((GpxLayer)layer).data.storageFile = file;
134 } else if (layer instanceof OsmDataLayer) {
135 save(file, (OsmDataLayer)layer);
136 }
137 }
138
139 public static void save(File file, OsmDataLayer layer) {
140 File tmpFile = null;
141 try {
142 if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(file.getPath())) {
143 GpxExportAction.exportGpx(file, layer);
144 } else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(file.getPath())) {
145 // use a tmp file because if something errors out in the
146 // process of writing the file, we might just end up with
147 // a truncated file. That can destroy lots of work.
148 if (file.exists()) {
149 tmpFile = new File(file.getPath() + "~");
150 copy(file, tmpFile);
151 }
152 OsmWriter.output(new FileOutputStream(file), new OsmWriter.All(layer.data, false));
153 if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null))
154 tmpFile.delete();
155 } else {
156 JOptionPane.showMessageDialog(Main.parent, tr("Unknown file extension."));
157 return;
158 }
159 layer.cleanData(null, false);
160 } catch (IOException e) {
161 e.printStackTrace();
162 JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while saving.")+"\n"+e.getMessage());
163
164 try {
165 // if the file save failed, then the tempfile will not
166 // be deleted. So, restore the backup if we made one.
167 if (tmpFile != null && tmpFile.exists()) {
168 copy(tmpFile, file);
169 }
170 } catch (IOException e2) {
171 e2.printStackTrace();
172 JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while restoring backup file.")+"\n"+e2.getMessage());
173 }
174 }
175 }
176
177 public static void save(File file, GpxLayer layer) {
178 File tmpFile = null;
179 try {
180 if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(file.getPath())) {
181
182 // use a tmp file because if something errors out in the
183 // process of writing the file, we might just end up with
184 // a truncated file. That can destroy lots of work.
185 if (file.exists()) {
186 tmpFile = new File(file.getPath() + "~");
187 copy(file, tmpFile);
188 }
189 FileOutputStream fo = new FileOutputStream(file);
190 new GpxWriter(fo).write(layer.data);
191 fo.flush();
192 fo.close();
193
194 if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null)) {
195 tmpFile.delete();
196 }
197 } else {
198 JOptionPane.showMessageDialog(Main.parent, tr("Unknown file extension."));
199 return;
200 }
201 } catch (IOException e) {
202 e.printStackTrace();
203 JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while saving.")+"\n"+e.getMessage());
204 }
205 try {
206 // if the file save failed, then the tempfile will not
207 // be deleted. So, restore the backup if we made one.
208 if (tmpFile != null && tmpFile.exists()) {
209 copy(tmpFile, file);
210 }
211 } catch (IOException e) {
212 e.printStackTrace();
213 JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while restoring backup file.")+"\n"+e.getMessage());
214 }
215 }
216
217 /**
218 * Check the data set if it would be empty on save. It is empty, if it contains
219 * no objects (after all objects that are created and deleted without being
220 * transfered to the server have been removed).
221 *
222 * @return <code>true</code>, if a save result in an empty data set.
223 */
224 private boolean isDataSetEmpty(OsmDataLayer layer) {
225 for (OsmPrimitive osm : layer.data.allNonDeletedPrimitives())
226 if (!osm.deleted || osm.id > 0)
227 return false;
228 return true;
229 }
230}
Note: See TracBrowser for help on using the repository browser.