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