00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdlib.h>
00016 #include <algorithm>
00017 #include <boost/shared_ptr.hpp>
00018 #include <iostream>
00019 #include <sstream>
00020 #include <stdexcept>
00021 #include <cassert>
00022
00023 #include "TClass.h"
00024 #include "TSystem.h"
00025 #include "TGComboBox.h"
00026 #include "TGLabel.h"
00027 #include "TGTextEntry.h"
00028 #include "TEveWindow.h"
00029
00030
00031 #include "Fireworks/Core/interface/FWColorManager.h"
00032 #include "Fireworks/Core/interface/FWCustomIconsButton.h"
00033 #include "Fireworks/Core/interface/FWModelChangeManager.h"
00034 #include "Fireworks/Core/interface/FWSelectionManager.h"
00035 #include "Fireworks/Core/interface/FWTableView.h"
00036 #include "Fireworks/Core/interface/FWTableViewManager.h"
00037 #include "Fireworks/Core/interface/FWEventItem.h"
00038 #include "Fireworks/Core/interface/FWConfiguration.h"
00039 #include "Fireworks/Core/interface/FWTableViewTableManager.h"
00040 #include "Fireworks/Core/interface/fwLog.h"
00041 #include "Fireworks/Core/src/FWGUIValidatingTextEntry.h"
00042 #include "Fireworks/Core/src/FWExpressionValidator.h"
00043 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
00044
00045 static const TString& coreIcondir()
00046 {
00047 static TString path = Form("%s/src/Fireworks/Core/icons/",gSystem->Getenv("CMSSW_BASE"));
00048 if ( gSystem->AccessPathName(path.Data()) ){
00049 assert(gSystem->Getenv("CMSSW_RELEASE_BASE"));
00050 path = Form("%s/src/Fireworks/Core/icons/",gSystem->Getenv("CMSSW_RELEASE_BASE"));
00051 }
00052 return path;
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static
00151 const TGPicture* arrow_right(bool iBackgroundIsBlack)
00152 {
00153 if(iBackgroundIsBlack) {
00154 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-white-right-blackbg.png");
00155 return s;
00156 }
00157 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-black-right-whitebg.png");
00158 return s;
00159 }
00160
00161 static
00162 const TGPicture* arrow_right_disabled(bool iBackgroundIsBlack)
00163 {
00164 if(iBackgroundIsBlack) {
00165 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-white-right-disabled-blackbg.png");
00166 return s;
00167 }
00168 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-black-right-disabled-whitebg.png");
00169 return s;
00170 }
00171
00172 static
00173 const TGPicture* arrow_down(bool iBackgroundIsBlack)
00174 {
00175 if(iBackgroundIsBlack) {
00176 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-white-down-blackbg.png");
00177 return s;
00178 }
00179 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-black-down-whitebg.png");
00180 return s;
00181 }
00182
00183 static
00184 const TGPicture* arrow_down_disabled(bool iBackgroundIsBlack)
00185 {
00186 if(iBackgroundIsBlack) {
00187 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-white-down-disabled-blackbg.png");
00188 return s;
00189 }
00190 static const TGPicture* s = gClient->GetPicture(coreIcondir()+"arrow-black-down-disabled-whitebg.png");
00191 return s;
00192 }
00193
00194
00195
00196
00197 static const std::string kTableView = "TableView";
00198 static const std::string kCollection = "collection";
00199 static const std::string kColumns = "columns";
00200 static const std::string kSortColumn = "sortColumn";
00201 static const std::string kDescendingSort = "descendingSort";
00202
00203
00204
00205
00206 FWTableView::FWTableView (TEveWindowSlot* iParent, FWTableViewManager *manager)
00207 : FWViewBase(FWViewType::kTable),
00208 m_iColl(-1),
00209 m_manager(manager),
00210 m_tableManager(new FWTableViewTableManager(this)),
00211 m_tableWidget(0),
00212 m_showColumnUI(false),
00213 m_validator(new FWExpressionValidator),
00214 m_currentColumn(-1),
00215 m_useColumnsFromConfig(false)
00216
00217 {
00218 m_eveWindow = iParent->MakeFrame(0);
00219 TGCompositeFrame *frame = m_eveWindow->GetGUICompositeFrame();
00220
00221
00222
00223
00224 m_vert = new TGVerticalFrame(frame);
00225 frame->AddFrame(m_vert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00226 TGHorizontalFrame *header = new TGHorizontalFrame(m_vert);
00227 m_vert->AddFrame(header, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
00228 const bool bgIsBlack = m_manager->colorManager().background() == kBlack;
00229 m_columnUIButton = new FWCustomIconsButton(header,
00230 arrow_right(bgIsBlack),
00231 arrow_right_disabled(bgIsBlack),
00232 arrow_right_disabled(bgIsBlack));
00233 m_columnUIButton->Connect("Clicked()", "FWTableView", this, "toggleShowHide()");
00234 header->AddFrame(m_columnUIButton, new TGLayoutHints(kLHintsCenterY | kLHintsLeft,6,10));
00235
00236 TGCompositeFrame *labfr = new TGHorizontalFrame(header, 60, 25, kFixedSize);
00237 TGLabel *label = new TGLabel(labfr, "Collection");
00238 labfr->AddFrame(label, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 1,3,0,0));
00239 header->AddFrame(labfr, new TGLayoutHints(kLHintsLeft));
00240
00241 m_collection = new TGComboBox(header);
00242 updateItems();
00243 header->AddFrame(m_collection, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY));
00244 m_collection->Connect("Selected(Int_t)", "FWTableView", this, "selectCollection(Int_t)");
00245 m_collection->Select(2, true);
00246 m_column_control = new TGVerticalFrame(m_vert);
00247 m_vert->AddFrame(m_column_control, new TGLayoutHints(kLHintsExpandX));
00248 TGLabel *column_control_label = new TGLabel(m_column_control, "Column editor");
00249
00250
00251
00252 m_column_control->AddFrame(column_control_label, new TGLayoutHints(kLHintsExpandX));
00253 TGHorizontalFrame *column_control_fields = new TGHorizontalFrame(m_column_control);
00254 m_column_control->AddFrame(column_control_fields, new TGLayoutHints(kLHintsExpandX));
00255 m_column_name_field = new TGTextEntry(column_control_fields);
00256 m_column_name_field->SetMaxWidth(10);
00257 m_column_expr_field = new FWGUIValidatingTextEntry(column_control_fields);
00258
00259 m_column_expr_field->setValidator(m_validator);
00260 m_column_prec_field = new TGTextEntry(column_control_fields);
00261 m_column_prec_field->SetMaxWidth(10);
00262 TGLabel *name_label = new TGLabel(column_control_fields, "Title");
00263 TGLabel *expr_label = new TGLabel(column_control_fields, "Expression");
00264 TGLabel *prec_label = new TGLabel(column_control_fields, "Precision");
00265 column_control_fields->AddFrame(name_label, new TGLayoutHints(kLHintsBottom, 1, 1, 2, 2));
00266 column_control_fields->AddFrame(m_column_name_field, new TGLayoutHints(kLHintsExpandX));
00267 column_control_fields->AddFrame(expr_label, new TGLayoutHints(kLHintsBottom, 1, 1, 2, 2));
00268 column_control_fields->AddFrame(m_column_expr_field, new TGLayoutHints(kLHintsExpandX));
00269 column_control_fields->AddFrame(prec_label, new TGLayoutHints( kLHintsBottom, 1, 1, 2, 2));
00270 column_control_fields->AddFrame(m_column_prec_field, new TGLayoutHints(kLHintsExpandX));
00271 TGTextButton *add_button = new TGTextButton(column_control_fields, "Add");
00272 TGTextButton *del_button = new TGTextButton(column_control_fields, "Delete");
00273 TGTextButton *mod_button = new TGTextButton(column_control_fields, "Modify");
00274 add_button->Connect("Clicked()", "FWTableView", this, "addColumn()");
00275 del_button->Connect("Clicked()", "FWTableView", this, "deleteColumn()");
00276 mod_button->Connect("Clicked()", "FWTableView", this, "modifyColumn()");
00277 column_control_fields->AddFrame(add_button, new TGLayoutHints);
00278 column_control_fields->AddFrame(del_button, new TGLayoutHints);
00279 column_control_fields->AddFrame(mod_button, new TGLayoutHints);
00280 m_tableWidget = new FWTableWidget(m_tableManager, m_vert);
00281 resetColors(m_manager->colorManager());
00282 m_tableWidget->SetHeaderBackgroundColor(gVirtualX->GetPixel(kWhite));
00283 m_tableWidget->Connect("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)", "FWTableView",
00284 this, "modelSelected(Int_t,Int_t,Int_t,Int_t,Int_t)");
00285 m_tableWidget->Connect("columnClicked(Int_t,Int_t,Int_t)", "FWTableView",
00286 this, "columnSelected(Int_t,Int_t,Int_t)");
00287 m_vert->AddFrame(m_tableWidget, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00288 frame->MapSubwindows();
00289 m_vert->HideFrame(m_column_control);
00290 frame->Layout();
00291 frame->MapWindow();
00292 }
00293
00294 FWTableView::~FWTableView()
00295 {
00296
00297 TGCompositeFrame *frame = m_eveWindow->GetGUICompositeFrame();
00298 frame->RemoveFrame(m_vert);
00299 delete m_vert;
00300
00301 m_eveWindow->DestroyWindowAndSlot();
00302 delete m_tableManager;
00303 delete m_validator;
00304 }
00305
00306 void
00307 FWTableView::setBackgroundColor(Color_t iColor)
00308 {
00309 m_tableWidget->SetBackgroundColor(gVirtualX->GetPixel(iColor));
00310
00311
00312 }
00313
00314 void FWTableView::resetColors (const FWColorManager &manager)
00315 {
00316 m_tableWidget->SetBackgroundColor(gVirtualX->GetPixel(manager.background()));
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 m_tableWidget->SetLineSeparatorColor(gVirtualX->GetPixel(manager.foreground()));
00327
00328 }
00329
00330
00331
00332
00333
00334
00335 void
00336 FWTableView::addTo(FWConfiguration& iTo) const
00337 {
00338
00339
00340
00341
00342 if (this == m_manager->m_views.front().get())
00343 m_manager->addToImpl(iTo);
00344
00345
00346 FWConfiguration main(1);
00347 std::string collectionName;
00348 if (m_manager->items()[m_iColl])
00349 collectionName = m_manager->items()[m_iColl]->name();
00350 else
00351 collectionName = "NULL";
00352
00353 FWConfiguration collection(collectionName);
00354 main.addKeyValue(kCollection, collection);
00355 FWConfiguration sortColumn(m_tableWidget->sortedColumn());
00356 main.addKeyValue(kSortColumn, sortColumn);
00357 FWConfiguration descendingSort(m_tableWidget->descendingSort());
00358 main.addKeyValue(kDescendingSort, descendingSort);
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 iTo.addKeyValue(kTableView, main);
00372
00373 FWConfigurableParameterizable::addTo(iTo);
00374 }
00375
00376 void
00377 FWTableView::setFrom(const FWConfiguration& iFrom)
00378 {
00379 if (this == m_manager->m_views.front().get())
00380 m_manager->setFrom(iFrom);
00381 try {
00382 const FWConfiguration *main = iFrom.valueForKey(kTableView);
00383 assert(main != 0);
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 const FWConfiguration *collection = main->valueForKey(kCollection);
00398 const std::string &collectionName = collection->value();
00399
00400 for (std::vector<const FWEventItem *>::const_iterator
00401 it = m_manager->items().begin(),
00402 itEnd = m_manager->items().end();
00403 it != itEnd; ++it) {
00404 if (*it && (*it)->name() == collectionName) {
00405 m_collection->Select(it - m_manager->items().begin(), true);
00406 break;
00407 }
00408 }
00409 const FWConfiguration *sortColumn = main->valueForKey(kSortColumn);
00410 const FWConfiguration *descendingSort = main->valueForKey(kDescendingSort);
00411 if (sortColumn != 0 && descendingSort != 0) {
00412 unsigned int sort = sortColumn->version();
00413 bool descending = descendingSort->version();
00414 if (sort < (( unsigned int) m_tableManager->numberOfColumns()))
00415 m_tableWidget->sort(sort, descending);
00416 }
00417 } catch (...) {
00418
00419 std::cerr << "This configuration file contains tables, but no column information. "
00420 "(It is probably old.) Using defaults." << std::endl;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 FWConfigurableParameterizable::setFrom(iFrom);
00440 }
00441
00442 void
00443 FWTableView::saveImageTo(const std::string& iName) const
00444 {
00445
00446
00447
00448
00449 }
00450
00451 void
00452 FWTableView::toggleShowHide ()
00453 {
00454 m_showColumnUI = not m_showColumnUI;
00455 const TGPicture* picture = 0;
00456 const TGPicture* down = 0;
00457 const TGPicture* disabled = 0;
00458 const bool bgIsBlack = m_manager->colorManager().background() == kBlack;
00459 if (m_showColumnUI) {
00460 picture = arrow_down(bgIsBlack);
00461 down = arrow_down_disabled(bgIsBlack);
00462 disabled = arrow_down_disabled(bgIsBlack);
00463 m_vert->ShowFrame(m_column_control);
00464 } else {
00465 picture = arrow_right(bgIsBlack);
00466 down = arrow_right_disabled(bgIsBlack);
00467 disabled = arrow_right_disabled(bgIsBlack);
00468 m_vert->HideFrame(m_column_control);
00469 }
00470 m_vert->Layout();
00471 m_columnUIButton->swapIcons(picture,down,disabled);
00472 }
00473
00477 void FWTableView::updateItems(void)
00478 {
00479 int selected = m_collection->GetSelected();
00480 m_collection->RemoveAll();
00481 int index = 0;
00482
00483 for (size_t i = 0, e = m_manager->items().size(); i != e; ++i)
00484 {
00485 const FWEventItem *item = m_manager->items()[i];
00486 if (item)
00487 m_collection->AddEntry(item->name().c_str(), i);
00488
00489 if (m_iColl == index && 0 == item)
00490 {
00491
00492 m_iColl = -1;
00493 selected = -1;
00494 }
00495 }
00496
00497 if (selected != -1 && selected < m_collection->GetNumberOfEntries())
00498 m_collection->Select(selected, false);
00499
00500 TGListBox *lb = m_collection->GetListBox();
00501 lb->SetHeight(TMath::Min(lb->GetNumberOfEntries()*lb->GetItemVsize() + 2*lb->GetBorderWidth(), 200u));
00502 }
00503
00504 void FWTableView::updateEvaluators ()
00505 {
00506 m_tableManager->updateEvaluators();
00507 }
00508
00509 const FWEventItem *FWTableView::item () const
00510 {
00511 if (m_iColl == -1)
00512 return 0;
00513 return m_manager->items()[m_iColl];
00514 }
00515
00516 void FWTableView::dataChanged ()
00517 {
00518
00519 updateEvaluators();
00520 m_tableManager->dataChanged();
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 }
00531
00536 void
00537 FWTableView::selectCollection(Int_t i_coll)
00538 {
00539
00540 const FWEventItem *item = m_manager->items()[i_coll];
00541 assert(0!=item);
00542
00543 m_iColl = i_coll;
00544
00545
00546 if (m_validator != 0) {
00547
00548 m_validator->setType(edm::TypeWithDict(*(item->modelType()->GetTypeInfo())));
00549 } else {
00550
00551 }
00552 if (not m_useColumnsFromConfig) {
00553 if (m_manager->tableFormats(*item->modelType()) == m_manager->m_tableFormats.end()) {
00554 fwLog(fwlog::kInfo) << "No table format for objects of this type " << item->modelType()->GetName() << std::endl;
00555 m_tableManager->m_tableFormats->clear();
00556 } else {
00557 m_tableManager->m_tableFormats = &m_manager->tableFormats(*item->modelType())->second;
00558 }
00559 }
00560
00561 if (m_tableWidget) m_tableWidget->forceLayout();
00562 dataChanged();
00563 }
00564
00565 void FWTableView::modelSelected(Int_t iRow,Int_t iButton,Int_t iKeyMod,Int_t iGlobalX,Int_t iGlobalY)
00566 {
00567 if(iKeyMod & kKeyControlMask) {
00568 item()->toggleSelect(iRow);
00569 } else {
00570 FWChangeSentry sentry(*(item()->changeManager()));
00571 item()->selectionManager()->clearSelection();
00572 item()->select(iRow);
00573 }
00574 if(iButton == kButton3) {
00575 openSelectedModelContextMenu_(iGlobalX,iGlobalY);
00576 }
00577 }
00578
00579 void FWTableView::columnSelected (Int_t iCol, Int_t iButton, Int_t iKeyMod)
00580 {
00581 if (iButton == 1 || iButton == 3)
00582 m_currentColumn = iCol;
00583
00584 if (m_currentColumn >= 0 &&
00585 m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
00586 const FWTableViewManager::TableEntry &entry =
00587 m_tableManager->m_tableFormats->at(m_currentColumn);
00588 m_column_name_field->SetText(entry.name.c_str());
00589 m_column_expr_field->SetText(entry.expression.c_str());
00590 m_column_prec_field->SetText(Form("%d", entry.precision));
00591 } else {
00592 m_column_name_field->SetText("");
00593 m_column_expr_field->SetText("");
00594 m_column_prec_field->SetText("");
00595 }
00596 }
00597
00598 void FWTableView::addColumn ()
00599 {
00600 std::string name = m_column_name_field->GetText();
00601 std::string expr = m_column_expr_field->GetText();
00602
00603 char *endptr = 0;
00604 int prec = (int) strtol(m_column_prec_field->GetText(), &endptr, 0);
00605 if (name == "" || expr == "" ||
00606 m_column_prec_field->GetText() == 0 || *endptr != 0) {
00607 fwLog(fwlog::kInfo) << "bad input\n";
00608 fflush(stdout);
00609 return;
00610 }
00611 fwLog(fwlog::kInfo) << "adding column "<< name << ": " << expr << ", precision " << prec << std::endl;
00612 fflush(stdout);
00613
00614 FWTableViewManager::TableEntry e = { expr, name, prec };
00615 m_tableManager->m_tableFormats->push_back(e);
00616 m_currentColumn = (int)m_tableManager->m_tableFormats->size() + 1;
00617
00618
00619
00620 m_tableWidget->forceLayout();
00621 m_manager->dataChanged();
00622 }
00623
00624 void FWTableView::deleteColumn ()
00625 {
00626 if (m_currentColumn >= 0 &&
00627 m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
00628 m_tableManager->m_tableFormats->erase(m_tableManager->m_tableFormats->begin() +
00629 m_currentColumn);
00630 m_column_name_field->SetText("");
00631 m_column_expr_field->SetText("");
00632 m_column_prec_field->SetText("");
00633 m_currentColumn = -1;
00634 }
00635
00636
00637
00638 m_tableWidget->forceLayout();
00639 m_manager->dataChanged();
00640 }
00641
00642 void FWTableView::modifyColumn ()
00643 {
00644 std::string name = m_column_name_field->GetText();
00645 std::string expr = m_column_expr_field->GetText();
00646
00647 char *endptr = 0;
00648 int prec = (int) strtol(m_column_prec_field->GetText(), &endptr, 0);
00649 if (name == "" || expr == "" ||
00650 m_column_prec_field->GetText() == 0 || *endptr != 0) {
00651 fwLog(fwlog::kInfo) << "bad input\n";
00652 fflush(stdout);
00653 return;
00654 }
00655 fwLog(fwlog::kInfo) << "modify column "<< name << ": " << expr << ", precision " << prec << std::endl;
00656 fflush(stdout);
00657
00658 FWTableViewManager::TableEntry e = { expr, name, prec };
00659 m_tableManager->m_tableFormats->at(m_currentColumn) = e;
00660
00661
00662
00663 m_tableWidget->forceLayout();
00664 m_manager->dataChanged();
00665 }
00666