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

Last change on this file since 4404 was 4374, checked in by bastiK, 13 years ago

no duplicate entries in file history

  • Property svn:eol-style set to native
File size: 8.8 KB
RevLine 
[319]1//License: GPL. Copyright 2007 by Immanuel Scholz and others
[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;
[1949]12import javax.swing.JFileChooser;
[290]13import javax.swing.JOptionPane;
[1949]14import javax.swing.filechooser.FileFilter;
[290]15
16import org.openstreetmap.josm.Main;
[1750]17import org.openstreetmap.josm.data.conflict.ConflictCollection;
[290]18import org.openstreetmap.josm.data.osm.OsmPrimitive;
[1397]19import org.openstreetmap.josm.gui.ExtendedDialog;
[1523]20import org.openstreetmap.josm.gui.layer.GpxLayer;
21import org.openstreetmap.josm.gui.layer.Layer;
[290]22import org.openstreetmap.josm.gui.layer.OsmDataLayer;
[1949]23import org.openstreetmap.josm.io.FileExporter;
[1084]24import org.openstreetmap.josm.tools.Shortcut;
[290]25
[1820]26public abstract class SaveActionBase extends DiskAccessAction {
[4371]27 private File file;
[290]28
[1808]29 public SaveActionBase(String name, String iconName, String tooltip, Shortcut shortcut) {
[1169]30 super(name, iconName, tooltip, shortcut);
31 }
[1023]32
[4371]33 @Override
[1169]34 public void actionPerformed(ActionEvent e) {
[4371]35 if (!isEnabled()) {
[1808]36 return;
[4371]37 }
38 boolean saved = doSave();
39 if (saved) {
40 addToFileOpenHistory();
41 }
[1373]42 }
43
[1808]44 public boolean doSave() {
45 Layer layer = null;
[2343]46 if (Main.isDisplayingMapView() && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
[1750]47 || Main.map.mapView.getActiveLayer() instanceof GpxLayer)) {
[1169]48 layer = Main.map.mapView.getActiveLayer();
[1750]49 }
[1808]50 if (layer == null)
51 return false;
52 return doSave(layer);
53 }
[290]54
[1808]55 public boolean doSave(Layer layer) {
[4114]56 if(!checkSaveConditions(layer))
[1808]57 return false;
[4371]58 file = getFile(layer);
59 return doInternalSave(layer, file);
[4114]60 }
61
62 public boolean doSave(Layer layer, File file) {
63 if(!checkSaveConditions(layer))
[1808]64 return false;
[4114]65 return doInternalSave(layer, file);
66 }
[290]67
[4114]68 private boolean doInternalSave(Layer layer, File file) {
[1169]69 if (file == null)
[1373]70 return false;
[290]71
[1949]72 try {
73 boolean exported = false;
74 for (FileExporter exporter : ExtensionFileFilter.exporters) {
75 if (exporter.acceptFile(file, layer)) {
76 exporter.exportData(file, layer);
77 exported = true;
78 }
79 }
80 if (!exported) {
[2017]81 JOptionPane.showMessageDialog(Main.parent, tr("No Exporter found! Nothing saved."), tr("Warning"),
[1949]82 JOptionPane.WARNING_MESSAGE);
83 return false;
84 }
85 layer.setName(file.getName());
86 layer.setAssociatedFile(file);
[2025]87 if (layer instanceof OsmDataLayer) {
88 ((OsmDataLayer) layer).onPostSaveToFile();
89 }
[1949]90 Main.parent.repaint();
91 } catch (IOException e) {
92 e.printStackTrace();
93 return false;
94 }
[1373]95 return true;
[1169]96 }
[319]97
[1169]98 protected abstract File getFile(Layer layer);
[290]99
[1169]100 /**
101 * Checks whether it is ok to launch a save (whether we have data,
102 * there is no conflict etc.)
103 * @return <code>true</code>, if it is safe to save.
104 */
105 public boolean checkSaveConditions(Layer layer) {
[4114]106 if (layer instanceof GpxLayer)
107 return ((GpxLayer)layer).data != null;
108 else if (layer instanceof OsmDataLayer) {
109 if (isDataSetEmpty((OsmDataLayer)layer)) {
110 ExtendedDialog dialog = new ExtendedDialog(
111 Main.parent,
112 tr("Empty document"),
113 new String[] {tr("Save anyway"), tr("Cancel")}
114 );
115 dialog.setContent(tr("The document contains no data."));
116 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
117 dialog.showDialog();
118 if (dialog.getValue() != 1) return false;
119 }
[2070]120
[1750]121 ConflictCollection conflicts = ((OsmDataLayer)layer).getConflicts();
122 if (conflicts != null && !conflicts.isEmpty()) {
[2070]123 ExtendedDialog dialog = new ExtendedDialog(
124 Main.parent,
[4045]125 /* I18N: Display title of the window showing conflicts */
[1750]126 tr("Conflicts"),
[2070]127 new String[] {tr("Reject Conflicts and Save"), tr("Cancel")}
128 );
129 dialog.setContent(tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"));
130 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
131 dialog.showDialog();
132 if (dialog.getValue() != 1) return false;
[1750]133 }
[4114]134 return true;
[1169]135 }
[4114]136 return false;
[1169]137 }
[290]138
[1169]139 public static File openFileDialog(Layer layer) {
[1646]140 if (layer instanceof OsmDataLayer)
[2029]141 return createAndOpenSaveFileChooser(tr("Save OSM file"), "osm");
[1646]142 else if (layer instanceof GpxLayer)
[2029]143 return createAndOpenSaveFileChooser(tr("Save GPX file"), "gpx");
144 return createAndOpenSaveFileChooser(tr("Save Layer"), "lay");
[1169]145 }
[319]146
[1169]147 /**
148 * Check the data set if it would be empty on save. It is empty, if it contains
149 * no objects (after all objects that are created and deleted without being
[1676]150 * transferred to the server have been removed).
[1169]151 *
152 * @return <code>true</code>, if a save result in an empty data set.
153 */
154 private boolean isDataSetEmpty(OsmDataLayer layer) {
155 for (OsmPrimitive osm : layer.data.allNonDeletedPrimitives())
[3336]156 if (!osm.isDeleted() || !osm.isNewOrUndeleted())
[1169]157 return false;
158 return true;
159 }
[1808]160
161 /**
162 * Refreshes the enabled state
[1949]163 *
[1808]164 */
[1820]165 @Override
166 protected void updateEnabledState() {
[1879]167 if (Main.applet) {
168 setEnabled(false);
169 return;
170 }
[1820]171 boolean check = Main.map != null
[1808]172 && Main.map.mapView !=null
173 && Main.map.mapView.getActiveLayer() != null;
174 if(!check) {
175 setEnabled(false);
176 return;
177 }
178 Layer layer = Main.map.mapView.getActiveLayer();
179 setEnabled(layer instanceof OsmDataLayer || layer instanceof GpxLayer);
180 }
[1949]181
182 public static File createAndOpenSaveFileChooser(String title, String extension) {
183 String curDir = Main.pref.get("lastDirectory");
184 if (curDir.equals("")) {
185 curDir = ".";
186 }
187 JFileChooser fc = new JFileChooser(new File(curDir));
188 if (title != null) {
189 fc.setDialogTitle(title);
190 }
191
192 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
193 fc.setMultiSelectionEnabled(false);
194 fc.setAcceptAllFileFilterUsed(false);
[2029]195 ExtensionFileFilter.applyChoosableExportFileFilters(fc, extension);
[1949]196 int answer = fc.showSaveDialog(Main.parent);
197 if (answer != JFileChooser.APPROVE_OPTION)
198 return null;
199
200 if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
201 Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
202 }
203
204 File file = fc.getSelectedFile();
[3570]205 String fn = file.getPath();
206 if(fn.indexOf('.') == -1)
207 {
208 FileFilter ff = fc.getFileFilter();
209 if (ff instanceof ExtensionFileFilter) {
210 fn += "." + ((ExtensionFileFilter)ff).getDefaultExtension();
211 } else if(extension != null) {
212 fn += "." + extension;
[1949]213 }
[3570]214 file = new File(fn);
[1949]215 }
[3863]216 if (!confirmOverride(file))
217 return null;
218 return file;
219 }
220
221 public static boolean confirmOverride(File file) {
222 if (file == null || (file.exists())) {
[2070]223 ExtendedDialog dialog = new ExtendedDialog(
224 Main.parent,
225 tr("Overwrite"),
226 new String[] {tr("Overwrite"), tr("Cancel")}
227 );
228 dialog.setContent(tr("File exists. Overwrite?"));
229 dialog.setButtonIcons(new String[] {"save_as.png", "cancel.png"});
230 dialog.showDialog();
[3863]231 return (dialog.getValue() == 1);
[2070]232 }
[3863]233 return true;
[1949]234 }
[4371]235
236 protected void addToFileOpenHistory() {
237 String filepath;
238 try {
239 filepath = file.getCanonicalPath();
240 } catch (IOException ign) {
241 return;
242 }
243
244 int maxsize = Math.max(0, Main.pref.getInteger("file-open.history.max-size", 15));
245 Collection<String> oldHistory = Main.pref.getCollection("file-open.history");
246 List<String> history = new LinkedList<String>(oldHistory);
[4374]247 history.remove(filepath);
[4371]248 history.add(0, filepath);
249 Main.pref.putCollectionBounded("file-open.history", maxsize, history);
250 }
[290]251}
Note: See TracBrowser for help on using the repository browser.