source: josm/trunk/src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java@ 12846

Last change on this file since 12846 was 12846, checked in by bastiK, 7 years ago

see #15229 - use Config.getPref() wherever possible

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