Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:07

0001 #include <stdexcept>
0002 #include <iostream>
0003 #include <fstream>
0004 #include <cstdlib>
0005 #include <set>
0006 #include "TGClient.h"
0007 #include "TGHtml.h"
0008 #include "TGButton.h"
0009 #include "TGMenu.h"
0010 #include "TGLabel.h"
0011 #include "TGTextEntry.h"
0012 #include "TPluginManager.h"
0013 #include "TUrl.h"
0014 #include "TSocket.h"
0015 #include "TSystem.h"
0016 #include "TVirtualX.h"
0017 #include "TPRegexp.h"
0018 #include "TVirtualX.h"
0019 #include "Fireworks/Core/interface/CmsShowSearchFiles.h"
0020 #include "Fireworks/Core/interface/fwLog.h"
0021 #include "Fireworks/Core/interface/fwPaths.h"
0022 
0023 class FWHtml : public TGHtml {
0024 public:
0025   FWHtml(const TGWindow* p, int w, int h, int id = -1) : TGHtml(p, w, h, id) {}
0026 
0027   int IsVisited(const char* iCheck) override {
0028     std::string check(GetBaseUri());
0029     check += iCheck;
0030     int value = m_visited.find(check) == m_visited.end() ? kFALSE : kTRUE;
0031     return value;
0032   }
0033   void addToVisited(const char* iToVisit) { m_visited.insert(iToVisit); }
0034 
0035 private:
0036   std::set<std::string> m_visited;
0037 };
0038 
0039 const static unsigned int s_columns = 3;
0040 const static char* const s_prefixes[][s_columns] = {{"http://", "Web site known by you", nullptr},
0041                                                     {"file:", "Local file [you must type full path name]", nullptr},
0042                                                     {"dcap://", "dCache [FNAL]", nullptr},
0043                                                     {"rfio://", "Castor [CERN]", nullptr}
0044 
0045 };
0046 
0047 static const std::string s_httpPrefix("http:");
0048 static const std::string s_filePrefix("file:");
0049 static const std::string s_rootPostfix(".root");
0050 
0051 CmsShowSearchFiles::CmsShowSearchFiles(
0052     const char* filename, const char* windowname, const TGWindow* p, UInt_t w, UInt_t h)
0053     : TGTransientFrame(gClient->GetDefaultRoot(), p, w, h) {
0054   TGVerticalFrame* vf = new TGVerticalFrame(this);
0055   this->AddFrame(vf, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5));
0056   TGHorizontalFrame* urlFrame = new TGHorizontalFrame(this);
0057   vf->AddFrame(urlFrame, new TGLayoutHints(kLHintsExpandX, 5, 0, 5, 5));
0058 
0059   TGLabel* urlLabel = new TGLabel(urlFrame, "URL");
0060   urlFrame->AddFrame(urlLabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 1, 1, 1, 1));
0061   m_choosePrefix = new TGTextButton(urlFrame, "Choose Prefix");
0062   urlFrame->AddFrame(m_choosePrefix, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1));
0063 
0064   m_file = new TGTextEntry(urlFrame);
0065   urlFrame->AddFrame(m_file, new TGLayoutHints(kLHintsExpandX, 1, 0, 1, 1));
0066   m_file->Connect("TextChanged(const char*)", "CmsShowSearchFiles", this, "fileEntryChanged(const char*)");
0067   m_file->Connect("ReturnPressed()", "CmsShowSearchFiles", this, "updateBrowser()");
0068 
0069   m_webFile = new FWHtml(vf, 1, 1);
0070   m_webFile->Connect("MouseDown(const char*)", "CmsShowSearchFiles", this, "hyperlinkClicked(const char*)");
0071   vf->AddFrame(m_webFile, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 1, 1, 1, 1));
0072 
0073   TGHorizontalFrame* buttonFrame = new TGHorizontalFrame(vf);
0074   vf->AddFrame(buttonFrame, new TGLayoutHints(kLHintsExpandX, 1, 10, 1, 10));
0075 
0076   m_openButton = new TGTextButton(buttonFrame, "Open");
0077   buttonFrame->AddFrame(m_openButton, new TGLayoutHints(kLHintsRight, 5, 5, 1, 1));
0078   m_openButton->SetEnabled(kFALSE);
0079   m_openButton->Connect("Clicked()", "CmsShowSearchFiles", this, "openClicked()");
0080 
0081   TGTextButton* cancel = new TGTextButton(buttonFrame, "Cancel");
0082   buttonFrame->AddFrame(cancel, new TGLayoutHints(kLHintsRight, 5, 5, 1, 1));
0083   cancel->Connect("Clicked()", "CmsShowSearchFiles", this, "UnmapWindow()");
0084 
0085   SetWindowName(windowname);
0086 
0087   std::string path =
0088       Form("http://cmsshow-rels.web.cern.ch/cmsShow-rels/samples/%d/", fireworks::supportedDataFormatsVersion()[0]);
0089 
0090   if (!path.empty())
0091     fwLog(fwlog::kInfo) << "Search files at " << path << "." << std::endl;
0092 
0093   sendToWebBrowser(path);
0094 
0095   MapSubwindows();
0096   Layout();
0097   m_prefixMenu = nullptr;
0098   m_choosePrefix->Connect("Clicked()", "CmsShowSearchFiles", this, "showPrefixes()");
0099 }
0100 
0101 CmsShowSearchFiles::~CmsShowSearchFiles() { delete m_prefixMenu; }
0102 
0103 //______________________________________________________________________________
0104 
0105 void CmsShowSearchFiles::prefixChoosen(Int_t iIndex) {
0106   //   printf ("pref chosen %d \n", iIndex);
0107   m_file->SetText(m_prefixes[iIndex].c_str(), kFALSE);
0108   m_openButton->SetEnabled(kFALSE);
0109 
0110   if (m_prefixComplete[iIndex]) {
0111     //gClient->NeedRedraw(this);
0112     gClient->NeedRedraw(m_choosePrefix);
0113     gClient->NeedRedraw(m_webFile);
0114     gClient->ProcessEventsFor(this);
0115     updateBrowser();
0116   } else {
0117     std::string p;
0118     sendToWebBrowser(p);
0119   }
0120 }
0121 
0122 //______________________________________________________________________________
0123 
0124 void CmsShowSearchFiles::fileEntryChanged(const char* iFileName) {
0125   std::string fileName = iFileName;
0126   size_t index = fileName.find_last_of('.');
0127   std::string postfix;
0128   if (index != std::string::npos) {
0129     postfix = fileName.substr(index, std::string::npos);
0130   }
0131   if (postfix == s_rootPostfix) {
0132     m_openButton->SetEnabled(kTRUE);
0133   } else {
0134     m_openButton->SetEnabled(kFALSE);
0135   }
0136 }
0137 
0138 //______________________________________________________________________________
0139 
0140 void CmsShowSearchFiles::updateBrowser() {
0141   std::string n = m_file->GetText();
0142   sendToWebBrowser(n);
0143 }
0144 
0145 //______________________________________________________________________________
0146 
0147 void CmsShowSearchFiles::hyperlinkClicked(const char* iLink) {
0148   m_file->SetText(iLink, kTRUE);
0149 
0150   m_webFile->addToVisited(iLink);
0151   std::string fileName = iLink;
0152   size_t index = fileName.find_last_of('.');
0153   std::string postfix = fileName.substr(index, std::string::npos);
0154 
0155   if (postfix != s_rootPostfix) {
0156     updateBrowser();
0157   } else {
0158     openClicked();
0159   }
0160 }
0161 
0162 //______________________________________________________________________________
0163 
0164 void CmsShowSearchFiles::openClicked() {
0165   m_openCalled = true;
0166   this->UnmapWindow();
0167 }
0168 
0169 //______________________________________________________________________________
0170 
0171 void CmsShowSearchFiles::showPrefixes() {
0172   if (nullptr == m_prefixMenu) {
0173     m_prefixMenu = new TGPopupMenu(this);
0174     const char* const(*itEnd)[s_columns] = s_prefixes + sizeof(s_prefixes) / sizeof(const char* [3]);
0175     int index = 0;
0176     for (const char* const(*it)[s_columns] = s_prefixes; it != itEnd; ++it, ++index) {
0177       //only add the protocols this version of the code actually can load
0178       std::string prefix = std::string((*it)[0]).substr(0, std::string((*it)[0]).find_first_of(':') + 1);
0179       if (s_httpPrefix == prefix || s_filePrefix == prefix ||
0180           (gPluginMgr->FindHandler("TSystem", prefix.c_str()) &&
0181            gPluginMgr->FindHandler("TSystem", prefix.c_str())->CheckPlugin() != -1)) {
0182         m_prefixMenu->AddEntry((std::string((*it)[0]) + " (" + ((*it)[1]) + ")").c_str(), index);
0183         m_prefixes.push_back((*it)[0]);
0184         m_prefixComplete.push_back(nullptr != (*it)[2]);
0185       }
0186     }
0187     m_prefixMenu->Connect("Activated(Int_t)", "CmsShowSearchFiles", this, "prefixChoosen(Int_t)");
0188   }
0189   m_prefixMenu->PlaceMenu(m_choosePrefix->GetX(), m_choosePrefix->GetY(), true, true);
0190 }
0191 
0192 //______________________________________________________________________________
0193 
0194 //Copied from TGHtmlBrowser
0195 static std::string readRemote(const char* url) {
0196   // Read (open) remote files.
0197 
0198   char* buf = nullptr;
0199   TUrl fUrl(url);
0200 
0201   TString msg = "GET ";
0202   msg += fUrl.GetProtocol();
0203   msg += "://";
0204   msg += fUrl.GetHost();
0205   msg += ":";
0206   msg += fUrl.GetPort();
0207   msg += "/";
0208   msg += fUrl.GetFile();
0209   msg += "\r\n";
0210 
0211   TString uri(url);
0212   if (!uri.BeginsWith("http://"))
0213     return std::string();
0214   TSocket s(fUrl.GetHost(), fUrl.GetPort());
0215   if (!s.IsValid())
0216     return std::string();
0217   if (s.SendRaw(msg.Data(), msg.Length()) == -1)
0218     return std::string();
0219   Int_t size = 1024 * 1024;
0220   buf = (char*)calloc(size, sizeof(char));
0221   if (s.RecvRaw(buf, size) == -1) {
0222     free(buf);
0223     return std::string();
0224   }
0225   std::string returnValue(buf);
0226   free(buf);
0227   return returnValue;
0228 }
0229 
0230 //______________________________________________________________________________
0231 
0232 void CmsShowSearchFiles::sendToWebBrowser(std::string& fileName) {
0233   //  std::cout << "CmsShowSearchFiles::sendToWebBrowser " <<  fileName << std::endl ;
0234 
0235   size_t index = fileName.find_first_of(':');
0236   if (index != std::string::npos) {
0237     ++index;
0238   } else {
0239     index = 0;
0240   }
0241   std::string prefix = fileName.substr(0, index);
0242 
0243   m_webFile->Clear();
0244   if (prefix == s_httpPrefix) {
0245     gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
0246     //If you clicked a hyperlink then the cursor is still a hand but we now
0247     // want it to be a watch
0248     gVirtualX->SetCursor(m_webFile->GetId(), gVirtualX->CreateCursor(kWatch));
0249     //If we don't call ProcessEventsFor then the cursor will not be updated
0250     gClient->ProcessEventsFor(this);
0251     TUrl url(fileName.c_str());
0252     std::string buffer = readRemote(url.GetUrl());
0253 
0254     if (!buffer.empty()) {
0255       m_webFile->SetBaseUri(url.GetUrl());
0256       m_webFile->ParseText(const_cast<char*>(buffer.c_str()));
0257     } else {
0258       readError();
0259     }
0260     gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
0261     gVirtualX->SetCursor(m_webFile->GetId(), gVirtualX->CreateCursor(kPointer));
0262   } else {
0263     readInfo();
0264   }
0265   m_webFile->Layout();
0266 }
0267 
0268 //______________________________________________________________________________
0269 void CmsShowSearchFiles::readError() {
0270   const static char* s_readError[] = {
0271       "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
0272       "\"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
0273       "<HTML><HEAD><TITLE>HTTP Read Error</TITLE> ",
0274       "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
0275       "<BODY> ",
0276       "<P>Unknown error while trying to get file via http</P>",
0277       "</BODY></HTML> ",
0278       nullptr};
0279 
0280   m_webFile->SetBaseUri("");
0281   for (int i = 0; s_readError[i]; i++) {
0282     m_webFile->ParseText(const_cast<char*>(s_readError[i]));
0283   }
0284 }
0285 
0286 void CmsShowSearchFiles::readInfo() {
0287   const static char* s_noBrowserMessage[] = {
0288       "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
0289       "\"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
0290       "<HTML><HEAD><TITLE>No Browser Available</TITLE> ",
0291       "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
0292       "<BODY> ",
0293       //"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>",
0294       //"Only a prefix beginning in <STRONG>http:</STRONG> which contains a site name (e.g. http://www.site.org) is supported for browsing."
0295       "<b>Welcome....</b><BR>",
0296       "<BR>",
0297       "<b>You may look at examples:</b><BR>",
0298       "If you are in Europe, open example data files at CERN :  ",
0299       " <a href=",
0300       Form("http://fireworks.web.cern.ch/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]),
0301       "> http://fireworks.web.cern.ch/fireworks/ </a><BR>",
0302       "If you are in US, open example data files at UCSD:  ",
0303       " <a href=",
0304       Form("http://uaf-2.t2.ucsd.edu/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]),
0305       ">http://uaf-2.t2.ucsd.edu/fireworks/ </a><BR>",
0306       "<BR>"
0307       "<b>You also may load files with Choose Prefix </b><BR>"
0308       "</BODY></HTML> ",
0309       nullptr};
0310 
0311   m_webFile->SetBaseUri("");
0312   for (int i = 0; s_noBrowserMessage[i]; i++) {
0313     m_webFile->ParseText((char*)s_noBrowserMessage[i]);
0314   }
0315 }
0316 //______________________________________________________________________________
0317 
0318 std::string CmsShowSearchFiles::chooseFileFromURL() {
0319   DontCallClose();
0320   Connect("CloseWindow()", "CmsShowSearchFiles", this, "UnmapWindow()");
0321   m_openCalled = false;
0322   MapWindow();
0323   gClient->WaitForUnmap(this);
0324 
0325   if (!m_openCalled) {
0326     return std::string();
0327   }
0328   return m_file->GetText();
0329 }