CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Fireworks/Core/src/CmsShowSearchFiles.cc

Go to the documentation of this file.
00001 #include <stdexcept>
00002 #include <iostream>
00003 #include <stdlib.h>
00004 #include <set>
00005 #include "TGClient.h"
00006 #include "TGHtml.h"
00007 #include "TGButton.h"
00008 #include "TGMenu.h"
00009 #include "TGLabel.h"
00010 #include "TGTextEntry.h"
00011 #include "TPluginManager.h"
00012 #include "TUrl.h"
00013 #include "TSocket.h"
00014 #include "TVirtualX.h"
00015 #include "Fireworks/Core/interface/CmsShowSearchFiles.h"
00016 
00017 
00018 class FWHtml : public TGHtml {
00019 public:
00020    FWHtml(const TGWindow* p, int w, int h, int id = -1):
00021    TGHtml(p,w,h,id) {}
00022    
00023    int  IsVisited(const char* iCheck) {
00024       std::string check(GetBaseUri());
00025       check +=iCheck;
00026       int value = m_visited.find(check)==m_visited.end()?kFALSE:kTRUE;
00027       return value;
00028    }
00029    void addToVisited(const char* iToVisit) {
00030       m_visited.insert(iToVisit);
00031    }
00032 private:
00033    std::set<std::string> m_visited;
00034 };
00035 
00036 static const unsigned int s_columns = 3;
00037 static const char* const s_prefixes[][s_columns] ={ 
00038   {"http://fireworks.web.cern.ch/fireworks/","Pre-selected example files at CERN","t"},
00039   {"http://uaf-2.t2.ucsd.edu/fireworks/","Pre-selected example files in USA","t"},
00040   {"http://", "Web site known by you",0},
00041   {"file:","Local file [you must type full path name]",0},
00042   {"dcap://","dCache [FNAL]",0},
00043   {"rfio://","Castor [CERN]",0}
00044   
00045 };
00046 
00047 static const std::string s_httpPrefix("http:");
00048 static const std::string s_filePrefix("file:");
00049 static const std::string s_rootPostfix(".root");
00050 
00051 
00052 static const char *s_noBrowserMessage[] = {
00053    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00054    "<HTML><HEAD><TITLE>No Browser Available</TITLE> ",
00055    "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00056    "<BODY> ",
00057    //"No file browser is available for this prefix.  You can still type the full URL into the above text box to open the EDM ROOT file.<BR>",
00058    //"Only a prefix beginning in <STRONG>http:</STRONG> which contains a site name (e.g. http://www.site.org) is supported for browsing."
00059    "<b>Welcome....</b><BR>",
00060    "<BR>",
00061    "<b>You may look at examples:</b><BR>",
00062    "If you are in Europe, open example data files at CERN: <a href=http://fireworks.web.cern.ch/fireworks/>http://fireworks.web.cern.ch/fireworks/</a><BR>",
00063    "If you are in US, open example data files at UCSD: <a href=http://uaf-2.t2.ucsd.edu/fireworks/>http://uaf-2.t2.ucsd.edu/fireworks/</a><BR>",
00064    "<BR>"
00065    "<b>You also may load files with Choose Prefix </b><BR>"
00066    "</BODY></HTML> ",
00067    0
00068 };
00069 
00070 static const char *s_readError[] = {
00071    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00072    "<HTML><HEAD><TITLE>HTTP Read Error</TITLE> ",
00073    "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00074    "<BODY> ",
00075    "<P>Unknown error while trying to get file via http</P>",
00076    "</BODY></HTML> ",
00077    0
00078 };
00079 
00080 
00081 CmsShowSearchFiles::CmsShowSearchFiles (const char *filename,
00082                                     const char* windowname,
00083                                     const TGWindow* p, UInt_t w, UInt_t h)
00084    : TGTransientFrame(gClient->GetDefaultRoot(), p, w, h)
00085 {
00086    TGVerticalFrame* vf = new TGVerticalFrame(this);
00087    this->AddFrame(vf,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5));
00088    TGHorizontalFrame* urlFrame = new TGHorizontalFrame(this);
00089    vf->AddFrame(urlFrame,new TGLayoutHints(kLHintsExpandX,5,0,5,5));
00090    
00091    TGLabel* urlLabel = new TGLabel(urlFrame,"URL");
00092    urlFrame->AddFrame(urlLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,1,1,1,1));
00093    m_choosePrefix = new TGTextButton(urlFrame,"Choose Prefix");
00094    urlFrame->AddFrame(m_choosePrefix, new TGLayoutHints(kLHintsLeft,1,1,1,1));
00095    
00096    m_file= new TGTextEntry(urlFrame);
00097    urlFrame->AddFrame(m_file, new TGLayoutHints(kLHintsExpandX,1,0,1,1));
00098    m_file->Connect("TextChanged(const char*)", "CmsShowSearchFiles",this,"fileEntryChanged(const char*)");
00099    m_file->Connect("ReturnPressed()", "CmsShowSearchFiles",this,"updateBrowser()");
00100    
00101    m_webFile = new FWHtml(vf,1,1);
00102    m_webFile->Connect("MouseDown(const char*)","CmsShowSearchFiles",this,"hyperlinkClicked(const char*)");
00103    vf->AddFrame(m_webFile, new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,1,1,1,1));
00104    
00105    TGHorizontalFrame* buttonFrame = new TGHorizontalFrame(vf);
00106    vf->AddFrame(buttonFrame, new TGLayoutHints(kLHintsExpandX,1,10,1,10));
00107    
00108    m_openButton = new TGTextButton(buttonFrame,"Open");
00109    buttonFrame->AddFrame(m_openButton, new TGLayoutHints(kLHintsRight,5,5,1,1));
00110    m_openButton->SetEnabled(kFALSE);
00111    m_openButton->Connect("Clicked()","CmsShowSearchFiles",this,"openClicked()");
00112 
00113    TGTextButton* cancel = new TGTextButton(buttonFrame,"Cancel");
00114    buttonFrame->AddFrame(cancel, new TGLayoutHints(kLHintsRight,5,5,1,1));
00115    cancel->Connect("Clicked()","CmsShowSearchFiles",this,"UnmapWindow()");
00116 
00117    SetWindowName(windowname);
00118    sendToWebBrowser("");
00119    MapSubwindows();
00120    Layout();
00121    m_prefixMenu=0;
00122    m_choosePrefix->Connect("Clicked()","CmsShowSearchFiles",this,"showPrefixes()");
00123 }
00124 
00125 CmsShowSearchFiles::~CmsShowSearchFiles()
00126 {
00127    delete m_prefixMenu;
00128 }
00129 
00130 void 
00131 CmsShowSearchFiles::prefixChoosen(Int_t iIndex)
00132 {
00133    m_file->SetText(m_prefixes[iIndex].c_str(),kFALSE);
00134    m_openButton->SetEnabled(kFALSE);
00135 
00136    if(m_prefixComplete[iIndex]) {
00137       //gClient->NeedRedraw(this);
00138       gClient->NeedRedraw(m_choosePrefix);
00139       gClient->NeedRedraw(m_webFile);
00140       gClient->ProcessEventsFor(this);
00141       updateBrowser();
00142    } else {
00143       sendToWebBrowser("");
00144    }
00145 }
00146 
00147 void 
00148 CmsShowSearchFiles::fileEntryChanged(const char* iFileName)
00149 {
00150    std::string fileName =iFileName;
00151    size_t index = fileName.find_last_of(".");
00152    std::string postfix;
00153    if(index != std::string::npos) {
00154       postfix=fileName.substr(index,std::string::npos);
00155    }
00156    if(postfix ==s_rootPostfix) {
00157       m_openButton->SetEnabled(kTRUE);
00158    } else {
00159       m_openButton->SetEnabled(kFALSE);
00160    }
00161 }
00162 
00163 void 
00164 CmsShowSearchFiles::updateBrowser()
00165 {
00166    sendToWebBrowser(m_file->GetText());
00167 }
00168 
00169 
00170 void 
00171 CmsShowSearchFiles::hyperlinkClicked(const char* iLink)
00172 {
00173    m_file->SetText(iLink,kTRUE);
00174    
00175    m_webFile->addToVisited(iLink);
00176    std::string fileName =iLink;
00177    size_t index = fileName.find_last_of(".");
00178    std::string postfix = fileName.substr(index,std::string::npos);
00179    
00180    if(postfix !=s_rootPostfix) {
00181       updateBrowser();
00182    } else {
00183       openClicked();
00184    }
00185 }
00186 
00187 void 
00188 CmsShowSearchFiles::openClicked()
00189 {
00190    m_openCalled=true;
00191    this->UnmapWindow();
00192 }
00193 
00194 
00195 void 
00196 CmsShowSearchFiles::showPrefixes()
00197 {
00198    if(0==m_prefixMenu) {
00199       m_prefixMenu = new TGPopupMenu(this);
00200       const char* const (*itEnd)[s_columns] = s_prefixes+sizeof(s_prefixes)/sizeof(const char*[3]);
00201       int index = 0;
00202       for(const char* const (*it)[s_columns] = s_prefixes;
00203           it != itEnd;
00204           ++it,++index) {
00205          //only add the protocols this version of the code actually can load
00206          std::string prefix = std::string((*it)[0]).substr(0,std::string((*it)[0]).find_first_of(":")+1);
00207          if(s_httpPrefix==prefix ||
00208             s_filePrefix==prefix ||
00209             (gPluginMgr->FindHandler("TSystem",prefix.c_str()) && 
00210              gPluginMgr->FindHandler("TSystem",prefix.c_str())->CheckPlugin() != -1)) {
00211                m_prefixMenu->AddEntry((std::string((*it)[0])+" ("+((*it)[1])+")").c_str(),index);
00212                m_prefixes.push_back((*it)[0]);
00213                m_prefixComplete.push_back(0!=(*it)[2]);
00214          }
00215       }
00216       m_prefixMenu->Connect("Activated(Int_t)","CmsShowSearchFiles",this,"prefixChoosen(Int_t)");
00217    }
00218    m_prefixMenu->PlaceMenu(m_choosePrefix->GetX(),m_choosePrefix->GetY(),true,true);
00219 }
00220 
00221 //Copied from TGHtmlBrowser
00222 static std::string readRemote(const char *url)
00223 {
00224    // Read (open) remote files.
00225    
00226    char *buf = 0;
00227    TUrl fUrl(url);
00228    
00229    TString msg = "GET ";
00230    msg += fUrl.GetProtocol();
00231    msg += "://";
00232    msg += fUrl.GetHost();
00233    msg += ":";
00234    msg += fUrl.GetPort();
00235    msg += "/";
00236    msg += fUrl.GetFile();
00237    msg += "\r\n";
00238    
00239    TString uri(url);
00240    if (!uri.BeginsWith("http://"))
00241       return std::string();
00242    TSocket s(fUrl.GetHost(), fUrl.GetPort());
00243    if (!s.IsValid())
00244       return std::string();
00245    if (s.SendRaw(msg.Data(), msg.Length()) == -1)
00246       return std::string();
00247    Int_t size = 1024*1024;
00248    buf = (char *)calloc(size, sizeof(char));
00249    if (s.RecvRaw(buf, size) == -1) {
00250       free(buf);
00251       return std::string();
00252    }
00253    std::string returnValue(buf);
00254    free(buf);
00255    return returnValue;
00256 }
00257 
00258 
00259 void 
00260 CmsShowSearchFiles::sendToWebBrowser(const char* iWebFile)
00261 {
00262    const std::string fileName(iWebFile);
00263    size_t index = fileName.find_first_of(":");
00264    if(index != std::string::npos) {
00265       ++index;
00266    } else {
00267       index = 0;
00268    }
00269    std::string prefix = fileName.substr(0,index);
00270 
00271    m_webFile->Clear();
00272    if(prefix == s_httpPrefix) {
00273       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kWatch));
00274       //If you clicked a hyperlink then the cursor is still a hand but we now
00275       // want it to be a watch
00276       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kWatch));
00277       //If we don't call ProcessEventsFor then the cursor will not be updated
00278       gClient->ProcessEventsFor(this);
00279       TUrl url(iWebFile);
00280       std::string buffer = readRemote(url.GetUrl());
00281       if (buffer.size()) {
00282          m_webFile->SetBaseUri(url.GetUrl());
00283          m_webFile->ParseText(const_cast<char*>(buffer.c_str()));
00284       }
00285       else {
00286          m_webFile->SetBaseUri("");
00287          for (int i=0; s_readError[i]; i++) {
00288             m_webFile->ParseText(const_cast<char *>(s_readError[i]));
00289          }
00290       }
00291       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kPointer));
00292       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kPointer));
00293    } else {
00294       m_webFile->SetBaseUri("");
00295       for (int i=0; s_noBrowserMessage[i]; i++) {
00296          m_webFile->ParseText((char *)s_noBrowserMessage[i]);
00297       }
00298    }
00299    m_webFile->Layout();
00300 }
00301 
00302 std::string 
00303 CmsShowSearchFiles::chooseFileFromURL()
00304 {
00305    DontCallClose();
00306    Connect("CloseWindow()","CmsShowSearchFiles",this,"UnmapWindow()");
00307    m_openCalled = false;
00308    MapWindow();
00309    gClient->WaitForUnmap(this);
00310 
00311    if(!m_openCalled) {
00312       return std::string();
00313    }
00314    return m_file->GetText();
00315 }
00316