CMS 3D CMS Logo

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