CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Fireworks/FWInterface/src/FWPSetTableManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FWInterface
00004 // Class  :     FWPSetTableManager
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  
00010 //         Created:  Mon Feb 28 17:06:54 CET 2011
00011 // $Id: FWPSetTableManager.cc,v 1.15 2011/03/31 20:49:34 amraktad Exp $
00012 //
00013 
00014 #include <map>
00015 
00016 #include "Fireworks/FWInterface/src/FWPSetTableManager.h"
00017 #include "Fireworks/FWInterface/src/FWPSetCellEditor.h"
00018 #include "Fireworks/TableWidget/src/FWTabularWidget.h"
00019 #include "Fireworks/TableWidget/interface/GlobalContexts.h"
00020 #include "Fireworks/Core/interface/fwLog.h"
00021 
00022 #include "FWCore/Framework/interface/ScheduleInfo.h"
00023 #include "FWCore/PythonParameterSet/interface/MakeParameterSets.h"
00024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00025 #include "FWCore/Utilities/interface/Exception.h"
00026 //
00027 // constants, enums and typedefs
00028 //
00029 
00030 //
00031 // static data member definitions
00032 //
00033 
00034 
00035 // FIXME: copied from Entry.cc should find a way to use the original
00036 //        table.
00037 struct TypeTrans {
00038    TypeTrans();
00039 
00040    typedef std::vector<std::string> CodeMap;
00041    CodeMap table_;
00042    std::map<std::string, char> type2Code_;
00043 };
00044 
00045 TypeTrans::TypeTrans():table_(255) {
00046    table_['b'] = "vBool";
00047    table_['B'] = "bool";
00048    table_['i'] = "vint32";
00049    table_['I'] = "int32";
00050    table_['u'] = "vuint32";
00051    table_['U'] = "uint32";
00052    table_['l'] = "vint64";
00053    table_['L'] = "int64";
00054    table_['x'] = "vuint64";
00055    table_['X'] = "uint64";
00056    table_['s'] = "vstring";
00057    table_['S'] = "string";
00058    table_['d'] = "vdouble";
00059    table_['D'] = "double";
00060    table_['p'] = "vPSet";
00061    table_['P'] = "PSet";
00062    table_['T'] = "path";
00063    table_['F'] = "FileInPath";
00064    table_['t'] = "InputTag";
00065    table_['v'] = "VInputTag";
00066    table_['g'] = "ESInputTag";
00067    table_['G'] = "VESInputTag";
00068    table_['e'] = "VEventID";
00069    table_['E'] = "EventID";
00070    table_['m'] = "VLuminosityBlockID";
00071    table_['M'] = "LuminosityBlockID";
00072    table_['a'] = "VLuminosityBlockRange";
00073    table_['A'] = "LuminosityBlockRange";
00074    table_['r'] = "VEventRange";
00075    table_['R'] = "EventRange";
00076 
00077    for(CodeMap::const_iterator itCode = table_.begin(), itCodeEnd = table_.end();
00078        itCode != itCodeEnd;
00079        ++itCode) {
00080       type2Code_[*itCode] = (itCode - table_.begin());
00081    }
00082 }
00083 
00084 static TypeTrans const sTypeTranslations;
00085 
00086 
00087 //
00088 // constructors and destructor
00089 //
00090 
00091 FWPSetTableManager::FWPSetTableManager()
00092    : m_selectedRow(-1)
00093 {  
00094 
00095    TGGC* hc =  new TGGC(FWTextTableCellRenderer::getDefaultHighlightGC());
00096    hc->SetForeground(0xdddddd);
00097 
00098    m_renderer.setHighlightContext(hc);
00099 
00100    recalculateVisibility();
00101    visualPropertiesChanged();
00102 }
00103 
00104 FWPSetTableManager::~FWPSetTableManager()
00105 {
00106 }
00107 
00108 //==============================================================================
00109 //==============================================================================
00110 //========== IMPORT CMSSW CONFIG TO TABLE ======================================
00111 //==============================================================================
00112 //==============================================================================
00113 
00114 void FWPSetTableManager::handlePSetEntry(const edm::ParameterSetEntry& entry, const std::string& key)
00115 {
00116    FWPSetTableManager::PSetData data;
00117    data.label = key;
00118    data.tracked = entry.isTracked();
00119    data.level = m_parentStack.size();
00120    data.parent = m_parentStack.back();
00121    data.type = 'P';
00122    data.module = m_modules.size() - 1;
00123    data.path = m_paths.size() - 1;
00124    data.pset = entry.pset();
00125    data.editable = false;
00126    m_parentStack.push_back(m_entries.size());
00127    m_entries.push_back(data);
00128 
00129    handlePSet(entry.pset());
00130    m_parentStack.pop_back();
00131 }
00132 
00133 void FWPSetTableManager::handleVPSetEntry(const edm::VParameterSetEntry& entry, const std::string& key)                     
00134 {
00135    PSetData data;
00136    data.label = key;
00137    data.tracked = entry.isTracked();
00138    data.level = m_parentStack.size();
00139    data.parent = m_parentStack.back();
00140    data.type = 'p';
00141    data.module = m_modules.size() - 1;
00142    data.path = m_paths.size() - 1;
00143    data.editable = false;
00144    m_parentStack.push_back(m_entries.size());
00145    m_entries.push_back(data);
00146 
00147    std::stringstream ss;
00148 
00149    for (size_t i = 0, e = entry.vpset().size(); i != e; ++i)
00150    {
00151       ss.str("");
00152       ss << key << "[" << i << "]";
00153       FWPSetTableManager::PSetData vdata;
00154       vdata.label = ss.str();
00155       vdata.tracked = entry.isTracked();
00156       vdata.level = m_parentStack.size();
00157       vdata.parent = m_parentStack.back();
00158       vdata.module = m_modules.size() - 1;
00159       vdata.path = m_paths.size() - 1;
00160       vdata.editable = false;
00161       m_parentStack.push_back(m_entries.size());
00162       m_entries.push_back(vdata);
00163       handlePSet(entry.vpset()[i]);
00164       m_parentStack.pop_back();
00165    }
00166    m_parentStack.pop_back();
00167 }
00168 
00169 void FWPSetTableManager::handlePSet(const edm::ParameterSet &ps)
00170 {
00171    typedef edm::ParameterSet::table::const_iterator TIterator;
00172    for (TIterator i = ps.tbl().begin(), e = ps.tbl().end(); i != e; ++i)
00173       handleEntry(i->second, i->first);
00174 
00175    typedef edm::ParameterSet::psettable::const_iterator PSIterator;
00176    for (PSIterator i = ps.psetTable().begin(), e = ps.psetTable().end(); i != e; ++i)
00177       handlePSetEntry(i->second, i->first);
00178 
00179    typedef edm::ParameterSet::vpsettable::const_iterator VPSIterator;
00180    for (VPSIterator i = ps.vpsetTable().begin(), e = ps.vpsetTable().end(); i != e; ++i)
00181       handleVPSetEntry(i->second, i->first);
00182 }
00183     
00184 template <class T>
00185 void FWPSetTableManager::createScalarString(PSetData &data, T v)
00186 {
00187    std::stringstream ss;
00188    ss << v;
00189    data.value = ss.str();
00190    m_entries.push_back(data);
00191 }
00192 
00193 template <typename T>
00194 void FWPSetTableManager::createVectorString(FWPSetTableManager::PSetData &data, const T &v, bool quotes)
00195 {
00196    std::stringstream ss;
00197    ss << "[";
00198    for (size_t ii = 0, ie = v.size(); ii != ie; ++ii)
00199    {
00200       if (quotes)
00201          ss << "\""; 
00202       ss << v[ii];
00203       if (quotes)
00204          ss << "\"";
00205       if (ii + 1 != ie) 
00206          ss << ", ";
00207    }
00208    ss << "]";
00209    data.value = ss.str();
00210    m_entries.push_back(data);
00211 }
00212 
00213 void FWPSetTableManager::handleEntry(const edm::Entry &entry,const std::string &key)
00214 {
00215    std::stringstream ss;
00216    FWPSetTableManager::PSetData data;
00217    data.label = key;
00218    data.tracked = entry.isTracked();
00219    data.type = entry.typeCode();
00220    data.level = m_parentStack.size();
00221    data.parent = m_parentStack.back();
00222    data.module = m_modules.size() - 1;
00223    data.type = entry.typeCode();
00224    if (data.label[0] == '@' || data.level > 2)
00225       data.editable = false;
00226    else
00227       data.editable = true;
00228 
00229    switch(entry.typeCode())
00230    {
00231       case 'b':
00232       {
00233          data.value = entry.getBool() ? "True" : "False";
00234          m_entries.push_back(data);
00235          break;
00236       }
00237       case 'B':
00238       {
00239          data.value = entry.getBool() ? "True" : "False";
00240          m_entries.push_back(data);
00241          break;
00242       }
00243       case 'i':
00244       {
00245          createVectorString(data, entry.getVInt32(), false);
00246          break;
00247       }
00248       case 'I':
00249       {
00250          createScalarString(data, entry.getInt32());
00251          break;
00252       }
00253       case 'u':
00254       {
00255          createVectorString(data, entry.getVUInt32(), false);
00256          break;
00257       }
00258       case 'U':
00259       {
00260          createScalarString(data, entry.getUInt32());
00261          break;
00262       }
00263       case 'l':
00264       {
00265          createVectorString(data, entry.getVInt64(), false);
00266          break;
00267       }
00268       case 'L':
00269       {
00270          createScalarString(data, entry.getInt32());
00271          break;
00272       }
00273       case 'x':
00274       {
00275          createVectorString(data, entry.getVUInt64(), false);
00276          break;
00277       }
00278       case 'X':
00279       {
00280          createScalarString(data, entry.getUInt64());
00281          break;
00282       }
00283       case 's':
00284       {
00285          createVectorString(data, entry.getVString(), false);
00286          break;
00287       }
00288       case 'S':
00289       {
00290          createScalarString(data, entry.getString());
00291          break;
00292       }
00293       case 'd':
00294       {
00295          createVectorString(data, entry.getVDouble(), false);
00296          break;
00297       }
00298       case 'D':
00299       { 
00300          createScalarString(data, entry.getDouble());
00301          break;
00302       }
00303       case 'p':
00304       {
00305          std::vector<edm::ParameterSet> psets = entry.getVPSet();
00306          for (size_t psi = 0, pse = psets.size(); psi != pse; ++psi)
00307             handlePSet(psets[psi]);
00308          break;
00309       }
00310       case 'P':
00311       {    
00312          handlePSet(entry.getPSet());
00313          break;
00314       }
00315       case 't':
00316       {
00317          data.value = entry.getInputTag().encode();
00318          m_entries.push_back(data);
00319          break;
00320       } 
00321       case 'v':
00322       {
00323          std::vector<std::string> tags;
00324          tags.resize(entry.getVInputTag().size());
00325          for (size_t iti = 0, ite = tags.size(); iti != ite; ++iti) 
00326             tags[iti] = entry.getVInputTag()[iti].encode();
00327          createVectorString(data, tags, true);
00328          break;
00329       }        
00330       case 'g':
00331       {
00332          data.value = entry.getESInputTag().encode();
00333          m_entries.push_back(data);
00334          break;
00335       }
00336       case 'G':
00337       {
00338          std::vector<std::string> tags;
00339          tags.resize(entry.getVESInputTag().size());
00340          for (size_t iti = 0, ite = tags.size(); iti != ite; ++iti) 
00341             tags[iti] = entry.getVESInputTag()[iti].encode();
00342          createVectorString(data, tags, true);
00343          break;
00344       }
00345       case 'F':
00346       {
00347          createScalarString(data, entry.getFileInPath().relativePath());
00348          break;
00349       }
00350       case 'e':
00351       {
00352          data.editable = false;
00353          std::vector<edm::EventID> ids;
00354          ids.resize(entry.getVEventID().size());
00355          for ( size_t iri = 0, ire = ids.size(); iri != ire; ++iri )
00356             ids[iri] = entry.getVEventID()[iri];
00357          createVectorString(data, ids, true);
00358          break;
00359       }
00360       case 'E':
00361       {
00362          data.editable = false;
00363          createScalarString(data, entry.getEventID());
00364          break;
00365       }
00366       case 'm':
00367       {
00368          data.editable = false;
00369          std::vector<edm::LuminosityBlockID> ids;
00370          ids.resize(entry.getVLuminosityBlockID().size());
00371          for ( size_t iri = 0, ire = ids.size(); iri != ire; ++iri )
00372             ids[iri] = entry.getVLuminosityBlockID()[iri];
00373          createVectorString(data, ids, true);
00374          break;
00375       }
00376       case 'M':
00377       {
00378          data.editable = false;
00379          createScalarString(data, entry.getLuminosityBlockID());
00380          break;
00381       }
00382       case 'a':
00383       {
00384          data.editable = false;
00385          std::vector<edm::LuminosityBlockRange> ranges;
00386          ranges.resize(entry.getVLuminosityBlockRange().size());
00387          for ( size_t iri = 0, ire = ranges.size(); iri != ire; ++iri )
00388             ranges[iri] = entry.getVLuminosityBlockRange()[iri];
00389          createVectorString(data, ranges, true);
00390          break;
00391       }
00392       case 'A':
00393       {
00394          data.editable = false;
00395          createScalarString(data, entry.getLuminosityBlockRange());
00396          break;
00397       }
00398       case 'r':
00399       {
00400          data.editable = false;
00401          std::vector<edm::EventRange> ranges;
00402          ranges.resize(entry.getVEventRange().size());
00403          for ( size_t iri = 0, ire = ranges.size(); iri != ire; ++iri )
00404             ranges[iri] = entry.getVEventRange()[iri];
00405          createVectorString(data, ranges, true);
00406          break;
00407       }
00408       case 'R':
00409       {
00410          data.editable = false;
00411          createScalarString(data, entry.getEventRange());
00412          break;          
00413       }
00414       default:
00415       {
00416          break;
00417       }
00418    }
00419 }
00420 
00421 /* the actual structure of the model will not change, only
00422    its contents, because of the way CMSSW is designed,
00423    hence this method only needs to be called once.
00424    */
00425 void FWPSetTableManager::updateSchedule(const edm::ScheduleInfo *info)
00426 {
00427    if (!m_entries.empty())
00428       return;
00429    // Execute only once since the schedule itself
00430    // cannot be altered.
00431    assert(m_availablePaths.empty());
00432    info->availablePaths(m_availablePaths);
00433          
00434    for (size_t i = 0, e = m_availablePaths.size(); i != e; ++i)
00435    {
00436       PSetData pathEntry;
00437       const std::string &pathName = m_availablePaths[i];
00438       pathEntry.label = pathName;
00439       m_pathIndex.insert(std::make_pair(pathName, m_paths.size()));
00440 
00441       pathEntry.value = "Path";
00442       pathEntry.level= 0;
00443       pathEntry.parent = -1;
00444       pathEntry.path = i;
00445       pathEntry.editable = false;
00446 
00447       PathInfo pathInfo;
00448       pathInfo.entryId = m_entries.size();
00449       pathInfo.passed = false;
00450       pathInfo.moduleStart = m_modules.size();
00451       m_paths.push_back(pathInfo);
00452 
00453       m_parentStack.push_back(m_entries.size());
00454       m_entries.push_back(pathEntry);
00455 
00456       std::vector<std::string> pathModules;
00457       info->modulesInPath(pathName, pathModules);
00458 
00459       for (size_t mi = 0, me = pathModules.size(); mi != me; ++mi)
00460       {
00461          PSetData moduleEntry;
00462 
00463          const edm::ParameterSet* ps = info->parametersForModule(pathModules[mi]);
00464          const edm::ParameterSet::table& pst = ps->tbl();
00465          const edm::ParameterSet::table::const_iterator ti = pst.find("@module_edm_type");
00466 
00467          if (ti == pst.end())
00468             moduleEntry.value = "Unknown module name";
00469          else
00470             moduleEntry.value = ti->second.getString();
00471 
00472          moduleEntry.label = pathModules[mi];
00473          moduleEntry.parent = m_parentStack.back();
00474          moduleEntry.level = m_parentStack.size();
00475          moduleEntry.module = mi;
00476          moduleEntry.path = i;
00477          moduleEntry.pset = *ps;
00478          moduleEntry.editable = false;
00479          ModuleInfo moduleInfo;
00480          moduleInfo.path = m_paths.size() - 1;
00481          moduleInfo.entry = m_entries.size();
00482          moduleInfo.passed = false;
00483          moduleInfo.dirty = false;
00484          m_modules.push_back(moduleInfo);
00485          m_parentStack.push_back(m_entries.size());
00486          m_entries.push_back(moduleEntry);
00487          handlePSet(moduleEntry.pset);
00488          m_parentStack.pop_back();
00489       }
00490       m_paths.back().moduleEnd = m_modules.size();
00491       m_parentStack.pop_back();
00492    }
00493 
00494    // Nothing is expanded by default.
00495    for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00496       m_entries[i].expandedUser = false;
00497 
00498    m_filter = "";
00499 
00500    recalculateVisibility();
00501 } //updateSchedule
00502 
00503 
00507 void FWPSetTableManager::update(std::vector<PathUpdate> &pathUpdates)
00508 {
00509    // Reset all the path / module status information, so that
00510    // by default paths and modules are considered "not passed".
00511    for (size_t pi = 0, pe = m_paths.size(); pi != pe; ++pi)
00512       m_paths[pi].passed = false;
00513    for (size_t mi = 0, me = m_modules.size(); mi != me; ++mi)
00514       m_modules[mi].passed = false;
00515          
00516    // Update whether or not a given path / module passed selection.
00517    for (size_t pui = 0, pue = pathUpdates.size(); pui != pue; ++pui)
00518    {
00519       PathUpdate &update = pathUpdates[pui];
00520       std::map<std::string, size_t>::const_iterator index = m_pathIndex.find(update.pathName);
00521       if (index == m_pathIndex.end())
00522       {
00523          fwLog(fwlog::kError) << "Path " << update.pathName << "cannot be found!" << std::endl;
00524          continue;
00525       }
00526       PathInfo &pathInfo = m_paths[index->second];
00527       pathInfo.passed = update.passed;
00528             
00529       for (size_t mi = pathInfo.moduleStart, me = pathInfo.moduleEnd; mi != me; ++mi)
00530       {
00531          ModuleInfo &moduleInfo = m_modules[mi];
00532          moduleInfo.passed = update.passed || ((mi-pathInfo.moduleStart) < update.choiceMaker);
00533       }
00534    }
00535 
00536    implSort(-1, true);
00537 }
00538 
00539 //==============================================================================
00540 //==============================================================================
00541 //=============== CELL EDITOR ACTIONS ==========================================
00542 //==============================================================================
00543 //==============================================================================
00544 
00545 void FWPSetTableManager::setCellValueEditor(FWPSetCellEditor *editor)
00546 {
00547    m_editor = editor;
00548    m_renderer.setCellEditor(m_editor);
00549 }
00550 
00551 
00553 void FWPSetTableManager::cancelEditor()
00554 {
00555    if (!m_editor)
00556       return;
00557      
00558    //  printf("FWPSetTableManager::cancelEditor() \n");  
00559    setSelection(-1, -1, 0);
00560    m_editor->UnmapWindow();      
00561 }
00562 
00567 bool FWPSetTableManager::applyEditor()
00568 {
00569    if (!m_editor)
00570       return false;
00571          
00572    if (m_selectedRow == -1 ||m_selectedColumn != 1 )
00573       return false;
00574 
00575          
00576    //  printf("FWPSetTableManager::applyEditor() \n"); 
00577    PSetData &data = m_entries[m_row_to_index[m_selectedRow]];
00578    PSetData &parent = m_entries[data.parent];
00579    bool success = false;
00580    try
00581    {
00582       success = m_editor->apply(data, parent);
00583       if (success)
00584       {
00585          data.value = m_editor->GetText();
00586          m_modules[data.module].dirty = true;
00587          setSelection(-1, -1, 0); 
00588          m_editor->UnmapWindow();
00589       }
00590    }
00591    catch(cms::Exception &e)
00592    {
00593       m_editor->SetForegroundColor(gVirtualX->GetPixel(kRed));
00594    }
00595    return success;
00596 }
00597 
00598 
00599 //==============================================================================
00600 //==============================================================================
00601 //========  TABLE UI MNG (virutals FWTableManagerBase virtuals, etc.)   =========
00602 //==============================================================================
00603 //==============================================================================
00604 const std::string FWPSetTableManager::title() const {
00605    return "Modules & their parameters";
00606 }
00607 
00608 std::vector<std::string> FWPSetTableManager::getTitles() const 
00609 {
00610    std::vector<std::string> returnValue;
00611    returnValue.reserve(numberOfColumns());
00612    returnValue.push_back("Label");
00613    returnValue.push_back("Value");
00614    return returnValue;
00615 }
00616 
00617 int FWPSetTableManager::selectedRow() const {
00618    return m_selectedRow;
00619 }
00620 
00621 int FWPSetTableManager::selectedColumn() const {
00622    return m_selectedColumn;
00623 }
00624 
00625 bool FWPSetTableManager::rowIsSelected(int row) const 
00626 {
00627    return m_selectedRow == row;
00628 }
00629 
00630 int FWPSetTableManager::unsortedRowNumber(int unsorted) const
00631 {
00632    return unsorted;
00633 }
00634 
00635 int FWPSetTableManager::numberOfRows() const {
00636    return m_row_to_index.size();
00637 }
00638 
00639 int FWPSetTableManager::numberOfColumns() const {
00640    return 2;
00641 }
00642 
00643 void FWPSetTableManager::setSelection (int iRow, int iColumn, int mask) 
00644 {     
00645    // printf("set selection %d %d mode %d\n", iRow, iColumn, mask);
00646   
00647    // Nothing changes if we clicked selected
00648    // twice the same cell.
00649    if (iRow == m_selectedRow && iColumn == m_selectedColumn)
00650       return;
00651 
00652    // Otherwise update the selection information
00653    // and notify observers.
00654    m_selectedRow = iRow;
00655    m_selectedColumn = iColumn;
00656    if (iColumn == 1 && iRow > 0 )
00657    {
00658       int unsortedRow =  m_row_to_index[iRow];
00659       const PSetData& data = m_entries[unsortedRow];
00660       if (m_editor && data.editable) {
00661          m_editor->MoveResize(0, cellHeight()*iRow, m_editor->GetWidth() , m_editor->GetHeight());
00662          m_editor->MapWindow();
00663          m_editor->SetText(data.value.c_str());
00664          m_editor->SetFocus();
00665          m_editor->SetCursorPosition(data.value.size()-1);
00666       }
00667    }
00668    else
00669    {
00670       if (m_editor) m_editor->UnmapWindow();
00671    }
00672    visualPropertiesChanged();
00673 }
00674   
00675 std::vector<unsigned int> FWPSetTableManager::maxWidthForColumns() const 
00676 {
00677    std::vector<unsigned int> ww = FWTableManagerBase::maxWidthForColumns();
00678    if (ww.size() > 1 && ww[1] > 0) 
00679    {
00680       // printf("dim W %d \n",ww[1]);
00681       // printf("dim H %d \n",cellHeight());
00682       if (m_editor)
00683          m_editor->MoveResize(m_editor->GetX(),m_editor->GetY(),  ww[1], cellHeight());
00684    }
00685    return ww;
00686 
00687 }
00688 
00689 void FWPSetTableManager::implSort(int, bool)
00690 {
00691 }
00692 //______________________________________________________________________________
00693 
00694 void FWPSetTableManager::setExpanded(int row)
00695 {
00696    if (row == -1)
00697       return;
00698 
00699    int index = rowToIndex()[row];
00700    PSetData& data = m_entries[index];
00701 
00702    if (m_filter.empty() == false && data.childMatches == false)
00703       return;
00704 
00705    if (m_filter.empty())
00706       data.expandedUser = !data.expandedUser;
00707    else
00708       data.expandedFilter = !data.expandedFilter;
00709 
00710    recalculateVisibility();
00711    dataChanged();
00712    visualPropertiesChanged();
00713 }
00714 
00715 //______________________________________________________________________________
00716 
00717 FWTableCellRendererBase* FWPSetTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
00718 {
00719    static size_t maxSize = 512; // maximum string length
00720 
00721    static TGGC boldGC(fireworks::boldGC()); 
00722    static TGGC italicGC(fireworks::italicGC()); 
00723    static TGGC defaultGC(FWTextTableCellRenderer::getDefaultGC()); 
00724    
00725    const static Pixel_t gray  = 0x777777;
00726    const static Pixel_t red   = gVirtualX->GetPixel(kRed-5);
00727    const static Pixel_t green = gVirtualX->GetPixel(kGreen-5);
00728 
00729    // return in case if nothing maches filter
00730    if (static_cast<int>(m_row_to_index.size()) <= iSortedRowNumber)
00731    {
00732       m_renderer.setData(std::string(), false);
00733       return &m_renderer;
00734    }
00735 
00736 
00737    int unsortedRow =  m_row_to_index[iSortedRowNumber];
00738    const PSetData& data = m_entries[unsortedRow];
00739 
00740    std::string value;
00741    std::string label;
00742    TGGC* gc = 0;
00743    if (data.level == 0)
00744    {
00745       const PathInfo &path = m_paths[data.path];
00746       label = data.label + " (" + data.value + ")";
00747       gc = &boldGC;
00748       gc->SetForeground(path.passed ? green: red);
00749    }
00750    else if (data.level == 1)
00751    { 
00752       // "passed" means if module made decision on path 
00753       const ModuleInfo &module = m_modules[m_paths[data.path].moduleStart + data.module];
00754       label = data.label + " (" + data.value + ")";
00755       gc = (TGGC*)&boldGC;
00756       gc->SetForeground(module.passed ? green : red);
00757    }
00758    else
00759    {
00760       if (data.type > 0)
00761          label = data.label + " (" + sTypeTranslations.table_[data.type] + ")";
00762       else
00763          label = data.label;
00764       value = data.value;
00765          
00766       if (data.editable)
00767       {
00768          gc = &defaultGC;
00769       }
00770       else
00771       {
00772          gc = &italicGC;
00773          gc->SetForeground(gray);
00774       }
00775    }
00776 
00777    // check string size and cut it if necessary (problems with X11)
00778    if (iCol == 1 && value.size() >= maxSize)
00779    { 
00780       if (iSortedRowNumber == m_selectedRow)
00781          fwLog(fwlog::kWarning) << "label: " << label << " has too long value " << value << std::endl << std::endl;  
00782 
00783       value = value.substr(0, maxSize);
00784       value += "[truncated]";
00785       gc->SetForeground(gVirtualX->GetPixel(kMagenta));
00786    }
00787 
00788    // debug
00789    // label = Form("%s m[%d] childm[%d] ", label.c_str(), data.matches, data.childMatches);
00790 
00791    // set text attributes
00792    m_renderer.setGraphicsContext(gc);
00793    bool selected = data.matches && (m_filter.empty() == false);
00794    m_renderer.setData(iCol ?  value : label, selected);
00795 
00796    // set  tree attributes
00797    bool isParent = false;
00798    bool isOpen = false;
00799    int indent = 0;
00800    if (iCol == 0)
00801    { 
00802       if (m_filter.empty())
00803       {
00804          size_t nextIdx =  unsortedRow + 1;
00805          isParent = (nextIdx < m_entries.size() &&  m_entries[nextIdx].parent == (size_t)unsortedRow);
00806          isOpen = data.expandedUser;
00807       }
00808       else 
00809       {
00810          isParent = data.childMatches;
00811          isOpen = data.expandedFilter && data.childMatches;
00812       }
00813 
00814       indent =  data.level * 10 ;
00815       if (!isParent) indent += FWTextTreeCellRenderer::iconWidth();
00816    }
00817    m_renderer.setIsParent(isParent);
00818    m_renderer.setIsOpen(isOpen);
00819    m_renderer.setIndentation(indent);
00820 
00821    
00822    // If we are rendering the selected cell,
00823    // we show the editor.
00824    bool showEdit =  (iCol == 1 && iSortedRowNumber == m_selectedRow && iCol == m_selectedColumn && value.size() < maxSize);
00825    m_renderer.showEditor(data.editable && showEdit);
00826 
00827    return &m_renderer;
00828 } // cellRender()
00829 
00830 //______________________________________________________________________________
00831 
00832 void FWPSetTableManager::updateFilter(const char *filter)
00833 {
00834    m_filter = filter;
00835 
00836    if (m_filter.empty())
00837    { 
00838       // collapse entries when filter is removed
00839       for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00840          m_entries[i].expandedFilter = false;
00841    }
00842    else
00843    {
00844       // Decide whether or not items match the filter.
00845       for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00846       {
00847          PSetData &data = m_entries[i];
00848 
00849          // First of all decide whether or not we match
00850          // the filter.
00851          if (strstr(data.label.c_str(), m_filter.c_str()) || strstr(data.value.c_str(), m_filter.c_str()) )
00852             data.matches = true;
00853          else
00854             data.matches = false;
00855       }
00856 
00857       // We reset whether or not a given parent has children that match the
00858       // filter, and we recompute the whole information by checking all the
00859       // children.
00860       for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00861          m_entries[i].childMatches = false;
00862 
00863       std::vector<int> stack;
00864       int previousLevel = 0;
00865       for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00866       {
00867          PSetData &data = m_entries[i];
00868          // Top level.
00869          if (data.parent == (size_t)-1)
00870          {
00871             previousLevel = 0;
00872             // std::cout << "reset stack for top level " << data.label << std::endl;
00873             stack.clear();
00874             continue;
00875          }
00876          // If the level is greater than the previous one,
00877          // it means we are among the children of the 
00878          // previous level, hence we push the parent to
00879          // the stack.
00880          // If the level is not greater than the previous
00881          // one it means we have popped out n levels of
00882          // parents, where N is the difference between the 
00883          // new and the old level. In this case we
00884          // pop up N parents from the stack.
00885          if (data.level > previousLevel)
00886             stack.push_back(data.parent);
00887          else
00888             for (size_t pi = 0, pe = previousLevel - data.level; pi != pe; ++pi)
00889                stack.pop_back();
00890  
00891          if (data.matches && m_entries[stack.back()].childMatches == false)
00892          {
00893             //  printf("match for %s with level %d\n",data.label.c_str(), data.level );
00894             for (size_t pi = 0, pe = stack.size(); pi != pe; ++pi)
00895             {
00896                //    printf("set child match to parent %s with level %d \n",m_entries[stack[pi]].label.c_str(), m_entries[stack[pi]].level);
00897                m_entries[stack[pi]].childMatches = true;
00898                
00899             }
00900          }
00901 
00902          previousLevel = data.level;
00903       }
00904    
00905       // expand to matching children
00906       for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00907          m_entries[i].expandedFilter = m_entries[i].childMatches;
00908 
00909    }
00910  
00911    recalculateVisibility();
00912 
00913    dataChanged();
00914 } // updateFilter()
00915 
00916 //______________________________________________________________________________
00917 
00918 void FWPSetTableManager::recalculateVisibility()
00919 {
00920    m_row_to_index.clear();
00921 
00922    // Decide about visibility.
00923    // * If the items are toplevel and they match the filter, they get shown
00924    //   in any case.
00925    // * If the item or any of its children match the filter, the item
00926    //   is visible.
00927    // * If the filter is empty and the parent is expanded.
00928    for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00929    { 
00930       PSetData &data = m_entries[i];
00931       if (data.parent == ((size_t) -1))
00932       {
00933          data.visible = data.childMatches || data.matches || m_filter.empty();
00934       }
00935       else
00936       {
00937          if (m_filter.empty())
00938          {
00939             data.visible = m_entries[data.parent].expandedUser && m_entries[data.parent].visible;
00940          }
00941          else
00942          {
00943             if (data.level < 2)
00944                data.visible = m_entries[data.parent].expandedFilter && m_entries[data.parent].visible && (data.matches || data.childMatches);
00945             else
00946                data.visible = m_entries[data.parent].expandedFilter && m_entries[data.parent].visible;
00947          }
00948       }
00949    }
00950 
00951    // Put in the index only the entries which are visible.
00952    for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00953       if (m_entries[i].visible)
00954          m_row_to_index.push_back(i);
00955 }
00956