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

Last change on this file since 6936 was 6920, checked in by Don-vip, 10 years ago

fix #9778, fix #9806 - access OSM API and JOSM website in HTTPS by default + other HTTPS links where applicable + update CONTRIBUTION

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