source: josm/trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java@ 6033

Last change on this file since 6033 was 5684, checked in by bastiK, 11 years ago

add session support for marker layers (see #4029)

The data is exported to a separate GPX file that contains one waypoint for each marker.
This is not very elegant, because most of the time, all the info is already contained in the original GPX File.
However, when dealing with audio markers, they can be synchronized, or additional markers are added
at certain playback positions. This info must be retained.
Another complication is, that two or more MarkerLayers can be merged to one.

All these problems are avoided by explicitly exporting the markers to a separate file (as done in this commit).

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.GridBagLayout;
10import java.awt.event.ActionEvent;
11import java.io.File;
12import java.io.IOException;
13import java.util.ArrayList;
14import java.util.Arrays;
15import java.util.Collection;
16import java.util.HashMap;
17import java.util.HashSet;
18import java.util.List;
19import java.util.Map;
20import java.util.Set;
21
22import javax.swing.BorderFactory;
23import javax.swing.JCheckBox;
24import javax.swing.JFileChooser;
25import javax.swing.JLabel;
26import javax.swing.JOptionPane;
27import javax.swing.JPanel;
28import javax.swing.JScrollPane;
29import javax.swing.JTabbedPane;
30import javax.swing.SwingConstants;
31import javax.swing.border.EtchedBorder;
32import javax.swing.filechooser.FileFilter;
33
34import org.openstreetmap.josm.Main;
35import org.openstreetmap.josm.gui.ExtendedDialog;
36import org.openstreetmap.josm.gui.HelpAwareOptionPane;
37import org.openstreetmap.josm.gui.layer.Layer;
38import org.openstreetmap.josm.io.session.SessionLayerExporter;
39import org.openstreetmap.josm.io.session.SessionWriter;
40import org.openstreetmap.josm.tools.GBC;
41import org.openstreetmap.josm.tools.MultiMap;
42import org.openstreetmap.josm.tools.WindowGeometry;
43
44public class SessionSaveAsAction extends DiskAccessAction {
45
46 private List<Layer> layers;
47 private Map<Layer, SessionLayerExporter> exporters;
48 private MultiMap<Layer, Layer> dependencies;
49
50 private boolean zipRequired;
51
52 public SessionSaveAsAction() {
53 super(tr("Save Session As..."), "save_as", tr("Save the current session to a new file."), null, true, "save_as-session", true);
54 putValue("help", ht("/Action/SessionSaveAs"));
55 }
56
57 @Override
58 public void actionPerformed(ActionEvent e) {
59 if (!isEnabled()) {
60 return;
61 }
62
63 SessionSaveAsDialog dlg = new SessionSaveAsDialog();
64 dlg.showDialog();
65 if (dlg.getValue() != 1) return;
66
67 zipRequired = false;
68 for (Layer l : layers) {
69 SessionLayerExporter ex = exporters.get(l);
70 if (ex != null && ex.requiresZip()) {
71 zipRequired = true;
72 break;
73 }
74 }
75
76 FileFilter joz = new ExtensionFileFilter("joz", "joz", tr("Session file (archive) (*.joz)"));
77 FileFilter jos = new ExtensionFileFilter("jos", "jos", tr("Session file (*.jos)"));
78
79 JFileChooser fc;
80
81 if (zipRequired) {
82 fc = createAndOpenFileChooser(false, false, tr("Save session"), joz, JFileChooser.FILES_ONLY, "lastDirectory");
83 } else {
84 fc = createAndOpenFileChooser(false, false, tr("Save session"), Arrays.asList(new FileFilter[]{jos, joz}), jos, JFileChooser.FILES_ONLY, "lastDirectory");
85 }
86
87 if (fc == null)
88 return;
89
90 File file = fc.getSelectedFile();
91 String fn = file.getName();
92
93 boolean zip;
94 FileFilter ff = fc.getFileFilter();
95 if (zipRequired) {
96 zip = true;
97 } else if (ff == joz) {
98 zip = true;
99 } else if (ff == jos) {
100 zip = false;
101 } else {
102 if (fn.toLowerCase().endsWith(".joz")) {
103 zip = true;
104 } else {
105 zip = false;
106 }
107 }
108 if (fn.indexOf('.') == -1) {
109 file = new File(file.getPath() + (zip ? ".joz" : ".jos"));
110 if (!SaveActionBase.confirmOverwrite(file))
111 return;
112 }
113
114 List<Layer> layersOut = new ArrayList<Layer>();
115 for (Layer layer : layers) {
116 if (exporters.get(layer) == null || !exporters.get(layer).shallExport()) continue;
117 // TODO: resolve dependencies for layers excluded by the user
118 layersOut.add(layer);
119 }
120
121 SessionWriter sw = new SessionWriter(layersOut, exporters, dependencies, zip);
122 try {
123 sw.write(file);
124 } catch (IOException ex) {
125 ex.printStackTrace();
126 HelpAwareOptionPane.showMessageDialogInEDT(
127 Main.parent,
128 tr("<html>Could not save session file ''{0}''.<br>Error is:<br>{1}</html>", file.getName(), ex.getMessage()),
129 tr("IO Error"),
130 JOptionPane.ERROR_MESSAGE,
131 null
132 );
133 }
134 }
135
136 public class SessionSaveAsDialog extends ExtendedDialog {
137
138 public SessionSaveAsDialog() {
139 super(Main.parent, tr("Save Session"), new String[] {tr("Save As"), tr("Cancel")});
140 initialize();
141 setButtonIcons(new String[] {"save_as", "cancel"});
142 setDefaultButton(1);
143 setRememberWindowGeometry(getClass().getName() + ".geometry",
144 WindowGeometry.centerInWindow(Main.parent, new Dimension(350, 450)));
145 setContent(build(), false);
146 }
147
148 public void initialize() {
149 layers = new ArrayList<Layer>(Main.map.mapView.getAllLayersAsList());
150 exporters = new HashMap<Layer, SessionLayerExporter>();
151 dependencies = new MultiMap<Layer, Layer>();
152
153 Set<Layer> noExporter = new HashSet<Layer>();
154
155 for (Layer layer : layers) {
156 SessionLayerExporter exporter = SessionWriter.getSessionLayerExporter(layer);
157 if (exporter != null) {
158 exporters.put(layer, exporter);
159 Collection<Layer> deps = exporter.getDependencies();
160 if (deps != null) {
161 dependencies.putAll(layer, deps);
162 } else {
163 dependencies.putVoid(layer);
164 }
165 } else {
166 noExporter.add(layer);
167 exporters.put(layer, null);
168 }
169 }
170
171 int numNoExporter = 0;
172 WHILE:while (numNoExporter != noExporter.size()) {
173 numNoExporter = noExporter.size();
174 for (Layer layer : layers) {
175 if (noExporter.contains(layer)) continue;
176 for (Layer depLayer : dependencies.get(layer)) {
177 if (noExporter.contains(depLayer)) {
178 noExporter.add(layer);
179 exporters.put(layer, null);
180 break WHILE;
181 }
182 }
183 }
184 }
185 }
186
187 public Component build() {
188 JPanel p = new JPanel(new GridBagLayout());
189 JPanel ip = new JPanel(new GridBagLayout());
190 for (Layer layer : layers) {
191 JPanel wrapper = new JPanel(new GridBagLayout());
192 wrapper.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
193 Component exportPanel;
194 SessionLayerExporter exporter = exporters.get(layer);
195 if (exporter == null) {
196 if (!exporters.containsKey(layer)) throw new AssertionError();
197 exportPanel = getDisabledExportPanel(layer);
198 } else {
199 exportPanel = exporter.getExportPanel();
200 }
201 wrapper.add(exportPanel, GBC.std().fill(GBC.HORIZONTAL));
202 ip.add(wrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(2,2,4,2));
203 }
204 ip.add(GBC.glue(0,1), GBC.eol().fill(GBC.VERTICAL));
205 JScrollPane sp = new JScrollPane(ip);
206 sp.setBorder(BorderFactory.createEmptyBorder());
207 p.add(sp, GBC.eol().fill());
208 final JTabbedPane tabs = new JTabbedPane();
209 tabs.addTab(tr("Layers"), p);
210 return tabs;
211 }
212
213 protected Component getDisabledExportPanel(Layer layer) {
214 JPanel p = new JPanel(new GridBagLayout());
215 JCheckBox include = new JCheckBox();
216 include.setEnabled(false);
217 JLabel lbl = new JLabel(layer.getName(), layer.getIcon(), SwingConstants.LEFT);
218 lbl.setToolTipText(tr("No exporter for this layer"));
219 lbl.setEnabled(false);
220 p.add(include, GBC.std());
221 p.add(lbl, GBC.std());
222 p.add(GBC.glue(1,0), GBC.std().fill(GBC.HORIZONTAL));
223 return p;
224 }
225 }
226
227}
Note: See TracBrowser for help on using the repository browser.