source: josm/trunk/src/org/openstreetmap/josm/io/GpxExporter.java@ 10308

Last change on this file since 10308 was 9461, checked in by bastiK, 8 years ago

applied #12369 - default extension for saving files read from preferences (patch by kolesar)

  • Property svn:eol-style set to native
File size: 13.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9import java.awt.event.KeyAdapter;
10import java.awt.event.KeyEvent;
11import java.io.File;
12import java.io.IOException;
13import java.io.OutputStream;
14import java.text.MessageFormat;
15import java.util.Calendar;
16
17import javax.swing.JButton;
18import javax.swing.JCheckBox;
19import javax.swing.JLabel;
20import javax.swing.JList;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.ListSelectionModel;
25
26import org.openstreetmap.josm.Main;
27import org.openstreetmap.josm.data.gpx.GpxConstants;
28import org.openstreetmap.josm.data.gpx.GpxData;
29import org.openstreetmap.josm.gui.ExtendedDialog;
30import org.openstreetmap.josm.gui.layer.GpxLayer;
31import org.openstreetmap.josm.gui.layer.Layer;
32import org.openstreetmap.josm.gui.layer.OsmDataLayer;
33import org.openstreetmap.josm.gui.widgets.JosmTextArea;
34import org.openstreetmap.josm.gui.widgets.JosmTextField;
35import org.openstreetmap.josm.tools.CheckParameterUtil;
36import org.openstreetmap.josm.tools.GBC;
37
38/**
39 * Exports data to a .gpx file. Data may be native GPX or OSM data which will be converted.
40 * @since 1949
41 */
42public class GpxExporter extends FileExporter implements GpxConstants {
43
44 private static final String GPL_WARNING = "<html><font color='red' size='-2'>"
45 + tr("Note: GPL is not compatible with the OSM license. Do not upload GPL licensed tracks.") + "</html>";
46
47 private static final String[] LICENSES = {
48 "Creative Commons By-SA",
49 "Open Database License (ODbL)",
50 "public domain",
51 "GNU Lesser Public License (LGPL)",
52 "BSD License (MIT/X11)"};
53
54 private static final String[] URLS = {
55 "https://creativecommons.org/licenses/by-sa/3.0",
56 "http://opendatacommons.org/licenses/odbl/1.0",
57 "public domain",
58 "https://www.gnu.org/copyleft/lesser.html",
59 "http://www.opensource.org/licenses/bsd-license.php"};
60
61 /**
62 * Constructs a new {@code GpxExporter}.
63 */
64 public GpxExporter() {
65 super(GpxImporter.getFileFilter());
66 }
67
68 @Override
69 public boolean acceptFile(File pathname, Layer layer) {
70 if (!(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
71 return false;
72 return super.acceptFile(pathname, layer);
73 }
74
75 @Override
76 public void exportData(File file, Layer layer) throws IOException {
77 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
78 if (!(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
79 throw new IllegalArgumentException(MessageFormat.format("Expected instance of OsmDataLayer or GpxLayer. Got ''{0}''.", layer
80 .getClass().getName()));
81 CheckParameterUtil.ensureParameterNotNull(file, "file");
82
83 String fn = file.getPath();
84 if (fn.indexOf('.') == -1) {
85 fn += ".gpx";
86 file = new File(fn);
87 }
88
89 // open the dialog asking for options
90 JPanel p = new JPanel(new GridBagLayout());
91
92 GpxData gpxData;
93 // At this moment, we only need to know the attributes of the GpxData,
94 // conversion of OsmDataLayer (if needed) will be done after the dialog is closed.
95 if (layer instanceof GpxLayer) {
96 gpxData = ((GpxLayer) layer).data;
97 } else {
98 gpxData = new GpxData();
99 }
100
101 p.add(new JLabel(tr("GPS track description")), GBC.eol());
102 JosmTextArea desc = new JosmTextArea(3, 40);
103 desc.setWrapStyleWord(true);
104 desc.setLineWrap(true);
105 desc.setText(gpxData.getString(META_DESC));
106 p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
107
108 JCheckBox author = new JCheckBox(tr("Add author information"), Main.pref.getBoolean("lastAddAuthor", true));
109 p.add(author, GBC.eol());
110
111 JLabel nameLabel = new JLabel(tr("Real name"));
112 p.add(nameLabel, GBC.std().insets(10, 0, 5, 0));
113 JosmTextField authorName = new JosmTextField();
114 p.add(authorName, GBC.eol().fill(GBC.HORIZONTAL));
115 nameLabel.setLabelFor(authorName);
116
117 JLabel emailLabel = new JLabel(tr("E-Mail"));
118 p.add(emailLabel, GBC.std().insets(10, 0, 5, 0));
119 JosmTextField email = new JosmTextField();
120 p.add(email, GBC.eol().fill(GBC.HORIZONTAL));
121 emailLabel.setLabelFor(email);
122
123 JLabel copyrightLabel = new JLabel(tr("Copyright (URL)"));
124 p.add(copyrightLabel, GBC.std().insets(10, 0, 5, 0));
125 JosmTextField copyright = new JosmTextField();
126 p.add(copyright, GBC.std().fill(GBC.HORIZONTAL));
127 copyrightLabel.setLabelFor(copyright);
128
129 JButton predefined = new JButton(tr("Predefined"));
130 p.add(predefined, GBC.eol().insets(5, 0, 0, 0));
131
132 JLabel copyrightYearLabel = new JLabel(tr("Copyright year"));
133 p.add(copyrightYearLabel, GBC.std().insets(10, 0, 5, 5));
134 JosmTextField copyrightYear = new JosmTextField("");
135 p.add(copyrightYear, GBC.eol().fill(GBC.HORIZONTAL));
136 copyrightYearLabel.setLabelFor(copyrightYear);
137
138 JLabel warning = new JLabel("<html><font size='-2'>&nbsp;</html");
139 p.add(warning, GBC.eol().fill(GBC.HORIZONTAL).insets(15, 0, 0, 0));
140 addDependencies(gpxData, author, authorName, email, copyright, predefined, copyrightYear, nameLabel, emailLabel,
141 copyrightLabel, copyrightYearLabel, warning);
142
143 p.add(new JLabel(tr("Keywords")), GBC.eol());
144 JosmTextField keywords = new JosmTextField();
145 keywords.setText(gpxData.getString(META_KEYWORDS));
146 p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
147
148 ExtendedDialog ed = new ExtendedDialog(Main.parent,
149 tr("Export options"),
150 new String[] {tr("Export and Save"), tr("Cancel")});
151 ed.setButtonIcons(new String[] {"exportgpx", "cancel"});
152 ed.setContent(p);
153 ed.showDialog();
154
155 if (ed.getValue() != 1) {
156 setCanceled(true);
157 return;
158 }
159 setCanceled(false);
160
161 Main.pref.put("lastAddAuthor", author.isSelected());
162 if (!authorName.getText().isEmpty()) {
163 Main.pref.put("lastAuthorName", authorName.getText());
164 }
165 if (!copyright.getText().isEmpty()) {
166 Main.pref.put("lastCopyright", copyright.getText());
167 }
168
169 if (layer instanceof OsmDataLayer) {
170 gpxData = ((OsmDataLayer) layer).toGpxData();
171 } else if (layer instanceof GpxLayer) {
172 gpxData = ((GpxLayer) layer).data;
173 } else {
174 gpxData = OsmDataLayer.toGpxData(Main.main.getCurrentDataSet(), file);
175 }
176
177 // add author and copyright details to the gpx data
178 if (author.isSelected()) {
179 if (!authorName.getText().isEmpty()) {
180 gpxData.put(META_AUTHOR_NAME, authorName.getText());
181 gpxData.put(META_COPYRIGHT_AUTHOR, authorName.getText());
182 }
183 if (!email.getText().isEmpty()) {
184 gpxData.put(META_AUTHOR_EMAIL, email.getText());
185 }
186 if (!copyright.getText().isEmpty()) {
187 gpxData.put(META_COPYRIGHT_LICENSE, copyright.getText());
188 }
189 if (!copyrightYear.getText().isEmpty()) {
190 gpxData.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
191 }
192 }
193
194 // add the description to the gpx data
195 if (!desc.getText().isEmpty()) {
196 gpxData.put(META_DESC, desc.getText());
197 }
198
199 // add keywords to the gpx data
200 if (!keywords.getText().isEmpty()) {
201 gpxData.put(META_KEYWORDS, keywords.getText());
202 }
203
204 try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
205 new GpxWriter(fo).write(gpxData);
206 fo.flush();
207 } catch (IOException x) {
208 Main.error(x);
209 JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}:\n{1}", fn, x.getMessage()),
210 tr("Error"), JOptionPane.ERROR_MESSAGE);
211 }
212 }
213
214 private static void enableCopyright(final GpxData data, final JosmTextField copyright, final JButton predefined,
215 final JosmTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel,
216 final JLabel warning, boolean enable) {
217 copyright.setEnabled(enable);
218 predefined.setEnabled(enable);
219 copyrightYear.setEnabled(enable);
220 copyrightLabel.setEnabled(enable);
221 copyrightYearLabel.setEnabled(enable);
222 warning.setText(enable ? GPL_WARNING : "<html><font size='-2'>&nbsp;</html");
223
224 if (enable) {
225 if (copyrightYear.getText().isEmpty()) {
226 String sCopyrightYear = data.getString(META_COPYRIGHT_YEAR);
227 if (sCopyrightYear == null) {
228 sCopyrightYear = Integer.toString(Calendar.getInstance().get(Calendar.YEAR));
229 }
230 copyrightYear.setText(sCopyrightYear);
231 }
232 if (copyright.getText().isEmpty()) {
233 String sCopyright = data.getString(META_COPYRIGHT_LICENSE);
234 if (sCopyright == null) {
235 sCopyright = Main.pref.get("lastCopyright", "https://creativecommons.org/licenses/by-sa/2.5");
236 }
237 copyright.setText(sCopyright);
238 copyright.setCaretPosition(0);
239 }
240 } else {
241 copyrightYear.setText("");
242 copyright.setText("");
243 }
244 }
245
246 // CHECKSTYLE.OFF: ParameterNumber
247
248 /**
249 * Add all those listeners to handle the enable state of the fields.
250 * @param data GPX data
251 * @param author Author checkbox
252 * @param authorName Author name textfield
253 * @param email E-mail textfield
254 * @param copyright Copyright textfield
255 * @param predefined Predefined button
256 * @param copyrightYear Copyright year textfield
257 * @param nameLabel Name label
258 * @param emailLabel E-mail label
259 * @param copyrightLabel Copyright label
260 * @param copyrightYearLabel Copyright year label
261 * @param warning Warning label
262 */
263 private static void addDependencies(
264 final GpxData data,
265 final JCheckBox author,
266 final JosmTextField authorName,
267 final JosmTextField email,
268 final JosmTextField copyright,
269 final JButton predefined,
270 final JosmTextField copyrightYear,
271 final JLabel nameLabel,
272 final JLabel emailLabel,
273 final JLabel copyrightLabel,
274 final JLabel copyrightYearLabel,
275 final JLabel warning) {
276
277 // CHECKSTYLE.ON: ParameterNumber
278 ActionListener authorActionListener = new ActionListener() {
279 @Override
280 public void actionPerformed(ActionEvent e) {
281 boolean b = author.isSelected();
282 authorName.setEnabled(b);
283 email.setEnabled(b);
284 nameLabel.setEnabled(b);
285 emailLabel.setEnabled(b);
286 if (b) {
287 String sAuthorName = data.getString(META_AUTHOR_NAME);
288 if (sAuthorName == null) {
289 sAuthorName = Main.pref.get("lastAuthorName");
290 }
291 authorName.setText(sAuthorName);
292 String sEmail = data.getString(META_AUTHOR_EMAIL);
293 if (sEmail == null) {
294 sEmail = Main.pref.get("lastAuthorEmail");
295 }
296 email.setText(sEmail);
297 } else {
298 authorName.setText("");
299 email.setText("");
300 }
301 boolean isAuthorSet = !authorName.getText().isEmpty();
302 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning,
303 b && isAuthorSet);
304 }
305 };
306 author.addActionListener(authorActionListener);
307
308 KeyAdapter authorNameListener = new KeyAdapter() {
309 @Override public void keyReleased(KeyEvent e) {
310 boolean b = !authorName.getText().isEmpty() && author.isSelected();
311 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning, b);
312 }
313 };
314 authorName.addKeyListener(authorNameListener);
315
316 predefined.addActionListener(new ActionListener() {
317 @Override
318 public void actionPerformed(ActionEvent e) {
319 JList<String> l = new JList<>(LICENSES);
320 l.setVisibleRowCount(LICENSES.length);
321 l.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
322 int answer = JOptionPane.showConfirmDialog(
323 Main.parent,
324 new JScrollPane(l),
325 tr("Choose a predefined license"),
326 JOptionPane.OK_CANCEL_OPTION,
327 JOptionPane.QUESTION_MESSAGE
328 );
329 if (answer != JOptionPane.OK_OPTION || l.getSelectedIndex() == -1)
330 return;
331 StringBuilder license = new StringBuilder();
332 for (int i : l.getSelectedIndices()) {
333 if (i == 2) {
334 license = new StringBuilder("public domain");
335 break;
336 }
337 if (license.length() > 0) {
338 license.append(", ");
339 }
340 license.append(URLS[i]);
341 }
342 copyright.setText(license.toString());
343 copyright.setCaretPosition(0);
344 }
345 });
346
347 authorActionListener.actionPerformed(null);
348 authorNameListener.keyReleased(null);
349 }
350}
Note: See TracBrowser for help on using the repository browser.