source: josm/trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java@ 2276

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

Using java instead of javaw for launching external help browser on non-windows OS

File size: 11.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.help;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.awt.event.WindowAdapter;
10import java.awt.event.WindowEvent;
11import java.io.BufferedReader;
12import java.io.IOException;
13import java.io.InputStreamReader;
14import java.util.Observable;
15import java.util.Observer;
16
17import javax.swing.AbstractAction;
18import javax.swing.JButton;
19import javax.swing.JComponent;
20import javax.swing.JEditorPane;
21import javax.swing.JFrame;
22import javax.swing.JOptionPane;
23import javax.swing.JPanel;
24import javax.swing.JScrollPane;
25import javax.swing.JSeparator;
26import javax.swing.JToolBar;
27import javax.swing.KeyStroke;
28import javax.swing.event.HyperlinkEvent;
29import javax.swing.event.HyperlinkListener;
30import javax.swing.text.html.HTMLEditorKit;
31import javax.swing.text.html.StyleSheet;
32
33import org.openstreetmap.josm.Main;
34import org.openstreetmap.josm.tools.ImageProvider;
35import org.openstreetmap.josm.tools.LanguageInfo;
36import org.openstreetmap.josm.tools.OpenBrowser;
37import org.openstreetmap.josm.tools.WikiReader;
38
39public class HelpBrowser extends JFrame {
40
41 private static HelpBrowser instance;
42
43 /**
44 * Replies the unique instance of the help browser
45 *
46 * @return the unique instance of the help browser
47 */
48 static public HelpBrowser getInstance() {
49 if (instance == null) {
50 instance = new HelpBrowser();
51 }
52 return instance;
53 }
54
55 /**
56 * Launches the internal help browser and directs it to the help page for
57 * <code>helpTopic</code>.
58 *
59 * @param helpTopic the help topic
60 */
61 static public void launchBrowser(String helpTopic) {
62 HelpBrowser browser = getInstance();
63 browser.setUrlForHelpTopic(helpTopic);
64 browser.setVisible(true);
65 browser.toFront();
66 }
67
68 /** the help browser */
69 private JEditorPane help;
70 /** the help browser history */
71 private HelpBrowserHistory history;
72
73 /** the currently displayed URL */
74 private String url;
75
76 private String languageCode = LanguageInfo.getLanguageCodeWiki();
77 private String baseurl = Main.pref.get("help.baseurl", "http://josm.openstreetmap.de");
78 private String pathbase = Main.pref.get("help.pathbase", "/wiki/");
79 private WikiReader reader = new WikiReader(baseurl);
80
81 /**
82 * Builds the style sheet used in the internal help browser
83 *
84 * @return the style sheet
85 */
86 protected StyleSheet buildStyleSheet() {
87 StyleSheet ss = new StyleSheet();
88 BufferedReader reader = new BufferedReader(
89 new InputStreamReader(
90 getClass().getResourceAsStream("help-browser.css")
91 )
92 );
93 StringBuffer css = new StringBuffer();
94 try {
95 String line = null;
96 while ((line = reader.readLine()) != null) {
97 css.append(line);
98 css.append("\n");
99 }
100 reader.close();
101 } catch(Exception e) {
102 System.err.println(tr("Failed to read CSS file ''help-browser.css''. Exception is: {0}", e.toString()));
103 e.printStackTrace();
104 return ss;
105 }
106 ss.addRule(css.toString());
107 return ss;
108 }
109
110 protected JToolBar buildToolBar() {
111 JToolBar tb = new JToolBar();
112 tb.add(new JButton(new HomeAction()));
113 tb.add(new JButton(new BackAction(history)));
114 tb.add(new JButton(new ForwardAction(history)));
115 tb.add(new JButton(new ReloadAction()));
116 tb.add(new JSeparator());
117 tb.add(new JButton(new OpenInBrowserAction()));
118 tb.add(new JButton(new EditAction()));
119 return tb;
120 }
121
122 protected void build() {
123 help = new JEditorPane();
124 HTMLEditorKit kit = new HTMLEditorKit();
125 kit.setStyleSheet(buildStyleSheet());
126 help.setEditorKit(kit);
127 help.setEditable(false);
128 help.addHyperlinkListener(new HyperlinkListener(){
129 public void hyperlinkUpdate(HyperlinkEvent e) {
130 if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED)
131 return;
132 if (e.getURL() == null) {
133 help.setText("<html>404 not found</html>");
134 } else if (e.getURL().toString().endsWith("action=edit")) {
135 OpenBrowser.displayUrl(e.getURL().toString());
136 } else {
137 url = e.getURL().toString();
138 setUrl(e.getURL().toString());
139 }
140 }
141 });
142 help.setContentType("text/html");
143
144
145 history = new HelpBrowserHistory(this);
146
147 JPanel p = new JPanel(new BorderLayout());
148 setContentPane(p);
149
150 p.add(new JScrollPane(help), BorderLayout.CENTER);
151
152 addWindowListener(new WindowAdapter(){
153 @Override public void windowClosing(WindowEvent e) {
154 setVisible(false);
155 }
156 });
157
158 p.add(buildToolBar(), BorderLayout.NORTH);
159 help.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Close");
160 help.getActionMap().put("Close", new AbstractAction(){
161 public void actionPerformed(ActionEvent e) {
162 setVisible(false);
163 }
164 });
165
166 setTitle(tr("JOSM Help Browser"));
167 }
168
169 public HelpBrowser() {
170 build();
171 }
172
173 public String getUrl() {
174 return url;
175 }
176
177 protected void loadUrl(String url) {
178 String langurl = url;
179 if(url.startsWith(baseurl+pathbase)){
180 int i = pathbase.length()+baseurl.length();
181 String title = url.substring(i);
182 if(languageCode.length() != 0 && !title.startsWith(languageCode)) {
183 title = languageCode + title;
184 }
185 langurl = url.substring(0, i) + title;
186 }
187 boolean loaded = false;
188 if(!langurl.equals(this.url) && !langurl.equals(url)){
189 loaded = loadHelpUrl(url, langurl, true);
190 }
191 if(!loaded) {
192 loaded = loadHelpUrl(url, langurl, false);
193 }
194 if(!loaded) {
195 help.setText(tr("Error while loading page {0}",url));
196 }
197 }
198
199 public void setUrl(String url) {
200 loadUrl(url);
201 if (!isVisible()) {
202 setVisible(true);
203 toFront();
204 } else {
205 toFront();
206 }
207 history.setCurrentUrl(url);
208 }
209
210 public void setUrlForHelpTopic(String topic) {
211 setUrl(baseurl+pathbase+ topic);
212 }
213
214 protected boolean loadHelpUrl(String url, String localizedUrl, boolean useLocalizedUrl){
215 this.url = useLocalizedUrl ? localizedUrl : url;
216 boolean loaded = false;
217 try {
218 String txt = reader.read(this.url);
219 if(txt.length() == 0){
220 if(useLocalizedUrl)
221 throw new IOException();
222 if(url.equals(localizedUrl)){
223 txt = ("<HTML>"+tr("Help page missing. Create it in <A HREF=\"{0}\">English</A>.",
224 url+"?action=edit")+"</HTML>");
225 } else{
226 txt = ("<HTML>"+tr("Help page missing. Create it in <A HREF=\"{0}\">English</A> or <A HREF=\"{1}\">your language</A>.",
227 url+"?action=edit", localizedUrl+"?action=edit")+"</HTML>");
228 }
229 }
230 help.setText(txt);
231 help.setCaretPosition(0);
232 loaded = true;
233 } catch (IOException ex) {
234 }
235 return loaded;
236 }
237
238 class OpenInBrowserAction extends AbstractAction {
239 public OpenInBrowserAction() {
240 //putValue(NAME, tr("Open in Browser"));
241 putValue(SHORT_DESCRIPTION, tr("Open the current help page in an external browser"));
242 putValue(SMALL_ICON, ImageProvider.get("help", "internet"));
243 }
244
245 public void actionPerformed(ActionEvent e) {
246 OpenBrowser.displayUrl(getUrl());
247 }
248 }
249
250 class EditAction extends AbstractAction {
251 public EditAction() {
252 // putValue(NAME, tr("Edit"));
253 putValue(SHORT_DESCRIPTION, tr("Edit the current help page"));
254 putValue(SMALL_ICON,ImageProvider.get("dialogs", "edit"));
255 }
256
257 public void actionPerformed(ActionEvent e) {
258 if (!getUrl().startsWith(baseurl)) {
259 JOptionPane.showMessageDialog(
260 Main.parent,
261 tr("Can only edit help pages from JOSM Online Help"),
262 tr("Warning"),
263 JOptionPane.WARNING_MESSAGE
264 );
265 return;
266 }
267 OpenBrowser.displayUrl(url+"?action=edit");
268 }
269 }
270
271 class ReloadAction extends AbstractAction {
272 public ReloadAction() {
273 //putValue(NAME, tr("Reload"));
274 putValue(SHORT_DESCRIPTION, tr("Reload the current help page"));
275 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
276 }
277
278 public void actionPerformed(ActionEvent e) {
279 setUrl(url);
280 }
281 }
282
283 class BackAction extends AbstractAction implements Observer {
284 private HelpBrowserHistory history;
285 public BackAction(HelpBrowserHistory history) {
286 this.history = history;
287 history.addObserver(this);
288 //putValue(NAME, tr("Back"));
289 putValue(SHORT_DESCRIPTION, tr("Go to the previous page"));
290 putValue(SMALL_ICON, ImageProvider.get("help", "previous"));
291 setEnabled(history.canGoBack());
292 }
293
294 public void actionPerformed(ActionEvent e) {
295 history.back();
296 }
297 public void update(Observable o, Object arg) {
298 System.out.println("BackAction: canGoBoack=" + history.canGoBack() );
299 setEnabled(history.canGoBack());
300 }
301 }
302
303 class ForwardAction extends AbstractAction implements Observer {
304 private HelpBrowserHistory history;
305 public ForwardAction(HelpBrowserHistory history) {
306 this.history = history;
307 history.addObserver(this);
308 //putValue(NAME, tr("Forward"));
309 putValue(SHORT_DESCRIPTION, tr("Go to the next page"));
310 putValue(SMALL_ICON, ImageProvider.get("help", "next"));
311 setEnabled(history.canGoForward());
312 }
313
314 public void actionPerformed(ActionEvent e) {
315 history.forward();
316 }
317 public void update(Observable o, Object arg) {
318 setEnabled(history.canGoForward());
319 }
320 }
321
322 class HomeAction extends AbstractAction {
323 public HomeAction() {
324 //putValue(NAME, tr("Home"));
325 putValue(SHORT_DESCRIPTION, tr("Go to the JOSM help home page"));
326 putValue(SMALL_ICON, ImageProvider.get("help", "home"));
327 }
328
329 public void actionPerformed(ActionEvent e) {
330 setUrlForHelpTopic("Help");
331 }
332 }
333}
Note: See TracBrowser for help on using the repository browser.