source: josm/trunk/src/org/openstreetmap/josm/gui/help/HelpUtil.java@ 2389

Last change on this file since 2389 was 2389, checked in by Gubaer, 14 years ago

see #3834: added context sensitive help

File size: 9.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.help;
3
4import java.awt.Component;
5import java.util.Locale;
6
7import javax.swing.AbstractButton;
8import javax.swing.Action;
9import javax.swing.JComponent;
10import javax.swing.JMenu;
11import javax.swing.KeyStroke;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.actions.HelpAction;
15import org.openstreetmap.josm.tools.LanguageInfo;
16
17public class HelpUtil {
18
19 /**
20 * Replies the base wiki URL.
21 *
22 * @return the base wiki URL
23 */
24 static public String getWikiBaseUrl() {
25 return Main.pref.get("help.baseurl", "http://josm.openstreetmap.de");
26 }
27
28 /**
29 * Replies the base wiki URL for help pages
30 *
31 * @return the base wiki URL for help pages
32 */
33 static public String getWikiBaseHelpUrl() {
34 return getWikiBaseUrl() + "/wiki";
35 }
36
37 /**
38 * Replies the URL on the wiki for an absolute help topic. The URL is encoded in UTF-8.
39 *
40 * @param absoluteHelpTopic the absolute help topic
41 * @return the url
42 * @see #buildAbsoluteHelpTopic(String)
43 * @see #buildAbsoluteHelpTopic(String, Locale)
44 */
45 static public String getHelpTopicUrl(String absoluteHelpTopic) {
46 String ret = getWikiBaseHelpUrl();
47 ret = ret.replaceAll("\\/+$", "");
48 absoluteHelpTopic =absoluteHelpTopic.replace(" ", "%20");
49 absoluteHelpTopic = absoluteHelpTopic.replaceAll("^\\/+", "/");
50 return ret + absoluteHelpTopic;
51 }
52
53 /**
54 * Replies the URL to the edit page for the absolute help topic.
55 *
56 * @param absoluteHelpTopic the absolute help topic
57 * @return the URL to the edit page
58 */
59 static public String getHelpTopicEditUrl(String absoluteHelpTopic) {
60 String topicUrl = getHelpTopicUrl(absoluteHelpTopic);
61 topicUrl = topicUrl.replaceAll("#[^#]*$", ""); // remove optional fragment
62 return topicUrl + "?action=edit";
63 }
64
65 /**
66 * Extracts the relative help topic from an URL. Replies null, if
67 * no relative help topic is found.
68 *
69 * @param url the url
70 * @return the relative help topic in the URL, i.e. "/Action/New"
71 */
72 static public String extractRelativeHelpTopic(String url) {
73 String topic = extractAbsoluteHelpTopic(url);
74 if (topic == null) return null;
75 String pattern = "/[A-Z][a-z]:" + getHelpTopicPrefix(Locale.ENGLISH).replaceAll("^\\/+", "");
76 if (url.matches(pattern))
77 return topic.substring(pattern.length());
78 return null;
79 }
80
81 /**
82 * Extracts the absolute help topic from an URL. Replies null, if
83 * no absolute help topic is found.
84 *
85 * @param url the url
86 * @return the absolute help topic in the URL, i.e. "/De:Help/Action/New"
87 */
88 static public String extractAbsoluteHelpTopic(String url) {
89 if (!url.startsWith(getWikiBaseHelpUrl())) return null;
90 url = url.substring(getWikiBaseHelpUrl().length());
91 String prefix = getHelpTopicPrefix(Locale.ENGLISH);
92 if (url.startsWith(prefix))
93 return url;
94
95 String pattern = "/[A-Z][a-z]:" + prefix.replaceAll("^\\/+", "");
96 if (url.matches(pattern))
97 return url;
98
99 return null;
100 }
101
102 /**
103 * Replies the help topic prefix for the current locale. Examples:
104 * <ul>
105 * <li>/Help if the current locale is a locale with language "en"</li>
106 * <li>/De:Help if the current locale is a locale with language "de"</li>
107 * </ul>
108 *
109 * @return the help topic prefix
110 * @see #getHelpTopicPrefix(Locale)
111 */
112 static public String getHelpTopicPrefix() {
113 return getHelpTopicPrefix(Locale.getDefault());
114 }
115
116 /**
117 * Replies the help topic prefix for the given locale. Examples:
118 * <ul>
119 * <li>/Help if the locale is a locale with language "en"</li>
120 * <li>/De:Help if the locale is a locale with language "de"</li>
121 * </ul>
122 *
123 * @param locale the locale. {@see Locale#ENGLISH} assumed, if null.
124 * @return the help topic prefix
125 * @see #getHelpTopicPrefix(Locale)
126 */
127 static public String getHelpTopicPrefix(Locale locale) {
128 if (locale == null) {
129 locale = Locale.ENGLISH;
130 }
131 String ret = Main.pref.get("help.pathhelp", "/Help");
132 ret = ret.replaceAll("^\\/+", ""); // remove leading /
133 ret = "/" + LanguageInfo.getWikiLanguagePrefix(locale) + ret;
134 return ret;
135 }
136
137 /**
138 * Replies the absolute, localized help topic for the given topic.
139 *
140 * Example: for a topic "/Dialog/RelationEditor" and the locale "de", this method
141 * replies "/De:Help/Dialog/RelationEditor"
142 *
143 * @param topic the relative help topic. Home help topic assumed, if null.
144 * @param locale the locale. {@see Locale#ENGLISH} assumed, if null.
145 * @return the absolute, localized help topic
146 */
147 static public String buildAbsoluteHelpTopic(String topic, Locale locale) {
148 if (locale == null) {
149 locale = Locale.ENGLISH;
150 }
151 if (topic == null || topic.trim().length() == 0 || topic.trim().equals("/"))
152 return getHelpTopicPrefix(locale);
153 String ret = getHelpTopicPrefix(locale);
154 if (topic.startsWith("/")) {
155 ret += topic;
156 } else {
157 ret += "/" + topic;
158 }
159 ret.replaceAll("\\/+", "\\/"); // just in case, collapse sequences of //
160 return ret;
161 }
162
163 /**
164 * Replies the absolute, localized help topic for the given topic and the
165 * current locale.
166 *
167 * @param topic the relative help topic. Home help topic assumed, if null.
168 * @return the absolute, localized help topic
169 * @see Locale#getDefault()
170 * @see #buildAbsoluteHelpTopic(String, Locale)
171 */
172 static public String buildAbsoluteHelpTopic(String topic) {
173 return buildAbsoluteHelpTopic(topic, Locale.getDefault());
174 }
175
176 /**
177 * Replies the context specific help topic configured for <code>context</code>.
178 *
179 * @return the help topic. null, if no context specific help topic is found
180 */
181 static public String getContextSpecificHelpTopic(Object context) {
182 if (context == null)
183 return null;
184 if (context instanceof Helpful)
185 return ((Helpful)context).helpTopic();
186 if (context instanceof JMenu) {
187 JMenu b = (JMenu)context;
188 if (b.getClientProperty("help") != null)
189 return (String)b.getClientProperty("help");
190 return null;
191 }
192 if (context instanceof AbstractButton) {
193 AbstractButton b = (AbstractButton)context;
194 if (b.getClientProperty("help") != null)
195 return (String)b.getClientProperty("help");
196 return getContextSpecificHelpTopic(b.getAction());
197 }
198 if (context instanceof Action)
199 return (String)((Action)context).getValue("help");
200 if (context instanceof JComponent && ((JComponent)context).getClientProperty("help") != null)
201 return (String)((JComponent)context).getClientProperty("help");
202 if (context instanceof Component)
203 return getContextSpecificHelpTopic(((Component)context).getParent());
204 return null;
205 }
206
207 /**
208 * Replies the global help action, if available. Otherwise, creates an instance
209 * of {@see HelpAction}.
210 *
211 * @return
212 */
213 static private Action getHelpAction() {
214 try {
215 return Main.main.menu.help;
216 } catch(NullPointerException e) {
217 return new HelpAction();
218 }
219 }
220
221 /**
222 * Makes a component aware of context sensitive help.
223 *
224 * A relative help topic doesn't start with /Help and doesn't include a locale
225 * code. Example: /Dialog/RelationEditor is a relative help topic, /De:Help/Dialog/RelationEditor
226 * is not.
227 *
228 * @param component the component the component
229 * @param topic the help topic. Set to the default help topic if null.
230 */
231 static public void setHelpContext(JComponent component, String relativeHelpTopic) {
232 if (relativeHelpTopic == null) {
233 relativeHelpTopic = "/";
234 }
235 component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F1"), "help");
236 component.getActionMap().put("help", getHelpAction());
237 component.putClientProperty("help", relativeHelpTopic);
238 }
239
240 /**
241 * This is a simple marker method for help topic literals. If you declare a help
242 * topic literal in the source you should enclose it in ht(...).
243 *
244 * <strong>Example</strong>
245 * <pre>
246 * String helpTopic = ht("/Dialog/RelationEditor");
247 * or
248 * putValue("help", ht("/Dialog/RelationEditor"));
249 * </pre>
250 *
251 *
252 * @param helpTopic
253 */
254 static public String ht(String helpTopic) {
255 // this is just a marker method
256 return helpTopic;
257 }
258}
Note: See TracBrowser for help on using the repository browser.