source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/properties/HelpAction.java@ 13521

Last change on this file since 13521 was 13521, checked in by Don-vip, 6 years ago

fix #16085 - add contextual menu in tag table of history dialog with following entries, similarly to properties dialog:

  • Copy Value
  • Copy selected Key(s)/Value(s)
  • Copy all Keys/Values
  • Go to OSM wiki for tag help
  • Go to Taginfo
  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.properties;
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.net.URI;
10import java.net.URISyntaxException;
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Map;
14import java.util.Objects;
15import java.util.function.Function;
16
17import javax.swing.AbstractAction;
18import javax.swing.JTable;
19import javax.swing.KeyStroke;
20
21import org.openstreetmap.josm.data.osm.Relation;
22import org.openstreetmap.josm.gui.MainApplication;
23import org.openstreetmap.josm.spi.preferences.Config;
24import org.openstreetmap.josm.tools.HttpClient;
25import org.openstreetmap.josm.tools.ImageProvider;
26import org.openstreetmap.josm.tools.LanguageInfo;
27import org.openstreetmap.josm.tools.Logging;
28import org.openstreetmap.josm.tools.OpenBrowser;
29import org.openstreetmap.josm.tools.Utils;
30
31/**
32 * Launch browser with wiki help for selected object.
33 * @since 13521
34 */
35public class HelpAction extends AbstractAction {
36 private final JTable tagTable;
37 private final Function<Integer, String> tagKeySupplier;
38 private final Function<Integer, Map<String, Integer>> tagValuesSupplier;
39
40 private final JTable membershipTable;
41 private final Function<Integer, Relation> memberValueSupplier;
42
43 /**
44 * Constructs a new {@code HelpAction}.
45 * @param tagTable The tag table. Cannot be null
46 * @param tagKeySupplier Finds the key from given row of tag table. Cannot be null
47 * @param tagValuesSupplier Finds the values from given row of tag table (map of values and number of occurrences). Cannot be null
48 * @param membershipTable The membership table. Can be null
49 * @param memberValueSupplier Finds the parent relation from given row of membership table. Can be null
50 */
51 public HelpAction(JTable tagTable, Function<Integer, String> tagKeySupplier, Function<Integer, Map<String, Integer>> tagValuesSupplier,
52 JTable membershipTable, Function<Integer, Relation> memberValueSupplier) {
53 this.tagTable = Objects.requireNonNull(tagTable);
54 this.tagKeySupplier = Objects.requireNonNull(tagKeySupplier);
55 this.tagValuesSupplier = Objects.requireNonNull(tagValuesSupplier);
56 this.membershipTable = membershipTable;
57 this.memberValueSupplier = memberValueSupplier;
58 putValue(NAME, tr("Go to OSM wiki for tag help"));
59 putValue(SHORT_DESCRIPTION, tr("Launch browser with wiki help for selected object"));
60 new ImageProvider("dialogs", "search").getResource().attachImageIcon(this, true);
61 putValue(ACCELERATOR_KEY, getKeyStroke());
62 }
63
64 /**
65 * Returns the keystroke launching this action (F1).
66 * @return the keystroke launching this action
67 */
68 public KeyStroke getKeyStroke() {
69 return KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0);
70 }
71
72 @Override
73 public void actionPerformed(ActionEvent e) {
74 try {
75 String base = Config.getPref().get("url.openstreetmap-wiki", "https://wiki.openstreetmap.org/wiki/");
76 String lang = LanguageInfo.getWikiLanguagePrefix();
77 final List<URI> uris = new ArrayList<>();
78 int row;
79 if (tagTable.getSelectedRowCount() == 1) {
80 row = tagTable.getSelectedRow();
81 String key = Utils.encodeUrl(tagKeySupplier.apply(row));
82 Map<String, Integer> m = tagValuesSupplier.apply(row);
83 if (!m.isEmpty()) {
84 String val = Utils.encodeUrl(m.entrySet().iterator().next().getKey());
85
86 uris.add(new URI(String.format("%s%sTag:%s=%s", base, lang, key, val)));
87 uris.add(new URI(String.format("%sTag:%s=%s", base, key, val)));
88 uris.add(new URI(String.format("%s%sKey:%s", base, lang, key)));
89 uris.add(new URI(String.format("%sKey:%s", base, key)));
90 uris.add(new URI(String.format("%s%sMap_Features", base, lang)));
91 uris.add(new URI(String.format("%sMap_Features", base)));
92 }
93 } else if (membershipTable != null && membershipTable.getSelectedRowCount() == 1) {
94 row = membershipTable.getSelectedRow();
95 String type = (memberValueSupplier.apply(row)).get("type");
96 if (type != null) {
97 type = Utils.encodeUrl(type);
98 }
99
100 if (type != null && !type.isEmpty()) {
101 uris.add(new URI(String.format("%s%sRelation:%s", base, lang, type)));
102 uris.add(new URI(String.format("%sRelation:%s", base, type)));
103 }
104
105 uris.add(new URI(String.format("%s%sRelations", base, lang)));
106 uris.add(new URI(String.format("%sRelations", base)));
107 } else {
108 // give the generic help page, if more than one element is selected
109 uris.add(new URI(String.format("%s%sMap_Features", base, lang)));
110 uris.add(new URI(String.format("%sMap_Features", base)));
111 }
112
113 MainApplication.worker.execute(() -> displayHelp(uris));
114 } catch (URISyntaxException e1) {
115 Logging.error(e1);
116 }
117 }
118
119 private void displayHelp(final List<URI> uris) {
120 try {
121 // find a page that actually exists in the wiki
122 HttpClient.Response conn;
123 for (URI u : uris) {
124 conn = HttpClient.create(u.toURL(), "HEAD").connect();
125
126 if (conn.getResponseCode() != 200) {
127 conn.disconnect();
128 } else {
129 long osize = conn.getContentLength();
130 if (osize > -1) {
131 conn.disconnect();
132
133 final URI newURI = new URI(u.toString()
134 .replace("=", "%3D") /* do not URLencode whole string! */
135 .replaceFirst("/wiki/", "/w/index.php?redirect=no&title=")
136 );
137 conn = HttpClient.create(newURI.toURL(), "HEAD").connect();
138 }
139
140 /* redirect pages have different content length, but retrieving a "nonredirect"
141 * page using index.php and the direct-link method gives slightly different
142 * content lengths, so we have to be fuzzy.. (this is UGLY, recode if u know better)
143 */
144 if (osize > -1 && conn.getContentLength() != -1 && Math.abs(conn.getContentLength() - osize) > 200) {
145 Logging.info("{0} is a mediawiki redirect", u);
146 conn.disconnect();
147 } else {
148 conn.disconnect();
149
150 OpenBrowser.displayUrl(u.toString());
151 break;
152 }
153 }
154 }
155 } catch (URISyntaxException | IOException e1) {
156 Logging.error(e1);
157 }
158 }
159}
Note: See TracBrowser for help on using the repository browser.