CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/Fireworks/Core/src/CmsShowMain.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     CmsShowMain
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:
00010 //         Created:  Mon Dec  3 08:38:38 PST 2007
00011 // $Id: CmsShowMain.cc,v 1.201 2012/05/08 03:16:09 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <sstream>
00016 #include <boost/bind.hpp>
00017 #include <boost/program_options.hpp>
00018 #include <string.h>
00019 
00020 #include "TSystem.h"
00021 #include "TGLWidget.h"
00022 #include "TTimer.h"
00023 #include "TROOT.h"
00024 #include "TGFileDialog.h"
00025 #include "TGMsgBox.h"
00026 #include "TMonitor.h"
00027 #include "TServerSocket.h"
00028 #include "TEveLine.h"
00029 #include "TEveManager.h"
00030 #include "TFile.h"
00031 #include "TGClient.h"
00032 
00033 #include "Fireworks/Core/src/CmsShowMain.h"
00034 
00035 #include "Fireworks/Core/interface/FWEveViewManager.h"
00036 
00037 #include "Fireworks/Core/interface/FWTableViewManager.h"
00038 #include "Fireworks/Core/interface/FWTriggerTableViewManager.h"
00039 #include "Fireworks/Core/interface/FWEventItemsManager.h"
00040 #include "Fireworks/Core/interface/FWViewManagerManager.h"
00041 #include "Fireworks/Core/interface/FWGUIManager.h"
00042 #include "Fireworks/Core/interface/FWLiteJobMetadataManager.h"
00043 #include "Fireworks/Core/interface/FWModelChangeManager.h"
00044 #include "Fireworks/Core/interface/FWColorManager.h"
00045 #include "Fireworks/Core/src/FWColorSelect.h"
00046 #include "Fireworks/Core/interface/FWSelectionManager.h"
00047 #include "Fireworks/Core/interface/FWConfigurationManager.h"
00048 #include "Fireworks/Core/interface/FWMagField.h"
00049 #include "Fireworks/Core/interface/Context.h"
00050 
00051 #include "Fireworks/Core/interface/CmsShowNavigator.h"
00052 #include "Fireworks/Core/interface/CSGAction.h"
00053 #include "Fireworks/Core/interface/CSGContinuousAction.h"
00054 #include "Fireworks/Core/interface/FWLiteJobMetadataUpdateRequest.h"
00055 
00056 #include "Fireworks/Core/interface/ActionsList.h"
00057 
00058 #include "Fireworks/Core/src/CmsShowTaskExecutor.h"
00059 #include "Fireworks/Core/interface/CmsShowMainFrame.h"
00060 #include "Fireworks/Core/interface/CmsShowSearchFiles.h"
00061 
00062 #include "Fireworks/Core/interface/fwLog.h"
00063 
00064 #include "FWCore/FWLite/interface/AutoLibraryLoader.h"
00065 
00066 #include "TGX11.h" // !!!! AMT has to be at the end to pass build
00067 
00068 //
00069 // constants, enums and typedefs
00070 //
00071 
00072 static const char* const kInputFilesOpt        = "input-files";
00073 static const char* const kInputFilesCommandOpt = "input-files,i";
00074 static const char* const kConfigFileOpt        = "config-file";
00075 static const char* const kConfigFileCommandOpt = "config-file,c";
00076 static const char* const kGeomFileOpt          = "geom-file";
00077 static const char* const kGeomFileCommandOpt   = "geom-file,g";
00078 static const char* const kSimGeomFileOpt       = "sim-geom-file";
00079 static const char* const kSimGeomFileCommandOpt= "sim-geom-file";
00080 static const char* const kNoConfigFileOpt      = "noconfig";
00081 static const char* const kNoConfigFileCommandOpt = "noconfig,n";
00082 static const char* const kPlayOpt              = "play";
00083 static const char* const kPlayCommandOpt       = "play,p";
00084 static const char* const kLoopOpt              = "loop";
00085 static const char* const kLoopCommandOpt       = "loop";
00086 static const char* const kLogLevelCommandOpt   = "log";
00087 static const char* const kLogLevelOpt          = "log";
00088 static const char* const kEveOpt               = "eve";
00089 static const char* const kEveCommandOpt        = "eve";
00090 static const char* const kAdvancedRenderOpt        = "shine";
00091 static const char* const kAdvancedRenderCommandOpt = "shine,s";
00092 static const char* const kHelpOpt        = "help";
00093 static const char* const kHelpCommandOpt = "help,h";
00094 static const char* const kSoftCommandOpt = "soft";
00095 static const char* const kPortCommandOpt = "port";
00096 static const char* const kPlainRootCommandOpt = "prompt";
00097 static const char* const kRootInteractiveCommandOpt = "root-interactive,r";
00098 static const char* const kChainCommandOpt = "chain";
00099 static const char* const kLiveCommandOpt  = "live";
00100 static const char* const kFieldCommandOpt = "field";
00101 static const char* const kFreePaletteCommandOpt = "free-palette";
00102 static const char* const kAutoSaveAllViews = "auto-save-all-views";
00103 static const char* const kEnableFPE        = "enable-fpe";
00104 static const char* const kZeroWinOffsets   = "zero-window-offsets";
00105 static const char* const kNoVersionCheck   = "no-version-check";
00106 
00107 
00108 //
00109 // constructors and destructor
00110 //
00111 CmsShowMain::CmsShowMain(int argc, char *argv[]) 
00112    : CmsShowMainBase(),
00113      m_navigator(new CmsShowNavigator(*this)),
00114      m_metadataManager(new FWLiteJobMetadataManager()),
00115      m_context(new fireworks::Context(changeManager(),
00116                                       selectionManager(),
00117                                       eiManager(),
00118                                       colorManager(),
00119                                       m_metadataManager.get())),
00120      m_loadedAnyInputFile(false),
00121      m_openFile(0),
00122      m_live(false),
00123      m_liveTimer(new SignalTimer()),
00124      m_liveTimeout(600000),
00125      m_lastXEventSerial(0),
00126      m_noVersionCheck(false)
00127 {
00128    try {
00129       TGLWidget* w = TGLWidget::Create(gClient->GetDefaultRoot(), kTRUE, kTRUE, 0, 10, 10);
00130       delete w;
00131    }
00132    catch (std::exception& iException) {
00133       fwLog(fwlog::kError) << "Failed creating an OpenGL window: " << iException.what() << "\n"
00134          "Things to check:\n"
00135          "- Is DISPLAY environment variable set?\n"
00136          "- Are OpenGL libraries installed?\n"
00137          "- If running remotely, make sure you use 'ssh -X' or 'ssh -Y'.\n"
00138          "See also: https://twiki.cern.ch/twiki/bin/viewauth/CMS/WorkBookFireworks\n";
00139       gSystem->Exit(1);
00140    }
00141 
00142    eiManager()->setContext(m_context.get());
00143 
00144    
00145    std::string descString(argv[0]);
00146    descString += " [options] <data file>\nAllowed options";
00147 
00148    namespace po = boost::program_options;
00149    po::options_description desc(descString);
00150    desc.add_options()
00151       (kInputFilesCommandOpt, po::value< std::vector<std::string> >(),   "Input root files")
00152       (kConfigFileCommandOpt, po::value<std::string>(),   "Include configuration file")
00153       (kGeomFileCommandOpt,   po::value<std::string>(),   "Include geometry file")
00154       (kNoConfigFileCommandOpt,                           "Don't load any configuration file")
00155       (kPlayCommandOpt, po::value<float>(),               "Start in play mode with given interval between events in seconds")
00156       (kPortCommandOpt, po::value<unsigned int>(),        "Listen to port for new data files to open")
00157       (kEveCommandOpt,                                    "Show Eve browser to help debug problems")
00158       (kLoopCommandOpt,                                   "Loop events in play mode")
00159       (kPlainRootCommandOpt,                              "Plain ROOT without event display")
00160       (kRootInteractiveCommandOpt,                        "Enable root interactive prompt")
00161       (kEnableFPE,                                        "Enable detection of floating-point exceptions")
00162       (kLogLevelCommandOpt, po::value<unsigned int>(),    "Set log level starting from 0 to 4 : kDebug, kInfo, kWarning, kError")
00163       (kAdvancedRenderCommandOpt,                         "Use advance options to improve rendering quality       (anti-alias etc)")
00164       (kSoftCommandOpt,                                   "Try to force software rendering to avoid problems with bad hardware drivers")
00165       (kChainCommandOpt, po::value<unsigned int>(),       "Chain up to a given number of recently open files. Default is 1 - no chain")
00166       (kLiveCommandOpt,                                   "Enforce playback mode if a user is not using display")
00167       (kFieldCommandOpt, po::value<double>(),             "Set magnetic field value explicitly. Default is auto-field estimation")
00168       (kFreePaletteCommandOpt,                            "Allow free color selection (requires special configuration!)")
00169       (kAutoSaveAllViews, po::value<std::string>(),       "Auto-save all views with given prefix (run_event_lumi_view.png is appended)")
00170       (kZeroWinOffsets,                                   "Disable auto-detection of window position offsets.")
00171       (kNoVersionCheck,                                   "No file version check.")
00172       (kSimGeomFileCommandOpt,po::value<std::string>(),   "Set simulation geometry file to browse")
00173       (kHelpCommandOpt,                                   "Display help message");
00174    po::positional_options_description p;
00175    p.add(kInputFilesOpt, -1);
00176 
00177    int newArgc = argc;
00178    char **newArgv = argv;
00179    po::variables_map vm;
00180    //po::store(po::parse_command_line(newArgc, newArgv, desc), vm);
00181    //po::notify(vm);
00182    try{ 
00183       po::store(po::command_line_parser(newArgc, newArgv).
00184                 options(desc).positional(p).run(), vm);
00185 
00186       po::notify(vm);
00187    }
00188    catch ( const std::exception& e)
00189    {
00190       // Return with exit status 0 to avoid generating crash reports
00191 
00192       fwLog(fwlog::kError) <<  e.what() << std::endl;
00193       std::cout << desc <<std::endl;
00194       exit(0); 
00195    }
00196 
00197    if(vm.count(kHelpOpt)) {
00198       std::cout << desc <<std::endl;
00199       exit(0);
00200    }
00201       
00202    if(vm.count(kLogLevelOpt)) {
00203       fwlog::LogLevel level = (fwlog::LogLevel)(vm[kLogLevelOpt].as<unsigned int>());
00204       fwlog::setPresentLogLevel(level);
00205    }
00206 
00207    if(vm.count(kPlainRootCommandOpt)) {
00208       fwLog(fwlog::kInfo) << "Plain ROOT prompt requested" << std::endl;
00209       return;
00210    }
00211 
00212    const char* cmspath = gSystem->Getenv("CMSSW_BASE");
00213    if(0 == cmspath) {
00214       throw std::runtime_error("CMSSW_BASE environment variable not set");
00215    }
00216 
00217    // input file
00218    if (vm.count(kInputFilesOpt)) {
00219       m_inputFiles = vm[kInputFilesOpt].as< std::vector<std::string> >();
00220    }
00221 
00222    if (!m_inputFiles.size())
00223       fwLog(fwlog::kInfo) << "No data file given." << std::endl;
00224    else if (m_inputFiles.size() == 1)
00225       fwLog(fwlog::kInfo) << "Input " << m_inputFiles.front() << std::endl;
00226    else
00227       fwLog(fwlog::kInfo) << m_inputFiles.size() << " input files; first: " << m_inputFiles.front() << ", last: " << m_inputFiles.back() << std::endl;
00228 
00229    // configuration file
00230    if (vm.count(kConfigFileOpt)) {
00231       setConfigFilename(vm[kConfigFileOpt].as<std::string>());
00232       if (access(configFilename(), R_OK) == -1)
00233       {
00234          fwLog(fwlog::kError) << "Specified configuration file does not exist. Quitting.\n";
00235          exit(0);
00236       }
00237    } else {
00238       if (vm.count(kNoConfigFileOpt)) {
00239          fwLog(fwlog::kInfo) << "No configuration is loaded, show everything.\n";
00240          setConfigFilename("");
00241       } else
00242          setConfigFilename("default.fwc");
00243    }
00244    fwLog(fwlog::kInfo) << "Config "  <<  configFilename() << std::endl;
00245 
00246    // geometry
00247    if (vm.count(kGeomFileOpt)) {
00248       setGeometryFilename(vm[kGeomFileOpt].as<std::string>());
00249    } else {
00250       //  fwLog(fwlog::kInfo) << "No geom file name.  Choosing default.\n";
00251       setGeometryFilename("cmsGeom10.root");
00252    }
00253    fwLog(fwlog::kInfo) << "Geometry file " << geometryFilename() << "\n";
00254 
00255    if (vm.count(kSimGeomFileOpt)) {
00256       setSimGeometryFilename(vm[kSimGeomFileOpt].as<std::string>());
00257    } else {
00258       setSimGeometryFilename("cmsSimGeom-14.root");
00259    }
00260    // Free-palette palette
00261    if (vm.count(kFreePaletteCommandOpt)) {
00262       FWColorPopup::EnableFreePalette();
00263       fwLog(fwlog::kInfo) << "Palette restriction removed on user request!\n";
00264    }
00265    bool eveMode = vm.count(kEveOpt);
00266 
00267    //Delay creating guiManager and enabling autoloading until here so that if we have a 'help' request we don't
00268    // open any graphics or build dictionaries
00269    AutoLibraryLoader::enable();
00270 
00271    TEveManager::Create(kFALSE, "FIV");
00272 
00273    setup(m_navigator.get(), m_context.get(), m_metadataManager.get());
00274 
00275    if (vm.count(kZeroWinOffsets))
00276    {
00277       guiManager()->resetWMOffsets();
00278       fwLog(fwlog::kInfo) << "Window offsets reset on user request!\n";
00279    }
00280 
00281    if ( vm.count(kAdvancedRenderOpt) ) 
00282    {
00283       TEveLine::SetDefaultSmooth(kTRUE);
00284    }
00285 
00286    //figure out where to find macros
00287    //tell ROOT where to find our macros
00288    CmsShowTaskExecutor::TaskFunctor f;
00289    // first check if port is not occupied
00290    if (vm.count(kPortCommandOpt)) {      
00291       f=boost::bind(&CmsShowMain::setupSocket, this, vm[kPortCommandOpt].as<unsigned int>());    
00292       startupTasks()->addTask(f);        
00293    }
00294     
00295    f=boost::bind(&CmsShowMainBase::loadGeometry,this);
00296    startupTasks()->addTask(f);
00297    f=boost::bind(&CmsShowMainBase::setupViewManagers,this);
00298    startupTasks()->addTask(f);
00299    f=boost::bind(&CmsShowMainBase::setupConfiguration,this);
00300    startupTasks()->addTask(f);
00301    f=boost::bind(&CmsShowMain::setupDataHandling,this);
00302    startupTasks()->addTask(f);
00303 
00304    if (vm.count(kLoopOpt))
00305       setPlayLoop();
00306 
00307    if (eveMode) {
00308       f = boost::bind(&CmsShowMainBase::setupDebugSupport,this);
00309       startupTasks()->addTask(f);
00310    }
00311    if(vm.count(kChainCommandOpt)) {
00312       f = boost::bind(&CmsShowNavigator::setMaxNumberOfFilesToChain, m_navigator.get(), vm[kChainCommandOpt].as<unsigned int>());
00313       startupTasks()->addTask(f);
00314    }
00315    if (vm.count(kPlayOpt)) {
00316       f = boost::bind(&CmsShowMainBase::setupAutoLoad, this, vm[kPlayOpt].as<float>());
00317       startupTasks()->addTask(f);
00318    }
00319 
00320    if(vm.count(kLiveCommandOpt))
00321    {
00322       f = boost::bind(&CmsShowMain::setLiveMode, this);
00323       startupTasks()->addTask(f);
00324    }
00325       
00326    if(vm.count(kFieldCommandOpt)) 
00327    {
00328       m_context->getField()->setSource(FWMagField::kUser);
00329       m_context->getField()->setUserField(vm[kFieldCommandOpt].as<double>());
00330    }
00331    if(vm.count(kAutoSaveAllViews)) {
00332       std::string fmt = vm[kAutoSaveAllViews].as<std::string>();
00333       fmt += "%u_%u_%u_%s.png";
00334       setAutoSaveAllViewsFormat(fmt);
00335    }
00336    if(vm.count(kNoVersionCheck)) {
00337       m_noVersionCheck=true;
00338    }
00339    if(vm.count(kEnableFPE)) {
00340       gSystem->SetFPEMask();
00341    }
00342 
00343    if (vm.count(kPortCommandOpt)) {      
00344       f=boost::bind(&CmsShowMain::connectSocket, this);          
00345       startupTasks()->addTask(f);        
00346    }
00347 
00348    startupTasks()->startDoingTasks();
00349 }
00350 
00351 //
00352 // Destruction
00353 //
00354 
00355 CmsShowMain::~CmsShowMain()
00356 {
00357    //avoids a seg fault from eve which happens if eve is terminated after the GUI is gone
00358    selectionManager()->clearSelection();
00359 }
00360 
00361 class DieTimer : public TTimer
00362 {
00363 protected:
00364    CmsShowMain* fApp;
00365 public:
00366    DieTimer(CmsShowMain* app) : TTimer(), fApp(app)
00367    {
00368       Start(0, kTRUE);
00369    }
00370 
00371    virtual Bool_t Notify()
00372    {
00373       TurnOff();
00374       fApp->doExit();
00375       delete this;
00376       return kFALSE;
00377    }
00378 };
00379 
00380 void CmsShowMain::quit()
00381 {
00382    new DieTimer(this);
00383 }
00384 
00385 void CmsShowMain::doExit()
00386 {
00387    // pre terminate eve
00388    m_context->deleteEveElements();
00389    guiManager()->evePreTerminate();
00390 
00391    // sleep at least 150 ms
00392    // windows in ROOT GUI are destroyed in 150 ms timeout after
00393    gSystem->Sleep(151);
00394    gSystem->ProcessEvents();
00395    gSystem->ExitLoop();
00396 }
00397 
00398 //
00399 // assignment operators
00400 //
00401 // const CmsShowMain& CmsShowMain::operator=(const CmsShowMain& rhs)
00402 // {
00403 //   //An exception safe implementation is
00404 //   CmsShowMain temp(rhs);
00405 //   swap(rhs);
00406 //
00407 //   return *this;
00408 // }
00409 
00410 //
00411 // member functions
00412 //
00413 
00414 const fwlite::Event* 
00415 CmsShowMain::getCurrentEvent() const
00416 {
00417    if (m_navigator.get())
00418      return static_cast<const fwlite::Event*>(m_navigator->getCurrentEvent());
00419    return 0;
00420 }
00421 
00422 void
00423 CmsShowMain::fileChangedSlot(const TFile *file)
00424 {
00425    m_openFile = file;
00426    if (file)
00427       guiManager()->titleChanged(m_navigator->frameTitle());
00428 
00429    m_metadataManager->update(new FWLiteJobMetadataUpdateRequest(getCurrentEvent(), m_openFile));
00430 }
00431 
00432 void
00433 CmsShowMain::eventChangedImp()
00434 {
00435    CmsShowMainBase::eventChangedImp();
00436    guiManager()->titleChanged(m_navigator->frameTitle());
00437    m_metadataManager->update(new FWLiteJobMetadataUpdateRequest(getCurrentEvent(), m_openFile));
00438 }
00439 
00440 void CmsShowMain::resetInitialization() {
00441    //printf("Need to reset\n");
00442 }
00443 
00444 void CmsShowMain::openData()
00445 {
00446    const char* kRootType[] = {"ROOT files","*.root", 0, 0};
00447    TGFileInfo fi;
00448    fi.fFileTypes = kRootType;
00449    /* this is how things used to be done:
00450       fi.fIniDir = ".";
00451       this is bad because the destructor calls delete[] on fIniDir.
00452     */
00453    fi.fIniDir = new char[128];
00454    strncpy(fi.fIniDir, ".", 127);  
00455    guiManager()->updateStatus("waiting for data file ...");
00456    new TGFileDialog(gClient->GetDefaultRoot(), guiManager()->getMainFrame(), kFDOpen, &fi);
00457    guiManager()->updateStatus("loading file ...");
00458    if (fi.fFilename) {
00459       m_navigator->openFile(fi.fFilename);
00460       m_loadedAnyInputFile = true;
00461       m_navigator->firstEvent();
00462       checkPosition();
00463       draw();
00464    }
00465    guiManager()->clearStatus();
00466 }
00467 
00468 void CmsShowMain::appendData()
00469 {
00470    const char* kRootType[] = {"ROOT files","*.root", 0, 0};
00471    TGFileInfo fi;
00472    fi.fFileTypes = kRootType;
00473    /* this is how things used to be done:
00474       fi.fIniDir = ".";
00475       this is bad because the destructor calls delete[] on fIniDir.
00476    */
00477    fi.fIniDir = new char[128];
00478    strncpy(fi.fIniDir,  ".", 127);
00479    guiManager()->updateStatus("waiting for data file ...");
00480    new TGFileDialog(gClient->GetDefaultRoot(), guiManager()->getMainFrame(), kFDOpen, &fi);
00481    guiManager()->updateStatus("loading file ...");
00482    if (fi.fFilename) {
00483       m_navigator->appendFile(fi.fFilename, false, false);
00484       m_loadedAnyInputFile = true;
00485       checkPosition();
00486       draw();
00487       guiManager()->titleChanged(m_navigator->frameTitle());
00488    }
00489    guiManager()->clearStatus();
00490 }
00491 
00492 void
00493 CmsShowMain::openDataViaURL()
00494 {
00495    if (m_searchFiles.get() == 0) {
00496       m_searchFiles = std::auto_ptr<CmsShowSearchFiles>(new CmsShowSearchFiles("",
00497                                                                                "Open Remote Data Files",
00498                                                                                guiManager()->getMainFrame(),
00499                                                                                500, 400));
00500       m_searchFiles->CenterOnParent(kTRUE,TGTransientFrame::kBottomRight);
00501    }
00502    std::string chosenFile = m_searchFiles->chooseFileFromURL();
00503    if(!chosenFile.empty()) {
00504       guiManager()->updateStatus("loading file ...");
00505       if(m_navigator->openFile(chosenFile.c_str())) {
00506          m_loadedAnyInputFile = true;
00507          m_navigator->firstEvent();
00508          checkPosition();
00509          draw();
00510          guiManager()->clearStatus();
00511       } else {
00512          guiManager()->updateStatus("failed to load data file");
00513       }
00514    }
00515 }
00516 
00517 //
00518 // const member functions
00519 //
00520 
00521 //_______________________________________________________________________________
00522 void 
00523 CmsShowMain::autoLoadNewEvent()
00524 {
00525    stopAutoLoadTimer();
00526    
00527    // case when start with no input file
00528    if (!m_loadedAnyInputFile)
00529    {
00530       if (m_monitor.get()) 
00531          startAutoLoadTimer();
00532       return;
00533    }
00534 
00535    bool reachedEnd = (forward() && m_navigator->isLastEvent()) || (!forward() && m_navigator->isFirstEvent());
00536 
00537    if (loop() && reachedEnd)
00538    {
00539       forward() ? m_navigator->firstEvent() : m_navigator->lastEvent();
00540       draw();
00541    }
00542    else if (!reachedEnd)
00543    {
00544       forward() ? m_navigator->nextEvent() : m_navigator->previousEvent();
00545       draw();
00546    }
00547 
00548    // stop loop in case no loop or monitor mode
00549    if (reachedEnd && (loop() || m_monitor.get()) == kFALSE)
00550    {
00551       if (forward() && m_navigator->isLastEvent())
00552       {
00553          guiManager()->enableActions();
00554          checkPosition();
00555       }
00556 
00557       if ((!forward()) && m_navigator->isFirstEvent())
00558       {
00559          guiManager()->enableActions();
00560          checkPosition();
00561       }
00562    }
00563    else
00564       startAutoLoadTimer();
00565 }
00566 
00567 //______________________________________________________________________________
00568 
00569 void 
00570 CmsShowMain::checkPosition()
00571 {
00572    if ((m_monitor.get() || loop() ) && isPlaying())
00573       return;
00574    
00575    guiManager()->getMainFrame()->enableNavigatorControls();
00576 
00577    if (m_navigator->isFirstEvent())
00578       guiManager()->disablePrevious();
00579 
00580    if (m_navigator->isLastEvent())
00581    {
00582       guiManager()->disableNext();
00583       // force enable play events action in --port mode
00584       if (m_monitor.get() && !guiManager()->playEventsAction()->isEnabled())
00585          guiManager()->playEventsAction()->enable();
00586    }
00587 }
00588 
00589 //==============================================================================
00590 void
00591 CmsShowMain::setupDataHandling()
00592 {
00593    guiManager()->updateStatus("Setting up data handling...");
00594 
00595 
00596    // navigator filtering  ->
00597    m_navigator->fileChanged_.connect(boost::bind(&CmsShowMain::fileChangedSlot, this, _1));
00598    m_navigator->editFiltersExternally_.connect(boost::bind(&FWGUIManager::updateEventFilterEnable, guiManager(), _1));
00599    m_navigator->filterStateChanged_.connect(boost::bind(&CmsShowMain::navigatorChangedFilterState, this, _1));
00600    m_navigator->postFiltering_.connect(boost::bind(&CmsShowMain::postFiltering, this));
00601 
00602    // navigator fitlering <-
00603    guiManager()->showEventFilterGUI_.connect(boost::bind(&CmsShowNavigator::showEventFilterGUI, m_navigator.get(),_1));
00604    guiManager()->filterButtonClicked_.connect(boost::bind(&CmsShowMain::filterButtonClicked,this));
00605 
00606    // Data handling. File related and therefore not in the base class.
00607    if (guiManager()->getAction(cmsshow::sOpenData)    != 0) 
00608       guiManager()->getAction(cmsshow::sOpenData)->activated.connect(sigc::mem_fun(*this, &CmsShowMain::openData));
00609    if (guiManager()->getAction(cmsshow::sAppendData)  != 0) 
00610       guiManager()->getAction(cmsshow::sAppendData)->activated.connect(sigc::mem_fun(*this, &CmsShowMain::appendData));
00611    if (guiManager()->getAction(cmsshow::sSearchFiles) != 0)
00612       guiManager()->getAction(cmsshow::sSearchFiles)->activated.connect(sigc::mem_fun(*this, &CmsShowMain::openDataViaURL));
00613 
00614    setupActions();
00615    // init data from  CmsShowNavigator configuration, can do this with signals since there were not connected yet
00616    guiManager()->setFilterButtonIcon(m_navigator->getFilterState());
00617 
00618    for (unsigned int ii = 0; ii < m_inputFiles.size(); ++ii)
00619    {
00620       const std::string& fname = m_inputFiles[ii];
00621       if (fname.empty())
00622          continue;
00623       guiManager()->updateStatus("loading data file ...");
00624       if (!m_navigator->appendFile(fname, false, false))
00625       {
00626          guiManager()->updateStatus("failed to load data file");
00627       }
00628       else
00629       {
00630          m_loadedAnyInputFile = true;
00631 
00632       }
00633    }
00634 
00635    if (m_loadedAnyInputFile)
00636    {
00637       m_navigator->firstEvent();
00638       checkPosition();
00639       draw();
00640    }
00641    else if (m_monitor.get() == 0 && (eiManager()->begin() != eiManager()->end()) )
00642    {
00643       if (m_inputFiles.empty())
00644          openDataViaURL();
00645       else
00646          openData();
00647    }
00648 }
00649 
00650 void
00651 CmsShowMain::setupSocket(unsigned int iSocket)
00652 {
00653    m_monitor = std::auto_ptr<TMonitor>(new TMonitor);
00654    TServerSocket* server = new TServerSocket(iSocket,kTRUE);
00655    if (server->GetErrorCode())
00656    {
00657       fwLog(fwlog::kError) << "CmsShowMain::setupSocket, can't create socket on port "<< iSocket << "." << std::endl;
00658       exit(0);
00659    }    
00660    m_monitor->Add(server);
00661 }
00662 
00663 void
00664 CmsShowMain::connectSocket()
00665 {
00666   m_monitor->Connect("Ready(TSocket*)","CmsShowMain",this,"notified(TSocket*)");
00667 
00668 }
00669 
00670 void
00671 CmsShowMain::notified(TSocket* iSocket)
00672 {
00673    TServerSocket* server = dynamic_cast<TServerSocket*> (iSocket);
00674    if (server)
00675    {
00676       TSocket* connection = server->Accept();
00677       if (connection)
00678       {
00679          m_monitor->Add(connection);
00680          std::stringstream s;
00681          s << "received connection from "<<iSocket->GetInetAddress().GetHostName();
00682          guiManager()->updateStatus(s.str().c_str());
00683       }
00684    }
00685    else
00686    {
00687       char buffer[4096];
00688       memset(buffer,0,sizeof(buffer));
00689       if (iSocket->RecvRaw(buffer, sizeof(buffer)) <= 0)
00690       {
00691          m_monitor->Remove(iSocket);
00692          //std::stringstream s;
00693          //s << "closing connection to "<<iSocket->GetInetAddress().GetHostName();
00694          //m_guiManager->updateStatus(s.str().c_str());
00695          delete iSocket;
00696          return;
00697       }
00698       std::string fileName(buffer);
00699       std::string::size_type lastNonSpace = fileName.find_last_not_of(" \n\t");
00700       if (lastNonSpace != std::string::npos)
00701       {
00702          fileName.erase(lastNonSpace+1);
00703       }
00704 
00705       std::stringstream s;
00706       s <<"New file notified '"<<fileName<<"'";
00707       guiManager()->updateStatus(s.str().c_str());
00708 
00709       bool appended = m_navigator->appendFile(fileName, true, m_live);
00710 
00711       if (appended)
00712       {
00713          if (m_live && isPlaying() && forward())
00714             m_navigator->activateNewFileOnNextEvent();
00715          else if (!isPlaying())
00716             checkPosition();
00717 
00718          // bootstrap case: --port  and no input file
00719          if (!m_loadedAnyInputFile)
00720          {
00721             m_loadedAnyInputFile = true;
00722             m_navigator->firstEvent();
00723             if (!isPlaying())
00724                draw();
00725          }
00726 
00727          std::stringstream sr;
00728          sr <<"New file registered '"<<fileName<<"'";
00729          guiManager()->updateStatus(sr.str().c_str());
00730       }
00731       else
00732       {
00733          std::stringstream sr;
00734          sr <<"New file NOT registered '"<<fileName<<"'";
00735          guiManager()->updateStatus(sr.str().c_str());
00736       }
00737    }
00738 }
00739 
00740 void
00741 CmsShowMain::stopPlaying()
00742 {
00743    stopAutoLoadTimer();
00744    if (m_live)
00745       m_navigator->resetNewFileOnNextEvent();
00746    setIsPlaying(false);
00747    guiManager()->enableActions();
00748    checkPosition();
00749 }
00750 
00751 void
00752 CmsShowMain::navigatorChangedFilterState(int state)
00753 {
00754    guiManager()->setFilterButtonIcon(state);
00755    if (m_navigator->filesNeedUpdate() == false)
00756    {
00757       guiManager()->setFilterButtonText(m_navigator->filterStatusMessage());
00758       checkPosition();
00759    }
00760 }
00761 
00762 void
00763 CmsShowMain::filterButtonClicked()
00764 {
00765    if (m_navigator->getFilterState() == CmsShowNavigator::kWithdrawn )
00766       guiManager()->showEventFilterGUI();
00767    else
00768       m_navigator->toggleFilterEnable();
00769 }
00770 
00771 void
00772 CmsShowMain::preFiltering()
00773 {
00774    // called only if filter has changed
00775    guiManager()->updateStatus("Filtering events");
00776 }
00777 
00778 void
00779 CmsShowMain::postFiltering()
00780 {
00781    // called only filter is changed
00782    guiManager()->clearStatus();
00783    draw();
00784    checkPosition();
00785    guiManager()->setFilterButtonText(m_navigator->filterStatusMessage());
00786 }
00787 
00788 //______________________________________________________________________________
00789 
00790 void
00791 CmsShowMain::setLiveMode()
00792 {
00793    m_live = true;
00794    m_liveTimer.reset(new SignalTimer());
00795    m_liveTimer->timeout_.connect(boost::bind(&CmsShowMain::checkLiveMode,this));
00796 
00797    Window_t rootw, childw;
00798    Int_t root_x, root_y, win_x, win_y;
00799    UInt_t mask;
00800    gVirtualX->QueryPointer(gClient->GetDefaultRoot()->GetId(),
00801                            rootw, childw,
00802                            root_x, root_y,
00803                            win_x, win_y,
00804                            mask);
00805 
00806 
00807    m_liveTimer->SetTime(m_liveTimeout);
00808    m_liveTimer->Reset();
00809    m_liveTimer->TurnOn();
00810 }
00811 
00812 void
00813 CmsShowMain::checkLiveMode()
00814 {
00815    m_liveTimer->TurnOff();
00816 
00817    TGX11 *x11 = dynamic_cast<TGX11*>(gVirtualX);
00818    if (x11) {
00819       XAnyEvent *ev = (XAnyEvent*) x11->GetNativeEvent();
00820       // printf("serial %d \n",(int)ev->serial );
00821 
00822       if ( !isPlaying() && m_lastXEventSerial == ev->serial )
00823          guiManager()->playEventsAction()->switchMode();
00824       m_lastXEventSerial = ev->serial;
00825    }
00826 
00827    m_liveTimer->SetTime((Long_t)(m_liveTimeout));
00828    m_liveTimer->Reset();
00829    m_liveTimer->TurnOn();
00830 }