Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:40

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWGUIManager
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Mon Feb 11 11:06:40 EST 2008
0011 // system include files
0012 #include <functional>
0013 #include <stdexcept>
0014 #include <iostream>
0015 #include <cstdio>
0016 #include <sstream>
0017 #include <thread>
0018 #include <future>
0019 
0020 #include "TGButton.h"
0021 #include "TGLabel.h"
0022 #include "TSystem.h"
0023 #include "TGLIncludes.h"
0024 #include "TGLViewer.h"
0025 #include "TEveBrowser.h"
0026 #include "TEveManager.h"
0027 #include "TGPack.h"
0028 #include "TEveWindow.h"
0029 #include "TEveViewer.h"
0030 #include "TEveWindowManager.h"
0031 #include "TEveSelection.h"
0032 #include "TVirtualX.h"
0033 #include "TFile.h"
0034 
0035 // user include files
0036 #include "Fireworks/Core/interface/FWGUIManager.h"
0037 #include "Fireworks/Core/interface/Context.h"
0038 #include "Fireworks/Core/interface/FWGUISubviewArea.h"
0039 #include "Fireworks/Core/interface/FWTEveViewer.h"
0040 
0041 #include "Fireworks/Core/interface/FWSelectionManager.h"
0042 #include "Fireworks/Core/interface/FWEventItemsManager.h"
0043 #include "Fireworks/Core/interface/FWSummaryManager.h"
0044 #include "Fireworks/Core/interface/FWColorManager.h"
0045 #include "Fireworks/Core/interface/FWDetailViewManager.h"
0046 #include "Fireworks/Core/interface/FWViewBase.h"
0047 #include "Fireworks/Core/interface/FWViewType.h"
0048 #include "Fireworks/Core/interface/FWGeometryTableViewBase.h"
0049 #include "Fireworks/Core/interface/FWJobMetadataManager.h"
0050 #include "Fireworks/Core/interface/FWInvMassDialog.h"
0051 
0052 #include "Fireworks/Core/interface/FWConfiguration.h"
0053 
0054 #include "Fireworks/Core/interface/CmsShowMainFrame.h"
0055 #include "Fireworks/Core/interface/FWNavigatorBase.h"
0056 
0057 #include "Fireworks/Core/src/FWGUIEventDataAdder.h"
0058 #include "Fireworks/Core/src/FWNumberEntry.h"
0059 
0060 #include "Fireworks/Core/interface/CSGAction.h"
0061 
0062 #include "Fireworks/Core/interface/ActionsList.h"
0063 
0064 #include "Fireworks/Core/interface/CmsShowEDI.h"
0065 #include "Fireworks/Core/interface/CmsShowCommon.h"
0066 #include "Fireworks/Core/interface/CmsShowCommonPopup.h"
0067 #include "Fireworks/Core/interface/CmsShowModelPopup.h"
0068 #include "Fireworks/Core/interface/CmsShowViewPopup.h"
0069 
0070 #include "Fireworks/Core/interface/CmsShowHelpPopup.h"
0071 
0072 #include "Fireworks/Core/interface/CmsShowTaskExecutor.h"
0073 
0074 #include "Fireworks/Core/interface/FWTypeToRepresentations.h"
0075 #include "Fireworks/Core/interface/FWIntValueListener.h"
0076 #include "Fireworks/Core/interface/FWCustomIconsButton.h"
0077 
0078 #include "Fireworks/Core/src/FWModelContextMenuHandler.h"
0079 
0080 #include "Fireworks/Core/interface/fwLog.h"
0081 
0082 #include "Fireworks/Core/interface/FWEventItem.h"
0083 #include "Fireworks/Core/interface/FW3DViewBase.h"
0084 #include "Fireworks/Core/interface/FWExpressionException.h"
0085 
0086 #include "FWCore/Common/interface/EventBase.h"
0087 
0088 #include "CommonTools/Utils/interface/parser/Grammar.h"
0089 #include "CommonTools/Utils/interface/parser/Exception.h"
0090 
0091 // constants, enums and typedefs
0092 //
0093 //
0094 // static data member definitions
0095 //
0096 FWGUIManager* FWGUIManager::m_guiManager = nullptr;
0097 
0098 //
0099 // constructors and destructor
0100 //
0101 
0102 FWGUIManager::FWGUIManager(fireworks::Context* ctx, const FWViewManagerManager* iVMMgr, FWNavigatorBase* navigator)
0103     : m_context(ctx),
0104       m_summaryManager(nullptr),
0105       m_detailViewManager(nullptr),
0106       m_viewManagerManager(iVMMgr),
0107       m_contextMenuHandler(nullptr),
0108       m_navigator(navigator),
0109       m_dataAdder(nullptr),
0110       m_ediFrame(nullptr),
0111       m_modelPopup(nullptr),
0112       m_viewPopup(nullptr),
0113       m_commonPopup(nullptr),
0114       m_invMassDialog(nullptr),
0115       m_helpPopup(nullptr),
0116       m_shortcutPopup(nullptr),
0117       m_helpGLPopup(nullptr),
0118       m_tasks(new CmsShowTaskExecutor),
0119       m_WMOffsetX(0),
0120       m_WMOffsetY(0),
0121       m_WMDecorH(0) {
0122   m_guiManager = this;
0123 
0124   measureWMOffsets();
0125 
0126   FWEventItemsManager* im = (FWEventItemsManager*)m_context->eventItemsManager();
0127   im->newItem_.connect(std::bind(&FWGUIManager::newItem, this, std::placeholders::_1));
0128 
0129   m_context->colorManager()->colorsHaveChangedFinished_.connect(std::bind(&FWGUIManager::finishUpColorChange, this));
0130 
0131   TEveCompositeFrame::IconBarCreator_foo foo = &FWGUIManager::makeGUIsubview;
0132   TEveCompositeFrame::SetupFrameMarkup(foo, 20, 4, false);
0133 
0134   {
0135     m_cmsShowMainFrame = new CmsShowMainFrame(gClient->GetRoot(), 950, 750, this);
0136 
0137     m_cmsShowMainFrame->SetCleanup(kDeepCleanup);
0138 
0139     /*
0140         int mlist[FWViewType::kTypeSize] = {FWViewType::kRhoPhi, FWViewType::kRhoZ, FWViewType::k3D, FWViewType::kISpy, FWViewType::kLego, FWViewType::kLegoHF, FWViewType::kGlimpse, 
0141         FWViewType::kTable, FWViewType::kTableL1, FWViewType::kTableHLT,
0142         FWViewType::kGeometryTable,
0143         FWViewType::kRhoPhiPF, FWViewType::kLegoPFECAL}; */
0144 
0145     for (int i = 0; i < FWViewType::kTypeSize; ++i) {
0146       if (m_context->getHidePFBuilders() && (i == FWViewType::kLegoPFECAL || i == FWViewType::kRhoPhiPF))
0147         continue;
0148 
0149       bool separator = (i == FWViewType::kGlimpse || i == FWViewType::kTableHLT || i == FWViewType::kLegoPFECAL);
0150       CSGAction* action = m_cmsShowMainFrame->createNewViewerAction(FWViewType::idToName(i), separator);
0151       action->activated.connect(std::bind(&FWGUIManager::newViewSlot, this, FWViewType::idToName(i)));
0152     }
0153 
0154     m_detailViewManager = new FWDetailViewManager(m_context);
0155     m_contextMenuHandler = new FWModelContextMenuHandler(
0156         m_context->selectionManager(), m_detailViewManager, m_context->colorManager(), this);
0157 
0158     getAction(cmsshow::sExportImage)->activated.connect(sigc::mem_fun(*this, &FWGUIManager::exportImageOfMainView));
0159     getAction(cmsshow::sExportAllImages)->activated.connect(sigc::mem_fun(*this, &FWGUIManager::exportImagesOfAllViews));
0160     getAction(cmsshow::sLoadConfig)
0161         ->activated.connect(sigc::mem_fun(*this, &FWGUIManager::promptForLoadConfigurationFile));
0162     getAction(cmsshow::sLoadPartialConfig)
0163         ->activated.connect(sigc::mem_fun(*this, &FWGUIManager::promptForPartialLoadConfigurationFile));
0164     getAction(cmsshow::sSaveConfig)->activated.connect(writeToPresentConfigurationFile_);
0165 
0166     getAction(cmsshow::sSavePartialConfig)
0167         ->activated.connect(sigc::mem_fun(*this, &FWGUIManager::savePartialToConfigurationFile));
0168     getAction(cmsshow::sSaveConfigAs)
0169         ->activated.connect(sigc::mem_fun(*this, &FWGUIManager::promptForSaveConfigurationFile));
0170     getAction(cmsshow::sSavePartialConfigAs)
0171         ->activated.connect(sigc::mem_fun(*this, &FWGUIManager::promptForPartialSaveConfigurationFile));
0172     getAction(cmsshow::sShowEventDisplayInsp)->activated.connect(std::bind(&FWGUIManager::showEDIFrame, this, -1));
0173     getAction(cmsshow::sShowMainViewCtl)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::showViewPopup));
0174     getAction(cmsshow::sShowObjInsp)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::showModelPopup));
0175 
0176     getAction(cmsshow::sBackgroundColor)
0177         ->activated.connect(sigc::mem_fun(*m_context->colorManager(), &FWColorManager::switchBackground));
0178     getAction(cmsshow::sShowCommonInsp)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::showCommonPopup));
0179 
0180     getAction(cmsshow::sShowInvMassDialog)
0181         ->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::showInvMassDialog));
0182 
0183     getAction(cmsshow::sShowAddCollection)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::addData));
0184     assert(getAction(cmsshow::sHelp) != nullptr);
0185     getAction(cmsshow::sHelp)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::createHelpPopup));
0186     assert(getAction(cmsshow::sKeyboardShort) != nullptr);
0187     getAction(cmsshow::sKeyboardShort)
0188         ->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::createShortcutPopup));
0189     getAction(cmsshow::sHelpGL)->activated.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::createHelpGLPopup));
0190 
0191     // toolbar special widget with non-void actions
0192     m_cmsShowMainFrame->m_delaySliderListener->valueChanged_.connect(
0193         std::bind(&FWGUIManager::delaySliderChanged, this, std::placeholders::_1));
0194 
0195     TQObject::Connect(m_cmsShowMainFrame->m_runEntry, "ReturnPressed()", "FWGUIManager", this, "runIdChanged()");
0196     TQObject::Connect(m_cmsShowMainFrame->m_lumiEntry, "ReturnPressed()", "FWGUIManager", this, "lumiIdChanged()");
0197     TQObject::Connect(m_cmsShowMainFrame->m_eventEntry, "ReturnPressed()", "FWGUIManager", this, "eventIdChanged()");
0198 
0199     TQObject::Connect(
0200         m_cmsShowMainFrame->m_filterShowGUIBtn, "Clicked()", "FWGUIManager", this, "showEventFilterGUI()");
0201     TQObject::Connect(
0202         m_cmsShowMainFrame->m_filterEnableBtn, "Clicked()", "FWGUIManager", this, "filterButtonClicked()");
0203 
0204     TQObject::Connect(gEve->GetWindowManager(),
0205                       "WindowSelected(TEveWindow*)",
0206                       "FWGUIManager",
0207                       this,
0208                       "checkSubviewAreaIconState(TEveWindow*)");
0209     TQObject::Connect(gEve->GetWindowManager(),
0210                       "WindowDocked(TEveWindow*)",
0211                       "FWGUIManager",
0212                       this,
0213                       "checkSubviewAreaIconState(TEveWindow*)");
0214     TQObject::Connect(gEve->GetWindowManager(),
0215                       "WindowUndocked(TEveWindow*)",
0216                       "FWGUIManager",
0217                       this,
0218                       "checkSubviewAreaIconState(TEveWindow*)");
0219   }
0220 }
0221 
0222 void FWGUIManager::connectSubviewAreaSignals(FWGUISubviewArea* a) {
0223   a->goingToBeDestroyed_.connect(std::bind(&FWGUIManager::subviewIsBeingDestroyed, this, std::placeholders::_1));
0224   a->selected_.connect(std::bind(&FWGUIManager::subviewInfoSelected, this, std::placeholders::_1));
0225   a->unselected_.connect(std::bind(&FWGUIManager::subviewInfoUnselected, this, std::placeholders::_1));
0226   a->swap_.connect(std::bind(&FWGUIManager::subviewSwapped, this, std::placeholders::_1));
0227 }
0228 
0229 //
0230 // Destructor
0231 //
0232 FWGUIManager::~FWGUIManager() {
0233   delete m_invMassDialog;
0234   delete m_summaryManager;
0235   delete m_detailViewManager;
0236   delete m_cmsShowMainFrame;
0237   delete m_viewPopup;
0238   delete m_ediFrame;
0239   delete m_contextMenuHandler;
0240 }
0241 
0242 void FWGUIManager::evePreTerminate() {
0243   gEve->GetWindowManager()->Disconnect("WindowSelected(TEveWindow*)", this, "checkSubviewAreaIconState(TEveWindow*)");
0244   gEve->GetWindowManager()->Disconnect("WindowDocked(TEveWindow*)", this, "checkSubviewAreaIconState(TEveWindow*)");
0245   gEve->GetWindowManager()->Disconnect("WindowUndocked(TEveWindow*)", this, "checkSubviewAreaIconState(TEveWindow*)");
0246 
0247   // avoid emit signals at end
0248   gEve->GetSelection()->Disconnect();
0249   gEve->GetHighlight()->Disconnect();
0250   gEve->GetSelection()->RemoveElements();
0251   gEve->GetHighlight()->RemoveElements();
0252 
0253   m_cmsShowMainFrame->UnmapWindow();
0254   for (ViewMap_i wIt = m_viewMap.begin(); wIt != m_viewMap.end(); ++wIt) {
0255     TEveCompositeFrameInMainFrame* mainFrame =
0256         dynamic_cast<TEveCompositeFrameInMainFrame*>((*wIt).first->GetEveFrame());
0257     //  main frames not to watch dying
0258     if (mainFrame)
0259       mainFrame->UnmapWindow();
0260     // destroy
0261     (*wIt).second->destroy();
0262   }
0263 }
0264 
0265 //______________________________________________________________________________
0266 // subviews construction
0267 //
0268 
0269 TGFrame* FWGUIManager::makeGUIsubview(TEveCompositeFrame* cp, TGCompositeFrame* parent, Int_t height) {
0270   TGFrame* frame = new FWGUISubviewArea(cp, parent, height);
0271   return frame;
0272 }
0273 
0274 void FWGUIManager::registerViewBuilder(const std::string& iName, ViewBuildFunctor& iBuilder) {
0275   m_nameToViewBuilder[iName] = iBuilder;
0276 }
0277 
0278 void FWGUIManager::newViewSlot(const std::string& iName) {
0279   // this function have to exist, becuse CSGAction binds to void functions
0280   createView(iName);
0281 }
0282 
0283 FWGUIManager::ViewMap_i FWGUIManager::createView(const std::string& iName, TEveWindowSlot* slot) {
0284   NameToViewBuilder::iterator itFind = m_nameToViewBuilder.find(iName);
0285   assert(itFind != m_nameToViewBuilder.end());
0286   if (itFind == m_nameToViewBuilder.end()) {
0287     throw std::runtime_error(std::string("Unable to create view named ") + iName + " because it is unknown");
0288   }
0289 
0290   if (!slot) {
0291     if (m_viewSecPack) {
0292       slot = m_viewSecPack->NewSlot();
0293     } else {
0294       slot = m_viewPrimPack->NewSlot();
0295       m_viewSecPack = m_viewPrimPack->NewSlot()->MakePack();
0296       m_viewSecPack->SetShowTitleBar(kFALSE);
0297     }
0298   }
0299   TEveCompositeFrame* ef = slot->GetEveFrame();
0300   FWViewBase* viewBase = itFind->second(slot, iName);
0301   //in future, get context from 'view'
0302   FWViewContextMenuHandlerBase* base = viewBase->contextMenuHandler();
0303   viewBase->openSelectedModelContextMenu_.connect(std::bind(
0304       &FWGUIManager::showSelectedModelContextMenu, m_guiManager, std::placeholders::_1, std::placeholders::_2, base));
0305 
0306   TEveWindow* eveWindow = ef->GetEveWindow();
0307   eveWindow->SetElementName(iName.c_str());
0308 
0309   std::pair<ViewMap_i, bool> insertPair = m_viewMap.insert(std::make_pair(eveWindow, viewBase));
0310   return insertPair.first;
0311 }
0312 
0313 //
0314 // actions
0315 //
0316 
0317 void FWGUIManager::enableActions(bool enable) { m_cmsShowMainFrame->enableActions(enable); }
0318 
0319 void FWGUIManager::titleChanged(const char* subtitle) {
0320   char title[128];
0321   snprintf(title, 127, "cmsShow: %s", subtitle);
0322   m_cmsShowMainFrame->SetWindowName(title);
0323 }
0324 
0325 void FWGUIManager::eventChangedCallback() {
0326   // To be replaced when we can get index from fwlite::Event
0327 
0328   TEveViewerList* viewers = gEve->GetViewers();
0329   for (TEveElement::List_i i = viewers->BeginChildren(); i != viewers->EndChildren(); ++i) {
0330     TEveViewer* ev = dynamic_cast<TEveViewer*>(*i);
0331     if (ev)
0332       ev->GetGLViewer()->DeleteOverlayAnnotations();
0333   }
0334 
0335   for (auto reg : m_regionViews) {
0336     for (ViewMap_i it = m_viewMap.begin(); it != m_viewMap.end(); ++it) {
0337       if (it->second == reg) {
0338         m_viewMap.erase(it);
0339         reg->destroy();
0340         break;
0341       }
0342     }
0343   }
0344 
0345   m_cmsShowMainFrame->loadEvent(*getCurrentEvent());
0346   m_detailViewManager->newEventCallback();
0347 }
0348 
0349 CSGAction* FWGUIManager::getAction(const std::string name) { return m_cmsShowMainFrame->getAction(name); }
0350 
0351 CSGContinuousAction* FWGUIManager::playEventsAction() { return m_cmsShowMainFrame->playEventsAction(); }
0352 
0353 CSGContinuousAction* FWGUIManager::playEventsBackwardsAction() {
0354   return m_cmsShowMainFrame->playEventsBackwardsAction();
0355 }
0356 
0357 CSGContinuousAction* FWGUIManager::loopAction() { return m_cmsShowMainFrame->loopAction(); }
0358 
0359 void FWGUIManager::disablePrevious() { m_cmsShowMainFrame->enablePrevious(false); }
0360 
0361 void FWGUIManager::disableNext() { m_cmsShowMainFrame->enableNext(false); }
0362 
0363 void FWGUIManager::setPlayMode(bool play) {
0364   m_cmsShowMainFrame->m_runEntry->SetEnabled(!play);
0365   m_cmsShowMainFrame->m_eventEntry->SetEnabled(!play);
0366 }
0367 
0368 void FWGUIManager::updateStatus(const char* status) { m_cmsShowMainFrame->updateStatusBar(status); }
0369 
0370 void FWGUIManager::clearStatus() { m_cmsShowMainFrame->clearStatusBar(); }
0371 
0372 void FWGUIManager::newItem(const FWEventItem* iItem) {
0373 #if defined(THIS_WILL_NEVER_BE_DEFINED)
0374   m_selectionItemsComboBox->AddEntry(iItem->name().c_str(), iItem->id());
0375   if (iItem->id() == 0) {
0376     m_selectionItemsComboBox->Select(0);
0377   }
0378 #endif
0379 }
0380 
0381 void FWGUIManager::addData() {
0382   if (nullptr == m_dataAdder) {
0383     m_dataAdder = new FWGUIEventDataAdder(100,
0384                                           100,
0385                                           (FWEventItemsManager*)m_context->eventItemsManager(),
0386                                           m_cmsShowMainFrame,
0387                                           m_context->metadataManager());
0388   }
0389   m_dataAdder->show();
0390 }
0391 
0392 //  subview actions
0393 //
0394 
0395 TEveWindow* FWGUIManager::getSwapCandidate() {
0396   TEveWindow* swapCandidate = nullptr;
0397 
0398   if (gEve->GetWindowManager()->GetCurrentWindow()) {
0399     swapCandidate = gEve->GetWindowManager()->GetCurrentWindow();
0400   } else {
0401     // swap with first docked view
0402     TEveCompositeFrame* pef;
0403     TGFrameElementPack* pel;
0404 
0405     // check if there is view in prim pack
0406     TGPack* pp = m_viewPrimPack->GetPack();
0407     if (pp->GetList()->GetSize() > 2) {
0408       pel = (TGFrameElementPack*)pp->GetList()->At(1);
0409       if (pel->fState)  // is first undocked
0410       {
0411         pef = dynamic_cast<TEveCompositeFrame*>(pel->fFrame);
0412         if (pef && pef->GetEveWindow())
0413           swapCandidate = pef->GetEveWindow();
0414       }
0415     }
0416     if (swapCandidate == nullptr) {
0417       // no eve window found in primary, check secondary
0418       TGPack* sp = m_viewSecPack->GetPack();
0419       TIter frame_iterator(sp->GetList());
0420       while ((pel = (TGFrameElementPack*)frame_iterator())) {
0421         pef = dynamic_cast<TEveCompositeFrame*>(pel->fFrame);
0422         if (pef && pef->GetEveWindow() && pel->fState) {
0423           swapCandidate = pef->GetEveWindow();
0424           break;
0425         }
0426       }
0427     }
0428   }
0429   return swapCandidate;
0430 }
0431 
0432 void FWGUIManager::checkSubviewAreaIconState(TEveWindow* /*ew*/) {
0433   // First argumet is needed for signals/slot symetry
0434 
0435   // disable swap on the first left TEveCompositeFrame
0436   // check info button
0437   TEveWindow* current = getSwapCandidate();
0438   bool checkInfoBtn = m_viewPopup ? m_viewPopup->mapped() : false;
0439   TEveWindow* selected = m_viewPopup ? m_viewPopup->getEveWindow() : nullptr;
0440 
0441   for (ViewMap_i it = m_viewMap.begin(); it != m_viewMap.end(); it++) {
0442     FWGUISubviewArea* ar = FWGUISubviewArea::getToolBarFromWindow(it->first);
0443     ar->setSwapIcon(current != it->first);
0444     if (checkInfoBtn && selected)
0445       ar->setInfoButton(selected == it->first);
0446   }
0447 }
0448 
0449 void FWGUIManager::subviewIsBeingDestroyed(FWGUISubviewArea* sva) {
0450   if (sva->isSelected())
0451     setViewPopup(nullptr);
0452 
0453   CmsShowTaskExecutor::TaskFunctor f;
0454   f = std::bind(&FWGUIManager::subviewDestroy, this, sva);
0455   m_tasks->addTask(f);
0456   m_tasks->startDoingTasks();
0457 }
0458 
0459 void FWGUIManager::subviewDestroy(FWGUISubviewArea* sva) {
0460   TEveWindow* ew = sva->getEveWindow();
0461   FWViewBase* viewBase = m_viewMap[ew];
0462   m_viewMap.erase(ew);
0463   viewBase->destroy();
0464 }
0465 
0466 void FWGUIManager::subviewDestroyAll() {
0467   std::vector<FWGUISubviewArea*> sd;
0468   for (ViewMap_i wIt = m_viewMap.begin(); wIt != m_viewMap.end(); ++wIt) {
0469     FWGUISubviewArea* ar = FWGUISubviewArea::getToolBarFromWindow(wIt->first);
0470     sd.push_back(ar);
0471   }
0472 
0473   for (std::vector<FWGUISubviewArea*>::iterator i = sd.begin(); i != sd.end(); ++i) {
0474     if ((*i)->isSelected())
0475       setViewPopup(nullptr);
0476     subviewDestroy(*i);
0477   }
0478 
0479   gSystem->ProcessEvents();
0480   gSystem->Sleep(200);
0481 
0482   while (m_viewPrimPack->HasChildren()) {
0483     TEveWindow* w = dynamic_cast<TEveWindow*>(m_viewPrimPack->FirstChild());
0484     if (w)
0485       w->DestroyWindowAndSlot();
0486   }
0487 
0488   gSystem->Sleep(200);
0489   m_viewSecPack = nullptr;
0490   gSystem->ProcessEvents();
0491 }
0492 
0493 void FWGUIManager::subviewInfoSelected(FWGUISubviewArea* sva) {
0494   // release button on previously selected
0495   TEveWindow* ew = sva->getEveWindow();
0496   for (ViewMap_i wIt = m_viewMap.begin(); wIt != m_viewMap.end(); ++wIt) {
0497     if (wIt->first != ew)
0498       FWGUISubviewArea::getToolBarFromWindow(wIt->first)->setInfoButton(kFALSE);
0499   }
0500   setViewPopup(sva->getEveWindow());
0501 }
0502 
0503 void FWGUIManager::subviewInfoUnselected(FWGUISubviewArea* sva) { m_viewPopup->UnmapWindow(); }
0504 
0505 void FWGUIManager::subviewSwapped(FWGUISubviewArea* sva) {
0506   TEveWindow* curr = getSwapCandidate();
0507   TEveWindow* swap = sva->getEveWindow();
0508   if (curr)
0509     swap->SwapWindow(curr);
0510 
0511   checkSubviewAreaIconState(nullptr);
0512 }
0513 
0514 TGVerticalFrame* FWGUIManager::createList(TGCompositeFrame* p) {
0515   TGVerticalFrame* listFrame = new TGVerticalFrame(p, p->GetWidth(), p->GetHeight());
0516 
0517   TGHorizontalFrame* addFrame = new TGHorizontalFrame(listFrame, p->GetWidth(), 10, kRaisedFrame);
0518   TGLabel* addLabel = new TGLabel(addFrame, "Summary View");
0519   addFrame->AddFrame(addLabel, new TGLayoutHints(kLHintsCenterX, 0, 0, 2, 2));
0520   listFrame->AddFrame(addFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop));
0521 
0522   m_summaryManager = new FWSummaryManager(listFrame,
0523                                           m_context->selectionManager(),
0524                                           (FWEventItemsManager*)m_context->eventItemsManager(),
0525                                           this,
0526                                           m_context->modelChangeManager(),
0527                                           m_context->colorManager());
0528 
0529   const unsigned int backgroundColor = 0x2f2f2f;
0530   TGTextButton* addDataButton = new TGTextButton(m_summaryManager->widget(), "Add Collection");
0531   addDataButton->ChangeOptions(kRaisedFrame);
0532   addDataButton->SetBackgroundColor(backgroundColor);
0533   addDataButton->SetTextColor(0xFFFFFF);
0534   addDataButton->SetToolTipText("Show additional collections");
0535   addDataButton->Connect("Clicked()", "FWGUIManager", this, "addData()");
0536   m_summaryManager->widget()->AddFrame(addDataButton, new TGLayoutHints(kLHintsExpandX | kLHintsLeft | kLHintsTop));
0537   listFrame->AddFrame(m_summaryManager->widget(), new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0538 
0539   return listFrame;
0540 }
0541 
0542 void FWGUIManager::createViews(TEveWindowSlot* slot) {
0543   m_viewPrimPack = slot->MakePack();
0544   m_viewPrimPack->SetHorizontal();
0545   m_viewPrimPack->SetElementName("Views");
0546   m_viewPrimPack->SetShowTitleBar(kFALSE);
0547   m_viewSecPack = nullptr;
0548 }
0549 
0550 void FWGUIManager::createEDIFrame() {
0551   if (m_ediFrame == nullptr) {
0552     m_ediFrame = new CmsShowEDI(m_cmsShowMainFrame, 200, 200, m_context->selectionManager(), m_context->colorManager());
0553     m_ediFrame->CenterOnParent(kTRUE, TGTransientFrame::kTopRight);
0554     m_cmsShowMainFrame->bindCSGActionKeys(m_ediFrame);
0555   }
0556 }
0557 
0558 void FWGUIManager::showEDIFrame(int iToShow) {
0559   createEDIFrame();
0560   if (-1 != iToShow) {
0561     m_ediFrame->show(static_cast<FWDataCategories>(iToShow));
0562   }
0563   m_ediFrame->MapRaised();
0564 }
0565 
0566 void FWGUIManager::open3DRegion() {
0567   try {
0568     FWModelId id = *(m_context->selectionManager()->selected().begin());
0569     float theta = 0, phi = 0;
0570     edm::TypeWithDict type = edm::TypeWithDict((TClass*)id.item()->modelType());
0571     using namespace boost::spirit::classic;
0572     reco::parser::ExpressionPtr tmpPtr;
0573     reco::parser::Grammar grammar(tmpPtr, type);
0574     edm::ObjectWithDict o(type, (void*)id.item()->modelData(id.index()));
0575     if (parse("theta()", grammar.use_parser<1>() >> end_p, space_p).full)
0576       theta = tmpPtr->value(o);
0577     else
0578       throw FWExpressionException("syntax error", -1);
0579     if (parse("phi()", grammar.use_parser<1>() >> end_p, space_p).full)
0580       phi = tmpPtr->value(o);
0581     else
0582       throw FWExpressionException("syntax error", -1);
0583     ViewMap_i it = createView("3D Tower", m_viewSecPack->NewSlot());
0584     FW3DViewBase* v = static_cast<FW3DViewBase*>(it->second);
0585     v->setClip(theta, phi);
0586     it->first->UndockWindow();
0587   } catch (const reco::parser::BaseException& e) {
0588     std::cout << " FWModelFilter failed to base " << e.what() << std::endl;
0589   }
0590 }
0591 
0592 void FWGUIManager::showCommonPopup() {
0593   if (!m_commonPopup) {
0594     m_commonPopup = new CmsShowCommonPopup(m_context->commonPrefs(), m_cmsShowMainFrame, 200, 200);
0595     m_context->commonPrefs()->setView(m_commonPopup);
0596     m_cmsShowMainFrame->bindCSGActionKeys(m_commonPopup);
0597   }
0598   m_commonPopup->MapRaised();
0599 }
0600 
0601 void FWGUIManager::createModelPopup() {
0602   m_modelPopup = new CmsShowModelPopup(
0603       m_detailViewManager, m_context->selectionManager(), m_context->colorManager(), m_cmsShowMainFrame, 200, 200);
0604   m_modelPopup->CenterOnParent(kTRUE, TGTransientFrame::kRight);
0605   m_cmsShowMainFrame->bindCSGActionKeys(m_modelPopup);
0606 }
0607 
0608 void FWGUIManager::showModelPopup() {
0609   if (!m_modelPopup)
0610     createModelPopup();
0611   m_modelPopup->MapRaised();
0612 }
0613 
0614 void FWGUIManager::popupViewClosed() {
0615   if (m_viewPopup->getEveWindow()) {
0616     FWGUISubviewArea* sa = FWGUISubviewArea::getToolBarFromWindow(m_viewPopup->getEveWindow());
0617     sa->setInfoButton(kFALSE);
0618   }
0619 }
0620 
0621 void FWGUIManager::showViewPopup() {
0622   // CSG action.
0623   setViewPopup(nullptr);
0624 }
0625 
0626 void FWGUIManager::setViewPopup(TEveWindow* ew) {
0627   FWViewBase* vb = ew ? m_viewMap[ew] : nullptr;
0628   if (m_viewPopup == nullptr) {
0629     m_viewPopup = new CmsShowViewPopup(nullptr, 200, 200, m_context->colorManager(), vb, ew);
0630     m_viewPopup->closed_.connect(sigc::mem_fun(*m_guiManager, &FWGUIManager::popupViewClosed));
0631   } else {
0632     m_viewPopup->UnmapWindow();
0633   }
0634   m_viewPopup->reset(vb, ew);
0635   m_viewPopup->MapRaised();
0636 }
0637 
0638 void FWGUIManager::showInvMassDialog() {
0639   if (!m_invMassDialog) {
0640     m_invMassDialog = new FWInvMassDialog(m_context->selectionManager());
0641     m_cmsShowMainFrame->bindCSGActionKeys(m_invMassDialog);
0642   }
0643   m_invMassDialog->MapRaised();
0644 }
0645 
0646 void FWGUIManager::createHelpPopup() {
0647   if (m_helpPopup == nullptr) {
0648     m_helpPopup = new CmsShowHelpPopup("help.html", "CmsShow Help", m_cmsShowMainFrame, 800, 600);
0649     m_helpPopup->CenterOnParent(kTRUE, TGTransientFrame::kBottomRight);
0650   }
0651   m_helpPopup->MapWindow();
0652 }
0653 
0654 void FWGUIManager::createShortcutPopup() {
0655   if (m_shortcutPopup == nullptr) {
0656     m_shortcutPopup = new CmsShowHelpPopup(
0657         "shortcuts.html", getAction(cmsshow::sKeyboardShort)->getName(), m_cmsShowMainFrame, 800, 600);
0658 
0659     m_shortcutPopup->CenterOnParent(kTRUE, TGTransientFrame::kBottomRight);
0660   }
0661   m_shortcutPopup->MapWindow();
0662 }
0663 
0664 void FWGUIManager::createHelpGLPopup() {
0665   if (m_helpGLPopup == nullptr) {
0666     m_helpGLPopup =
0667         new CmsShowHelpPopup("helpGL.html", getAction(cmsshow::sHelpGL)->getName(), m_cmsShowMainFrame, 800, 600);
0668 
0669     m_helpGLPopup->CenterOnParent(kTRUE, TGTransientFrame::kBottomRight);
0670   }
0671   m_helpGLPopup->MapWindow();
0672 }
0673 
0674 void FWGUIManager::showSelectedModelContextMenu(Int_t iGlobalX,
0675                                                 Int_t iGlobalY,
0676                                                 FWViewContextMenuHandlerBase* iHandler) {
0677   if (!m_context->selectionManager()->selected().empty()) {
0678     m_contextMenuHandler->showSelectedModelContext(iGlobalX, iGlobalY, iHandler);
0679   }
0680 }
0681 
0682 //
0683 // const member functions
0684 //
0685 
0686 FWGUIManager* FWGUIManager::getGUIManager() { return m_guiManager; }
0687 
0688 const edm::EventBase* FWGUIManager::getCurrentEvent() const { return m_navigator->getCurrentEvent(); }
0689 
0690 /** Helper method for a load / save configuration dialog.
0691 
0692     @a result where the picked file is stored.
0693     
0694     @a mode the mode for the dialog (i.e. Load / Save).
0695     
0696     @return true if a file was successfully picked, false otherwise.
0697   */
0698 bool FWGUIManager::promptForConfigurationFile(std::string& result, enum EFileDialogMode mode) {
0699   const static char* kFileTypes[] = {"Fireworks Configuration files", "*.fwc", "All Files", "*", nullptr, nullptr};
0700 
0701   static TString dir(".");
0702 
0703   TGFileInfo fi;
0704   fi.fFileTypes = kFileTypes;
0705   fi.fIniDir = StrDup(dir);
0706   new TGFileDialog(gClient->GetDefaultRoot(), m_cmsShowMainFrame, mode, &fi);
0707   dir = fi.fIniDir;
0708   if (fi.fFilename == nullptr)  // to handle "cancel" button properly
0709     return false;
0710   std::string name = fi.fFilename;
0711   // if the extension isn't already specified by hand, specify it now
0712   std::string ext = kFileTypes[fi.fFileTypeIdx + 1] + 1;
0713   if (!ext.empty() && name.find(ext) == name.npos)
0714     name += ext;
0715   result = name;
0716   return true;
0717 }
0718 
0719 /** Emits the signal which request to load the configuration file picked up 
0720     in a dialog.
0721   */
0722 void FWGUIManager::promptForLoadConfigurationFile() {
0723   std::string name;
0724   if (!promptForConfigurationFile(name, kFDOpen))
0725     return;
0726 
0727   loadFromConfigurationFile_(name);
0728 }
0729 
0730 void FWGUIManager::promptForPartialLoadConfigurationFile() {
0731   std::string name;
0732   if (!promptForConfigurationFile(name, kFDOpen))
0733     return;
0734 
0735   loadPartialFromConfigurationFile_(name);
0736   //
0737 }
0738 
0739 /** Emits the signal which requests to save the current configuration in the 
0740     file picked up in the dialog.
0741   */
0742 void FWGUIManager::promptForSaveConfigurationFile() {
0743   std::string name;
0744   if (!promptForConfigurationFile(name, kFDSave))
0745     return;
0746 
0747   writeToConfigurationFile_(name);
0748 }
0749 
0750 void FWGUIManager::promptForPartialSaveConfigurationFile() {
0751   std::string name;
0752   if (!promptForConfigurationFile(name, kFDSave))
0753     return;
0754 
0755   writePartialToConfigurationFile_(name);
0756 }
0757 
0758 void FWGUIManager::savePartialToConfigurationFile() { writePartialToConfigurationFile_("current"); }
0759 
0760 void FWGUIManager::exportImageOfMainView() {
0761   if (m_viewPrimPack->GetPack()->GetList()->GetSize() > 2) {
0762     TGFrameElementPack* frameEL = (TGFrameElementPack*)m_viewPrimPack->GetPack()->GetList()->At(1);
0763     TEveCompositeFrame* ef = dynamic_cast<TEveCompositeFrame*>(frameEL->fFrame);
0764     m_viewMap[ef->GetEveWindow()]->promptForSaveImageTo(m_cmsShowMainFrame);
0765   } else {
0766     fwLog(fwlog::kError) << "Main view has been destroyed." << std::endl;
0767   }
0768 }
0769 
0770 void FWGUIManager::exportImagesOfAllViews() {
0771   try {
0772     static TString dir(".");
0773     const char* kImageExportTypes[] = {"PNG",
0774                                        "*.png",
0775                                        "GIF",
0776                                        "*.gif",
0777                                        "JPEG",
0778                                        "*.jpg",
0779                                        "PDF",
0780                                        "*.pdf",
0781                                        "Encapsulated PostScript",
0782                                        "*.eps",
0783                                        nullptr,
0784                                        nullptr};
0785 
0786     TGFileInfo fi;
0787     fi.fFileTypes = kImageExportTypes;
0788     fi.fIniDir = StrDup(dir);
0789     new TGFileDialog(gClient->GetDefaultRoot(), m_cmsShowMainFrame, kFDSave, &fi);
0790     dir = fi.fIniDir;
0791     if (fi.fFilename != nullptr) {
0792       std::string name = fi.fFilename;
0793       // fi.fFileTypeIdx points to the name of the file type
0794       // selected in the drop-down menu, so fi.fFileTypeIdx gives us
0795       // the extension
0796       std::string ext = kImageExportTypes[fi.fFileTypeIdx + 1] + 1;
0797       if (name.find(ext) == name.npos)
0798         name += ext;
0799       // now add format trailing before the extension
0800       name.insert(name.rfind('.'), "-%u_%u_%u_%s");
0801       exportAllViews(name, -1);
0802     }
0803   } catch (std::runtime_error& e) {
0804     std::cout << e.what() << std::endl;
0805   }
0806 }
0807 
0808 void FWGUIManager::exportAllViews(const std::string& format, int height) {
0809   // Save all GL views.
0810   // Expects format to have "%u %u %llu %s" which are replaced with
0811   //   run-number, event number, lumi block and view-name.
0812   // Blanks in view-name are removed.
0813   // If several views shave the same name, they are post-fixed
0814   // with "_%d". They are sorted by view diagonal.
0815 
0816   typedef std::list<FWTEveViewer*> viewer_list_t;
0817   typedef viewer_list_t::iterator viewer_list_i;
0818 
0819   typedef std::map<TString, viewer_list_t> name_map_t;
0820   typedef name_map_t::iterator name_map_i;
0821 
0822   name_map_t vls;
0823 
0824   for (ViewMap_i i = m_viewMap.begin(); i != m_viewMap.end(); ++i) {
0825     FWTEveViewer* ev = dynamic_cast<FWTEveViewer*>(i->first);
0826     if (ev) {
0827       TString name(ev->GetElementName());
0828       name.ReplaceAll(" ", "");
0829       viewer_list_t& l = vls[name];
0830       viewer_list_i li = l.begin();
0831       while (li != l.end() && (*li)->GetGLViewer()->ViewportDiagonal() < ev->GetGLViewer()->ViewportDiagonal())
0832         ++li;
0833       l.insert(li, ev);
0834     }
0835   }
0836 
0837   std::vector<std::future<int>> futures;
0838 
0839   const edm::EventBase* event = getCurrentEvent();
0840   for (name_map_i i = vls.begin(); i != vls.end(); ++i) {
0841     bool multi_p = (i->second.size() > 1);
0842     int view_count = 1;
0843     for (viewer_list_i j = i->second.begin(); j != i->second.end(); ++j, ++view_count) {
0844       TString view_name(i->first);
0845       if (multi_p) {
0846         view_name += "_";
0847         view_name += view_count;
0848       }
0849       TString file;
0850       file.Form(format.c_str(), event->id().run(), event->id().event(), event->luminosityBlock(), view_name.Data());
0851 
0852       if (GLEW_EXT_framebuffer_object) {
0853         // Multi-threaded save
0854         futures.push_back((*j)->CaptureAndSaveImage(file, height));
0855       } else {
0856         // Single-threaded save
0857         if (height == -1)
0858           (*j)->GetGLViewer()->SavePicture(file);
0859         else
0860           (*j)->GetGLViewer()->SavePictureHeight(file, height);
0861       }
0862     }
0863   }
0864 
0865   for (auto& f : futures) {
0866     f.get();
0867   }
0868 }
0869 
0870 static const std::string kMainWindow("main window");
0871 static const std::string kViews("views");
0872 static const std::string kViewArea("view area");
0873 static const std::string kUndocked("undocked views");
0874 static const std::string kControllers("controllers");
0875 static const std::string kCollectionController("collection");
0876 static const std::string kViewController("view");
0877 static const std::string kObjectController("object");
0878 static const std::string kCommonController("common");
0879 
0880 static void addWindowInfoTo(const TGFrame* iMain, FWConfiguration& oTo) {
0881   Window_t wdummy;
0882   Int_t ax, ay;
0883   gVirtualX->TranslateCoordinates(iMain->GetId(),
0884                                   gClient->GetDefaultRoot()->GetId(),
0885                                   0,
0886                                   0,  //0,0 in local coordinates
0887                                   ax,
0888                                   ay,  //coordinates of screen
0889                                   wdummy);
0890   {
0891     std::stringstream s;
0892     s << ax;
0893     oTo.addKeyValue("x", FWConfiguration(s.str()));
0894   }
0895   {
0896     std::stringstream s;
0897     s << ay;
0898     oTo.addKeyValue("y", FWConfiguration(s.str()));
0899   }
0900   {
0901     std::stringstream s;
0902     s << iMain->GetWidth();
0903     oTo.addKeyValue("width", FWConfiguration(s.str()));
0904   }
0905   {
0906     std::stringstream s;
0907     s << iMain->GetHeight();
0908     oTo.addKeyValue("height", FWConfiguration(s.str()));
0909   }
0910 }
0911 
0912 class areaInfo {
0913   // helper class to save and restore view area
0914 public:
0915   areaInfo(TGFrameElementPack* frameElement) {
0916     eveWindow = nullptr;
0917     originalSlot = nullptr;
0918     undockedMainFrame = nullptr;
0919     weight = frameElement->fWeight;
0920     undocked = !frameElement->fState;
0921 
0922     TEveCompositeFrame* eveFrame = dynamic_cast<TEveCompositeFrame*>(frameElement->fFrame);
0923     assert(eveFrame);
0924 
0925     if (frameElement->fState)
0926       eveWindow = eveFrame->GetEveWindow();
0927     else
0928       originalSlot = eveFrame->GetEveWindow();
0929   }
0930 
0931   areaInfo() : weight(0), undocked(false) {}
0932 
0933   Float_t weight;
0934   Bool_t undocked;
0935   TEveWindow* eveWindow;
0936   TGMainFrame* undockedMainFrame;  // cached to help find original slot for undocked windows
0937   TEveWindow* originalSlot;
0938 };
0939 
0940 static void addAreaInfoTo(areaInfo& pInfo, FWConfiguration& oTo) {
0941   {
0942     std::stringstream s;
0943     s << pInfo.weight;
0944     oTo.addKeyValue("weight", FWConfiguration(s.str()));
0945   }
0946   {
0947     std::stringstream s;
0948     s << pInfo.undocked;
0949     oTo.addKeyValue("undocked", FWConfiguration(s.str()));
0950   }
0951 
0952   if (pInfo.undockedMainFrame) {
0953     FWConfiguration temp(oTo);
0954     addWindowInfoTo(pInfo.undockedMainFrame, temp);
0955     oTo.addKeyValue("UndockedWindowPos", temp);
0956   }
0957 }
0958 
0959 //______________________________________________________________________________
0960 void FWGUIManager::addTo(FWConfiguration& oTo) const {
0961   Int_t cfgVersion = 3;
0962 
0963   FWConfiguration mainWindow(cfgVersion);
0964   float leftWeight, rightWeight;
0965   addWindowInfoTo(m_cmsShowMainFrame, mainWindow);
0966   {
0967     // write summary view weight
0968     {
0969       std::stringstream ss;
0970       ss << m_cmsShowMainFrame->getSummaryViewWeight();
0971       mainWindow.addKeyValue("summaryWeight", FWConfiguration(ss.str()));
0972     }
0973 
0974     // write proportions of horizontal pack (can be standalone item outside main frame)
0975     if (m_viewPrimPack->GetPack()->GetList()->GetSize() > 2) {
0976       TGFrameElementPack* frameEL;
0977       frameEL = (TGFrameElementPack*)m_viewPrimPack->GetPack()->GetList()->At(
0978           1);  // read every second  element, first on is splitter
0979       leftWeight = frameEL->fWeight;
0980       frameEL = (TGFrameElementPack*)m_viewPrimPack->GetPack()->GetList()->At(3);
0981       rightWeight = frameEL->fWeight;
0982     } else {
0983       leftWeight = 0;
0984       rightWeight = 1;
0985     }
0986     std::stringstream sL;
0987     sL << leftWeight;
0988     mainWindow.addKeyValue("leftWeight", FWConfiguration(sL.str()));
0989     std::stringstream sR;
0990     sR << rightWeight;
0991     mainWindow.addKeyValue("rightWeight", FWConfiguration(sR.str()));
0992   }
0993   oTo.addKeyValue(kMainWindow, mainWindow, true);
0994 
0995   //------------------------------------------------------------
0996   // organize info about all docked frames includding hidden, which point to undocked
0997   std::vector<areaInfo> wpacked;
0998   if (leftWeight > 0) {
0999     TGPack* pp = m_viewPrimPack->GetPack();
1000     TGFrameElementPack* frameEL = (TGFrameElementPack*)pp->GetList()->At(1);
1001     if (frameEL->fWeight > 0)
1002       wpacked.push_back(areaInfo(frameEL));
1003   }
1004   TGPack* sp = m_viewSecPack->GetPack();
1005   TGFrameElementPack* seFE;
1006   TIter frame_iterator(sp->GetList());
1007   while ((seFE = (TGFrameElementPack*)frame_iterator())) {
1008     if (seFE->fWeight)
1009       wpacked.push_back(areaInfo(seFE));
1010   }
1011 
1012   //  undocked info
1013 
1014   for (ViewMap_i wIt = m_viewMap.begin(); wIt != m_viewMap.end(); ++wIt) {
1015     TEveWindow* ew = wIt->first;
1016     TEveCompositeFrameInMainFrame* mainFrame = dynamic_cast<TEveCompositeFrameInMainFrame*>(ew->GetEveFrame());
1017     if (mainFrame) {
1018       for (std::vector<areaInfo>::iterator pIt = wpacked.begin(); pIt != wpacked.end(); ++pIt) {
1019         if ((*pIt).originalSlot && mainFrame->GetOriginalSlot() == (*pIt).originalSlot) {
1020           (*pIt).eveWindow = wIt->first;
1021           (*pIt).undockedMainFrame = (TGMainFrame*)mainFrame;
1022           // printf("found original slot for docked view %s\n", pInfo->viewBase->typeName().c_str());
1023           break;
1024         }  // found match
1025       }
1026     }  // end main frames
1027   }
1028 
1029   //------------------------------------------------------------
1030   // add sorted list in view area and FW-views configuration
1031   FWConfiguration views(1);
1032   FWConfiguration viewArea(cfgVersion);
1033   for (std::vector<areaInfo>::iterator it = wpacked.begin(); it != wpacked.end(); ++it) {
1034     TEveWindow* ew = (*it).eveWindow;
1035     if (ew) {
1036       FWViewBase* wb = m_viewMap[ew];
1037       FWConfiguration tempWiew(wb->version());
1038       wb->addTo(tempWiew);
1039       views.addKeyValue(wb->typeName(), tempWiew, true);
1040       FWConfiguration tempArea(cfgVersion);
1041       addAreaInfoTo((*it), tempArea);
1042       viewArea.addKeyValue(wb->typeName(), tempArea, true);
1043     }
1044   }
1045   oTo.addKeyValue(kViews, views, true);
1046   oTo.addKeyValue(kViewArea, viewArea, true);
1047 
1048   //------------------------------------------------------------
1049   //Remember where controllers were placed if they are open
1050   FWConfiguration controllers(1);
1051   {
1052     if (nullptr != m_ediFrame && m_ediFrame->IsMapped()) {
1053       FWConfiguration temp(1);
1054       addWindowInfoTo(m_ediFrame, temp);
1055       controllers.addKeyValue(kCollectionController, temp, true);
1056     }
1057     if (nullptr != m_viewPopup && m_viewPopup->IsMapped()) {
1058       FWConfiguration temp(1);
1059       addWindowInfoTo(m_viewPopup, temp);
1060       controllers.addKeyValue(kViewController, temp, true);
1061     }
1062     if (nullptr != m_modelPopup && m_modelPopup->IsMapped()) {
1063       FWConfiguration temp(1);
1064       addWindowInfoTo(m_modelPopup, temp);
1065       controllers.addKeyValue(kObjectController, temp, true);
1066     }
1067     if (nullptr != m_commonPopup && m_commonPopup->IsMapped()) {
1068       FWConfiguration temp(1);
1069       addWindowInfoTo(m_commonPopup, temp);
1070       controllers.addKeyValue(kCommonController, temp, true);
1071     }
1072   }
1073   oTo.addKeyValue(kControllers, controllers, true);
1074 }
1075 
1076 //----------------------------------------------------------------
1077 void FWGUIManager::setWindowInfoFrom(const FWConfiguration& iFrom, TGMainFrame* iFrame) {
1078   int x = atoi(iFrom.valueForKey("x")->value().c_str()) + m_WMOffsetX;
1079   int y = atoi(iFrom.valueForKey("y")->value().c_str()) + m_WMOffsetY;
1080   if (y < m_WMDecorH)
1081     y = m_WMDecorH;
1082   int width = atoi(iFrom.valueForKey("width")->value().c_str());
1083   int height = atoi(iFrom.valueForKey("height")->value().c_str());
1084   iFrame->MoveResize(x, y, width, height);
1085   iFrame->SetWMPosition(x, y);
1086 }
1087 
1088 void FWGUIManager::setFrom(const FWConfiguration& iFrom) {
1089   gEve->DisableRedraw();
1090   // main window
1091   if (m_viewSecPack)
1092     subviewDestroyAll();
1093 
1094   const FWConfiguration* mw = iFrom.valueForKey(kMainWindow);
1095   assert(mw != nullptr);
1096   // Window needs to mapped before moving, otherwise move can lead
1097   // to wrong results on some window managers.
1098 
1099   // set from view reading area info nd view info
1100   float_t leftWeight = 1;
1101   float_t rightWeight = 1;
1102   if (mw->version() >= 2) {
1103     leftWeight = atof(mw->valueForKey("leftWeight")->value().c_str());
1104     rightWeight = atof(mw->valueForKey("rightWeight")->value().c_str());
1105   }
1106 
1107   if (mw->version() >= 3) {
1108     float summaryWeight = atof(mw->valueForKey("summaryWeight")->value().c_str());
1109     m_cmsShowMainFrame->setSummaryViewWeight(summaryWeight);
1110   }
1111 
1112   TEveWindowSlot* primSlot = (leftWeight > 0) ? m_viewPrimPack->NewSlotWithWeight(leftWeight) : nullptr;
1113   m_viewSecPack = m_viewPrimPack->NewSlotWithWeight(rightWeight)->MakePack();
1114   m_viewSecPack->SetVertical();
1115   m_viewSecPack->SetShowTitleBar(kFALSE);
1116 
1117   // views list
1118   const FWConfiguration* views = iFrom.valueForKey(kViews);
1119   assert(nullptr != views);
1120   const FWConfiguration::KeyValues* keyVals = views->keyValues();
1121   const FWConfiguration* viewArea = iFrom.valueForKey(kViewArea);
1122 
1123   // area list (ignored in older version)
1124   if (viewArea->version() > 1) {
1125     const FWConfiguration::KeyValues* akv = viewArea->keyValues();
1126     FWConfiguration::KeyValuesIt areaIt = akv->begin();
1127 
1128     for (FWConfiguration::KeyValuesIt it = keyVals->begin(); it != keyVals->end(); ++it) {
1129       float weight = atof((areaIt->second).valueForKey("weight")->value().c_str());
1130       TEveWindowSlot* slot =
1131           (!m_viewMap.empty() || (primSlot == nullptr)) ? m_viewSecPack->NewSlotWithWeight(weight) : primSlot;
1132       std::string name = FWViewType::checkNameWithViewVersion(it->first, it->second.version());
1133       ViewMap_i lastViewIt = createView(name, slot);
1134       lastViewIt->second->setFrom(it->second);
1135 
1136       bool undocked = atof((areaIt->second).valueForKey("undocked")->value().c_str());
1137       if (undocked) {
1138         TEveWindow* lastWindow = lastViewIt->first;
1139         lastWindow->UndockWindow();
1140         TEveCompositeFrameInMainFrame* emf = dynamic_cast<TEveCompositeFrameInMainFrame*>(lastWindow->GetEveFrame());
1141         if (emf) {
1142           const TGMainFrame* mf = dynamic_cast<const TGMainFrame*>(emf->GetParent());
1143           if (mf) {
1144             m_cmsShowMainFrame->bindCSGActionKeys(mf);
1145             TGMainFrame* mfp = (TGMainFrame*)mf;  // have to cast in non-const
1146             const FWConfiguration* mwc = (areaIt->second).valueForKey("UndockedWindowPos");
1147             setWindowInfoFrom(*mwc, mfp);
1148           }
1149         }
1150       }
1151       areaIt++;
1152     }
1153   } else {  // create views with same weight in old version
1154     for (FWConfiguration::KeyValuesIt it = keyVals->begin(); it != keyVals->end(); ++it) {
1155       std::string name = FWViewType::checkNameWithViewVersion(it->first, it->second.version());
1156       createView(name, !m_viewMap.empty() ? m_viewSecPack->NewSlot() : primSlot);
1157 
1158       ViewMap_i lastViewIt = m_viewMap.end();
1159       lastViewIt--;
1160       lastViewIt->second->setFrom(it->second);
1161     }
1162     // handle undocked windows in old version
1163     const FWConfiguration* undocked = iFrom.valueForKey(kUndocked);
1164     if (nullptr != undocked) {
1165       fwLog(fwlog::kWarning) << "Restrore of undocked windows with old window management not supported." << std::endl;
1166     }
1167   }
1168 
1169   //handle controllers
1170   const FWConfiguration* controllers = iFrom.valueForKey(kControllers);
1171   if (nullptr != controllers) {
1172     const FWConfiguration::KeyValues* keyVals = controllers->keyValues();
1173     if (nullptr != keyVals) {
1174       //we have open controllers
1175       for (FWConfiguration::KeyValuesIt it = keyVals->begin(); it != keyVals->end(); ++it) {
1176         const std::string& controllerName = it->first;
1177         // std::cout <<"found controller "<<controllerName<<std::endl;
1178         if (controllerName == kCollectionController) {
1179           showEDIFrame();
1180           setWindowInfoFrom(it->second, m_ediFrame);
1181         } else if (controllerName == kViewController) {
1182           setViewPopup(nullptr);
1183           setWindowInfoFrom(it->second, m_viewPopup);
1184         } else if (controllerName == kObjectController) {
1185           showModelPopup();
1186           setWindowInfoFrom(it->second, m_modelPopup);
1187         } else if (controllerName == kCommonController) {
1188           showCommonPopup();
1189           setWindowInfoFrom(it->second, m_commonPopup);
1190         }
1191       }
1192     }
1193   }
1194 
1195   for (ViewMap_i it = m_viewMap.begin(); it != m_viewMap.end(); ++it) {
1196     if (it->second->typeId() >= FWViewType::kGeometryTable) {
1197       FWGeometryTableViewBase* gv = (FWGeometryTableViewBase*)it->second;
1198       gv->populate3DViewsFromConfig();
1199     }
1200   }
1201 
1202   gEve->EnableRedraw();
1203   // disable first docked view
1204   checkSubviewAreaIconState(nullptr);
1205 
1206   m_cmsShowMainFrame->MapWindow();
1207   setWindowInfoFrom(*mw, m_cmsShowMainFrame);
1208   m_cmsShowMainFrame->MapSubwindows();
1209   m_cmsShowMainFrame->Layout();
1210   m_cmsShowMainFrame->MapRaised();
1211 }
1212 
1213 void FWGUIManager::openEveBrowserForDebugging() const { gEve->GetBrowser()->MapWindow(); }
1214 
1215 //
1216 // toolbar widgets callbacks
1217 //
1218 void FWGUIManager::delaySliderChanged(Int_t val) {
1219   Float_t sec = val * 0.001;
1220   m_cmsShowMainFrame->setPlayDelayGUI(sec, kFALSE);
1221   changedDelayBetweenEvents_.emit(sec);
1222 }
1223 
1224 void FWGUIManager::setDelayBetweenEvents(Float_t val) { m_cmsShowMainFrame->setPlayDelayGUI(val, kTRUE); }
1225 
1226 void FWGUIManager::runIdChanged() {
1227   if (m_cmsShowMainFrame->m_runEntry->GetUIntNumber() == edm::invalidRunNumber) {
1228     m_cmsShowMainFrame->m_runEntry->SetUIntNumber(1);
1229   }
1230 
1231   m_cmsShowMainFrame->m_lumiEntry->SetText("", kFALSE);
1232   m_cmsShowMainFrame->m_lumiEntry->SetFocus();
1233 }
1234 
1235 void FWGUIManager::lumiIdChanged() {
1236   if (m_cmsShowMainFrame->m_lumiEntry->GetUIntNumber() == edm::invalidLuminosityBlockNumber) {
1237     m_cmsShowMainFrame->m_lumiEntry->SetUIntNumber(1);
1238   }
1239 
1240   m_cmsShowMainFrame->m_eventEntry->SetText("", kFALSE);
1241   m_cmsShowMainFrame->m_eventEntry->SetFocus();
1242 }
1243 
1244 void FWGUIManager::eventIdChanged() {
1245   if (m_cmsShowMainFrame->m_eventEntry->GetUIntNumber() == edm::invalidEventNumber) {
1246     m_cmsShowMainFrame->m_eventEntry->SetULong64Number(1);
1247   }
1248 
1249   changedEventId_.emit(m_cmsShowMainFrame->m_runEntry->GetUIntNumber(),
1250                        m_cmsShowMainFrame->m_lumiEntry->GetUIntNumber(),
1251                        m_cmsShowMainFrame->m_eventEntry->GetULong64Number());
1252 }
1253 
1254 void FWGUIManager::finishUpColorChange() {
1255   if (m_commonPopup)
1256     m_commonPopup->colorSetChanged();
1257   if (m_modelPopup)
1258     m_modelPopup->colorSetChanged();
1259   if (m_ediFrame)
1260     m_ediFrame->colorSetChanged();
1261 
1262   gEve->FullRedraw3D();
1263 }
1264 //______________________________________________________________________________
1265 
1266 void FWGUIManager::showEventFilterGUI() { showEventFilterGUI_.emit(m_cmsShowMainFrame); }
1267 
1268 void FWGUIManager::filterButtonClicked() { filterButtonClicked_.emit(); }
1269 
1270 void FWGUIManager::setFilterButtonText(const char* txt) { m_cmsShowMainFrame->m_filterShowGUIBtn->SetText(txt); }
1271 
1272 void FWGUIManager::setFilterButtonIcon(int state) {
1273   int i = state * 3;
1274   m_cmsShowMainFrame->m_filterEnableBtn->setIcons(m_cmsShowMainFrame->m_filterIcons[i],
1275                                                   m_cmsShowMainFrame->m_filterIcons[i + 1],
1276                                                   m_cmsShowMainFrame->m_filterIcons[i + 2]);
1277 }
1278 
1279 void FWGUIManager::updateEventFilterEnable(bool btnEnabled) {
1280   m_cmsShowMainFrame->m_filterEnableBtn->SetEnabled(btnEnabled);
1281 }
1282 
1283 void FWGUIManager::measureWMOffsets() {
1284   const Int_t x = 100, y = 100;
1285 
1286   TGMainFrame* mf1 = new TGMainFrame(nullptr, 0, 0);
1287   mf1->MapWindow();
1288   mf1->Move(x, y);
1289 
1290   // This seems to be the only reliable way to make sure Move() has been processed.
1291   {
1292     TGMainFrame* mf2 = new TGMainFrame(nullptr, 0, 0);
1293     mf2->MapWindow();
1294     while (!mf2->IsMapped())
1295       gClient->HandleInput();
1296     delete mf2;
1297   }
1298   {
1299     Int_t xm, ym;
1300     Window_t childdum;
1301     WindowAttributes_t attr;
1302     gVirtualX->TranslateCoordinates(mf1->GetId(), gClient->GetDefaultRoot()->GetId(), 0, 0, xm, ym, childdum);
1303     gVirtualX->GetWindowAttributes(mf1->GetId(), attr);
1304     m_WMOffsetX = x - xm;
1305     m_WMOffsetY = y - ym;
1306     m_WMDecorH = attr.fY;
1307     fwLog(fwlog::kDebug) << Form(
1308         "FWGUIManager::measureWMOffsets: required (%d,%d), measured(%d, %d) => dx=%d, dy=%d; decor_h=%d.\n",
1309         x,
1310         y,
1311         xm,
1312         ym,
1313         m_WMOffsetX,
1314         m_WMOffsetY,
1315         m_WMDecorH);
1316   }
1317   delete mf1;
1318 }
1319 
1320 void FWGUIManager::resetWMOffsets() { m_WMOffsetX = m_WMOffsetY = m_WMDecorH = 0; }
1321 
1322 void FWGUIManager::initEmpty() {
1323   int x = 150 + m_WMOffsetX;
1324   int y = 50 + m_WMOffsetY;
1325   m_cmsShowMainFrame->Move(x, y);
1326   m_cmsShowMainFrame->SetWMPosition(x, y < m_WMDecorH ? m_WMDecorH : y);
1327 
1328   createView("Rho Phi");
1329   createView("Rho Z");
1330 
1331   m_cmsShowMainFrame->MapSubwindows();
1332   m_cmsShowMainFrame->Layout();
1333   m_cmsShowMainFrame->MapRaised();
1334 }