00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4ParaEdit.h"
00015
00016 #include <QMenu>
00017 #include <QLabel>
00018 #include <QMessageBox>
00019 #include <QFileDialog>
00020 #include <QToolTip>
00021 #include <QHeaderView>
00022
00023 #include "TROOT.h"
00024 #include "TFile.h"
00025 #include "TObjArray.h"
00026 #include "TList.h"
00027 #include "TClass.h"
00028 #include "TDataMember.h"
00029 #include "TDataType.h"
00030 #include "TBaseClass.h"
00031 #include "TGo4LockGuard.h"
00032 #include "TGo4Parameter.h"
00033 #include "TGo4ParameterMember.h"
00034 #include "TGo4ParameterStatus.h"
00035 #include "TGo4Fitter.h"
00036 #include "TGo4Slot.h"
00037 #include "TGo4BrowserProxy.h"
00038
00039 TGo4ParaEdit::TGo4ParaEdit(QWidget *parent, const char* name) :
00040 QGo4Widget(parent,name)
00041 {
00042 setupUi(this);
00043
00044 fItems = 0;
00045 PleaseUpdateLabel->setVisible(false);
00046 parentWidget()->adjustSize();
00047
00048 ParamNameLbl->setText("");
00049 ParamClassLbl->setText("");
00050
00051 fItemName = "";
00052 fFillingTable = false;
00053 MemberTable->setContextMenuPolicy(Qt::CustomContextMenu);
00054 MemberTable->horizontalHeader()->setStretchLastSection(true);
00055 }
00056
00057 TGo4ParaEdit::~TGo4ParaEdit()
00058 {
00059 if (fItems!=0) {
00060 delete fItems;
00061 fItems = 0;
00062 }
00063 }
00064
00065 bool TGo4ParaEdit::IsAcceptDrag(const char* itemname, TClass* cl, int kind)
00066 {
00067 if (kind==TGo4Access::kndGo4Param) return true;
00068
00069 return (cl==0) ? false : cl->InheritsFrom(TGo4Parameter::Class());
00070 }
00071
00072 void TGo4ParaEdit::DropItem(const char* itemname, TClass* cl, int kind)
00073 {
00074 if ((kind==TGo4Access::kndGo4Param) ||
00075 ((cl!=0) && cl->InheritsFrom(TGo4Parameter::Class())))
00076 WorkWithParameter(itemname, false);
00077 }
00078
00079 void TGo4ParaEdit::linkedObjectUpdated(const char* linkname, TObject* obj)
00080 {
00081
00082
00083 if (strcmp(linkname,"Parameter")==0)
00084 RefreshWidget(dynamic_cast<TGo4Parameter*> (obj));
00085 else
00086 if (strcmp(linkname,"ParStatus")==0)
00087 RefreshWidget(dynamic_cast<TGo4ParameterStatus*> (obj));
00088
00089
00090 }
00091
00092 void TGo4ParaEdit::linkedObjectRemoved( const char * linkname )
00093 {
00094
00095
00096
00097
00098 if (strcmp(linkname,"Fitter")!=0)
00099 ShootCloseWidget(true);
00100
00101
00102 }
00103
00104 void TGo4ParaEdit::WorkWithParameter(const char* itemname, bool isrefresh)
00105 {
00106
00107
00108 if (PleaseUpdateLabel->isVisible() && !isrefresh) {
00109 TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",0));
00110 const char* previtem = GetLinkedName("Parameter");
00111 if ((par!=0) && (previtem!=0)) {
00112 int res = QMessageBox::warning(this, "Parameter editor",
00113 QString("Current parameter ")+previtem+" is modified!\n"+
00114 "New parameter " + itemname + " is selected.",
00115 QString("Continue with current"),
00116 QString("Start with new"), QString::null, 0);
00117
00118 if (res==0) return;
00119
00120 }
00121 }
00122
00123
00124
00125 ResetWidget();
00126
00127
00128
00129
00130 ParamNameLbl->setText(itemname);
00131
00132 fItemName = itemname;
00133
00134 QString iconname = ":/icons/right.png";
00135 QString tooltip = "Refresh parameter values from analysis";
00136
00137 if (BrowserItemRemote(itemname)) {
00138 TGo4Slot* tgtslot = AddSlot("ParStatus");
00139 TGo4BrowserProxy* br = Browser();
00140 if (br!=0)
00141 br->RequestObjectStatus(itemname, tgtslot);
00142
00143 AddLink(itemname, "ParameterLock");
00144 } else {
00145 iconname = ":/icons/refresh.png";
00146 tooltip = "Refresh parameter values from source";
00147 AddLink(itemname, "Parameter");
00148 TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",2));
00149 if (par!=0) RefreshWidget(par);
00150 }
00151
00152 RefreshButton->setIcon(QIcon(iconname));
00153 RefreshButton->setToolTip(tooltip);
00154
00155 setFocus();
00156 }
00157
00158 void TGo4ParaEdit::ResetWidget()
00159 {
00160 QGo4Widget::ResetWidget();
00161
00162 ParamNameLbl->setText("");
00163 ParamClassLbl->setText("");
00164
00165 fItemName="";
00166
00167 RefreshButton->setEnabled(false);
00168 ApplyButton->setEnabled(false);
00169
00170 delete fItems;
00171 fItems = 0;
00172
00173 ShowVisibleItems();
00174
00175 PleaseUpdateLabel->setVisible(false);
00176 }
00177
00178 void TGo4ParaEdit::RefreshWidget(TGo4Parameter* par)
00179 {
00180 RefreshButton->setEnabled(par!=0);
00181 ApplyButton->setEnabled(par!=0);
00182
00183 delete fItems;
00184 fItems = new TObjArray(100);
00185 fItems->SetOwner(kTRUE);
00186
00187 if (par!=0) {
00188 par->GetMemberValues(fItems);
00189 ParamClassLbl->setText(QString(" - ")+par->ClassName());
00190 }
00191
00192 ShowVisibleItems();
00193
00194 PleaseUpdateLabel->setVisible(false);
00195 }
00196
00197
00198 void TGo4ParaEdit::RefreshWidget(TGo4ParameterStatus* status)
00199 {
00200
00201
00202 RefreshButton->setEnabled(status!=0);
00203 ApplyButton->setEnabled(status!=0);
00204
00205
00206
00207 delete fItems;
00208 fItems = 0;
00209
00210
00211
00212 if (status!=0) {
00213 fItems = status->GetMemberValues(kTRUE);
00214 ParamClassLbl->setText(QString(" - ") + status->GetObjectClass());
00215 }
00216
00217 ShowVisibleItems();
00218
00219 PleaseUpdateLabel->setVisible(false);
00220
00221
00222 }
00223
00224 void TGo4ParaEdit::ShowVisibleItems()
00225 {
00226 if (fItems==0) {
00227 MemberTable->setRowCount(0);
00228 return;
00229 }
00230
00231 fFillingTable = true;
00232
00233 MemberTable->hide();
00234
00235 MemberTable->horizontalHeaderItem(fiColType)->setText("Type");
00236 MemberTable->horizontalHeaderItem(fiColName)->setText("Name");
00237 MemberTable->horizontalHeaderItem(fiColValue)->setText("Value");
00238 MemberTable->horizontalHeaderItem(fiColComment)->setText("Comments");
00239
00240 int memnum = fItems->GetLast()+1;
00241 MemberTable->setRowCount(memnum);
00242
00243 MemberTable->verticalHeader()->hide();
00244 TString buf;
00245 int ih=QApplication::fontMetrics().height();
00246
00247 for(int row=0; row<memnum; row++) {
00248 MemberTable->setRowHeight(row, ih);
00249 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
00250
00251 QTableWidgetItem* item = new QTableWidgetItem(info->GetTypeName());
00252 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
00253 MemberTable->setItem(row, fiColType, item);
00254
00255 item = new QTableWidgetItem(info->GetFullName(buf));
00256 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
00257 MemberTable->setItem(row, fiColName, item);
00258
00259 item = new QTableWidgetItem(info->GetStrValue());
00260 if (info->CanStrEdit())
00261 item->setFlags(item->flags() | Qt::ItemIsEditable);
00262 else
00263 item->setFlags(item->flags() & ~ Qt::ItemIsEditable);
00264 MemberTable->setItem(row, fiColValue, item);
00265
00266 item = new QTableWidgetItem(info->GetTitle());
00267 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
00268 MemberTable->setItem(row, fiColComment, item);
00269
00270 MemberTable->setRowHidden(row, !info->IsVisible());
00271 }
00272
00273 fFillingTable = false;
00274
00275 MemberTable->show();
00276 ensurePolished();
00277 update();
00278 show();
00279 raise();
00280 MemberTable->show();
00281 }
00282
00283 void TGo4ParaEdit::clearTextFields()
00284 {
00285 if (fItems==0) return;
00286
00287 for(int n=0;n<=fItems->GetLast();n++) {
00288 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(n);
00289 info->SetStrValue("");
00290 }
00291
00292 PleaseUpdateLabel->setVisible(true);
00293
00294 ShowVisibleItems();
00295 }
00296
00297 void TGo4ParaEdit::ChangedTable( int row, int col )
00298 {
00299 if ((col==fiColValue) && !fFillingTable) {
00300 QString txt = MemberTable->item(row, col)->text();
00301 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
00302 info->SetStrValue(txt.toLatin1().constData());
00303 PleaseUpdateLabel->setVisible(true);
00304 }
00305 }
00306
00307 void TGo4ParaEdit::TableDoubleClick( int row, int col )
00308 {
00309 if(col!=fiColName) return;
00310
00311 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
00312
00313 if (info->IsArrayItem()) {
00314 fiCurrentRow = row;
00315 ExpandShrinkArray();
00316 } else
00317 if (info->IsFitterItem()) {
00318 fiCurrentRow = row;
00319 EditFitter();
00320 }
00321 }
00322
00323 void TGo4ParaEdit::ContextMenu(const QPoint& pnt)
00324 {
00325 QTableWidgetItem* item = MemberTable->itemAt (pnt);
00326
00327 if ((item==0) || (MemberTable->column(item) != fiColName)) return;
00328
00329 int row = MemberTable->row(item);
00330
00331 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
00332
00333 if (info->IsArrayItem()) {
00334 fiCurrentRow = row;
00335 QMenu contextMenu(this );
00336 contextMenu.addAction("Array View");
00337
00338 if (row<fItems->GetLast()) {
00339 TGo4ParameterMember* next = (TGo4ParameterMember*) fItems->At(row+1);
00340 if ((next->GetMemberId() == info->GetMemberId()) && !next->IsVisible())
00341 contextMenu.addAction( "++ \t(next index)", this, SLOT(IncArrayIndex()));
00342 }
00343
00344 if (row>0) {
00345 TGo4ParameterMember* prev = (TGo4ParameterMember*) fItems->At(row-1);
00346 if ((prev->GetMemberId() == info->GetMemberId()) && !prev->IsVisible())
00347 contextMenu.addAction( "-- \t(prev index)", this, SLOT(DecArrayIndex()));
00348 }
00349
00350 contextMenu.addAction( "Expand/Shrink", this, SLOT(ExpandShrinkArray()));
00351 contextMenu.exec(QCursor::pos());
00352 } else
00353
00354 if (info->IsFitterItem()) {
00355 fiCurrentRow = row;
00356 QMenu contextMenu(this );
00357 contextMenu.addAction("Modify Fitter");
00358
00359 contextMenu.addAction( "Edit...", this, SLOT(EditFitter()));
00360
00361 TGo4Fitter* fitter = 0;
00362 ServiceCall("GetFitterFromFitPanel", &fitter);
00363 if ((fitter!=0) && (info->GetObject()!=fitter))
00364 contextMenu.addAction( "Get from FitPanel", this, SLOT(GetFitterFromEditor()));
00365 contextMenu.exec(QCursor::pos());
00366 }
00367 }
00368
00369 void TGo4ParaEdit::ExpandShrinkArray()
00370 {
00371 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(fiCurrentRow);
00372
00373 Int_t memberid = info->GetMemberId();
00374 for(int n=0;n<=fItems->GetLast();n++) {
00375 TGo4ParameterMember* item = (TGo4ParameterMember*) fItems->At(n);
00376 if (item->GetMemberId()==memberid)
00377 item->SetVisible(!item->IsVisible());
00378 }
00379 info->SetVisible(kTRUE);
00380 ShowVisibleItems();
00381 }
00382
00383 void TGo4ParaEdit::IncArrayIndex()
00384 {
00385 if (fiCurrentRow>fItems->GetLast()) return;
00386 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(fiCurrentRow);
00387 TGo4ParameterMember* next = (TGo4ParameterMember*) fItems->At(fiCurrentRow+1);
00388 if (next->GetMemberId() == info->GetMemberId()) {
00389 info->SetVisible(kFALSE);
00390 next->SetVisible(kTRUE);
00391 ShowVisibleItems();
00392 }
00393 }
00394
00395 void TGo4ParaEdit::DecArrayIndex()
00396 {
00397 if (fiCurrentRow==0) return;
00398 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(fiCurrentRow);
00399 TGo4ParameterMember* prev = (TGo4ParameterMember*) fItems->At(fiCurrentRow-1);
00400 if (prev->GetMemberId() == info->GetMemberId()) {
00401 info->SetVisible(kFALSE);
00402 prev->SetVisible(kTRUE);
00403 ShowVisibleItems();
00404 }
00405 }
00406
00407 void TGo4ParaEdit::EditFitter()
00408 {
00409 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(fiCurrentRow);
00410 TGo4Fitter* fitter = dynamic_cast<TGo4Fitter*> (info->GetObject());
00411
00412 if(fitter==0) {
00413 fitter= new TGo4Fitter("Fitter","Fitter from parameter editor");
00414 info->SetObject(fitter, kTRUE);
00415 }
00416
00417 TGo4Slot* fitterslot = AddSlot("Fitter");
00418 fitterslot->AssignObject(fitter, kFALSE);
00419 EditObjectInSlot(fitterslot);
00420 PleaseUpdateLabel->setVisible(true);
00421 }
00422
00423 void TGo4ParaEdit::GetFitterFromEditor()
00424 {
00425 TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(fiCurrentRow);
00426 if ((info==0) || !info->IsFitterItem()) return;
00427
00428 TGo4Fitter* fitter = 0;
00429 ServiceCall("CloneFitterFromFitPanel", &fitter);
00430
00431 if (fitter!=0) info->SetObject(fitter, kTRUE);
00432 }
00433
00434 void TGo4ParaEdit::saveFile()
00435 {
00436 TGo4LockGuard lock(0,true);
00437
00438 if (fItems==0) return;
00439
00440 if (GetLinkedName("Parameter")!=0) {
00441 TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",0));
00442 if (par==0) return;
00443 if (par->SetMemberValues(fItems))
00444 if (SaveItemToFile(GetLinkedName("Parameter"), "Parameters"))
00445 PleaseUpdateLabel->setVisible(false);
00446 } else
00447 if (fItemName.length()>0) {
00448 const char* parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
00449 if (parclass==0) return;
00450 if (gROOT->GetClass(parclass)==0) {
00451 QMessageBox::warning(this, "Parameter editor",
00452 QString("Parameter class ") + parclass + " not known to gui");
00453 return;
00454 }
00455 TString foldname, parname;
00456 TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
00457
00458 TGo4ParameterStatus status(parname, parclass, (TObjArray*)fItems->Clone());
00459
00460 TGo4Parameter* par = status.CreateParameter();
00461
00462 if (par==0) {
00463 QMessageBox::warning(this, "Parameter editor",
00464 QString("Can not crate parameter object of class ") + parclass);
00465 return;
00466 }
00467
00468 QFileDialog fd(this, QString("Save ") + fItemName + " in root file",
00469 QString(), "ROOT (*.root);;ROOT XML (*.xml)");
00470 fd.setFileMode( QFileDialog::AnyFile);
00471 fd.setAcceptMode(QFileDialog::AcceptSave);
00472 fd.selectFile("file.root");
00473 if (fd.exec() != QDialog::Accepted) return;
00474
00475 QStringList flst = fd.selectedFiles();
00476 if (flst.isEmpty()) return;
00477
00478 TFile* f = TFile::Open(flst[0].toLatin1().constData(),"UPDATE");
00479 if (f!=0) {
00480 f->WriteTObject(par, par->GetName(), "WriteDelete") > 0;
00481 delete f;
00482 }
00483 }
00484 }
00485
00486 void TGo4ParaEdit::RefreshClicked()
00487 {
00488 WorkWithParameter(ParamNameLbl->text().toLatin1().constData(), true);
00489 }
00490
00491 void TGo4ParaEdit::ApplyClicked()
00492 {
00493 TGo4LockGuard lock(0,true);
00494
00495 if ((fItemName.length()==0) || (fItems==0)) return;
00496
00497 TString foldname, parname;
00498 TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
00499
00500 const char* parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
00501 if (parclass==0) return;
00502
00503 TGo4ParameterStatus status(parname, parclass, (TObjArray*)fItems->Clone());
00504
00505 if (UpdateItemInAnalysis(fItemName.toLatin1().constData(), &status))
00506 if (BrowserItemRemote(fItemName.toLatin1().constData()))
00507 RefreshClicked();
00508 else
00509 PleaseUpdateLabel->setVisible(false);
00510 }