File indexing completed on 2024-07-18 23:17:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cstdlib>
0015 #include <algorithm>
0016 #include <memory>
0017 #include <iostream>
0018 #include <sstream>
0019 #include <stdexcept>
0020 #include <cassert>
0021
0022 #include "TMath.h"
0023 #include "TClass.h"
0024 #include "TSystem.h"
0025 #include "TGComboBox.h"
0026 #include "TGLabel.h"
0027 #include "TGTextEntry.h"
0028 #include "TEveWindow.h"
0029 #include "TVirtualX.h"
0030
0031
0032 #include "Fireworks/Core/interface/FWColorManager.h"
0033 #include "Fireworks/Core/interface/FWCustomIconsButton.h"
0034 #include "Fireworks/Core/interface/FWModelChangeManager.h"
0035 #include "Fireworks/Core/interface/FWSelectionManager.h"
0036 #include "Fireworks/Core/interface/FWTableView.h"
0037 #include "Fireworks/Core/interface/FWTableViewManager.h"
0038 #include "Fireworks/Core/interface/FWEventItem.h"
0039 #include "Fireworks/Core/interface/FWConfiguration.h"
0040 #include "Fireworks/Core/interface/FWTableViewTableManager.h"
0041 #include "Fireworks/Core/interface/fwLog.h"
0042 #include "Fireworks/Core/src/FWGUIValidatingTextEntry.h"
0043 #include "Fireworks/Core/src/FWExpressionValidator.h"
0044 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
0045
0046 static const TString &coreIcondir() {
0047 static TString path = Form("%s/src/Fireworks/Core/icons/", gSystem->Getenv("CMSSW_BASE"));
0048 if (gSystem->AccessPathName(path.Data())) {
0049 assert(gSystem->Getenv("CMSSW_RELEASE_BASE"));
0050 path = Form("%s/src/Fireworks/Core/icons/", gSystem->Getenv("CMSSW_RELEASE_BASE"));
0051 }
0052 return path;
0053 }
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 static const TGPicture *arrow_right(bool iBackgroundIsBlack) {
0151 if (iBackgroundIsBlack) {
0152 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-white-right-blackbg.png");
0153 return s;
0154 }
0155 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-black-right-whitebg.png");
0156 return s;
0157 }
0158
0159 static const TGPicture *arrow_right_disabled(bool iBackgroundIsBlack) {
0160 if (iBackgroundIsBlack) {
0161 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-white-right-disabled-blackbg.png");
0162 return s;
0163 }
0164 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-black-right-disabled-whitebg.png");
0165 return s;
0166 }
0167
0168 static const TGPicture *arrow_down(bool iBackgroundIsBlack) {
0169 if (iBackgroundIsBlack) {
0170 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-white-down-blackbg.png");
0171 return s;
0172 }
0173 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-black-down-whitebg.png");
0174 return s;
0175 }
0176
0177 static const TGPicture *arrow_down_disabled(bool iBackgroundIsBlack) {
0178 if (iBackgroundIsBlack) {
0179 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-white-down-disabled-blackbg.png");
0180 return s;
0181 }
0182 static const TGPicture *s = gClient->GetPicture(coreIcondir() + "arrow-black-down-disabled-whitebg.png");
0183 return s;
0184 }
0185
0186
0187
0188
0189 static const std::string kTableView = "TableView";
0190 static const std::string kCollection = "collection";
0191
0192 static const std::string kSortColumn = "sortColumn";
0193 static const std::string kDescendingSort = "descendingSort";
0194
0195
0196
0197
0198 FWTableView::FWTableView(TEveWindowSlot *iParent, FWTableViewManager *manager)
0199 : FWViewBase(FWViewType::kTable),
0200 m_iColl(-1),
0201 m_manager(manager),
0202 m_tableManager(new FWTableViewTableManager(this)),
0203 m_tableWidget(nullptr),
0204 m_showColumnUI(false),
0205 m_validator(new FWExpressionValidator),
0206 m_currentColumn(-1),
0207 m_useColumnsFromConfig(false)
0208
0209 {
0210 m_eveWindow = iParent->MakeFrame(nullptr);
0211 TGCompositeFrame *frame = m_eveWindow->GetGUICompositeFrame();
0212
0213
0214
0215
0216 m_vert = new TGVerticalFrame(frame);
0217 frame->AddFrame(m_vert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0218 TGHorizontalFrame *header = new TGHorizontalFrame(m_vert);
0219 m_vert->AddFrame(header, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
0220 const bool bgIsBlack = m_manager->colorManager().background() == kBlack;
0221 m_columnUIButton = new FWCustomIconsButton(
0222 header, arrow_right(bgIsBlack), arrow_right_disabled(bgIsBlack), arrow_right_disabled(bgIsBlack));
0223 m_columnUIButton->Connect("Clicked()", "FWTableView", this, "toggleShowHide()");
0224 header->AddFrame(m_columnUIButton, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 6, 10));
0225
0226 TGCompositeFrame *labfr = new TGHorizontalFrame(header, 60, 25, kFixedSize);
0227 TGLabel *label = new TGLabel(labfr, "Collection");
0228 labfr->AddFrame(label, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 1, 3, 0, 0));
0229 header->AddFrame(labfr, new TGLayoutHints(kLHintsLeft));
0230
0231 m_collection = new TGComboBox(header);
0232 updateItems();
0233 header->AddFrame(m_collection, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY));
0234 m_collection->Connect("Selected(Int_t)", "FWTableView", this, "selectCollection(Int_t)");
0235 m_collection->Select(2, true);
0236 m_column_control = new TGVerticalFrame(m_vert);
0237 m_vert->AddFrame(m_column_control, new TGLayoutHints(kLHintsExpandX));
0238 TGLabel *column_control_label = new TGLabel(m_column_control, "Column editor");
0239
0240
0241
0242 m_column_control->AddFrame(column_control_label, new TGLayoutHints(kLHintsExpandX));
0243 TGHorizontalFrame *column_control_fields = new TGHorizontalFrame(m_column_control);
0244 m_column_control->AddFrame(column_control_fields, new TGLayoutHints(kLHintsExpandX));
0245 m_column_name_field = new TGTextEntry(column_control_fields);
0246 m_column_name_field->SetMaxWidth(10);
0247 m_column_expr_field = new FWGUIValidatingTextEntry(column_control_fields);
0248
0249 m_column_expr_field->setValidator(m_validator);
0250 m_column_prec_field = new TGTextEntry(column_control_fields);
0251 m_column_prec_field->SetMaxWidth(10);
0252 TGLabel *name_label = new TGLabel(column_control_fields, "Title");
0253 TGLabel *expr_label = new TGLabel(column_control_fields, "Expression");
0254 TGLabel *prec_label = new TGLabel(column_control_fields, "Precision");
0255 column_control_fields->AddFrame(name_label, new TGLayoutHints(kLHintsBottom, 1, 1, 2, 2));
0256 column_control_fields->AddFrame(m_column_name_field, new TGLayoutHints(kLHintsExpandX));
0257 column_control_fields->AddFrame(expr_label, new TGLayoutHints(kLHintsBottom, 1, 1, 2, 2));
0258 column_control_fields->AddFrame(m_column_expr_field, new TGLayoutHints(kLHintsExpandX));
0259 column_control_fields->AddFrame(prec_label, new TGLayoutHints(kLHintsBottom, 1, 1, 2, 2));
0260 column_control_fields->AddFrame(m_column_prec_field, new TGLayoutHints(kLHintsExpandX));
0261 TGTextButton *add_button = new TGTextButton(column_control_fields, "Add");
0262 TGTextButton *del_button = new TGTextButton(column_control_fields, "Delete");
0263 TGTextButton *mod_button = new TGTextButton(column_control_fields, "Modify");
0264 add_button->Connect("Clicked()", "FWTableView", this, "addColumn()");
0265 del_button->Connect("Clicked()", "FWTableView", this, "deleteColumn()");
0266 mod_button->Connect("Clicked()", "FWTableView", this, "modifyColumn()");
0267 column_control_fields->AddFrame(add_button, new TGLayoutHints);
0268 column_control_fields->AddFrame(del_button, new TGLayoutHints);
0269 column_control_fields->AddFrame(mod_button, new TGLayoutHints);
0270 m_tableWidget = new FWTableWidget(m_tableManager, m_vert);
0271 m_tableWidget->disableGrowInWidth();
0272 resetColors(m_manager->colorManager());
0273 m_tableWidget->SetHeaderBackgroundColor(gVirtualX->GetPixel(kWhite));
0274 m_tableWidget->Connect(
0275 "rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)", "FWTableView", this, "modelSelected(Int_t,Int_t,Int_t,Int_t,Int_t)");
0276 m_tableWidget->Connect("columnClicked(Int_t,Int_t,Int_t)", "FWTableView", this, "columnSelected(Int_t,Int_t,Int_t)");
0277 m_vert->AddFrame(m_tableWidget, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0278 frame->MapSubwindows();
0279 m_vert->HideFrame(m_column_control);
0280 frame->Layout();
0281 frame->MapWindow();
0282 }
0283
0284 FWTableView::~FWTableView() {
0285
0286 TGCompositeFrame *frame = m_eveWindow->GetGUICompositeFrame();
0287 frame->RemoveFrame(m_vert);
0288 delete m_vert;
0289
0290 m_eveWindow->DestroyWindowAndSlot();
0291 delete m_tableManager;
0292 delete m_validator;
0293 }
0294
0295 void FWTableView::setBackgroundColor(Color_t iColor) {
0296 m_tableWidget->SetBackgroundColor(gVirtualX->GetPixel(iColor));
0297
0298
0299 }
0300
0301 void FWTableView::resetColors(const FWColorManager &manager) {
0302 m_tableWidget->SetBackgroundColor(gVirtualX->GetPixel(manager.background()));
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 m_tableWidget->SetLineSeparatorColor(gVirtualX->GetPixel(manager.foreground()));
0313
0314 }
0315
0316
0317
0318
0319
0320 void FWTableView::addTo(FWConfiguration &iTo) const {
0321
0322
0323
0324
0325 if (this == m_manager->m_views.front().get())
0326 m_manager->addToImpl(iTo);
0327
0328
0329 FWConfiguration main(1);
0330 std::string collectionName;
0331 if (m_manager->items()[m_iColl])
0332 collectionName = m_manager->items()[m_iColl]->name();
0333 else
0334 collectionName = "NULL";
0335
0336 FWConfiguration collection(collectionName);
0337 main.addKeyValue(kCollection, collection);
0338 FWConfiguration sortColumn(m_tableWidget->sortedColumn());
0339 main.addKeyValue(kSortColumn, sortColumn);
0340 FWConfiguration descendingSort(m_tableWidget->descendingSort());
0341 main.addKeyValue(kDescendingSort, descendingSort);
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 iTo.addKeyValue(kTableView, main);
0355
0356 FWConfigurableParameterizable::addTo(iTo);
0357 }
0358
0359 void FWTableView::setFrom(const FWConfiguration &iFrom) {
0360 if (this == m_manager->m_views.front().get())
0361 m_manager->setFrom(iFrom);
0362 try {
0363 const FWConfiguration *main = iFrom.valueForKey(kTableView);
0364 assert(main != nullptr);
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 const FWConfiguration *collection = main->valueForKey(kCollection);
0379 const std::string &collectionName = collection->value();
0380
0381 for (std::vector<const FWEventItem *>::const_iterator it = m_manager->items().begin(),
0382 itEnd = m_manager->items().end();
0383 it != itEnd;
0384 ++it) {
0385 if (*it && (*it)->name() == collectionName) {
0386 m_collection->Select(it - m_manager->items().begin(), true);
0387 break;
0388 }
0389 }
0390 const FWConfiguration *sortColumn = main->valueForKey(kSortColumn);
0391 const FWConfiguration *descendingSort = main->valueForKey(kDescendingSort);
0392 if (sortColumn != nullptr && descendingSort != nullptr) {
0393 unsigned int sort = sortColumn->version();
0394 bool descending = descendingSort->version();
0395 if (sort < ((unsigned int)m_tableManager->numberOfColumns()))
0396 m_tableWidget->sort(sort, descending);
0397 }
0398 } catch (...) {
0399
0400 std::cerr << "This configuration file contains tables, but no column information. "
0401 "(It is probably old.) Using defaults."
0402 << std::endl;
0403 }
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 FWConfigurableParameterizable::setFrom(iFrom);
0422 }
0423
0424 void FWTableView::saveImageTo(const std::string & ) const {
0425 TString format;
0426 TString data;
0427 FWTextTableCellRenderer *textRenderer;
0428
0429
0430 int ndheader = TMath::Ceil(TMath::Log10(m_tableManager->numberOfRows()));
0431
0432 std::vector<size_t> widths(m_tableManager->numberOfColumns());
0433
0434 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c)
0435 widths[c] = m_tableManager->m_tableFormats->at(c).name.size();
0436
0437 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c) {
0438 for (int r = 0; r < m_tableManager->numberOfRows(); r++) {
0439 textRenderer = (FWTextTableCellRenderer *)m_tableManager->cellRenderer(r, c);
0440 size_t ss = textRenderer->data().size();
0441 if (widths[c] < ss)
0442 widths[c] = ss;
0443 }
0444 }
0445
0446 int rlen = 0;
0447 for (size_t c = 0; c < (size_t)m_tableManager->numberOfColumns(); ++c)
0448 rlen += widths[c];
0449 rlen += (m_tableManager->numberOfColumns() - 1) * 3;
0450 rlen++;
0451
0452
0453 printf("\n");
0454 TString headerFormat;
0455 headerFormat.Form("%%%ds", ndheader + 3);
0456 data.Form(headerFormat, " ");
0457 printf("%s", data.Data());
0458
0459 int lastCol = m_tableManager->numberOfColumns() - 1;
0460
0461 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c) {
0462 format.Form("%%%ds", (int)widths[c]);
0463 data.Form(format, m_tableManager->m_tableFormats->at(c).name.c_str());
0464
0465 if (c == lastCol)
0466 printf("%s", data.Data());
0467 else
0468 printf("%s | ", data.Data());
0469 }
0470 printf("\n");
0471
0472 std::string splitter(rlen, '-');
0473 std::cout << splitter << std::endl;
0474
0475
0476 headerFormat.Form("[%%%dd] ", ndheader);
0477 for (int r = 0; r < m_tableManager->numberOfRows(); r++) {
0478 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c) {
0479 if (!c) {
0480 data.Form(headerFormat, m_tableManager->unsortedRowNumber(r));
0481 printf("%s", data.Data());
0482 }
0483 format.Form("%%%ds", (int)widths[c]);
0484 textRenderer = (FWTextTableCellRenderer *)m_tableManager->cellRenderer(r, c);
0485 data.Form(format, textRenderer->data().c_str());
0486 if (c == lastCol)
0487 printf("%s", data.Data());
0488 else
0489 printf("%s | ", data.Data());
0490 }
0491 printf("\n");
0492 }
0493 }
0494
0495 void FWTableView::toggleShowHide() {
0496 m_showColumnUI = not m_showColumnUI;
0497 const TGPicture *picture = nullptr;
0498 const TGPicture *down = nullptr;
0499 const TGPicture *disabled = nullptr;
0500 const bool bgIsBlack = m_manager->colorManager().background() == kBlack;
0501 if (m_showColumnUI) {
0502 picture = arrow_down(bgIsBlack);
0503 down = arrow_down_disabled(bgIsBlack);
0504 disabled = arrow_down_disabled(bgIsBlack);
0505 m_vert->ShowFrame(m_column_control);
0506 } else {
0507 picture = arrow_right(bgIsBlack);
0508 down = arrow_right_disabled(bgIsBlack);
0509 disabled = arrow_right_disabled(bgIsBlack);
0510 m_vert->HideFrame(m_column_control);
0511 }
0512 m_vert->Layout();
0513 m_columnUIButton->swapIcons(picture, down, disabled);
0514 }
0515
0516
0517
0518
0519 void FWTableView::updateItems(void) {
0520 int selected = m_collection->GetSelected();
0521 m_collection->RemoveAll();
0522 int index = 0;
0523
0524 for (size_t i = 0, e = m_manager->items().size(); i != e; ++i) {
0525 const FWEventItem *item = m_manager->items()[i];
0526 if (item)
0527 m_collection->AddEntry(item->name().c_str(), i);
0528
0529 if (m_iColl == index && nullptr == item) {
0530
0531 m_iColl = -1;
0532 selected = -1;
0533 }
0534 }
0535
0536 if (selected != -1 && selected < m_collection->GetNumberOfEntries())
0537 m_collection->Select(selected, false);
0538
0539 TGListBox *lb = m_collection->GetListBox();
0540 lb->SetHeight(TMath::Min(lb->GetNumberOfEntries() * lb->GetItemVsize() + 2 * lb->GetBorderWidth(), 200u));
0541 }
0542
0543 void FWTableView::updateEvaluators() { m_tableManager->updateEvaluators(); }
0544
0545 const FWEventItem *FWTableView::item() const {
0546 if (m_iColl == -1)
0547 return nullptr;
0548 return m_manager->items()[m_iColl];
0549 }
0550
0551 void FWTableView::dataChanged() {
0552
0553 updateEvaluators();
0554 m_tableManager->dataChanged();
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 }
0565
0566
0567
0568
0569
0570 void FWTableView::selectCollection(Int_t i_coll) {
0571
0572 const FWEventItem *item = m_manager->items()[i_coll];
0573 assert(nullptr != item);
0574
0575 m_iColl = i_coll;
0576
0577
0578 if (m_validator != nullptr) {
0579
0580 m_validator->setType(edm::TypeWithDict(*(item->modelType()->GetTypeInfo())));
0581 } else {
0582
0583 }
0584 if (not m_useColumnsFromConfig) {
0585 if (m_manager->tableFormats(*item->modelType()) == m_manager->m_tableFormats.end()) {
0586 fwLog(fwlog::kInfo) << "No table format for objects of this type " << item->modelType()->GetName() << std::endl;
0587 m_tableManager->m_tableFormats->clear();
0588 } else {
0589 m_tableManager->m_tableFormats = &m_manager->tableFormats(*item->modelType())->second;
0590 }
0591 }
0592
0593 if (m_tableWidget)
0594 m_tableWidget->forceLayout();
0595 dataChanged();
0596 }
0597
0598 void FWTableView::modelSelected(Int_t iRow, Int_t iButton, Int_t iKeyMod, Int_t iGlobalX, Int_t iGlobalY) {
0599 if (iKeyMod & kKeyControlMask) {
0600 item()->toggleSelect(iRow);
0601 } else {
0602 FWChangeSentry sentry(*(item()->changeManager()));
0603 item()->selectionManager()->clearSelection();
0604 item()->select(iRow);
0605 }
0606 if (iButton == kButton3) {
0607 openSelectedModelContextMenu_(iGlobalX, iGlobalY);
0608 }
0609 }
0610
0611 void FWTableView::columnSelected(Int_t iCol, Int_t iButton, Int_t iKeyMod) {
0612 if (iButton == 1 || iButton == 3)
0613 m_currentColumn = iCol;
0614
0615 if (m_currentColumn >= 0 && m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
0616 const FWTableViewManager::TableEntry &entry = m_tableManager->m_tableFormats->at(m_currentColumn);
0617 m_column_name_field->SetText(entry.name.c_str());
0618 m_column_expr_field->SetText(entry.expression.c_str());
0619 m_column_prec_field->SetText(Form("%d", entry.precision));
0620 } else {
0621 m_column_name_field->SetText("");
0622 m_column_expr_field->SetText("");
0623 m_column_prec_field->SetText("");
0624 }
0625 }
0626
0627 void FWTableView::addColumn() {
0628 std::string name = m_column_name_field->GetText();
0629 std::string expr = m_column_expr_field->GetText();
0630
0631 char *endptr = nullptr;
0632 int prec = (int)strtol(m_column_prec_field->GetText(), &endptr, 0);
0633 if (name.empty() || expr.empty() || m_column_prec_field->GetText() == nullptr || *endptr != 0) {
0634 fwLog(fwlog::kInfo) << "bad input\n";
0635 fflush(stdout);
0636 return;
0637 }
0638 fwLog(fwlog::kInfo) << "adding column " << name << ": " << expr << ", precision " << prec << std::endl;
0639 fflush(stdout);
0640
0641 FWTableViewManager::TableEntry e = {expr, name, prec};
0642 m_tableManager->m_tableFormats->push_back(e);
0643 m_currentColumn = (int)m_tableManager->m_tableFormats->size() + 1;
0644
0645
0646
0647 m_tableWidget->forceLayout();
0648 m_manager->dataChanged();
0649 }
0650
0651 void FWTableView::deleteColumn() {
0652 if (m_currentColumn >= 0 && m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
0653 m_tableManager->m_tableFormats->erase(m_tableManager->m_tableFormats->begin() + m_currentColumn);
0654 m_column_name_field->SetText("");
0655 m_column_expr_field->SetText("");
0656 m_column_prec_field->SetText("");
0657 m_currentColumn = -1;
0658 }
0659
0660
0661
0662 m_tableWidget->forceLayout();
0663 m_manager->dataChanged();
0664 }
0665
0666 void FWTableView::modifyColumn() {
0667 std::string name = m_column_name_field->GetText();
0668 std::string expr = m_column_expr_field->GetText();
0669
0670 char *endptr = nullptr;
0671 int prec = (int)strtol(m_column_prec_field->GetText(), &endptr, 0);
0672 if (name.empty() || expr.empty() || m_column_prec_field->GetText() == nullptr || *endptr != 0) {
0673 fwLog(fwlog::kInfo) << "bad input\n";
0674 fflush(stdout);
0675 return;
0676 }
0677 fwLog(fwlog::kInfo) << "modify column " << name << ": " << expr << ", precision " << prec << std::endl;
0678 fflush(stdout);
0679
0680 FWTableViewManager::TableEntry e = {expr, name, prec};
0681 m_tableManager->m_tableFormats->at(m_currentColumn) = e;
0682
0683
0684
0685 m_tableWidget->forceLayout();
0686 m_manager->dataChanged();
0687 }