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 "TMath.h"
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& ) const
00444 {
00445 TString format;
00446 TString data;
00447 FWTextTableCellRenderer* textRenderer;
00448
00449
00450 int ndheader = TMath::Ceil(TMath::Log10(m_tableManager->numberOfRows()));
00451
00452 std::vector<size_t> widths(m_tableManager->numberOfColumns());
00453
00454 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c )
00455 widths[c] = m_tableManager->m_tableFormats->at(c).name.size();
00456
00457 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c )
00458 {
00459 for (int r = 0; r < m_tableManager->numberOfRows(); r++ )
00460 {
00461 textRenderer = (FWTextTableCellRenderer*) m_tableManager->cellRenderer(r, c);
00462 size_t ss = textRenderer->data().size();
00463 if (widths[c] < ss) widths[c] = ss;
00464 }
00465 }
00466
00467 int rlen = 0;
00468 for (size_t c = 0; c < (size_t)m_tableManager->numberOfColumns(); ++c )
00469 rlen += widths[c];
00470 rlen += (m_tableManager->numberOfColumns() -1 )*3 ;
00471 rlen++;
00472
00473
00474
00475 printf("\n");
00476 TString headerFormat;
00477 headerFormat.Form("%%%ds",ndheader +3);
00478 data.Form(headerFormat, " ");
00479 printf("%s", data.Data());
00480
00481 int lastCol = m_tableManager->numberOfColumns() -1;
00482
00483 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c )
00484 {
00485 format.Form("%%%ds", (int)widths[c]);
00486 data.Form(format, m_tableManager->m_tableFormats->at(c).name.c_str());
00487
00488 if (c == lastCol)
00489 printf("%s", data.Data());
00490 else
00491 printf("%s | ", data.Data());
00492 }
00493 printf("\n");
00494
00495 std::string splitter(rlen, '-');
00496 std::cout << splitter << std::endl;
00497
00498
00499 headerFormat.Form("[%%%dd] ",ndheader );
00500 for (int r = 0; r < m_tableManager->numberOfRows(); r++ )
00501 {
00502 for (int c = 0; c < m_tableManager->numberOfColumns(); ++c )
00503 {
00504 if (!c) {
00505 data.Form(headerFormat, m_tableManager->unsortedRowNumber(r));
00506 printf("%s", data.Data());
00507 }
00508 format.Form("%%%ds", (int)widths[c]);
00509 textRenderer = (FWTextTableCellRenderer*) m_tableManager->cellRenderer(r, c);
00510 data.Form(format, textRenderer->data().c_str());
00511 if (c == lastCol)
00512 printf("%s", data.Data());
00513 else
00514 printf("%s | ", data.Data());
00515 }
00516 printf("\n");
00517 }
00518 }
00519
00520 void
00521 FWTableView::toggleShowHide ()
00522 {
00523 m_showColumnUI = not m_showColumnUI;
00524 const TGPicture* picture = 0;
00525 const TGPicture* down = 0;
00526 const TGPicture* disabled = 0;
00527 const bool bgIsBlack = m_manager->colorManager().background() == kBlack;
00528 if (m_showColumnUI) {
00529 picture = arrow_down(bgIsBlack);
00530 down = arrow_down_disabled(bgIsBlack);
00531 disabled = arrow_down_disabled(bgIsBlack);
00532 m_vert->ShowFrame(m_column_control);
00533 } else {
00534 picture = arrow_right(bgIsBlack);
00535 down = arrow_right_disabled(bgIsBlack);
00536 disabled = arrow_right_disabled(bgIsBlack);
00537 m_vert->HideFrame(m_column_control);
00538 }
00539 m_vert->Layout();
00540 m_columnUIButton->swapIcons(picture,down,disabled);
00541 }
00542
00546 void FWTableView::updateItems(void)
00547 {
00548 int selected = m_collection->GetSelected();
00549 m_collection->RemoveAll();
00550 int index = 0;
00551
00552 for (size_t i = 0, e = m_manager->items().size(); i != e; ++i)
00553 {
00554 const FWEventItem *item = m_manager->items()[i];
00555 if (item)
00556 m_collection->AddEntry(item->name().c_str(), i);
00557
00558 if (m_iColl == index && 0 == item)
00559 {
00560
00561 m_iColl = -1;
00562 selected = -1;
00563 }
00564 }
00565
00566 if (selected != -1 && selected < m_collection->GetNumberOfEntries())
00567 m_collection->Select(selected, false);
00568
00569 TGListBox *lb = m_collection->GetListBox();
00570 lb->SetHeight(TMath::Min(lb->GetNumberOfEntries()*lb->GetItemVsize() + 2*lb->GetBorderWidth(), 200u));
00571 }
00572
00573 void FWTableView::updateEvaluators ()
00574 {
00575 m_tableManager->updateEvaluators();
00576 }
00577
00578 const FWEventItem *FWTableView::item () const
00579 {
00580 if (m_iColl == -1)
00581 return 0;
00582 return m_manager->items()[m_iColl];
00583 }
00584
00585 void FWTableView::dataChanged ()
00586 {
00587
00588 updateEvaluators();
00589 m_tableManager->dataChanged();
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 }
00600
00605 void
00606 FWTableView::selectCollection(Int_t i_coll)
00607 {
00608
00609 const FWEventItem *item = m_manager->items()[i_coll];
00610 assert(0!=item);
00611
00612 m_iColl = i_coll;
00613
00614
00615 if (m_validator != 0) {
00616
00617 m_validator->setType(Reflex::Type::ByTypeInfo(*(item->modelType()->GetTypeInfo())));
00618 } else {
00619
00620 }
00621 if (not m_useColumnsFromConfig) {
00622 if (m_manager->tableFormats(*item->modelType()) == m_manager->m_tableFormats.end()) {
00623 fwLog(fwlog::kInfo) << "No table format for objects of this type " << item->modelType()->GetName() << std::endl;
00624 m_tableManager->m_tableFormats->clear();
00625 } else {
00626 m_tableManager->m_tableFormats = &m_manager->tableFormats(*item->modelType())->second;
00627 }
00628 }
00629
00630 if (m_tableWidget) m_tableWidget->forceLayout();
00631 dataChanged();
00632 }
00633
00634 void FWTableView::modelSelected(Int_t iRow,Int_t iButton,Int_t iKeyMod,Int_t iGlobalX,Int_t iGlobalY)
00635 {
00636 if(iKeyMod & kKeyControlMask) {
00637 item()->toggleSelect(iRow);
00638 } else {
00639 FWChangeSentry sentry(*(item()->changeManager()));
00640 item()->selectionManager()->clearSelection();
00641 item()->select(iRow);
00642 }
00643 if(iButton == kButton3) {
00644 openSelectedModelContextMenu_(iGlobalX,iGlobalY);
00645 }
00646 }
00647
00648 void FWTableView::columnSelected (Int_t iCol, Int_t iButton, Int_t iKeyMod)
00649 {
00650 if (iButton == 1 || iButton == 3)
00651 m_currentColumn = iCol;
00652
00653 if (m_currentColumn >= 0 &&
00654 m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
00655 const FWTableViewManager::TableEntry &entry =
00656 m_tableManager->m_tableFormats->at(m_currentColumn);
00657 m_column_name_field->SetText(entry.name.c_str());
00658 m_column_expr_field->SetText(entry.expression.c_str());
00659 m_column_prec_field->SetText(Form("%d", entry.precision));
00660 } else {
00661 m_column_name_field->SetText("");
00662 m_column_expr_field->SetText("");
00663 m_column_prec_field->SetText("");
00664 }
00665 }
00666
00667 void FWTableView::addColumn ()
00668 {
00669 std::string name = m_column_name_field->GetText();
00670 std::string expr = m_column_expr_field->GetText();
00671
00672 char *endptr = 0;
00673 int prec = (int) strtol(m_column_prec_field->GetText(), &endptr, 0);
00674 if (name == "" || expr == "" ||
00675 m_column_prec_field->GetText() == 0 || *endptr != 0) {
00676 fwLog(fwlog::kInfo) << "bad input\n";
00677 fflush(stdout);
00678 return;
00679 }
00680 fwLog(fwlog::kInfo) << "adding column "<< name << ": " << expr << ", precision " << prec << std::endl;
00681 fflush(stdout);
00682
00683 FWTableViewManager::TableEntry e = { expr, name, prec };
00684 m_tableManager->m_tableFormats->push_back(e);
00685 m_currentColumn = (int)m_tableManager->m_tableFormats->size() + 1;
00686
00687
00688
00689 m_tableWidget->forceLayout();
00690 m_manager->dataChanged();
00691 }
00692
00693 void FWTableView::deleteColumn ()
00694 {
00695 if (m_currentColumn >= 0 &&
00696 m_currentColumn < (int)m_tableManager->m_tableFormats->size()) {
00697 m_tableManager->m_tableFormats->erase(m_tableManager->m_tableFormats->begin() +
00698 m_currentColumn);
00699 m_column_name_field->SetText("");
00700 m_column_expr_field->SetText("");
00701 m_column_prec_field->SetText("");
00702 m_currentColumn = -1;
00703 }
00704
00705
00706
00707 m_tableWidget->forceLayout();
00708 m_manager->dataChanged();
00709 }
00710
00711 void FWTableView::modifyColumn ()
00712 {
00713 std::string name = m_column_name_field->GetText();
00714 std::string expr = m_column_expr_field->GetText();
00715
00716 char *endptr = 0;
00717 int prec = (int) strtol(m_column_prec_field->GetText(), &endptr, 0);
00718 if (name == "" || expr == "" ||
00719 m_column_prec_field->GetText() == 0 || *endptr != 0) {
00720 fwLog(fwlog::kInfo) << "bad input\n";
00721 fflush(stdout);
00722 return;
00723 }
00724 fwLog(fwlog::kInfo) << "modify column "<< name << ": " << expr << ", precision " << prec << std::endl;
00725 fflush(stdout);
00726
00727 FWTableViewManager::TableEntry e = { expr, name, prec };
00728 m_tableManager->m_tableFormats->at(m_currentColumn) = e;
00729
00730
00731
00732 m_tableWidget->forceLayout();
00733 m_manager->dataChanged();
00734 }
00735