Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "Fireworks/FWInterface/src/FWPathsPopup.h"
0002 #include "Fireworks/FWInterface/src/FWPSetTableManager.h"
0003 #include "Fireworks/FWInterface/src/FWPSetCellEditor.h"
0004 
0005 #include "Fireworks/FWInterface/interface/FWFFLooper.h"
0006 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
0007 
0008 #include "Fireworks/Core/interface/FWDialogBuilder.h"
0009 #include "Fireworks/Core/interface/FWGUIManager.h"
0010 #include "Fireworks/Core/interface/fwLog.h"
0011 
0012 #include "FWCore/Framework/interface/ScheduleInfo.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 #include "FWCore/Common/interface/TriggerNames.h"
0016 
0017 #include "FWCore/Utilities/interface/Exception.h"
0018 
0019 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0020 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0021 #include "DataFormats/Common/interface/TriggerResults.h"
0022 
0023 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0024 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0025 
0026 #include "FWCore/PythonParameterSet/interface/PyBind11Wrapper.h"
0027 #include <boost/python/errors.hpp>
0028 #include "TGLabel.h"
0029 #include "KeySymbols.h"
0030 
0031 void FWPathsPopup::windowIsClosing() {
0032   UnmapWindow();
0033   DontCallClose();
0034 }
0035 
0036 FWPathsPopup::FWPathsPopup(FWFFLooper *looper, FWGUIManager *guiManager)
0037     : TGMainFrame(gClient->GetRoot(), 400, 600),
0038       m_info(nullptr),
0039       m_looper(looper),
0040       m_hasChanges(false),
0041       m_moduleLabel(nullptr),
0042       m_moduleName(nullptr),
0043       m_apply(nullptr),
0044       m_psTable(new FWPSetTableManager()),
0045       m_guiManager(guiManager) {
0046   gVirtualX->SelectInput(GetId(),
0047                          kKeyPressMask | kKeyReleaseMask | kExposureMask | kPointerMotionMask | kStructureNotifyMask |
0048                              kFocusChangeMask | kEnterWindowMask | kLeaveWindowMask);
0049   this->Connect("CloseWindow()", "FWPathsPopup", this, "windowIsClosing()");
0050 
0051   FWDialogBuilder builder(this);
0052   builder.indent(4)
0053       .spaceDown(10)
0054       .addLabel("Filter:")
0055       .floatLeft(4)
0056       .expand(false, false)
0057       .addTextEntry("", &m_search)
0058       .expand(true, false)
0059       .spaceDown(10)
0060       .addTable(m_psTable, &m_tableWidget)
0061       .expand(true, true)
0062       .addTextButton("Apply changes and reload", &m_apply);
0063 
0064   FWPSetCellEditor *editor = new FWPSetCellEditor(m_tableWidget->body(), "");
0065   editor->SetBackgroundColor(gVirtualX->GetPixel(kYellow - 7));
0066   editor->SetFrameDrawn(false);
0067   m_psTable->setCellValueEditor(editor);
0068   m_psTable->m_editor->Connect("ReturnPressed()", "FWPathsPopup", this, "applyEditor()");
0069 
0070   m_apply->Connect("Clicked()", "FWPathsPopup", this, "scheduleReloadEvent()");
0071   m_apply->SetEnabled(false);
0072   m_search->SetEnabled(true);
0073   m_search->Connect("TextChanged(const char *)", "FWPathsPopup", this, "updateFilterString(const char *)");
0074   m_tableWidget->SetBackgroundColor(0xffffff);
0075   m_tableWidget->SetLineSeparatorColor(0x000000);
0076   m_tableWidget->SetHeaderBackgroundColor(0xececec);
0077   m_tableWidget->Connect("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)",
0078                          "FWPathsPopup",
0079                          this,
0080                          "cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)");
0081   m_tableWidget->disableGrowInWidth();
0082 
0083   SetWindowName("CMSSW Configuration Editor");
0084   MapSubwindows();
0085   editor->UnmapWindow();
0086 
0087   Layout();
0088 }
0089 
0090 /** Handle pressing of esc. 
0091  */
0092 Bool_t FWPathsPopup::HandleKey(Event_t *event) {
0093   UInt_t keysym = event->fCode;
0094 
0095   if (keysym == (UInt_t)gVirtualX->KeysymToKeycode(kKey_Escape)) {
0096     // called from FWPSetCellEditor
0097     m_psTable->cancelEditor();
0098     m_psTable->setSelection(-1, -1, 0);
0099   }
0100   return TGMainFrame::HandleKey(event);
0101 }
0102 
0103 /** Proxies the applyEditor() method in the model so that it can be connected to GUI, signals.
0104   */
0105 void FWPathsPopup::applyEditor() {
0106   bool applied = m_psTable->applyEditor();
0107   if (applied)
0108     m_apply->SetEnabled(true);
0109 }
0110 
0111 /** Handles clicking on the table cells.
0112     
0113     * Clicking on a cell in the first column opens / closes a given node. 
0114     * Clicking on a cell in the second column moves the editor to that cell. 
0115  
0116   */
0117 void FWPathsPopup::cellClicked(Int_t iRow, Int_t iColumn, Int_t iButton, Int_t iKeyMod, Int_t, Int_t) {
0118   if (iButton != kButton1)
0119     return;
0120 
0121   if (iColumn == 0 || iColumn == 1) {
0122     // Save and close the previous editor, if required.
0123     if (m_psTable->selectedColumn() == 1 && m_psTable->selectedRow() != -1) {
0124       int oldIndex = m_psTable->rowToIndex()[m_psTable->selectedRow()];
0125       FWPSetTableManager::PSetData &oldData = m_psTable->data()[oldIndex];
0126 
0127       if (oldData.editable)
0128         applyEditor();
0129     }
0130 
0131     m_psTable->setSelection(iRow, iColumn, iKeyMod);
0132 
0133     if (iColumn == 0)
0134       m_psTable->setExpanded(iRow);
0135   }
0136 }
0137 
0138 void FWPathsPopup::updateFilterString(const char *str) {
0139   m_psTable->applyEditor();
0140   m_psTable->setSelection(-1, -1, 0);
0141   m_psTable->updateFilter(str);
0142 }
0143 
0144 /** Finish the setup of the GUI */
0145 void FWPathsPopup::setup(const edm::ScheduleInfo *info) {
0146   assert(info);
0147   m_info = info;
0148 }
0149 
0150 /** Gets called by CMSSW as modules are about to be processed. **/
0151 void FWPathsPopup::postModuleEvent(edm::StreamContext const &s, edm::ModuleCallingContext const &mcc) {
0152   m_guiManager->updateStatus((mcc.moduleDescription()->moduleName() + " processed.").c_str());
0153   gSystem->ProcessEvents();
0154 }
0155 
0156 /** Gets called by CMSSW as we process modules. **/
0157 void FWPathsPopup::preModuleEvent(edm::StreamContext const &s, edm::ModuleCallingContext const &mcc) {
0158   m_guiManager->updateStatus(("Processing " + mcc.moduleDescription()->moduleName() + "...").c_str());
0159   gSystem->ProcessEvents();
0160 }
0161 
0162 void FWPathsPopup::postEvent(edm::Event const &event) {
0163   m_guiManager->updateStatus("Done processing.");
0164   gSystem->ProcessEvents();
0165 
0166   // Get the last process name from the process history:
0167   // this should be the one specified in the cfg file
0168 
0169   if (event.processHistory().empty()) {
0170     fwLog(fwlog::kInfo) << "Path GUI:: no process history available.\n";
0171     return;
0172   }
0173   edm::ProcessHistory::const_iterator pi = event.processHistory().end() - 1;
0174   std::string processName = pi->processName();
0175 
0176   // It's called TriggerResults but actually contains info on all paths
0177   edm::InputTag tag("TriggerResults", "", processName);
0178   edm::Handle<edm::TriggerResults> triggerResults;
0179   event.getByLabel(tag, triggerResults);
0180 
0181   std::vector<FWPSetTableManager::PathUpdate> pathUpdates;
0182 
0183   if (triggerResults.isValid()) {
0184     const edm::TriggerNames &triggerNames = event.triggerNames(*triggerResults);
0185 
0186     for (size_t i = 0, e = triggerResults->size(); i != e; ++i) {
0187       FWPSetTableManager::PathUpdate update;
0188       update.pathName = triggerNames.triggerName(i);
0189       update.passed = triggerResults->accept(i);
0190       update.choiceMaker = triggerResults->index(i);
0191       pathUpdates.push_back(update);
0192     }
0193   }
0194   m_psTable->updateSchedule(m_info);
0195   m_psTable->update(pathUpdates);
0196   m_psTable->dataChanged();
0197   m_tableWidget->body()->DoRedraw();
0198 }
0199 
0200 /** Modifies the module and asks the looper to reload the event.
0201  
0202     1. Read the configuration snippet from the GUI,
0203     2. Use the python interpreter to parse it and get the new
0204       parameter set.
0205     3. Notify the looper about the changes.
0206 
0207     FIXME: implement 2 and 3.
0208   */
0209 void FWPathsPopup::scheduleReloadEvent() {
0210   applyEditor();
0211   try {
0212     for (size_t mni = 0, mne = m_psTable->modules().size(); mni != mne; ++mni) {
0213       FWPSetTableManager::ModuleInfo &module = m_psTable->modules()[mni];
0214       if (module.dirty == false)
0215         continue;
0216       FWPSetTableManager::PSetData &data = m_psTable->entries()[module.entry];
0217       m_looper->requestChanges(data.label, *module.current_pset);
0218     }
0219     m_hasChanges = true;
0220     m_apply->SetEnabled(false);
0221     gSystem->ExitLoop();
0222   } catch (boost::python::error_already_set const &) {
0223     edm::pythonToCppException("Configuration", "");
0224     Py_Finalize();
0225   } catch (cms::Exception &exception) {
0226     std::cout << exception.what() << std::endl;
0227   }
0228   // Return control to the FWFFLooper so that it can decide what to do next.
0229 }