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