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

Last change on this file since 8819 was 8802, checked in by simon04, 9 years ago

fix #9113 - Session: save into recently used files

  • Property svn:eol-style set to native
File size: 9.1 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.gui.widgets.AbstractFileChooser;
39import org.openstreetmap.josm.io.session.SessionLayerExporter;
40import org.openstreetmap.josm.io.session.SessionWriter;
41import org.openstreetmap.josm.tools.GBC;
42import org.openstreetmap.josm.tools.MultiMap;
43import org.openstreetmap.josm.tools.Utils;
44import org.openstreetmap.josm.tools.WindowGeometry;
45
46/**
47 * Saves a JOSM session
48 * @since 4685
49 */
50public class SessionSaveAsAction extends DiskAccessAction {
51
52 private transient List<Layer> layers;
53 private transient Map<Layer, SessionLayerExporter> exporters;
54 private transient MultiMap<Layer, Layer> dependencies;
55
56 /**
57 * Constructs a new {@code SessionSaveAsAction}.
58 */
59 public SessionSaveAsAction() {
60 super(tr("Save Session As..."), "session", tr("Save the current session to a new file."), null, true, "save_as-session", true);
61 putValue("help", ht("/Action/SessionSaveAs"));
62 }
63
64 @Override
65 public void actionPerformed(ActionEvent e) {
66 if (!isEnabled()) {
67 return;
68 }
69
70 SessionSaveAsDialog dlg = new SessionSaveAsDialog();
71 dlg.showDialog();
72 if (dlg.getValue() != 1) return;
73
74 boolean zipRequired = false;
75 for (Layer l : layers) {
76 SessionLayerExporter ex = exporters.get(l);
77 if (ex != null && ex.requiresZip()) {
78 zipRequired = true;
79 break;
80 }
81 }
82
83 FileFilter joz = new ExtensionFileFilter("joz", "joz", tr("Session file (archive) (*.joz)"));
84 FileFilter jos = new ExtensionFileFilter("jos", "jos", tr("Session file (*.jos)"));
85
86 AbstractFileChooser fc;
87
88 if (zipRequired) {
89 fc = createAndOpenFileChooser(false, false, tr("Save session"), joz, JFileChooser.FILES_ONLY, "lastDirectory");
90 } else {
91 fc = createAndOpenFileChooser(false, false, tr("Save session"), Arrays.asList(new FileFilter[]{jos, joz}), jos,
92 JFileChooser.FILES_ONLY, "lastDirectory");
93 }
94
95 if (fc == null)
96 return;
97
98 File file = fc.getSelectedFile();
99 String fn = file.getName();
100
101 boolean zip;
102 FileFilter ff = fc.getFileFilter();
103 if (zipRequired) {
104 zip = true;
105 } else if (joz.equals(ff)) {
106 zip = true;
107 } else if (jos.equals(ff)) {
108 zip = false;
109 } else {
110 if (Utils.hasExtension(fn, "joz")) {
111 zip = true;
112 } else {
113 zip = false;
114 }
115 }
116 if (fn.indexOf('.') == -1) {
117 file = new File(file.getPath() + (zip ? ".joz" : ".jos"));
118 if (!SaveActionBase.confirmOverwrite(file))
119 return;
120 }
121
122 List<Layer> layersOut = new ArrayList<>();
123 for (Layer layer : layers) {
124 if (exporters.get(layer) == null || !exporters.get(layer).shallExport()) continue;
125 // TODO: resolve dependencies for layers excluded by the user
126 layersOut.add(layer);
127 }
128
129 int active = -1;
130 Layer activeLayer = Main.map.mapView.getActiveLayer();
131 if (activeLayer != null) {
132 active = layersOut.indexOf(activeLayer);
133 }
134
135 SessionWriter sw = new SessionWriter(layersOut, active, exporters, dependencies, zip);
136 try {
137 sw.write(file);
138 SaveActionBase.addToFileOpenHistory(file);
139 } catch (IOException ex) {
140 Main.error(ex);
141 HelpAwareOptionPane.showMessageDialogInEDT(
142 Main.parent,
143 tr("<html>Could not save session file ''{0}''.<br>Error is:<br>{1}</html>", file.getName(), ex.getMessage()),
144 tr("IO Error"),
145 JOptionPane.ERROR_MESSAGE,
146 null
147 );
148 }
149 }
150
151 /**
152 * The "Save Session" dialog
153 */
154 public class SessionSaveAsDialog extends ExtendedDialog {
155
156 /**
157 * Constructs a new {@code SessionSaveAsDialog}.
158 */
159 public SessionSaveAsDialog() {
160 super(Main.parent, tr("Save Session"), new String[] {tr("Save As"), tr("Cancel")});
161 initialize();
162 setButtonIcons(new String[] {"save_as", "cancel"});
163 setDefaultButton(1);
164 setRememberWindowGeometry(getClass().getName() + ".geometry",
165 WindowGeometry.centerInWindow(Main.parent, new Dimension(350, 450)));
166 setContent(build(), false);
167 }
168
169 /**
170 * Initializes action.
171 */
172 public final void initialize() {
173 layers = new ArrayList<>(Main.map.mapView.getAllLayersAsList());
174 exporters = new HashMap<>();
175 dependencies = new MultiMap<>();
176
177 Set<Layer> noExporter = new HashSet<>();
178
179 for (Layer layer : layers) {
180 SessionLayerExporter exporter = SessionWriter.getSessionLayerExporter(layer);
181 if (exporter != null) {
182 exporters.put(layer, exporter);
183 Collection<Layer> deps = exporter.getDependencies();
184 if (deps != null) {
185 dependencies.putAll(layer, deps);
186 } else {
187 dependencies.putVoid(layer);
188 }
189 } else {
190 noExporter.add(layer);
191 exporters.put(layer, null);
192 }
193 }
194
195 int numNoExporter = 0;
196 WHILE: while (numNoExporter != noExporter.size()) {
197 numNoExporter = noExporter.size();
198 for (Layer layer : layers) {
199 if (noExporter.contains(layer)) continue;
200 for (Layer depLayer : dependencies.get(layer)) {
201 if (noExporter.contains(depLayer)) {
202 noExporter.add(layer);
203 exporters.put(layer, null);
204 break WHILE;
205 }
206 }
207 }
208 }
209 }
210
211 protected final Component build() {
212 JPanel p = new JPanel(new GridBagLayout());
213 JPanel ip = new JPanel(new GridBagLayout());
214 for (Layer layer : layers) {
215 JPanel wrapper = new JPanel(new GridBagLayout());
216 wrapper.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
217 Component exportPanel;
218 SessionLayerExporter exporter = exporters.get(layer);
219 if (exporter == null) {
220 if (!exporters.containsKey(layer)) throw new AssertionError();
221 exportPanel = getDisabledExportPanel(layer);
222 } else {
223 exportPanel = exporter.getExportPanel();
224 }
225 wrapper.add(exportPanel, GBC.std().fill(GBC.HORIZONTAL));
226 ip.add(wrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 2, 4, 2));
227 }
228 ip.add(GBC.glue(0, 1), GBC.eol().fill(GBC.VERTICAL));
229 JScrollPane sp = new JScrollPane(ip);
230 sp.setBorder(BorderFactory.createEmptyBorder());
231 p.add(sp, GBC.eol().fill());
232 final JTabbedPane tabs = new JTabbedPane();
233 tabs.addTab(tr("Layers"), p);
234 return tabs;
235 }
236
237 protected final Component getDisabledExportPanel(Layer layer) {
238 JPanel p = new JPanel(new GridBagLayout());
239 JCheckBox include = new JCheckBox();
240 include.setEnabled(false);
241 JLabel lbl = new JLabel(layer.getName(), layer.getIcon(), SwingConstants.LEFT);
242 lbl.setToolTipText(tr("No exporter for this layer"));
243 lbl.setLabelFor(include);
244 lbl.setEnabled(false);
245 p.add(include, GBC.std());
246 p.add(lbl, GBC.std());
247 p.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
248 return p;
249 }
250 }
251
252 @Override
253 protected void updateEnabledState() {
254 setEnabled(Main.isDisplayingMapView());
255 }
256}
Note: See TracBrowser for help on using the repository browser.