49 ClassImp(TGHtmlBrowser);
 
   51 enum EMyMessageTypes {
 
   61 static const char *gHtmlFTypes[] = {
 
   62    "HTML files",    
"*.htm*",
 
   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> ",
 
   72 "<TABLE cellSpacing=0 cellPadding=0 width=730 border=0> ",
 
   75 "    <TD id=infoIconAlign vAlign=top align=left width=60 rowSpan=2> ",
 
   76 "    <IMG src=\"info.gif\"> ",
 
   78 "    <TD id=mainTitleAlign vAlign=center align=left width=*> ",
 
   79 "      <H1 id=mainTitle>RHTML cannot display the webpage</H1></TD></TR> ",
 
   81 "    <TD class=errorCodeAndDivider id=errorCodeAlign align=right>   ",
 
   82 "      <DIV class=divider></DIV></TD></TR> ",
 
   87 "    <TD id=MostLikelyAlign vAlign=top align=left> ",
 
   88 "      <H3 id=likelyCauses>Most likely causes:</H3> ",
 
   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> ",
 
   96 "    <TD id=infoBlockAlign vAlign=top align=right>  </TD> ",
 
   97 "    <TD id=moreInformationAlign vAlign=center align=left> ",
 
  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,  ",
 
  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.  ",
 
  115 "      <P></P></DIV></TD></TR></TBODY></TABLE></BODY></HTML> ",
 
  122 TGHtmlBrowser::TGHtmlBrowser(
const char *filename, 
const TGWindow *p, UInt_t w, UInt_t h)
 
  123              : TGMainFrame(p, w, h)
 
  125    SetCleanup(kDeepCleanup);
 
  127    fMenuBar = 
new TGMenuBar(
this, 35, 50, kHorizontalFrame);
 
  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);
 
  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);
 
  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);
 
  153    fMenuHelp = 
new TGPopupMenu(gClient->GetDefaultRoot());
 
  154    fMenuHelp->AddEntry(
" &About...", kM_HELP_ABOUT, 0, gClient->GetPicture(
"about.xpm"));
 
  155    fMenuHelp->Associate(
this);
 
  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));
 
  162    AddFrame(fMenuBar, 
new TGLayoutHints(kLHintsTop | kLHintsExpandX));
 
  165    fVerticalFrame = 
new TGVerticalFrame(
this,727,600,kVerticalFrame);
 
  167    fHorizontalFrame = 
