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

Last change on this file since 12487 was 12279, checked in by Don-vip, 7 years ago

sonar - squid:S3878 - Arrays should not be created for varargs parameters

  • Property svn:eol-style set to native
File size: 13.1 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.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.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 tr("Export and Save"), tr("Cancel"))
151 .setButtonIcons("exportgpx", "cancel")
152 .setContent(p);
153
154 if (ed.showDialog().getValue() != 1) {
155 setCanceled(true);
156 return;
157 }
158 setCanceled(false);
159
160 Main.pref.put("lastAddAuthor", author.isSelected());
161 if (!authorName.getText().isEmpty()) {
162 Main.pref.put("lastAuthorName", authorName.getText());
163 }
164 if (!copyright.getText().isEmpty()) {
165 Main.pref.put("lastCopyright", copyright.getText());
166 }
167
168 if (layer instanceof OsmDataLayer) {
169 gpxData = ((OsmDataLayer) layer).toGpxData();
170 } else if (layer instanceof GpxLayer) {
171 gpxData = ((GpxLayer) layer).data;
172 } else {
173 gpxData = OsmDataLayer.toGpxData(Main.getLayerManager().getEditDataSet(), file);
174 }
175
176 // add author and copyright details to the gpx data
177 if (author.isSelected()) {
178 if (!authorName.getText().isEmpty()) {
179 gpxData.put(META_AUTHOR_NAME, authorName.getText());
180 gpxData.put(META_COPYRIGHT_AUTHOR, authorName.getText());
181 }
182 if (!email.getText().isEmpty()) {
183 gpxData.put(META_AUTHOR_EMAIL, email.getText());
184 }
185 if (!copyright.getText().isEmpty()) {
186 gpxData.put(META_COPYRIGHT_LICENSE, copyright.getText());
187 }
188 if (!copyrightYear.getText().isEmpty()) {
189 gpxData.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
190 }
191 }
192
193 // add the description to the gpx data
194 if (!desc.getText().isEmpty()) {
195 gpxData.put(META_DESC, desc.getText());
196 }
197
198 // add keywords to the gpx data
199 if (!keywords.getText().isEmpty()) {
200 gpxData.put(META_KEYWORDS, keywords.getText());
201 }
202
203 try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
204 new GpxWriter(fo).write(gpxData);
205 fo.flush();
206 } catch (IOException ex) {
207 Main.error(ex);
208 JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}:\n{1}", fn, ex.getMessage()),
209 tr("Error"), JOptionPane.ERROR_MESSAGE);
210 }
211 }
212
213 private static void enableCopyright(final GpxData data, final JosmTextField copyright, final JButton predefined,
214 final JosmTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel,
215 final JLabel warning, boolean enable) {
216 copyright.setEnabled(enable);
217 predefined.setEnabled(enable);
218 copyrightYear.setEnabled(enable);
219 copyrightLabel.setEnabled(enable);
220 copyrightYearLabel.setEnabled(enable);
221 warning.setText(enable ? GPL_WARNING : "<html><font size='-2'>&nbsp;</html");
222
223 if (enable) {
224 if (copyrightYear.getText().isEmpty()) {
225 copyrightYear.setText(Optional.ofNullable(data.getString(META_COPYRIGHT_YEAR)).orElseGet(
226 () -> Year.now().toString()));
227 }
228 if (copyright.getText().isEmpty()) {
229 copyright.setText(Optional.ofNullable(data.getString(META_COPYRIGHT_LICENSE)).orElseGet(
230 () -> Main.pref.get("lastCopyright", "https://creativecommons.org/licenses/by-sa/2.5")));
231 copyright.setCaretPosition(0);
232 }
233 } else {
234 copyrightYear.setText("");
235 copyright.setText("");
236 }
237 }
238
239 // CHECKSTYLE.OFF: ParameterNumber
240
241 /**
242 * Add all those listeners to handle the enable state of the fields.
243 * @param data GPX data
244 * @param author Author checkbox
245 * @param authorName Author name textfield
246 * @param email E-mail textfield
247 * @param copyright Copyright textfield
248 * @param predefined Predefined button
249 * @param copyrightYear Copyright year textfield
250 * @param nameLabel Name label
251 * @param emailLabel E-mail label
252 * @param copyrightLabel Copyright label
253 * @param copyrightYearLabel Copyright year label
254 * @param warning Warning label
255 */
256 private static void addDependencies(
257 final GpxData data,
258 final JCheckBox author,
259 final JosmTextField authorName,
260 final JosmTextField email,
261 final JosmTextField copyright,
262 final JButton predefined,
263 final JosmTextField copyrightYear,
264 final JLabel nameLabel,
265 final JLabel emailLabel,
266 final JLabel copyrightLabel,
267 final JLabel copyrightYearLabel,
268 final JLabel warning) {
269
270 // CHECKSTYLE.ON: ParameterNumber
271 ActionListener authorActionListener = e -> {
272 boolean b = author.isSelected();
273 authorName.setEnabled(b);
274 email.setEnabled(b);
275 nameLabel.setEnabled(b);
276 emailLabel.setEnabled(b);
277 if (b) {
278 authorName.setText(Optional.ofNullable(data.getString(META_AUTHOR_NAME)).orElseGet(() -> Main.pref.get("lastAuthorName")));
279 email.setText(Optional.ofNullable(data.getString(META_AUTHOR_EMAIL)).orElseGet(() -> Main.pref.get("lastAuthorEmail")));
280 } else {
281 authorName.setText("");
282 email.setText("");
283 }
284 boolean isAuthorSet = !authorName.getText().isEmpty();
285 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning,
286 b && isAuthorSet);
287 };
288 author.addActionListener(authorActionListener);
289
290 KeyAdapter authorNameListener = new KeyAdapter() {
291 @Override public void keyReleased(KeyEvent e) {
292 boolean b = !authorName.getText().isEmpty() && author.isSelected();
293 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning, b);
294 }
295 };
296 authorName.addKeyListener(authorNameListener);
297
298 predefined.addActionListener(e -> {
299 JList<String> l = new JList<>(LICENSES);
300 l.setVisibleRowCount(LICENSES.length);
301 l.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
302 int answer = JOptionPane.showConfirmDialog(
303 Main.parent,
304 new JScrollPane(l),
305 tr("Choose a predefined license"),
306 JOptionPane.OK_CANCEL_OPTION,
307 JOptionPane.QUESTION_MESSAGE
308 );
309 if (answer != JOptionPane.OK_OPTION || l.getSelectedIndex() == -1)
310 return;
311 StringBuilder license = new StringBuilder();
312 for (int i : l.getSelectedIndices()) {
313 if (i == 2) {
314 license = new StringBuilder("public domain");
315 break;
316 }
317 if (license.length() > 0) {
318 license.append(", ");
319 }
320 license.append(URLS[i]);
321 }
322 copyright.setText(license.toString());
323 copyright.setCaretPosition(0);
324 });
325
326 authorActionListener.actionPerformed(null);
327 authorNameListener.keyReleased(null);
328 }
329}
Note: See TracBrowser for help on using the repository browser.