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

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

fixed #1647 - patch by dmuecke - Improve export

  • Property svn:eol-style set to native
File size: 8.1 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.IOException;
9
10import javax.swing.JFileChooser;
11import javax.swing.JOptionPane;
12import javax.swing.filechooser.FileFilter;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.conflict.ConflictCollection;
16import org.openstreetmap.josm.data.osm.OsmPrimitive;
17import org.openstreetmap.josm.gui.ExtendedDialog;
18import org.openstreetmap.josm.gui.OptionPaneUtil;
19import org.openstreetmap.josm.gui.layer.GpxLayer;
20import org.openstreetmap.josm.gui.layer.Layer;
21import org.openstreetmap.josm.gui.layer.OsmDataLayer;
22import org.openstreetmap.josm.io.FileExporter;
23import org.openstreetmap.josm.tools.Shortcut;
24
25public abstract class SaveActionBase extends DiskAccessAction {
26
27 public SaveActionBase(String name, String iconName, String tooltip, Shortcut shortcut) {
28 super(name, iconName, tooltip, shortcut);
29 }
30
31 public void actionPerformed(ActionEvent e) {
32 if (!isEnabled())
33 return;
34 doSave();
35 }
36
37 public boolean doSave() {
38 Layer layer = null;
39 if (layer == null && Main.map != null && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
40 || Main.map.mapView.getActiveLayer() instanceof GpxLayer)) {
41 layer = Main.map.mapView.getActiveLayer();
42 }
43 if (layer == null)
44 return false;
45 return doSave(layer);
46 }
47
48 public boolean doSave(Layer layer) {
49 if (layer == null)
50 return false;
51 if ( !(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
52 return false;
53 if (!checkSaveConditions(layer))
54 return false;
55
56 File file = getFile(layer);
57 if (file == null)
58 return false;
59
60 try {
61 boolean exported = false;
62 for (FileExporter exporter : ExtensionFileFilter.exporters) {
63 if (exporter.acceptFile(file, layer)) {
64 exporter.exportData(file, layer);
65 exported = true;
66 }
67 }
68 if (!exported) {
69 OptionPaneUtil.showMessageDialog(Main.parent, tr("No Exporter found! Nothing saved."), tr("Warning"),
70 JOptionPane.WARNING_MESSAGE);
71 return false;
72 }
73 layer.setName(file.getName());
74 layer.setAssociatedFile(file);
75 Main.parent.repaint();
76 } catch (IOException e) {
77 e.printStackTrace();
78 return false;
79 }
80 return true;
81 }
82
83 protected abstract File getFile(Layer layer);
84
85 /**
86 * Checks whether it is ok to launch a save (whether we have data,
87 * there is no conflict etc.)
88 * @return <code>true</code>, if it is safe to save.
89 */
90 public boolean checkSaveConditions(Layer layer) {
91 if (layer == null) {
92 OptionPaneUtil.showMessageDialog(
93 Main.parent,
94 tr("Internal Error: cannot check conditions for no layer. Please report this as a bug."),
95 tr("Error"),
96 JOptionPane.ERROR_MESSAGE
97 );
98 return false;
99 }
100 if (Main.map == null) {
101 OptionPaneUtil.showMessageDialog(
102 Main.parent,
103 tr("No document open so nothing to save."),
104 tr("Warning"),
105 JOptionPane.WARNING_MESSAGE
106 );
107 return false;
108 }
109
110 if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && 1 != new ExtendedDialog(Main.parent, tr("Empty document"), tr("The document contains no data."), new String[] {tr("Save anyway"), tr("Cancel")}, new String[] {"save.png", "cancel.png"}).getValue())
111 return false;
112 if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null)
113 return false;
114 if (layer instanceof OsmDataLayer) {
115 ConflictCollection conflicts = ((OsmDataLayer)layer).getConflicts();
116 if (conflicts != null && !conflicts.isEmpty()) {
117 int answer = new ExtendedDialog(Main.parent,
118 tr("Conflicts"),
119 tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"),
120 new String[] {tr("Reject Conflicts and Save"), tr("Cancel")},
121 new String[] {"save.png", "cancel.png"}).getValue();
122
123 if (answer != 1) return false;
124 }
125 }
126 return true;
127 }
128
129 public static File openFileDialog(Layer layer) {
130 if (layer instanceof OsmDataLayer)
131 return createAndOpenSaveFileChooser(tr("Save OSM file"), ".osm");
132 else if (layer instanceof GpxLayer)
133 return createAndOpenSaveFileChooser(tr("Save GPX file"), ".gpx");
134 return createAndOpenSaveFileChooser(tr("Save Layer"), ".lay");
135 }
136
137
138 /**
139 * Check the data set if it would be empty on save. It is empty, if it contains
140 * no objects (after all objects that are created and deleted without being
141 * transferred to the server have been removed).
142 *
143 * @return <code>true</code>, if a save result in an empty data set.
144 */
145 private boolean isDataSetEmpty(OsmDataLayer layer) {
146 for (OsmPrimitive osm : layer.data.allNonDeletedPrimitives())
147 if (!osm.deleted || osm.id > 0)
148 return false;
149 return true;
150 }
151
152 /**
153 * Refreshes the enabled state
154 *
155 */
156 @Override
157 protected void updateEnabledState() {
158 if (Main.applet) {
159 setEnabled(false);
160 return;
161 }
162 boolean check = Main.map != null
163 && Main.map.mapView !=null
164 && Main.map.mapView.getActiveLayer() != null;
165 if(!check) {
166 setEnabled(false);
167 return;
168 }
169 Layer layer = Main.map.mapView.getActiveLayer();
170 setEnabled(layer instanceof OsmDataLayer || layer instanceof GpxLayer);
171 }
172
173 public static File createAndOpenSaveFileChooser(String title, String extension) {
174 String curDir = Main.pref.get("lastDirectory");
175 if (curDir.equals("")) {
176 curDir = ".";
177 }
178 JFileChooser fc = new JFileChooser(new File(curDir));
179 if (title != null) {
180 fc.setDialogTitle(title);
181 }
182
183 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
184 fc.setMultiSelectionEnabled(false);
185 fc.setAcceptAllFileFilterUsed(false);
186
187 FileFilter defaultFilter = null;
188 for (FileExporter exporter : ExtensionFileFilter.exporters) {
189 fc.addChoosableFileFilter(exporter.filter);
190 if (extension.endsWith(exporter.filter.defaultExtension)) {
191 defaultFilter = exporter.filter;
192 }
193 }
194 if (defaultFilter != null) {
195 fc.setFileFilter(defaultFilter);
196 }
197
198 int answer = fc.showSaveDialog(Main.parent);
199 if (answer != JFileChooser.APPROVE_OPTION)
200 return null;
201
202 if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
203 Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
204 }
205
206 File file = fc.getSelectedFile();
207 if(extension != null){
208 String fn = file.getPath();
209 if(fn.indexOf('.') == -1)
210 {
211 FileFilter ff = fc.getFileFilter();
212 if (ff instanceof ExtensionFileFilter) {
213 fn += "." + ((ExtensionFileFilter)ff).defaultExtension;
214 } else {
215 fn += extension;
216 }
217 file = new File(fn);
218 }
219 }
220 if(file == null || (file.exists() && 1 != new ExtendedDialog(Main.parent,
221 tr("Overwrite"), tr("File exists. Overwrite?"),
222 new String[] {tr("Overwrite"), tr("Cancel")},
223 new String[] {"save_as.png", "cancel.png"}).getValue()))
224 return null;
225 return file;
226 }
227}
Note: See TracBrowser for help on using the repository browser.