new TGHorizontalFrame(fVerticalFrame,727,600);
 
  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()");
 
  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()");
 
  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()");
 
  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()");
 
  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\")");
 
  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()");
 
  208       fComboBox->AddEntry(filename, 1);
 
  209       fURL->SetText(filename);
 
  211    fComboBox->Select(0);
 
  212    fComboBox->Connect(
"Selected(char *)", 
"TGHtmlBrowser", 
this, 
"Selected(char *)");
 
  214    fHorizontalFrame->AddFrame(fComboBox, 
new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX,2,2,2,2));
 
  216    fVerticalFrame->AddFrame(fHorizontalFrame, 
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
 
  219    fHtml = 
new TGHtml(fVerticalFrame, 10, 10, -1);
 
  220    fVerticalFrame->AddFrame(fHtml, 
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
 
  222    AddFrame(fVerticalFrame, 
new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
 
  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));
 
  230    fHtml->Connect(
"MouseOver(const char *)", 
"TGHtmlBrowser", 
this, 
"MouseOver(const char *)");
 
  231    fHtml->Connect(
"MouseDown(const char *)", 
"TGHtmlBrowser", 
this, 
"MouseDown(const char *)");
 
  234    Resize(GetDefaultSize());
 
  245 Ssiz_t ReadSize(
const char *url)
 
  251    TString msg = 
"HEAD ";
 
  252    msg += fUrl.GetProtocol();
 
  254    msg += fUrl.GetHost();
 
  256    msg += fUrl.GetPort();
 
  258    msg += fUrl.GetFile();
 
  261    msg += 
"User-Agent: ROOT-TWebFile/1.1";
 
  266    if (!uri.BeginsWith(
"http://") && !uri.BeginsWith(
"https://"))
 
  268    if (uri.BeginsWith(
"https://")) {
 
  270       s = 
new TSSLSocket(fUrl.GetHost(), fUrl.GetPort());
 
  272       ::Error(
"ReadSize", 
"library compiled without SSL, https not supported");
 
  277       s = 
new TSocket(fUrl.GetHost(), fUrl.GetPort());
 
  283    if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
 
  287    if (s->RecvRaw(buf, 4096) == -1) {
 
  292    Ssiz_t idx = reply.Index(
"Content-length:", 0, TString::kIgnoreCase);
 
  295       TString slen = reply(idx, reply.Length() - idx);
 
  297       return (Ssiz_t)atol(slen.Data());
 
  306 static char *ReadRemote(
const char *url)
 
  308    static char *buf = 0;
 
  311    Ssiz_t size = ReadSize(url);
 
  312    if (size <= 0) size = 1024*1024;
 
  314    TString msg = 
"GET ";
 
  315    msg += fUrl.GetProtocol();
 
  317    msg += fUrl.GetHost();
 
  319    msg += fUrl.GetPort();
 
  321    msg += fUrl.GetFile();
 
  326    if (!uri.BeginsWith(
"http://") && !uri.BeginsWith(
"https://"))
 
  328    if (uri.BeginsWith(
"https://")) {
 
  330       s = 
new TSSLSocket(fUrl.GetHost(), fUrl.GetPort());
 
  332       ::Error(
"ReadRemote", 
"library compiled without SSL, https not supported");
 
  337       s = 
new TSocket(fUrl.GetHost(), fUrl.GetPort());
 
  343    if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
 
  347    buf = (
char *)calloc(size+1, 
sizeof(
char));
 
  348    if (s->RecvRaw(buf, size) == -1) {
 
  360 void TGHtmlBrowser::Selected(
const char *uri)
 
  365    if (CheckAnchors(uri))
 
  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://");
 
  374          surl.Prepend(
"file://");
 
  376    if (surl.EndsWith(
".root")) {
 
  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));
 
  385    gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kWatch));
 
  386    TUrl url(surl.Data());
 
  387    if (surl.EndsWith(
".pdf", TString::kIgnoreCase)) {
 
  390       if (!gVirtualX->InheritsFrom(
"TGX11")) {
 
  391          TString cmd = TString::Format(
"explorer %s", surl.Data());
 
  392          gSystem->Exec(cmd.Data());
 
  394       gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
 
  397    if (surl.EndsWith(
".gif") || surl.EndsWith(
".jpg") || surl.EndsWith(
".png")) {
 
  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);
 
  408       gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
 
  411    if (!strcmp(url.GetProtocol(), 
"http") ||
 
  412        !strcmp(url.GetProtocol(), 
"https")) {
 
  414       buf = ReadRemote(url.GetUrl());
 
  418          fHtml->SetBaseUri(url.GetUrl());
 
  419          fHtml->ParseText(buf);
 
  421          fURL->SetText(surl.Data());
 
  422          if (!fComboBox->FindEntry(surl.Data()))
 
  423             fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
 
  428          fHtml->SetBaseUri(
"");
 
  429          for (
int i=0; HtmlError[i]; i++) {
 
  430             fHtml->ParseText((
char *)HtmlError[i]);
 
  436       f = fopen(url.GetFile(), 
"r");
 
  438          TString fpath = url.GetUrl();
 
  439          fpath.ReplaceAll(gSystem->BaseName(fpath.Data()), 
"");
 
  440          fpath.ReplaceAll(
"file://", 
"");
 
  443          fHtml->SetBaseUri(fpath.Data());
 
  444          buf = (
char *)calloc(4096, 
sizeof(
char));
 
  446             while (fgets(buf, 4096, f)) {
 
  447                fHtml->ParseText(buf);
 
  452          fURL->SetText(surl.Data());
 
  453          if (!fComboBox->FindEntry(surl.Data()))
 
  454             fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
 
  459          fHtml->SetBaseUri(
"");
 
  460          for (
int i=0; HtmlError[i]; i++) {
 
  461             fHtml->ParseText((
char *)HtmlError[i]);
 
  466    gVirtualX->SetCursor(fHtml->GetId(), gVirtualX->CreateCursor(kPointer));
 
  468    Ssiz_t idx = surl.Last(
'#');
 
  471       TString anchor = surl(idx, surl.Length() - idx);
 
  472       fHtml->GotoAnchor(anchor.Data());
 
  474    SetWindowName(Form(
"%s - RHTML",surl.Data()));
 
  480 void TGHtmlBrowser::URLChanged()
 
  482    const char *
string = fURL->GetText();
 
  484       Selected(gSystem->UnixPathName(
string));
 
  491 void TGHtmlBrowser::Back()
 
  494    const char *
string = fURL->GetText();
 
  495    TGLBEntry * lbe1 = fComboBox->FindEntry(
string);
 
  497       index = lbe1->EntryId();
 
  499       fComboBox->Select(index - 1, kTRUE);
 
  500       TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
 
  502          string = entry->GetTitle();
 
  513 Bool_t TGHtmlBrowser::CheckAnchors(
const char *uri)
 
  515    TString surl(gSystem->UnixPathName(uri));
 
  517    if (!fHtml->GetBaseUri())
 
  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());
 
  525       short1 = surl(0, idx);
 
  527       short2 = actual(0, idy);
 
  529    if (short1 == short2) {
 
  532          TString anchor = surl(idx, surl.Length() - idx);
 
  533          fHtml->GotoAnchor(anchor.Data());
 
  536          fHtml->ScrollToPosition(TGLongPosition(0, 0));
 
  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()));
 
  552 void TGHtmlBrowser::Forward()
 
  555    const char *
string = fURL->GetText();
 
  556    TGLBEntry * lbe1 = fComboBox->FindEntry(
string);
 
  558       index = lbe1->EntryId();
 
  559    if (index < fComboBox->GetNumberOfEntries()) {
 
  560       fComboBox->Select(index + 1, kTRUE);
 
  561       TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
 
  563          string = entry->GetTitle();
 
  573 void TGHtmlBrowser::Reload()
 
  575    const char *
string = fURL->GetText();
 
  583 void TGHtmlBrowser::Stop()
 
  590 void TGHtmlBrowser::MouseOver(
const char *url)
 
  592    fStatusBar->SetText(url, 0);
 
  598 void TGHtmlBrowser::MouseDown(
const char *url)
 
  606 Bool_t TGHtmlBrowser::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
 
  608    switch (GET_MSG(msg)) {
 
  611          switch (GET_SUBMSG(msg)) {
 
  624                         static TString dir(
".");
 
  626                         fi.fFileTypes = gHtmlFTypes;
 
  627                         fi.fIniDir    = StrDup(dir);
 
  628                         new TGFileDialog(fClient->GetRoot(), 
this,
 
  632                            Selected(Form(
"file://%s",
 
  633                               gSystem->UnixPathName(fi.fFilename)));
 
  640                         static TString sdir(
".");
 
  642                         fi.fFileTypes = gHtmlFTypes;
 
  643                         fi.fIniDir    = StrDup(sdir);
 
  644                         new TGFileDialog(fClient->GetRoot(), 
this,
 
  648                            TGText txt(fHtml->GetText());
 
  649                            txt.Save(gSystem->UnixPathName(fi.fFilename));
 
  654                   case kM_FAVORITES_ADD:
 
  655                      fMenuFavorites->AddEntry(Form(
"%s",
 
  656                            fURL->GetText()), fNbFavorites++, 0,
 
  657                            gClient->GetPicture(
"htmlfile.gif"));
 
  660                   case kM_TOOLS_CLEARHIST:
 
  661                      fComboBox->RemoveEntries(1,fComboBox->GetNumberOfEntries());
 
  671                         TString rootx = TROOT::GetBinDir() + 
"/root -a &";
 
  672                         gSystem->Exec(rootx);
 
  675                         new TWin32SplashThread(kTRUE);
 
  678                         snprintf(str, 32, 
"About ROOT %s...", gROOT->GetVersion());
 
  679                         TRootHelpDialog *hd = 
new TRootHelpDialog(
this, str,
 
  681                         hd->SetText(gHelpAbout);
 
  690                         if (parm1 < 1000) 
break;
 
  691                         TGMenuEntry *entry = fMenuFavorites->GetEntry(parm1);
 
  693                         const char *shortcut = entry->GetName();