File indexing completed on 2024-04-06 12:11:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <iostream>
0015 #include <sigc++/signal.h>
0016 #include <functional>
0017 #include <algorithm>
0018 #include <cctype>
0019 #include <string>
0020
0021 #include "TGFrame.h"
0022 #include "TGTextEntry.h"
0023 #include "TGButton.h"
0024 #include "TGMsgBox.h"
0025 #include "TClass.h"
0026 #include "TFile.h"
0027 #include "TTree.h"
0028 #include "TBranch.h"
0029
0030
0031 #include "Fireworks/Core/src/FWGUIEventDataAdder.h"
0032 #include "Fireworks/Core/interface/FWPhysicsObjectDesc.h"
0033 #include "Fireworks/Core/interface/FWEventItemsManager.h"
0034 #include "Fireworks/Core/interface/FWEventItem.h"
0035 #include "Fireworks/Core/interface/FWItemAccessorFactory.h"
0036 #include "Fireworks/Core/interface/FWJobMetadataManager.h"
0037 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
0038 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
0039 #include "Fireworks/TableWidget/interface/FWTextTableCellRenderer.h"
0040 #include "Fireworks/Core/interface/fwLog.h"
0041 #include "Fireworks/Core/interface/FWDialogBuilder.h"
0042
0043
0044
0045 static const std::string &dataForColumn(const FWJobMetadataManager::Data &iData, int iCol) {
0046 switch (iCol) {
0047 case 0:
0048 return iData.purpose_;
0049 break;
0050 case 4:
0051 return iData.type_;
0052 break;
0053 case 1:
0054 return iData.moduleLabel_;
0055 break;
0056 case 2:
0057 return iData.productInstanceLabel_;
0058 break;
0059 case 3:
0060 return iData.processName_;
0061 break;
0062 default:
0063 break;
0064 }
0065 static const std::string s_blank;
0066 return s_blank;
0067 }
0068
0069 static const unsigned int kNColumns = 5;
0070 class DataAdderTableManager : public FWTableManagerBase {
0071 public:
0072 DataAdderTableManager(FWJobMetadataManager *manager) : m_manager(manager), m_selectedRow(-1), m_filter() { reset(); }
0073
0074 int numberOfRows() const override { return m_row_to_index.size(); }
0075 int numberOfColumns() const override { return kNColumns; }
0076
0077
0078
0079
0080
0081 virtual void sortWithFilter(const char *filter) {
0082 m_filter = filter;
0083 sort(-1, sortOrder());
0084 dataChanged();
0085 }
0086
0087 int unsortedRowNumber(int iSortedRowNumber) const override { return m_row_to_index[iSortedRowNumber]; }
0088
0089 void implSort(int col, bool sortOrder) override;
0090 std::vector<std::string> getTitles() const override {
0091 std::vector<std::string> returnValue;
0092 returnValue.reserve(kNColumns);
0093 returnValue.push_back("Purpose");
0094 returnValue.push_back("Module Label");
0095 returnValue.push_back("Product Instance Label");
0096 returnValue.push_back("Process Name");
0097 returnValue.push_back("C++ Class");
0098 return returnValue;
0099 }
0100
0101 FWTableCellRendererBase *cellRenderer(int iSortedRowNumber, int iCol) const override {
0102 if (static_cast<int>(m_row_to_index.size()) > iSortedRowNumber) {
0103 int unsortedRow = m_row_to_index[iSortedRowNumber];
0104 const FWJobMetadataManager::Data &data = (m_manager->usableData())[unsortedRow];
0105
0106 m_renderer.setData(dataForColumn(data, iCol), m_selectedRow == unsortedRow);
0107 } else {
0108 m_renderer.setData(std::string(), false);
0109 }
0110 return &m_renderer;
0111 }
0112
0113 void setSelection(int row, int mask) {
0114 if (mask == 4) {
0115 if (row == m_selectedRow) {
0116 row = -1;
0117 }
0118 }
0119 changeSelection(row);
0120 }
0121
0122 virtual const std::string title() const { return "Viewable Collections"; }
0123
0124 int selectedRow() const { return m_selectedRow; }
0125
0126 virtual bool rowIsSelected(int row) const { return m_selectedRow == row; }
0127
0128 void reset() {
0129 changeSelection(-1);
0130 m_row_to_index.clear();
0131 m_row_to_index.reserve(m_manager->usableData().size());
0132 for (unsigned int i = 0; i < m_manager->usableData().size(); ++i) {
0133 m_row_to_index.push_back(i);
0134 }
0135 dataChanged();
0136 }
0137 sigc::signal<void(int)> indexSelected_;
0138
0139 private:
0140 void changeSelection(int iRow) {
0141 if (iRow != m_selectedRow) {
0142 m_selectedRow = iRow;
0143 if (-1 == iRow) {
0144 indexSelected_(-1);
0145 } else {
0146 indexSelected_(iRow);
0147 }
0148 visualPropertiesChanged();
0149 }
0150 }
0151 FWJobMetadataManager *m_manager;
0152 std::vector<int> m_row_to_index;
0153 int m_selectedRow;
0154 std::string m_filter;
0155 mutable FWTextTableCellRenderer m_renderer;
0156 };
0157
0158 namespace {
0159 void strip(std::string &source, const char *str) {
0160 std::string remove(str);
0161 while (true) {
0162 size_t found = source.find(remove);
0163 if (found == std::string::npos)
0164 break;
0165 source.erase(found, remove.size());
0166 }
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 class SortAndFilter {
0187 public:
0188 SortAndFilter(const char *filter, int column, bool order, const std::vector<FWJobMetadataManager::Data> &data)
0189 : m_filter(filter), m_column(column), m_order(order), m_data(data) {
0190 simplify(m_filter);
0191 m_weights.resize(data.size());
0192
0193
0194
0195
0196 for (size_t i = 0, e = m_weights.size(); i != e; ++i)
0197 m_weights[i] = matchesFilter(m_data[i]);
0198 }
0199
0200
0201
0202
0203 static void simplify(std::string &str) {
0204 std::transform(str.begin(), str.end(), str.begin(), tolower);
0205 strip(str, "std::");
0206 strip(str, "edm::");
0207 strip(str, "vector<");
0208 strip(str, "clonepolicy");
0209 strip(str, "ownvector");
0210 strip(str, "rangemap<");
0211 strip(str, "strictweakordering<");
0212 strip(str, "sortedcollection<");
0213 strip(str, "reco::");
0214 strip(str, "edmnew::");
0215 }
0216
0217 unsigned int matches(const std::string &str) const {
0218 std::string up(str);
0219 simplify(up);
0220 const char *begin = up.c_str();
0221
0222
0223
0224
0225
0226 if ((!m_filter.empty()) && str.empty())
0227 return 0;
0228
0229
0230
0231
0232 if (strstr(begin, m_filter.c_str()))
0233 return 2;
0234
0235 return 0;
0236 }
0237
0238
0239
0240
0241
0242
0243 unsigned int matchesFilter(const FWJobMetadataManager::Data &data) const {
0244 std::vector<unsigned int> scores;
0245 scores.reserve(10);
0246 scores.push_back(matches(data.purpose_));
0247 scores.push_back(matches(data.type_));
0248 scores.push_back(matches(data.moduleLabel_));
0249 scores.push_back(matches(data.productInstanceLabel_));
0250 scores.push_back(matches(data.processName_));
0251 std::sort(scores.begin(), scores.end());
0252 return scores.back();
0253 }
0254
0255
0256
0257
0258 bool operator()(const int &aIndex, const int &bIndex) {
0259
0260
0261 if (m_column == -1)
0262 return m_weights[aIndex] >= m_weights[bIndex];
0263
0264 const FWJobMetadataManager::Data &a = m_data[aIndex];
0265 const FWJobMetadataManager::Data &b = m_data[bIndex];
0266
0267 if (m_order)
0268 return dataForColumn(a, m_column) < dataForColumn(b, m_column);
0269 else
0270 return dataForColumn(a, m_column) > dataForColumn(b, m_column);
0271 }
0272
0273 private:
0274 std::string m_filter;
0275 int m_column;
0276 bool m_order;
0277
0278 const std::vector<FWJobMetadataManager::Data> &m_data;
0279 std::vector<unsigned int> m_weights;
0280 };
0281
0282 void doSort(int column,
0283 const char *filter,
0284 bool descentSort,
0285 const std::vector<FWJobMetadataManager::Data> &iData,
0286 std::vector<int> &oRowToIndex) {
0287 std::vector<int> ordered;
0288 ordered.reserve(iData.size());
0289
0290 for (size_t i = 0, e = iData.size(); i != e; ++i)
0291 ordered.push_back(i);
0292
0293 SortAndFilter sorter(filter, column, descentSort, iData);
0294
0295 std::stable_sort(ordered.begin(), ordered.end(), sorter);
0296
0297 oRowToIndex.clear();
0298 oRowToIndex.reserve(ordered.size());
0299
0300 for (size_t i = 0, e = ordered.size(); i != e; ++i)
0301 if (sorter.matchesFilter(iData[ordered[i]]) != 0)
0302 oRowToIndex.push_back(ordered[i]);
0303 }
0304 }
0305
0306 void DataAdderTableManager::implSort(int column, bool sortOrder) {
0307 doSort(column, m_filter.c_str(), sortOrder, m_manager->usableData(), m_row_to_index);
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318 FWGUIEventDataAdder::FWGUIEventDataAdder(UInt_t iWidth,
0319 UInt_t iHeight,
0320 FWEventItemsManager *iManager,
0321 TGFrame *iParent,
0322 FWJobMetadataManager *iMetadataManager)
0323 : m_manager(iManager), m_metadataManager(iMetadataManager), m_parentFrame(iParent) {
0324 m_metadataManager->metadataChanged_.connect(std::bind(&FWGUIEventDataAdder::metadataUpdatedSlot, this));
0325 createWindow();
0326 }
0327
0328
0329
0330
0331
0332
0333 FWGUIEventDataAdder::~FWGUIEventDataAdder() {
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 void FWGUIEventDataAdder::addNewItem() {
0361 TClass *theClass = TClass::GetClass(m_type.c_str());
0362 if (nullptr == theClass) {
0363 return;
0364 }
0365 const std::string moduleLabel = m_moduleLabel;
0366 if (moduleLabel.empty()) {
0367 return;
0368 }
0369
0370 const std::string name = m_name->GetText();
0371 if (name.empty()) {
0372 return;
0373 }
0374
0375 if (m_manager->find(name)) {
0376 TString msg("Event item '");
0377 msg += name;
0378 msg += "' is already registered. Please use another name.";
0379 fwLog(fwlog::kWarning) << msg.Data() << std::endl;
0380 new TGMsgBox(gClient->GetDefaultRoot(), m_frame, "Error - Name conflict", msg, kMBIconExclamation, kMBOk);
0381 return;
0382 }
0383
0384 int largest = -1;
0385 if (m_manager->begin() != m_manager->end()) {
0386 if (*(m_manager->begin()))
0387 largest = (*(m_manager->begin()))->layer();
0388 }
0389 for (FWEventItemsManager::const_iterator it = m_manager->begin(), itEnd = m_manager->end(); it != itEnd; ++it) {
0390 if ((*it) && largest < (*it)->layer()) {
0391 largest = (*it)->layer();
0392 }
0393 }
0394 ++largest;
0395 std::string processName = m_processName;
0396 if (m_doNotUseProcessName->IsOn() && m_doNotUseProcessName->IsEnabled()) {
0397 processName = "";
0398 }
0399 FWPhysicsObjectDesc desc(name,
0400 theClass,
0401 m_purpose,
0402 FWDisplayProperties::defaultProperties,
0403 moduleLabel,
0404 m_productInstanceLabel,
0405 processName,
0406 "",
0407 largest);
0408 m_manager->add(desc);
0409 }
0410
0411 void FWGUIEventDataAdder::addNewItemAndClose() {
0412 addNewItem();
0413 windowIsClosing();
0414 }
0415
0416 void FWGUIEventDataAdder::show() {
0417
0418 if (nullptr == m_frame) {
0419 createWindow();
0420 }
0421 m_frame->MapWindow();
0422 }
0423
0424 void FWGUIEventDataAdder::windowIsClosing() {
0425 m_name->SetText("");
0426 m_search->SetText("");
0427 m_purpose.clear();
0428 m_type.clear();
0429 m_moduleLabel.clear();
0430 m_processName.clear();
0431 m_productInstanceLabel.clear();
0432 m_apply->SetEnabled(false);
0433 m_applyAndClose->SetEnabled(false);
0434
0435 m_frame->UnmapWindow();
0436 m_frame->DontCallClose();
0437 }
0438
0439 void FWGUIEventDataAdder::updateFilterString(const char *str) {
0440 m_tableManager->sortWithFilter(str);
0441 m_tableManager->dataChanged();
0442 }
0443
0444 void FWGUIEventDataAdder::createWindow() {
0445 m_tableManager = new DataAdderTableManager(m_metadataManager);
0446 m_tableManager->indexSelected_.connect(
0447 std::bind(&FWGUIEventDataAdder::newIndexSelected, this, std::placeholders::_1));
0448
0449 m_frame = new TGTransientFrame(gClient->GetDefaultRoot(), m_parentFrame, 600, 400);
0450 m_frame->Connect("CloseWindow()", "FWGUIEventDataAdder", this, "windowIsClosing()");
0451
0452 FWDialogBuilder builder(m_frame);
0453 TGTextButton *cancelButton, *resetButton;
0454
0455 builder.indent(10)
0456 .spaceDown(15)
0457 .addLabel("Search:", 0)
0458 .expand(false)
0459 .spaceUp(4)
0460 .floatLeft(4)
0461 .addTextEntry("", &m_search)
0462 .spaceUp(0)
0463 .frameSpaceDown(10)
0464 .addLabel("Viewable Collections", 8)
0465 .frameSpaceDown(5)
0466 .addTable(m_tableManager, &m_tableWidget)
0467 .expand(true, true)
0468 .addLabel("Name:", 0)
0469 .expand(false)
0470 .spaceUp(4)
0471 .floatLeft(4)
0472 .addTextEntry("", &m_name)
0473 .spaceUp(0)
0474 .floatLeft(4)
0475 .addTextButton(" Reset ", &resetButton)
0476 .expand(false, false)
0477 .frameSpaceUpDown(5)
0478 .addCheckbox(
0479 "Do not use Process Name and "
0480 "instead only get this data "
0481 "from the most recent Process",
0482 &m_doNotUseProcessName)
0483 .frameSpaceDown(15)
0484 .hSpacer()
0485 .floatLeft(0)
0486 .addTextButton(" Close ", &cancelButton)
0487 .expand(false)
0488 .floatLeft(4)
0489 .addTextButton(" Add Data ", &m_apply)
0490 .expand(false)
0491 .floatLeft(4)
0492 .addTextButton(" Add Data && Close ", &m_applyAndClose)
0493 .expand(false)
0494 .spaceRight(25)
0495 .spaceDown(15);
0496
0497 m_search->Connect("TextChanged(const char *)", "FWGUIEventDataAdder", this, "updateFilterString(const char *)");
0498 m_search->SetEnabled(true);
0499 m_tableWidget->SetBackgroundColor(0xffffff);
0500 m_tableWidget->SetLineSeparatorColor(0x000000);
0501 m_tableWidget->SetHeaderBackgroundColor(0xececec);
0502 m_tableWidget->Connect("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)",
0503 "FWGUIEventDataAdder",
0504 this,
0505 "rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)");
0506
0507 m_tableWidget->disableGrowInWidth();
0508 m_name->SetState(true);
0509 resetButton->SetEnabled(true);
0510 resetButton->Connect("Clicked()", "FWGUIEventDataAdder", this, "resetNameEntry()");
0511 m_doNotUseProcessName->SetState(kButtonDown);
0512 cancelButton->Connect("Clicked()", "FWGUIEventDataAdder", this, "windowIsClosing()");
0513 cancelButton->SetEnabled(true);
0514 m_apply->Connect("Clicked()", "FWGUIEventDataAdder", this, "addNewItem()");
0515 m_applyAndClose->Connect("Clicked()", "FWGUIEventDataAdder", this, "addNewItemAndClose()");
0516
0517 m_frame->SetWindowName("Add Collection");
0518 m_frame->MapSubwindows();
0519 m_frame->Layout();
0520 }
0521
0522
0523
0524
0525
0526 void FWGUIEventDataAdder::metadataUpdatedSlot(void) {
0527 m_tableManager->reset();
0528 m_tableManager->sort(0, true);
0529 }
0530
0531 void FWGUIEventDataAdder::resetNameEntry() {
0532 m_name->SetText(m_apply->IsEnabled() ? m_moduleLabel.c_str() : "", kFALSE);
0533 }
0534
0535 void FWGUIEventDataAdder::newIndexSelected(int iSelectedIndex) {
0536 if (-1 != iSelectedIndex) {
0537 std::vector<FWJobMetadataManager::Data> &metadata = m_metadataManager->usableData();
0538 m_purpose = metadata[iSelectedIndex].purpose_;
0539 m_type = metadata[iSelectedIndex].type_;
0540 std::string oldModuleLabel = m_moduleLabel;
0541 m_moduleLabel = metadata[iSelectedIndex].moduleLabel_;
0542 m_productInstanceLabel = metadata[iSelectedIndex].productInstanceLabel_;
0543 m_processName = metadata[iSelectedIndex].processName_;
0544
0545 if (strlen(m_name->GetText()) == 0 || oldModuleLabel == m_name->GetText()) {
0546 m_name->SetText(m_moduleLabel.c_str());
0547 }
0548 m_apply->SetEnabled(true);
0549 m_applyAndClose->SetEnabled(true);
0550
0551
0552
0553
0554
0555 bool isMostRecentProcess = true;
0556 int index = 0;
0557 for (std::vector<FWJobMetadataManager::Data>::iterator it = metadata.begin(), itEnd = metadata.end();
0558 it != itEnd && isMostRecentProcess;
0559 ++it, ++index) {
0560 if (index == iSelectedIndex) {
0561 continue;
0562 }
0563 if (it->moduleLabel_ == m_moduleLabel && it->purpose_ == m_purpose && it->type_ == m_type &&
0564 it->productInstanceLabel_ == m_productInstanceLabel) {
0565
0566
0567 for (size_t pni = 0, pne = m_metadataManager->processNamesInJob().size(); pni != pne; ++pni) {
0568 const std::string &processName = m_metadataManager->processNamesInJob()[pni];
0569 if (m_processName == processName)
0570 break;
0571
0572 if (it->processName_ == processName) {
0573 isMostRecentProcess = false;
0574 break;
0575 }
0576 }
0577 }
0578 }
0579 if (isMostRecentProcess) {
0580 if (!m_doNotUseProcessName->IsEnabled()) {
0581 m_doNotUseProcessName->SetEnabled(true);
0582 }
0583 } else {
0584
0585
0586 m_doNotUseProcessName->SetEnabled(false);
0587 }
0588 }
0589 }
0590
0591 void FWGUIEventDataAdder::rowClicked(Int_t iRow, Int_t iButton, Int_t iKeyMod, Int_t, Int_t) {
0592 if (iButton == kButton1) {
0593 m_tableManager->setSelection(iRow, iKeyMod);
0594 }
0595 }
0596
0597
0598
0599
0600
0601
0602
0603