Changeset 28469 in osm for applications/editors/josm/plugins/wikipedia/src/org
- Timestamp:
- 2012-07-11T15:16:48+02:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaToggleDialog.java
r28293 r28469 7 7 import java.awt.event.MouseAdapter; 8 8 import java.awt.event.MouseEvent; 9 import java.io.IOException; 9 10 import java.io.UnsupportedEncodingException; 10 11 import java.net.URL; 11 12 import java.net.URLDecoder; 13 import java.net.URLEncoder; 14 import java.util.ArrayList; 12 15 import java.util.Arrays; 16 import java.util.Collection; 13 17 import java.util.Collections; 18 import java.util.HashSet; 14 19 import java.util.LinkedList; 15 20 import java.util.List; 21 import java.util.Map; 22 import java.util.Scanner; 23 import java.util.Set; 16 24 import java.util.regex.Matcher; 17 25 import java.util.regex.Pattern; 18 26 import javax.swing.AbstractAction; 27 import javax.swing.DefaultListCellRenderer; 19 28 import javax.swing.DefaultListModel; 29 import javax.swing.JLabel; 20 30 import javax.swing.JList; 21 31 import javax.swing.JOptionPane; … … 25 35 import javax.xml.xpath.XPathFactory; 26 36 import org.openstreetmap.josm.Main; 37 import org.openstreetmap.josm.actions.search.SearchAction; 27 38 import org.openstreetmap.josm.command.ChangePropertyCommand; 28 39 import org.openstreetmap.josm.data.coor.LatLon; 40 import org.openstreetmap.josm.data.osm.OsmPrimitive; 29 41 import org.openstreetmap.josm.data.osm.Tag; 42 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; 43 import org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter; 44 import org.openstreetmap.josm.data.osm.event.DatasetEventManager; 45 import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode; 30 46 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 31 47 import org.openstreetmap.josm.data.preferences.StringProperty; 48 import org.openstreetmap.josm.gui.MapView; 32 49 import org.openstreetmap.josm.gui.SideButton; 33 50 import org.openstreetmap.josm.gui.dialogs.ToggleDialog; 51 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 34 52 import org.openstreetmap.josm.tools.ImageProvider; 35 53 import org.openstreetmap.josm.tools.LanguageInfo; … … 38 56 import org.w3c.dom.NodeList; 39 57 40 public class WikipediaToggleDialog extends ToggleDialog {58 public class WikipediaToggleDialog extends ToggleDialog implements MapView.EditLayerChangeListener, DataSetListenerAdapter.Listener { 41 59 42 60 public WikipediaToggleDialog() { 43 61 super(tr("Wikipedia"), "wikipedia", tr("Fetch Wikipedia articles with coordinates"), null, 150); 44 62 createLayout(list, true, Arrays.asList( 45 new SideButton(new WikipediaDownloadAction()), 63 new SideButton(new WikipediaLoadCoordinatesAction()), 64 new SideButton(new WikipediaLoadCategoryAction()), 46 65 new SideButton(new AddWikipediaTagAction()), 47 66 new SideButton(new OpenWikipediaArticleAction()), … … 49 68 } 50 69 final StringProperty wikipediaLang = new StringProperty("wikipedia.lang", LanguageInfo.getJOSMLocaleCode().substring(0, 2)); 70 final Set<String> articles = new HashSet<String>(); 51 71 final DefaultListModel model = new DefaultListModel(); 52 72 final JList list = new JList(model) { … … 58 78 public void mouseClicked(MouseEvent e) { 59 79 if (e.getClickCount() == 2 && getSelectedValue() != null) { 60 BoundingXYVisitor bbox = new BoundingXYVisitor(); 61 bbox.visit(((WikipediaEntry) getSelectedValue()).coordinate); 62 Main.map.mapView.recalculateCenterScale(bbox); 80 final WikipediaEntry entry = (WikipediaEntry) getSelectedValue(); 81 if (entry.coordinate != null) { 82 BoundingXYVisitor bbox = new BoundingXYVisitor(); 83 bbox.visit(entry.coordinate); 84 Main.map.mapView.recalculateCenterScale(bbox); 85 } 86 SearchAction.search(entry.name.replaceAll("\\(.*\\)", ""), SearchAction.SearchMode.replace); 63 87 } 88 } 89 }); 90 91 setCellRenderer(new DefaultListCellRenderer() { 92 93 @Override 94 public JLabel getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 95 JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 96 if (articles.contains(((WikipediaEntry) value).name)) { 97 label.setIcon(ImageProvider.getIfAvailable("misc", "green_check")); 98 } 99 return label; 64 100 } 65 101 }); … … 70 106 final int index = locationToIndex(e.getPoint()); 71 107 if (index >= 0) { 72 return "<html>" + ((WikipediaEntry) model.getElementAt(index)).description + "</html>"; 108 final String description = ((WikipediaEntry) model.getElementAt(index)).description; 109 return description == null ? null : ("<html>" + description + "</html>"); 73 110 } else { 74 111 return null; … … 77 114 }; 78 115 116 static class WikipediaLangArticle { 117 118 final String lang, article; 119 120 public WikipediaLangArticle(String lang, String article) { 121 this.lang = lang; 122 this.article = article; 123 } 124 125 public static WikipediaLangArticle parseFromUrl(String url) { 126 if (url == null) { 127 return null; 128 } 129 // decode URL for nicer value 130 try { 131 url = URLDecoder.decode(url, "UTF-8"); 132 } catch (UnsupportedEncodingException ex) { 133 throw new IllegalStateException(ex); 134 } 135 // extract Wikipedia language and 136 final Matcher m = Pattern.compile("https?://(\\w*)\\.wikipedia\\.org/wiki/(.*)").matcher(url); 137 if (!m.matches()) { 138 return null; 139 } 140 return new WikipediaLangArticle(m.group(1), m.group(2)); 141 } 142 } 143 79 144 static class WikipediaEntry implements Comparable<WikipediaEntry> { 80 145 81 String name, description; 82 LatLon coordinate; 146 final String name, description; 147 final String wikipediaLang, wikipediaArticle; 148 final LatLon coordinate; 83 149 84 150 public WikipediaEntry(String name, String description, LatLon coordinate) { … … 86 152 this.description = description; 87 153 this.coordinate = coordinate; 88 } 89 90 public String getHrefFromDescription() { 154 155 final WikipediaLangArticle wp = WikipediaLangArticle.parseFromUrl(getHrefFromDescription()); 156 if (wp == null) { 157 System.err.println("Could not extract Wikipedia tag from: " + getHrefFromDescription()); 158 } 159 this.wikipediaLang = wp == null ? null : wp.lang; 160 this.wikipediaArticle = wp == null ? null : wp.article; 161 } 162 163 public WikipediaEntry(String name, String wikipediaLang, String wikipediaArticle) { 164 this.name = name; 165 this.description = null; 166 this.wikipediaLang = wikipediaLang; 167 this.wikipediaArticle = wikipediaArticle; 168 this.coordinate = null; 169 } 170 171 protected final String getHrefFromDescription() { 91 172 final Matcher m = Pattern.compile(".*href=\"(.+?)\".*").matcher(description); 92 173 if (m.matches()) { … … 98 179 } 99 180 100 public Tag createWikipediaTag() { 101 // get URL from description 102 String url = getHrefFromDescription(); 103 if (url == null) { 104 return null; 105 } 106 // decode URL for nicer value 107 try { 108 url = URLDecoder.decode(url, "UTF-8"); 109 } catch (UnsupportedEncodingException ex) { 110 throw new IllegalStateException(ex); 111 } 112 // extract Wikipedia language and 113 final Matcher m = Pattern.compile("https?://(\\w*)\\.wikipedia\\.org/wiki/(.*)").matcher(url); 114 if (!m.matches()) { 115 System.err.println("Could not extract Wikipedia tag from: " + url); 116 return null; 117 } 118 return new Tag("wikipedia", m.group(1) + ":" + m.group(2)); 181 protected final Tag createWikipediaTag() { 182 return new Tag("wikipedia", wikipediaLang + ":" + wikipediaArticle); 119 183 } 120 184 … … 130 194 } 131 195 132 class Wikipedia DownloadAction extends AbstractAction {133 134 public Wikipedia DownloadAction() {135 super(tr(" Reload"), ImageProvider.get("dialogs", "refresh"));196 class WikipediaLoadCoordinatesAction extends AbstractAction { 197 198 public WikipediaLoadCoordinatesAction() { 199 super(tr("Coordinates"), ImageProvider.get("dialogs", "refresh")); 136 200 putValue(SHORT_DESCRIPTION, tr("Fetches all coordinates from Wikipedia in the current view")); 137 201 } … … 179 243 } 180 244 245 class WikipediaLoadCategoryAction extends AbstractAction { 246 247 public WikipediaLoadCategoryAction() { 248 super(tr("Category"), ImageProvider.get("dialogs", "refresh")); 249 putValue(SHORT_DESCRIPTION, tr("Fetches a list of all Wikipedia articles of a category")); 250 } 251 252 @Override 253 public void actionPerformed(ActionEvent e) { 254 try { 255 final String category = JOptionPane.showInputDialog( 256 Main.parent, 257 tr("Enter the Wikipedia category")); 258 final String url = "http://toolserver.org/~daniel/WikiSense/CategoryIntersect.php?" 259 + "wikilang=" + wikipediaLang.get() 260 + "&wikifam=.wikipedia.org" 261 + "&basecat=" + URLEncoder.encode(category, "UTF-8") 262 + "&basedeep=3&templates=&mode=al&format=csv"; 263 System.out.println("Wikipedia: GET " + url); 264 final Scanner scanner = new Scanner(new URL(url).openStream()).useDelimiter("\n"); 265 if (scanner.hasNext()) { 266 model.clear(); 267 } 268 while (scanner.hasNext()) { 269 final String article = scanner.next().split("\t")[1].replace("_", " "); 270 model.addElement(new WikipediaEntry(article, wikipediaLang.get(), article)); 271 } 272 } catch (IOException ex) { 273 throw new RuntimeException(ex); 274 } 275 } 276 } 277 181 278 class OpenWikipediaArticleAction extends AbstractAction { 182 279 … … 189 286 public void actionPerformed(ActionEvent e) { 190 287 if (list.getSelectedValue() != null) { 191 String url = ((WikipediaEntry) list.getSelectedValue()).getHrefFromDescription(); 192 if (url != null) { 193 System.out.println("Wikipedia: opening " + url); 194 OpenBrowser.displayUrl(url); 195 } 288 WikipediaEntry entry = (WikipediaEntry) list.getSelectedValue(); 289 final String url; 290 if (entry.getHrefFromDescription() != null) { 291 url = entry.getHrefFromDescription(); 292 } else { 293 url = "http://" + entry.wikipediaLang + ".wikipedia.org/wiki/" + entry.wikipediaArticle.replace(" ", "_"); 294 } 295 System.out.println("Wikipedia: opening " + url); 296 OpenBrowser.displayUrl(url); 196 297 } 197 298 } … … 208 309 public void actionPerformed(ActionEvent e) { 209 310 String lang = JOptionPane.showInputDialog( 210 WikipediaToggleDialog.this,311 Main.parent, 211 312 tr("Enter the Wikipedia language"), 212 313 wikipediaLang.get()); 213 314 if (lang != null) { 214 315 wikipediaLang.put(lang); 316 updateWikipediaArticles(); 215 317 } 216 318 } … … 237 339 } 238 340 } 341 342 protected void updateWikipediaArticles() { 343 articles.clear(); 344 if (Main.main != null && Main.main.getCurrentDataSet() != null) { 345 for (final OsmPrimitive p : Main.main.getCurrentDataSet().allPrimitives()) { 346 articles.addAll(getWikipediaArticles(p)); 347 } 348 } 349 } 350 351 protected Collection<String> getWikipediaArticles(OsmPrimitive p) { 352 Collection<String> r = new ArrayList<String>(); 353 final Map<String, String> tags = p.getKeys(); 354 // consider wikipedia=[lang]:* 355 final String wp = tags.get("wikipedia"); 356 if (wp != null && wp.startsWith("http")) { 357 //wikipedia=http... 358 final WikipediaLangArticle item = WikipediaLangArticle.parseFromUrl(wp); 359 if (item != null && wikipediaLang.get().equals(item.lang)) { 360 r.add(item.article.replace("_", " ")); 361 } 362 } else if (wp != null) { 363 //wikipedia=[lang]:[article] 364 try { 365 String[] item = URLDecoder.decode(wp, "UTF-8").split(":", 2); 366 if (item.length == 2 && wikipediaLang.get().equals(item[0])) { 367 r.add(item[1].replace("_", " ")); 368 } 369 } catch (UnsupportedEncodingException ex) { 370 throw new IllegalStateException(ex); 371 } 372 } 373 // consider wikipedia:[lang]=* 374 final String wpLang = tags.get("wikipedia:" + wikipediaLang.get()); 375 if (wpLang != null && wpLang.startsWith("http")) { 376 //wikipedia:[lang]=http... 377 final WikipediaLangArticle item = WikipediaLangArticle.parseFromUrl(wpLang); 378 if (wikipediaLang.get().equals(item.lang)) { 379 r.add(item.article.replace("_", " ")); 380 } 381 } else if (wpLang != null) { 382 //wikipedia:[lang]=[lang]:[article] 383 //wikipedia:[lang]=[article] 384 try { 385 String[] item = URLDecoder.decode(wpLang, "UTF-8").split(":", 2); 386 r.add(item[item.length == 2 ? 1 : 0].replace("_", " ")); 387 } catch (UnsupportedEncodingException ex) { 388 throw new IllegalStateException(ex); 389 } 390 } 391 return r; 392 } 393 394 private final DataSetListenerAdapter dataChangedAdapter = new DataSetListenerAdapter(this); 395 396 @Override 397 public void showNotify() { 398 DatasetEventManager.getInstance().addDatasetListener(dataChangedAdapter, FireMode.IN_EDT_CONSOLIDATED); 399 MapView.addEditLayerChangeListener(this); 400 updateWikipediaArticles(); 401 } 402 403 @Override 404 public void hideNotify() { 405 DatasetEventManager.getInstance().removeDatasetListener(dataChangedAdapter); 406 MapView.removeEditLayerChangeListener(this); 407 articles.clear(); 408 } 409 410 @Override 411 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 412 updateWikipediaArticles(); 413 list.repaint(); 414 } 415 416 @Override 417 public void processDatasetEvent(AbstractDatasetChangedEvent event) { 418 updateWikipediaArticles(); 419 list.repaint(); 420 } 239 421 }
Note:
See TracChangeset
for help on using the changeset viewer.