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

Last change on this file since 8324 was 8308, checked in by Don-vip, 9 years ago

fix potential NPEs and Sonar issues related to serialization

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