source: josm/trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java@ 4089

Last change on this file since 4089 was 4081, checked in by bastiK, 13 years ago

applied #6251 (patch by akks) - Download multiple objects on Ctrl-Shift-O

  • Property svn:eol-style set to native
File size: 11.2 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.Font;
9import java.awt.GridBagLayout;
10import java.awt.event.ActionEvent;
11import java.awt.event.KeyEvent;
12import java.lang.reflect.InvocationTargetException;
13import java.util.List;
14import java.util.Set;
15import java.util.TreeSet;
16import javax.swing.BorderFactory;
17import javax.swing.GroupLayout;
18
19import javax.swing.JCheckBox;
20import javax.swing.JLabel;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.JTextArea;
25import javax.swing.KeyStroke;
26import javax.swing.SwingUtilities;
27import javax.swing.border.EtchedBorder;
28
29import org.openstreetmap.josm.Main;
30import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
31import org.openstreetmap.josm.data.osm.DataSet;
32import org.openstreetmap.josm.data.osm.OsmPrimitive;
33import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
34import org.openstreetmap.josm.data.osm.PrimitiveId;
35import org.openstreetmap.josm.gui.ExtendedDialog;
36import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask;
37import org.openstreetmap.josm.gui.layer.OsmDataLayer;
38import org.openstreetmap.josm.gui.widgets.HtmlPanel;
39import org.openstreetmap.josm.gui.widgets.OsmIdTextField;
40import org.openstreetmap.josm.gui.widgets.OsmPrimitiveTypesComboBox;
41import org.openstreetmap.josm.tools.GBC;
42import org.openstreetmap.josm.tools.Shortcut;
43import org.openstreetmap.josm.tools.Utils;
44
45/**
46 * Download an OsmPrimitive by specifying type and ID
47 *
48 * @author Matthias Julius
49 */
50public class DownloadPrimitiveAction extends JosmAction {
51
52 public DownloadPrimitiveAction() {
53 super(tr("Download object..."), "downloadprimitive", tr("Download OSM object by ID."),
54 Shortcut.registerShortcut("system:download_primitive", tr("File: {0}", tr("Download object...")), KeyEvent.VK_O, Shortcut.GROUP_MENU + Shortcut.GROUPS_ALT1), true);
55 putValue("help", ht("/Action/DownloadObject"));
56 }
57
58 public void actionPerformed(ActionEvent e) {
59
60 JPanel all = new JPanel();
61 GroupLayout layout = new GroupLayout(all);
62 all.setLayout(layout);
63 layout.setAutoCreateGaps(true);
64 layout.setAutoCreateContainerGaps(true);
65
66 JLabel lbl1 = new JLabel(tr("Object type:"));
67 OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox();
68 cbType.addItem(new SimpleListItem("mixed", tr("mixed")));
69 cbType.setToolTipText(tr("Choose the OSM object type"));
70 JLabel lbl2 = new JLabel(tr("Object ID:"));
71 OsmIdTextField tfId = new OsmIdTextField();
72 tfId.setToolTipText(tr("Enter the ID of the object that should be downloaded"));
73 // forward the enter key stroke to the download button
74 tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
75 JCheckBox layer = new JCheckBox(tr("Separate Layer"));
76 layer.setToolTipText(tr("Select if the data should be downloaded into a new layer"));
77 layer.setSelected(Main.pref.getBoolean("download.newlayer"));
78 JCheckBox referrers = new JCheckBox(tr("Download referrers"));
79 referrers.setToolTipText(tr("Select if the referrers of the object should be downloaded as well"));
80 referrers.setSelected(Main.pref.getBoolean("downloadprimitive.referrers"));
81 HtmlPanel help = new HtmlPanel(tr("Object IDs can be separated by comma or space.<br/>"
82 + " Examples: <b><ul><li>1 2 5</li><li>1,2,5</li></ul><br/></b>"
83 + " In mixed mode, specify objects like this: <b>w123, n110, w12, r15</b><br/>"));
84 help.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
85
86 layout.setVerticalGroup(layout.createSequentialGroup()
87 .addGroup(layout.createParallelGroup()
88 .addComponent(lbl1)
89 .addComponent(cbType, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
90 .addGroup(layout.createParallelGroup()
91 .addComponent(lbl2)
92 .addComponent(tfId, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
93 .addComponent(referrers)
94 .addComponent(layer)
95 .addComponent(help)
96 );
97
98 layout.setHorizontalGroup(layout.createParallelGroup()
99 .addGroup(layout.createSequentialGroup()
100 .addGroup(layout.createParallelGroup()
101 .addComponent(lbl1)
102 .addComponent(lbl2)
103 )
104 .addGroup(layout.createParallelGroup()
105 .addComponent(cbType)
106 .addComponent(tfId))
107 )
108 .addComponent(referrers)
109 .addComponent(layer)
110 .addComponent(help)
111 );
112
113 ExtendedDialog dialog = new ExtendedDialog(Main.parent,
114 tr("Download object"),
115 new String[] {tr("Download object"), tr("Cancel")}
116 );
117 dialog.setContent(all, false);
118 dialog.setButtonIcons(new String[] {"download.png", "cancel.png"});
119 dialog.setToolTipTexts(new String[] {
120 tr("Start downloading"),
121 tr("Close dialog and cancel downloading")
122 });
123 dialog.setDefaultButton(1);
124 dialog.configureContextsensitiveHelp("/Action/DownloadObject", true /* show help button */);
125 cbType.setSelectedIndex(Main.pref.getInteger("downloadprimitive.lasttype", 0));
126 dialog.showDialog();
127 if (dialog.getValue() != 1) return;
128 Main.pref.putInteger("downloadprimitive.lasttype", cbType.getSelectedIndex());
129 Main.pref.put("downloadprimitive.referrers", referrers.isSelected());
130 Main.pref.put("download.newlayer", layer.isSelected());
131
132 tfId.setType(cbType.getType());
133 if(tfId.readOsmIds()==false) {
134 JOptionPane.showMessageDialog(
135 Main.parent,
136 tr("Invalid ID list specified\n"
137 + " Cannot download object."),
138 tr("Information"),
139 JOptionPane.INFORMATION_MESSAGE
140 );
141 return;
142 }
143
144 processItems(layer.isSelected(), cbType.getType(), tfId.getIds(), referrers.isSelected());
145 }
146
147 void processItems(boolean newLayer, OsmPrimitiveType type,
148 final List<PrimitiveId> ids,
149 boolean downloadReferrers) {
150 OsmDataLayer layer = getEditLayer();
151 if ((layer == null) || newLayer) {
152 layer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
153 Main.main.addLayer(layer);
154 }
155 final DownloadPrimitivesTask task = new DownloadPrimitivesTask(layer, ids);
156 Main.worker.submit(task);
157
158 if (downloadReferrers) {
159 for (PrimitiveId id : ids) {
160 Main.worker.submit(new DownloadReferrersTask(layer, id));
161 }
162 }
163
164 Runnable showErrorsAndWarnings = new Runnable() {
165 @Override
166 public void run() {
167 Set<PrimitiveId> errs = task.getMissingPrimitives();
168 if (errs != null && !errs.isEmpty()) {
169 final ExtendedDialog dlg = reportProblemDialog(errs,
170 trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
171 trn("One object could not be downloaded.<br>",
172 "{0} objects could not be downloaded.<br>",
173 errs.size(),
174 errs.size())
175 + tr("The server replied with response code 404.<br>"
176 + "This usually means, the server does not know an object with the requested id."),
177 tr("missing objects:"),
178 JOptionPane.ERROR_MESSAGE
179 );
180 try {
181 SwingUtilities.invokeAndWait(new Runnable() {
182 @Override
183 public void run() {
184 dlg.showDialog();
185 }
186 });
187 } catch (InterruptedException ex) {
188 } catch (InvocationTargetException ex) {
189 }
190 }
191
192 Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
193 DataSet ds = getCurrentDataSet();
194 for (PrimitiveId id : ids) {
195 OsmPrimitive osm = ds.getPrimitiveById(id);
196 if (osm != null && osm.isDeleted()) {
197 del.add(id);
198 }
199 }
200 if (del != null && !del.isEmpty()) {
201 final ExtendedDialog dlg = reportProblemDialog(del,
202 trn("Object deleted", "Objects deleted", del.size()),
203 trn(
204 "One downloaded object is deleted.",
205 "{0} downloaded objects are deleted.",
206 del.size(),
207 del.size()),
208 null,
209 JOptionPane.WARNING_MESSAGE
210 );
211 SwingUtilities.invokeLater(new Runnable() {
212 @Override
213 public void run() {
214 dlg.showDialog();
215 }
216 });
217 }
218 }
219 };
220 Main.worker.submit(showErrorsAndWarnings);
221 }
222
223 private ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
224 String TITLE, String TEXT, String LIST_LABEL, int msgType) {
225 JPanel p = new JPanel(new GridBagLayout());
226 p.add(new HtmlPanel(TEXT), GBC.eop());
227 if (LIST_LABEL != null) {
228 JLabel missing = new JLabel(LIST_LABEL);
229 missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
230 p.add(missing, GBC.eol());
231 }
232 JTextArea txt = new JTextArea();
233 txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
234 txt.setEditable(false);
235 txt.setBackground(p.getBackground());
236 txt.setColumns(40);
237 txt.setRows(1);
238 txt.setText(Utils.join(", ", errs));
239 JScrollPane scroll = new JScrollPane(txt);
240 p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
241
242 return new ExtendedDialog(
243 Main.parent,
244 TITLE,
245 new String[] { tr("Ok") })
246 .setButtonIcons(new String[] { "ok" })
247 .setIcon(msgType)
248 .setContent(p, false);
249 }
250
251 private static class SimpleListItem {
252 final String data;
253 final String text;
254
255 public SimpleListItem(String data, String text) {
256 this.data = data;
257 this.text = text;
258 }
259
260 @Override public String toString() {
261 return text;
262 }
263 }
264}
Note: See TracBrowser for help on using the repository browser.