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

Last change on this file since 8674 was 8540, checked in by Don-vip, 9 years ago

fix remaining checkstyle issues

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