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

Last change on this file since 14397 was 14397, checked in by Don-vip, 5 years ago

fix #16935 - simplify/cleanup help topics of ToggleDialog/ToggleDialogAction

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