CMS 3D CMS Logo

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