source: josm/trunk/src/org/openstreetmap/josm/actions/DownloadReferrersAction.java@ 2256

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

Removed inefficient DataSet:getSelected() when responding to fireSelectionChanged() in JOSM actions, see thread on dev
Still uses DataSet:getSelected() when responding to layer change events, this is less critical.

File size: 6.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.io.IOException;
9import java.util.Collection;
10
11import javax.swing.JOptionPane;
12import javax.swing.SwingUtilities;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.OsmPrimitive;
17import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
18import org.openstreetmap.josm.gui.DefaultNameFormatter;
19import org.openstreetmap.josm.gui.PleaseWaitRunnable;
20import org.openstreetmap.josm.gui.layer.OsmDataLayer;
21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
22import org.openstreetmap.josm.io.OsmApi;
23import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
24import org.openstreetmap.josm.io.OsmTransferException;
25import org.openstreetmap.josm.tools.Shortcut;
26import org.xml.sax.SAXException;
27
28/**
29 * This action loads the set of primitives referring to the current selection from the OSM
30 * server.
31 *
32 *
33 */
34public class DownloadReferrersAction extends JosmAction{
35
36 public DownloadReferrersAction() {
37 super(tr("Download parent ways/relations..."), "downloadreferrers", tr("Download primitives referring to one of the selected primitives"),
38 Shortcut.registerShortcut("file:downloadreferrers", tr("File: {0}", tr("Download parent ways/relations...")), KeyEvent.VK_D, Shortcut.GROUPS_ALT2+Shortcut.GROUP_HOTKEY), true);
39 }
40
41 /**
42 * Downloads the primitives referring to the primitives in <code>primitives</code>.
43 * Does nothing if primitives is null or empty.
44 *
45 * @param primitives the collection of primitives.
46 */
47 public void downloadReferrers(Collection<OsmPrimitive> primitives) {
48 if (primitives == null || primitives.isEmpty()) return;
49 Main.worker.submit(new DownloadReferrersTask(primitives));
50 }
51
52
53 public void actionPerformed(ActionEvent e) {
54 if (!isEnabled())
55 return;
56 OsmDataLayer layer = Main.map.mapView.getEditLayer();
57 Collection<OsmPrimitive> primitives = layer.data.getSelected();
58 downloadReferrers(primitives);
59 }
60
61 /**
62 * The asynchronous task for downloading referring primitives
63 *
64 */
65 class DownloadReferrersTask extends PleaseWaitRunnable {
66 private DataSet ds;
67 private boolean cancelled;
68 Exception lastException;
69 private Collection<OsmPrimitive> primitives;
70 private DataSet parents;
71
72 public DownloadReferrersTask(Collection<OsmPrimitive> primitives) {
73 super("Download referrers", false /* don't ignore exception*/);
74 cancelled = false;
75 this.primitives = primitives;
76 parents = new DataSet();
77 }
78
79 protected void showLastException() {
80 String msg = lastException.getMessage();
81 if (msg == null) {
82 msg = lastException.toString();
83 }
84 JOptionPane.showMessageDialog(
85 Main.map,
86 msg,
87 tr("Error"),
88 JOptionPane.ERROR_MESSAGE
89 );
90 }
91
92 @Override
93 protected void cancel() {
94 cancelled = true;
95 OsmApi.getOsmApi().cancel();
96 }
97
98 @Override
99 protected void finish() {
100 if (cancelled)
101 return;
102 if (lastException != null) {
103 showLastException();
104 return;
105 }
106
107 MergeVisitor visitor = new MergeVisitor(Main.map.mapView.getEditLayer().data, parents);
108 visitor.merge();
109 SwingUtilities.invokeLater(
110 new Runnable() {
111 public void run() {
112 Main.map.mapView.getEditLayer().fireDataChange();
113 Main.map.mapView.repaint();
114 }
115 }
116 );
117 if (visitor.getConflicts().isEmpty())
118 return;
119 Main.map.mapView.getEditLayer().getConflicts().add(visitor.getConflicts());
120 JOptionPane.showMessageDialog(
121 Main.parent,
122 tr("There were {0} conflicts during import.",
123 visitor.getConflicts().size()
124 ),
125 tr("Conflicts during download"),
126 JOptionPane.WARNING_MESSAGE
127 );
128 }
129
130 protected void downloadParents(OsmPrimitive primitive, ProgressMonitor progressMonitor) throws OsmTransferException{
131 OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(primitive);
132 DataSet ds = reader.parseOsm(progressMonitor);
133 MergeVisitor visitor = new MergeVisitor(parents, ds);
134 visitor.merge();
135 }
136
137 @Override
138 protected void realRun() throws SAXException, IOException, OsmTransferException {
139 try {
140 progressMonitor.setTicksCount(primitives.size());
141 int i=1;
142 for (OsmPrimitive primitive: primitives) {
143 if (cancelled)
144 return;
145 progressMonitor.subTask(tr("({0}/{1}) Loading parents of primitive {2}", i+1,primitives.size(), primitive.getDisplayName(DefaultNameFormatter.getInstance())));
146 downloadParents(primitive, progressMonitor.createSubTaskMonitor(1, false));
147 i++;
148 }
149 } catch(Exception e) {
150 if (cancelled)
151 return;
152 lastException = e;
153 }
154 }
155 }
156
157 @Override
158 protected void updateEnabledState() {
159 if (getCurrentDataSet() == null) {
160 setEnabled(false);
161 } else {
162 updateEnabledState(getCurrentDataSet().getSelected());
163 }
164 }
165
166 @Override
167 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
168 setEnabled(selection != null && !selection.isEmpty());
169 }
170}
Note: See TracBrowser for help on using the repository browser.