source: josm/trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java@ 1808

Last change on this file since 1808 was 1808, checked in by Gubaer, 15 years ago

improved enabling/disabling of menu entries and action buttons depending on current state of JOSM (number of open layers, type of active layer, etc.)

  • Property svn:eol-style set to native
File size: 13.8 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
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.FileOutputStream;
13import java.io.IOException;
14import java.util.Calendar;
15
16import javax.swing.JButton;
17import javax.swing.JCheckBox;
18import javax.swing.JFileChooser;
19import javax.swing.JLabel;
20import javax.swing.JList;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.JTextArea;
25import javax.swing.JTextField;
26import javax.swing.ListSelectionModel;
27
28import org.openstreetmap.josm.Main;
29import org.openstreetmap.josm.data.gpx.GpxData;
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.layer.Layer.LayerChangeListener;
35import org.openstreetmap.josm.io.GpxWriter;
36import org.openstreetmap.josm.tools.GBC;
37import org.openstreetmap.josm.tools.Shortcut;
38
39/**
40 * Exports data to gpx.
41 */
42public class GpxExportAction extends DiskAccessAction implements LayerChangeListener {
43
44 private final static String warningGpl = "<html><font color='red' size='-2'>"+tr("Note: GPL is not compatible with the OSM license. Do not upload GPL licensed tracks.")+"</html>";
45
46 public GpxExportAction() {
47 super(tr("Export to GPX..."), "exportgpx", tr("Export the data to GPX file."),
48 Shortcut.registerShortcut("file:exportgpx", tr("Export to GPX..."), KeyEvent.VK_E, Shortcut.GROUP_MENU));
49 Layer.listeners.add(this);
50 refreshEnabled();
51 }
52
53 protected GpxLayer getLayer() {
54 if (Main.map == null) return null;
55 if (Main.map.mapView == null) return null;
56 if (Main.map.mapView.getActiveLayer() == null) return null;
57 Layer layer = Main.map.mapView.getActiveLayer();
58 if (! (layer instanceof GpxLayer)) return null;
59 return (GpxLayer)layer;
60 }
61
62 public void actionPerformed(ActionEvent e) {
63 if (!isEnabled())
64 return;
65 GpxLayer layer = getLayer();
66 if (layer == null) {
67 JOptionPane.showMessageDialog(Main.parent, tr("Nothing to export. Get some data first."));
68 return;
69 }
70 export(layer);
71 }
72
73 /**
74 * Exports a layer to a file. Launches a file chooser to request the user to enter a file name.
75 *
76 * <code>layer</code> must not be null. <code>layer</code> must be an instance of
77 * {@see OsmDataLayer} or {@see GpxLayer}.
78 *
79 * @param layer the layer
80 * @exception IllegalArgumentException thrown if layer is null
81 * @exception IllegalArgumentException thrown if layer is neither an instance of {@see OsmDataLayer}
82 * nor of {@see GpxLayer}
83 */
84 public void export(Layer layer) {
85 if (layer == null)
86 throw new IllegalArgumentException(tr("paramenter ''{0'' must not be null", "layer"));
87 if (! (layer instanceof OsmDataLayer) && ! (layer instanceof GpxLayer))
88 throw new IllegalArgumentException(tr("expected instance of OsmDataLayer or GpxLayer. Got ''{0}''.", layer.getClass().getName()));
89
90 JFileChooser fc = createAndOpenFileChooser(false, false, null);
91 if (fc == null)
92 return;
93 File file = fc.getSelectedFile();
94 if (file == null)
95 return;
96
97 exportGpx(file, layer);
98 }
99
100 public static void exportGpx(File file, Layer layer) {
101 String fn = file.getPath();
102 if (fn.indexOf('.') == -1) {
103 fn += ".gpx";
104 file = new File(fn);
105 }
106
107 // open the dialog asking for options
108 JPanel p = new JPanel(new GridBagLayout());
109
110 p.add(new JLabel(tr("gps track description")), GBC.eol());
111 JTextArea desc = new JTextArea(3,40);
112 desc.setWrapStyleWord(true);
113 desc.setLineWrap(true);
114 p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
115
116 JCheckBox author = new JCheckBox(tr("Add author information"), Main.pref.getBoolean("lastAddAuthor", true));
117 author.setSelected(true);
118 p.add(author, GBC.eol());
119 JLabel nameLabel = new JLabel(tr("Real name"));
120 p.add(nameLabel, GBC.std().insets(10,0,5,0));
121 JTextField authorName = new JTextField(Main.pref.get("lastAuthorName"));
122 p.add(authorName, GBC.eol().fill(GBC.HORIZONTAL));
123 JLabel emailLabel = new JLabel(tr("E-Mail"));
124 p.add(emailLabel, GBC.std().insets(10,0,5,0));
125 JTextField email = new JTextField(Main.pref.get("osm-server.username"));
126 p.add(email, GBC.eol().fill(GBC.HORIZONTAL));
127 JLabel copyrightLabel = new JLabel(tr("Copyright (URL)"));
128 p.add(copyrightLabel, GBC.std().insets(10,0,5,0));
129 JTextField copyright = new JTextField();
130 p.add(copyright, GBC.std().fill(GBC.HORIZONTAL));
131 JButton predefined = new JButton(tr("Predefined"));
132 p.add(predefined, GBC.eol().insets(5,0,0,0));
133 JLabel copyrightYearLabel = new JLabel(tr("Copyright year"));
134 p.add(copyrightYearLabel, GBC.std().insets(10,0,5,5));
135 JTextField copyrightYear = new JTextField("");
136 p.add(copyrightYear, GBC.eol().fill(GBC.HORIZONTAL));
137 JLabel warning = new JLabel("<html><font size='-2'>&nbsp;</html");
138 p.add(warning, GBC.eol().fill(GBC.HORIZONTAL).insets(15,0,0,0));
139 addDependencies(author, authorName, email, copyright, predefined, copyrightYear, nameLabel, emailLabel, copyrightLabel, copyrightYearLabel, warning);
140
141 // if the user name is not the email address, but the osm user name
142 // move it from the email textfield to the author textfield
143 if(!email.getText().contains("@")) {
144 authorName.setText(email.getText());
145 email.setText("");
146 }
147
148 p.add(new JLabel(tr("Keywords")), GBC.eol());
149 JTextField keywords = new JTextField();
150 p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
151
152 int answer = new ExtendedDialog(Main.parent,
153 tr("Export options"),
154 p,
155 new String[] {tr("Export and Save"), tr("Cancel")},
156 new String[] {"exportgpx.png", "cancel.png"}).getValue();
157 if (answer != 1)
158 return;
159
160 Main.pref.put("lastAddAuthor", author.isSelected());
161 if (authorName.getText().length() != 0) {
162 Main.pref.put("lastAuthorName", authorName.getText());
163 }
164 if (copyright.getText().length() != 0) {
165 Main.pref.put("lastCopyright", copyright.getText());
166 }
167
168 GpxData gpxData;
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.ds, file);
175 }
176
177 // add author and copyright details to the gpx data
178 if(author.isSelected()) {
179 if(authorName.getText().length() > 0) {
180 gpxData.attr.put(GpxData.META_AUTHOR_NAME, authorName.getText());
181 gpxData.attr.put(GpxData.META_COPYRIGHT_AUTHOR, authorName.getText());
182 }
183 if(email.getText().length() > 0) {
184 gpxData.attr.put(GpxData.META_AUTHOR_EMAIL, email.getText());
185 }
186 if(copyright.getText().length() > 0) {
187 gpxData.attr.put(GpxData.META_COPYRIGHT_LICENSE, copyright.getText());
188 }
189 if(copyrightYear.getText().length() > 0) {
190 gpxData.attr.put(GpxData.META_COPYRIGHT_YEAR, copyrightYear.getText());
191 }
192 }
193
194 // add the description to the gpx data
195 if(desc.getText().length() > 0) {
196 gpxData.attr.put(GpxData.META_DESC, desc.getText());
197 }
198
199 // add keywords to the gpx data
200 if(keywords.getText().length() > 0) {
201 gpxData.attr.put(GpxData.META_KEYWORDS, keywords.getText());
202 }
203
204 try {
205 FileOutputStream fo = new FileOutputStream(file);
206 new GpxWriter(fo).write(gpxData);
207 fo.flush();
208 fo.close();
209 } catch (IOException x) {
210 x.printStackTrace();
211 JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}:\n{1}", fn,x.getMessage()), tr("Error"), JOptionPane.ERROR_MESSAGE);
212 }
213 }
214
215 /**
216 * Add all those listeners to handle the enable state of the fields.
217 * @param copyrightYearLabel
218 * @param copyrightLabel
219 * @param emailLabel
220 * @param nameLabel
221 * @param warning
222 */
223 private static void addDependencies(
224 final JCheckBox author,
225 final JTextField authorName,
226 final JTextField email,
227 final JTextField copyright,
228 final JButton predefined,
229 final JTextField copyrightYear,
230 final JLabel nameLabel,
231 final JLabel emailLabel,
232 final JLabel copyrightLabel,
233 final JLabel copyrightYearLabel,
234 final JLabel warning) {
235
236 ActionListener authorActionListener = new ActionListener(){
237 public void actionPerformed(ActionEvent e) {
238 boolean b = author.isSelected();
239 authorName.setEnabled(b);
240 email.setEnabled(b);
241 nameLabel.setEnabled(b);
242 emailLabel.setEnabled(b);
243 authorName.setText(b ? Main.pref.get("lastAuthorName") : "");
244 email.setText(b ? Main.pref.get("osm-server.username") : "");
245
246 boolean authorSet = authorName.getText().length() != 0;
247 enableCopyright(copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning, b && authorSet);
248 }
249 };
250 author.addActionListener(authorActionListener);
251
252 KeyAdapter authorNameListener = new KeyAdapter(){
253 @Override public void keyReleased(KeyEvent e) {
254 boolean b = authorName.getText().length()!=0 && author.isSelected();
255 enableCopyright(copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning, b);
256 }
257 };
258 authorName.addKeyListener(authorNameListener);
259
260 predefined.addActionListener(new ActionListener(){
261 public void actionPerformed(ActionEvent e) {
262 JList l = new JList(new String[]{"Creative Commons By-SA", "public domain", "GNU Lesser Public License (LGPL)", "BSD License (MIT/X11)"});
263 l.setVisibleRowCount(4);
264 l.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
265 int answer = JOptionPane.showConfirmDialog(Main.parent, new JScrollPane(l),tr("Choose a predefined license"), JOptionPane.OK_CANCEL_OPTION);
266 if (answer != JOptionPane.OK_OPTION || l.getSelectedIndex() == -1)
267 return;
268 final String[] urls = {
269 "http://creativecommons.org/licenses/by-sa/2.5",
270 "public domain",
271 "http://www.gnu.org/copyleft/lesser.html",
272 "http://www.opensource.org/licenses/bsd-license.php"};
273 String license = "";
274 for (int i : l.getSelectedIndices()) {
275 if (i == 1) {
276 license = "public domain";
277 break;
278 }
279 license += license.length()==0 ? urls[i] : ", "+urls[i];
280 }
281 copyright.setText(license);
282 copyright.setCaretPosition(0);
283 }
284 });
285
286 authorActionListener.actionPerformed(null);
287 authorNameListener.keyReleased(null);
288 }
289
290 private static void enableCopyright(final JTextField copyright, final JButton predefined, final JTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel, final JLabel warning, boolean enable) {
291 copyright.setEnabled(enable);
292 predefined.setEnabled(enable);
293 copyrightYear.setEnabled(enable);
294 copyrightLabel.setEnabled(enable);
295 copyrightYearLabel.setEnabled(enable);
296 warning.setText(enable ? warningGpl : "<html><font size='-2'>&nbsp;</html");
297
298 if (enable && copyrightYear.getText().length()==0) {
299 copyrightYear.setText(enable ? Integer.toString(Calendar.getInstance().get(Calendar.YEAR)) : "");
300 } else if (!enable) {
301 copyrightYear.setText("");
302 }
303
304 if (enable && copyright.getText().length()==0) {
305 copyright.setText(enable ? Main.pref.get("lastCopyright", "http://creativecommons.org/licenses/by-sa/2.5") : "");
306 copyright.setCaretPosition(0);
307 } else if (!enable) {
308 copyright.setText("");
309 }
310 }
311
312 /**
313 * Refreshes the enabled state
314 *
315 */
316 protected void refreshEnabled() {
317 boolean check = Main.main != null
318 && Main.map != null
319 && Main.map.mapView !=null
320 && Main.map.mapView.getActiveLayer() != null;
321 if(!check) {
322 setEnabled(false);
323 return;
324 }
325 Layer layer = Main.map.mapView.getActiveLayer();
326 setEnabled(layer instanceof GpxLayer);
327 }
328
329 /* ---------------------------------------------------------------------------------- */
330 /* Interface LayerChangeListener */
331 /* ---------------------------------------------------------------------------------- */
332 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
333 refreshEnabled();
334 }
335
336 public void layerAdded(Layer newLayer) {
337 refreshEnabled();
338 }
339
340 public void layerRemoved(Layer oldLayer) {
341 refreshEnabled();
342 }
343}
Note: See TracBrowser for help on using the repository browser.