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

Last change on this file since 9692 was 9631, checked in by Don-vip, 8 years ago

checkstyle

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