Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGHtmlBrowser.cxx
Go to the documentation of this file.
1 // @(#)root/guitml:$Id$
2 // Author: Bertrand Bellenot 26/09/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "TApplication.h"
14 #include "TSystem.h"
15 #include "TGMenu.h"
16 #include "TGComboBox.h"
17 #include "TGFrame.h"
18 #include "TGButton.h"
19 #include "TGTextBuffer.h"
20 #include "TGTextEntry.h"
21 #include "TGStatusBar.h"
22 #include "TGFileDialog.h"
23 #include "TFile.h"
24 #include "TBrowser.h"
25 #include "TGHtml.h"
26 #include "TString.h"
27 #include "TUrl.h"
28 #include "TSocket.h"
29 #include "Riostream.h"
30 #include "TGHtmlBrowser.h"
31 #include "TGText.h"
32 #include "TError.h"
33 #ifdef R__SSL
34 #include "TSSLSocket.h"
35 #endif
36 #ifdef WIN32
37 #include "TWin32SplashThread.h"
38 #endif
39 
40 #include <stdlib.h>
41 
42 //_____________________________________________________________________________
43 //
44 // TGHtmlBrowser
45 //
46 // A very simple HTML browser.
47 //_____________________________________________________________________________
48 
49 ClassImp(TGHtmlBrowser);
50 
51 enum EMyMessageTypes {
52  kM_FILE_OPEN,
53  kM_FILE_SAVEAS,
54  kM_FILE_BROWSE,
55  kM_FILE_EXIT,
56  kM_FAVORITES_ADD,
57  kM_TOOLS_CLEARHIST,
58  kM_HELP_ABOUT
59 };
60 
61 static const char *gHtmlFTypes[] = {
62  "HTML files", "*.htm*",
63  "All files", "*",
64  0, 0
65 };
66 
67 const char *HtmlError[] = {
68 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
69 "<HTML><HEAD><TITLE>RHTML cannot display the webpage</TITLE> ",
70 "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
71 "<BODY> ",
72 "<TABLE cellSpacing=0 cellPadding=0 width=730 border=0> ",
73 " <TBODY> ",
74 " <TR> ",
75 " <TD id=infoIconAlign vAlign=top align=left width=60 rowSpan=2> ",
76 " <IMG src=\"info.gif\"> ",
77 " </TD> ",
78 " <TD id=mainTitleAlign vAlign=center align=left width=*> ",
79 " <H1 id=mainTitle>RHTML cannot display the webpage</H1></TD></TR> ",
80 " <TR> ",
81 " <TD class=errorCodeAndDivider id=errorCodeAlign align=right>&nbsp; ",
82 " <DIV class=divider></DIV></TD></TR> ",
83 " <TR> ",
84 " <UL> ",
85 " </UL> ",
86 " <TD>&nbsp; </TD> ",
87 " <TD id=MostLikelyAlign vAlign=top align=left> ",
88 " <H3 id=likelyCauses>Most likely causes:</H3> ",
89 " <UL> ",
90 " <LI id=causeNotConnected>You are not connected to the Internet. ",
91 " <LI id=causeSiteProblem>The website is encountering problems. ",
92 " <LI id=causeErrorInAddress>There might be a typing error in the address. ",
93 " <LI id=causeOtherError> ",
94 " </LI></UL></TD></TR> ",
95 " <TR> ",
96 " <TD id=infoBlockAlign vAlign=top align=right>&nbsp; </TD> ",
97 " <TD id=moreInformationAlign vAlign=center align=left> ",
98 " <H4> ",
99 " <TABLE> ",
100 " <TBODY> ",
101 " <TR> ",
102 " <TD vAlign=top><SPAN id=moreInfoContainer></SPAN><ID ",
103 " id=moreInformation>More information</ID> ",
104 " </TD></TR></TBODY></TABLE></H4> ",
105 " <DIV class=infoBlock id=infoBlockID> ",
106 " <P><ID id=errorExpl1>This problem can be caused by a variety of issues, ",
107 " including:</ID> ",
108 " <UL> ",
109 " <LI id=errorExpl2>Internet connectivity has been lost. ",
110 " <LI id=errorExpl3>The website is temporarily unavailable. ",
111 " <LI id=errorExpl4>The Domain Name Server (DNS) is not reachable. ",
112 " <LI id=errorExpl5>The Domain Name Server (DNS) does not have a listing ",
113 " for the website's domain. ",
114 " <P></P> ",
115 " <P></P></DIV></TD></TR></TBODY></TABLE></BODY></HTML> ",
116 0
117 };
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// TGHtmlBrowser constructor.
121 
122 TGHtmlBrowser::TGHtmlBrowser(const char *filename, const TGWindow *p, UInt_t w, UInt_t h)
123  : TGMainFrame(p, w, h)
124 {
125  SetCleanup(kDeepCleanup);
126  fNbFavorites = 1000;
127  fMenuBar = new TGMenuBar(this, 35, 50, kHorizontalFrame);
128 
129  fMenuFile = new TGPopupMenu(gClient->GetDefaultRoot());
130  fMenuFile->AddEntry(" &Open...\tCtrl+O", kM_FILE_OPEN, 0,
131  gClient->GetPicture("ed_open.png"));
132  fMenuFile->AddEntry(" Save &As...\tCtrl+A", kM_FILE_SAVEAS, 0,
133  gClient->GetPicture("ed_save.png"));
134  fMenuFile->AddEntry(" &Browse...\tCtrl+B", kM_FILE_BROWSE);
135  fMenuFile->AddSeparator();
136  fMenuFile->AddEntry(" E&xit\tCtrl+Q", kM_FILE_EXIT, 0,
137  gClient->GetPicture("bld_exit.png"));
138  fMenuFile->Associate(this);
139 
140  fMenuFavorites = new TGPopupMenu(gClient->GetDefaultRoot());
141  fMenuFavorites->AddEntry("&Add to Favorites", kM_FAVORITES_ADD, 0,
142  gClient->GetPicture("bld_plus.png"));
143  fMenuFavorites->AddSeparator();
144  fMenuFavorites->AddEntry("http://root.cern.ch", fNbFavorites++, 0,
145  gClient->GetPicture("htmlfile.gif"));
146  fMenuFavorites->Associate(this);
147 
148  fMenuTools = new TGPopupMenu(gClient->GetDefaultRoot());
149  fMenuTools->AddEntry("&Clear History", kM_TOOLS_CLEARHIST, 0,
150  gClient->GetPicture("ed_delete.png"));
151  fMenuTools->Associate(this);
152 
153  fMenuHelp = new TGPopupMenu(gClient->GetDefaultRoot());
154  fMenuHelp->AddEntry(" &About...", kM_HELP_ABOUT, 0, gClient->GetPicture("about.xpm"));
155  fMenuHelp->Associate(this);
156 
157  fMenuBar->AddPopup("&File", fMenuFile, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
158  fMenuBar->AddPopup("&Favorites", fMenuFavorites, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
159  fMenuBar->AddPopup("&Tools", fMenuTools, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
160  fMenuBar->AddPopup("&Help", fMenuHelp, new TGLayoutHints(kLHintsTop | kLHintsRight));
161 
162  AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
163 
164  // vertical frame
165  fVerticalFrame = new TGVerticalFrame(this,727,600,kVerticalFrame);
166 
167  fHorizontalFrame = new TGHorizontalFrame(fVerticalFrame,727,600);
168 
169  fBack = new TGPictureButton(fHorizontalFrame,gClient->GetPicture("GoBack.gif"));
170  fBack->SetStyle(gClient->GetStyle());
171  fBack->SetToolTipText("Go Back");
172  fHorizontalFrame->AddFrame(fBack, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
173  fBack->Connect("Clicked()", "TGHtmlBrowser", this, "Back()");
174 
175  fForward = new TGPictureButton(fHorizontalFrame,gClient->GetPicture("GoForward.gif"));
176  fForward->SetStyle(gClient->GetStyle());
177  fForward->SetToolTipText("Go Forward");
178  fHorizontalFrame->AddFrame(fForward, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
179  fForward->Connect("Clicked()", "TGHtmlBrowser", this, "Forward()");
180 
181  fReload = new TGPictureButton(fHorizontalFrame,gClient->GetPicture("ReloadPage.gif"));
182  fReload->SetStyle(gClient->GetStyle());
183  fReload->SetToolTipText("Reload Page");
184  fHorizontalFrame->AddFrame(fReload, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
185  fReload->Connect("Clicked()", "TGHtmlBrowser", this, "Reload()");
186 
187  fStop = new TGPictureButton(fHorizontalFrame,gClient->GetPicture("StopLoading.gif"));
188  fStop->SetStyle(gClient->GetStyle());
189  fStop->SetToolTipText("Stop Loading");
190  fHorizontalFrame->AddFrame(fStop, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
191  fStop->Connect("Clicked()", "TGHtmlBrowser", this, "Stop()");
192 
193  fHome = new TGPictureButton(fHorizontalFrame,gClient->GetPicture("GoHome.gif"));
194  fHome->SetStyle(gClient->GetStyle());
195  fHome->SetToolTipText("Go to ROOT HomePage\n (http://root.cern.ch)");
196  fHorizontalFrame->AddFrame(fHome, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
197  fHome->Connect("Clicked()", "TGHtmlBrowser", this, "Selected(=\"http://root.cern.ch\")");
198 
199  // combo box
200  fURLBuf = new TGTextBuffer(256);
201  fComboBox = new TGComboBox(fHorizontalFrame, "");
202  fURL = fComboBox->GetTextEntry();
203  fURLBuf = fURL->GetBuffer();
204  fComboBox->Resize(200, fURL->GetDefaultHeight());
205  fURL->Connect("ReturnPressed()", "TGHtmlBrowser", this, "URLChanged()");
206 
207  if (filename) {
208  fComboBox->AddEntry(filename, 1);
209  fURL->SetText(filename);
210  }
211  fComboBox->Select(0);
212  fComboBox->Connect("Selected(char *)", "TGHtmlBrowser", this, "Selected(char *)");
213 
214  fHorizontalFrame->AddFrame(fComboBox, new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX,2,2,2,2));
215 
216  fVerticalFrame->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
217 
218  // embedded canvas
219  fHtml = new TGHtml(fVerticalFrame, 10, 10, -1);
220  fVerticalFrame->AddFrame(fHtml, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
221 
222  AddFrame(fVerticalFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
223 
224  // status bar
225  fStatusBar = new TGStatusBar(this,100,20);
226  Int_t partsusBar[] = {75,25};
227  fStatusBar->SetParts(partsusBar,2);
228  AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX));
229 
230  fHtml->Connect("MouseOver(const char *)", "TGHtmlBrowser", this, "MouseOver(const char *)");
231  fHtml->Connect("MouseDown(const char *)", "TGHtmlBrowser", this, "MouseDown(const char *)");
232 
233  MapSubwindows();
234  Resize(GetDefaultSize());
235  MapWindow();
236  Resize(w, h);
237 
238  if (filename)
239  Selected(filename);
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Read (open) remote files.
244 
245 Ssiz_t ReadSize(const char *url)
246 {
247  char buf[4096];
248  TUrl fUrl(url);
249 
250  // Give full URL so Apache's virtual hosts solution works.
251  TString msg = "HEAD ";
252  msg += fUrl.GetProtocol();
253  msg += "://";
254  msg += fUrl.GetHost();
255  msg += ":";
256  msg += fUrl.GetPort();
257  msg += "/";
258  msg += fUrl.GetFile();
259  msg += " HTTP/1.0";
260  msg += "\r\n";
261  msg += "User-Agent: ROOT-TWebFile/1.1";
262  msg += "\r\n\r\n";
263 
264  TSocket *s;
265  TString uri(url);
266  if (!uri.BeginsWith("http://") && !uri.BeginsWith("https://"))
267  return 0;
268  if (uri.BeginsWith("https://")) {
269 #ifdef R__SSL
270  s = new TSSLSocket(fUrl.GetHost(), fUrl.GetPort());
271 #else
272  ::Error("ReadSize", "library compiled without SSL, https not supported");
273  return 0;
274 #endif
275  }
276  else {
277  s = new TSocket(fUrl.GetHost(), fUrl.GetPort());
278  }
279  if (!s->IsValid()) {
280  delete s;
281  return 0;
282  }
283  if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
284  delete s;
285  return 0;
286  }
287  if (s->RecvRaw(buf, 4096) == -1) {
288  delete s;
289  return 0;
290  }
291  TString reply(buf);
292  Ssiz_t idx = reply.Index("Content-length:", 0, TString::kIgnoreCase);
293  if (idx > 0) {
294  idx += 15;
295  TString slen = reply(idx, reply.Length() - idx);
296  delete s;
297  return (Ssiz_t)atol(slen.Data());
298  }
299  delete s;
300  return 0;
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Read (open) remote files.
305 
306 static char *ReadRemote(const char *url)
307 {
308  static char *buf = 0;
309  TUrl fUrl(url);
310 
311  Ssiz_t size = ReadSize(url);
312  if (size <= 0) size = 1024*1024;
313 
314  TString msg = "GET ";
315  msg += fUrl.GetProtocol();
316  msg += "://";
317  msg += fUrl.GetHost();
318  msg += ":";
319  msg += fUrl.GetPort();
320  msg += "/";
321  msg += fUrl.GetFile();
322  msg += "\r\n";
323 
324  TSocket *s;
325  TString uri(url);
326  if (!uri.BeginsWith("http://") && !uri.BeginsWith("https://"))
327  return 0;
328  if (uri.BeginsWith("https://")) {
329 #ifdef R__SSL
330  s = new TSSLSocket(fUrl.GetHost(), fUrl.GetPort());
331 #else
332  ::Error("ReadRemote", "library compiled without SSL, https not supported");
333  return 0;
334 #endif
335  }
336  else {
337  s = new TSocket(fUrl.GetHost(), fUrl.GetPort());
338  }
339  if (!s->IsValid()) {
340  delete s;
341  return 0;
342  }
343  if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
344  delete s;
345  return 0;
346  }
347  buf = (char *)calloc(size+1, sizeof(char));
348  if (s->RecvRaw(buf, size) == -1) {
349  free(buf);
350  delete s;
351  return 0;
352  }
353  delete s;
354  return buf;
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Open (browse) selected URL.
359 
360 void TGHtmlBrowser::Selected(const char *uri)
361 {
362  char *buf = 0;
363  FILE *f;
364 
365  if (CheckAnchors(uri))
366  return;
367 
368  TString surl(gSystem->UnixPathName(uri));
369  if (!surl.BeginsWith("http://") && !surl.BeginsWith("https://") &&
370  !surl.BeginsWith("ftp://") && !surl.BeginsWith("file://")) {
371  if (surl.BeginsWith("file:"))
372  surl.ReplaceAll("file:", "file://");
373  else
374  surl.Prepend("file://");
375  }
376  if (surl.EndsWith(".root")) {
377  // in case of root file, just open it and refresh browsers
378  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kWatch));
379  gROOT->ProcessLine(Form("TFile::Open(\"%s\");", surl.Data()));
380  Clicked((char *)surl.Data());
381  gROOT->RefreshBrowsers();
382  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
383  return;
384  }
385  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kWatch));
386  TUrl url(surl.Data());
387  if (surl.EndsWith(".pdf", TString::kIgnoreCase)) {
388  // special case: open pdf files with external viewer
389  // works only on Windows for the time being...
390  if (!gVirtualX->InheritsFrom("TGX11")) {
391  TString cmd = TString::Format("explorer %s", surl.Data());
392  gSystem->Exec(cmd.Data());
393  }
394  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
395  return;
396  }
397  if (surl.EndsWith(".gif") || surl.EndsWith(".jpg") || surl.EndsWith(".png")) {
398  // special case: single picture
399  fHtml->Clear();
400  char imgHtml[1024];
401  snprintf(imgHtml, 1000, "<IMG src=\"%s\"> ", surl.Data());
402  fHtml->ParseText(imgHtml);
403  fHtml->SetBaseUri(url.GetUrl());
404  fURL->SetText(surl.Data());
405  if (!fComboBox->FindEntry(surl.Data()))
406  fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
407  fHtml->Layout();
408  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
409  return;
410  }
411  if (!strcmp(url.GetProtocol(), "http") ||
412  !strcmp(url.GetProtocol(), "https")) {
413  // standard web page
414  buf = ReadRemote(url.GetUrl());
415  if (buf) {
416  fHtml->Clear();
417  fHtml->Layout();
418  fHtml->SetBaseUri(url.GetUrl());
419  fHtml->ParseText(buf);
420  free(buf);
421  fURL->SetText(surl.Data());
422  if (!fComboBox->FindEntry(surl.Data()))
423  fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
424  }
425  else {
426  fHtml->Clear();
427  fHtml->Layout();
428  fHtml->SetBaseUri("");
429  for (int i=0; HtmlError[i]; i++) {
430  fHtml->ParseText((char *)HtmlError[i]);
431  }
432  }
433  }
434  else {
435  // local file
436  f = fopen(url.GetFile(), "r");
437  if (f) {
438  TString fpath = url.GetUrl();
439  fpath.ReplaceAll(gSystem->BaseName(fpath.Data()), "");
440  fpath.ReplaceAll("file://", "");
441  fHtml->Clear();
442  fHtml->Layout();
443  fHtml->SetBaseUri(fpath.Data());
444  buf = (char *)calloc(4096, sizeof(char));
445  if (buf) {
446  while (fgets(buf, 4096, f)) {
447  fHtml->ParseText(buf);
448  }
449  free(buf);
450  }
451  fclose(f);
452  fURL->SetText(surl.Data());
453  if (!fComboBox->FindEntry(surl.Data()))
454  fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
455  }
456  else {
457  fHtml->Clear();
458  fHtml->Layout();
459  fHtml->SetBaseUri("");
460  for (int i=0; HtmlError[i]; i++) {
461  fHtml->ParseText((char *)HtmlError[i]);
462  }
463  }
464  }
465  // restore cursor
466  gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
467  fHtml->Layout();
468  Ssiz_t idx = surl.Last('#');
469  if (idx > 0) {
470  idx +=1; // skip #
471  TString anchor = surl(idx, surl.Length() - idx);
472  fHtml->GotoAnchor(anchor.Data());
473  }
474  SetWindowName(Form("%s - RHTML",surl.Data()));
475 }
476 
477 ////////////////////////////////////////////////////////////////////////////////
478 /// URL combobox has changed.
479 
480 void TGHtmlBrowser::URLChanged()
481 {
482  const char *string = fURL->GetText();
483  if (string) {
484  Selected(gSystem->UnixPathName(string));
485  }
486 }
487 
488 ////////////////////////////////////////////////////////////////////////////////
489 /// Handle "Back" navigation button.
490 
491 void TGHtmlBrowser::Back()
492 {
493  Int_t index = 0;
494  const char *string = fURL->GetText();
495  TGLBEntry * lbe1 = fComboBox->FindEntry(string);
496  if (lbe1)
497  index = lbe1->EntryId();
498  if (index > 0) {
499  fComboBox->Select(index - 1, kTRUE);
500  TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
501  if (entry) {
502  string = entry->GetTitle();
503  if (string)
504  Selected(string);
505  }
506  }
507 }
508 
509 ////////////////////////////////////////////////////////////////////////////////
510 /// Check if we just change position in the page (using anchor)
511 /// and return kTRUE if any anchor has been found and followed.
512 
513 Bool_t TGHtmlBrowser::CheckAnchors(const char *uri)
514 {
515  TString surl(gSystem->UnixPathName(uri));
516 
517  if (!fHtml->GetBaseUri())
518  return kFALSE;
519  TString actual = fHtml->GetBaseUri();
520  Ssiz_t idx = surl.Last('#');
521  Ssiz_t idy = actual.Last('#');
522  TString short1(surl.Data());
523  TString short2(actual.Data());
524  if (idx > 0)
525  short1 = surl(0, idx);
526  if (idy > 0)
527  short2 = actual(0, idy);
528 
529  if (short1 == short2) {
530  if (idx > 0) {
531  idx +=1; // skip #
532  TString anchor = surl(idx, surl.Length() - idx);
533  fHtml->GotoAnchor(anchor.Data());
534  }
535  else {
536  fHtml->ScrollToPosition(TGLongPosition(0, 0));
537  }
538  fHtml->SetBaseUri(surl.Data());
539  if (!fComboBox->FindEntry(surl.Data()))
540  fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
541  fURL->SetText(surl.Data());
542  fComboBox->Select(fComboBox->GetNumberOfEntries(), kFALSE);
543  SetWindowName(Form("%s - RHTML",surl.Data()));
544  return kTRUE;
545  }
546  return kFALSE;
547 }
548 
549 ////////////////////////////////////////////////////////////////////////////////
550 /// Handle "Forward" navigation button.
551 
552 void TGHtmlBrowser::Forward()
553 {
554  Int_t index = 0;
555  const char *string = fURL->GetText();
556  TGLBEntry * lbe1 = fComboBox->FindEntry(string);
557  if (lbe1)
558  index = lbe1->EntryId();
559  if (index < fComboBox->GetNumberOfEntries()) {
560  fComboBox->Select(index + 1, kTRUE);
561  TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
562  if (entry) {
563  string = entry->GetTitle();
564  if (string)
565  Selected(string);
566  }
567  }
568 }
569 
570 ////////////////////////////////////////////////////////////////////////////////
571 /// Handle "Reload" navigation button.
572 
573 void TGHtmlBrowser::Reload()
574 {
575  const char *string = fURL->GetText();
576  if (string)
577  Selected(string);
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// Handle "Reload" navigation button.
582 
583 void TGHtmlBrowser::Stop()
584 {
585 }
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Handle "MouseOver" TGHtml signal.
589 
590 void TGHtmlBrowser::MouseOver(const char *url)
591 {
592  fStatusBar->SetText(url, 0);
593 }
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 /// Handle "MouseDown" TGHtml signal.
597 
598 void TGHtmlBrowser::MouseDown(const char *url)
599 {
600  Selected(url);
601 }
602 
603 ////////////////////////////////////////////////////////////////////////////////
604 /// Process Events.
605 
606 Bool_t TGHtmlBrowser::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
607 {
608  switch (GET_MSG(msg)) {
609  case kC_COMMAND:
610  {
611  switch (GET_SUBMSG(msg)) {
612 
613  case kCM_MENU:
614  case kCM_BUTTON:
615 
616  switch(parm1) {
617 
618  case kM_FILE_EXIT:
619  CloseWindow();
620  break;
621 
622  case kM_FILE_OPEN:
623  {
624  static TString dir(".");
625  TGFileInfo fi;
626  fi.fFileTypes = gHtmlFTypes;
627  fi.fIniDir = StrDup(dir);
628  new TGFileDialog(fClient->GetRoot(), this,
629  kFDOpen, &fi);
630  dir = fi.fIniDir;
631  if (fi.fFilename) {
632  Selected(Form("file://%s",
633  gSystem->UnixPathName(fi.fFilename)));
634  }
635  }
636  break;
637 
638  case kM_FILE_SAVEAS:
639  {
640  static TString sdir(".");
641  TGFileInfo fi;
642  fi.fFileTypes = gHtmlFTypes;
643  fi.fIniDir = StrDup(sdir);
644  new TGFileDialog(fClient->GetRoot(), this,
645  kFDSave, &fi);
646  sdir = fi.fIniDir;
647  if (fi.fFilename) {
648  TGText txt(fHtml->GetText());
649  txt.Save(gSystem->UnixPathName(fi.fFilename));
650  }
651  }
652  break;
653 
654  case kM_FAVORITES_ADD:
655  fMenuFavorites->AddEntry(Form("%s",
656  fURL->GetText()), fNbFavorites++, 0,
657  gClient->GetPicture("htmlfile.gif"));
658  break;
659 
660  case kM_TOOLS_CLEARHIST:
661  fComboBox->RemoveEntries(1,fComboBox->GetNumberOfEntries());
662  break;
663 
664  case kM_FILE_BROWSE:
665  new TBrowser();
666  break;
667 
668  case kM_HELP_ABOUT:
669  {
670 #ifdef R__UNIX
671  TString rootx = TROOT::GetBinDir() + "/root -a &";
672  gSystem->Exec(rootx);
673 #else
674 #ifdef WIN32
675  new TWin32SplashThread(kTRUE);
676 #else
677  char str[32];
678  snprintf(str, 32, "About ROOT %s...", gROOT->GetVersion());
679  TRootHelpDialog *hd = new TRootHelpDialog(this, str,
680  600, 400);
681  hd->SetText(gHelpAbout);
682  hd->Popup();
683 #endif
684 #endif
685  }
686  break;
687 
688  default:
689  {
690  if (parm1 < 1000) break;
691  TGMenuEntry *entry = fMenuFavorites->GetEntry(parm1);
692  if (!entry) break;
693  const char *shortcut = entry->GetName();
694  if (shortcut)
695  Selected(shortcut);
696  }
697  break;
698  }
699  break;
700  }
701  break;
702  }
703  }
704  return kTRUE;
705 }
706