GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4ParaEdit.cpp
Go to the documentation of this file.
1// $Id$
2//-----------------------------------------------------------------------
3// The GSI Online Offline Object Oriented (Go4) Project
4// Experiment Data Processing at EE department, GSI
5//-----------------------------------------------------------------------
6// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7// Planckstr. 1, 64291 Darmstadt, Germany
8// Contact: http://go4.gsi.de
9//-----------------------------------------------------------------------
10// This software can be used under the license agreements as stated
11// in Go4License.txt file which is part of the distribution.
12//-----------------------------------------------------------------------
13
14#include "TGo4ParaEdit.h"
15
16#include <QMenu>
17#include <QMessageBox>
18#include <QFileDialog>
19
20#include "TROOT.h"
21#include "TFile.h"
22#include "TObjArray.h"
23#include "TClass.h"
24#include "TGo4LockGuard.h"
25#include "TGo4Parameter.h"
26#include "TGo4ParameterMember.h"
27#include "TGo4ParameterStatus.h"
28#include "TGo4Fitter.h"
29#include "TGo4Slot.h"
30#include "TGo4BrowserProxy.h"
31#include "TGo4ServerProxy.h"
32
33TGo4ParaEdit::TGo4ParaEdit(QWidget *parent, const char *name) :
34 QGo4Widget(parent,name)
35{
36 setupUi(this);
37
38 QObject::connect(MemberTable, &QTableWidget::cellChanged, this, &TGo4ParaEdit::ChangedTable);
39 QObject::connect(MemberTable, &QTableWidget::cellDoubleClicked, this, &TGo4ParaEdit::TableDoubleClick);
40 QObject::connect(MemberTable, &QTableWidget::customContextMenuRequested, this, &TGo4ParaEdit::TableContextMenu);
41 QObject::connect(CancelButton, &QPushButton::pressed, this, &TGo4ParaEdit::CloseMDIParentSlot);
42 QObject::connect(ApplyButton, &QPushButton::pressed, this, &TGo4ParaEdit::ApplyClicked);
43 QObject::connect(RefreshButton, &QPushButton::pressed, this, &TGo4ParaEdit::RefreshClicked);
44 QObject::connect(ClearButton, &QPushButton::pressed, this, &TGo4ParaEdit::clearTextFields);
45 QObject::connect(SavePar, &QPushButton::clicked, this, &TGo4ParaEdit::saveFile);
46
47 fItems = nullptr;
48 PleaseUpdateLabel->setVisible(false);
49 parentWidget()->adjustSize();
50
51 ParamNameLbl->setText("");
52 ParamClassLbl->setText("");
53
54 fItemName = "";
55 fFillingTable = false;
56 MemberTable->setContextMenuPolicy(Qt::CustomContextMenu);
57 MemberTable->horizontalHeader()->setStretchLastSection(true);
58}
59
61{
62 if (fItems) {
63 delete fItems;
64 fItems = nullptr;
65 }
66}
67
68bool TGo4ParaEdit::IsAcceptDrag(const char *itemname, TClass *cl, int kind)
69{
70 if (kind==TGo4Access::kndGo4Param) return true;
71
72 return !cl ? false : cl->InheritsFrom(TGo4Parameter::Class());
73}
74
75void TGo4ParaEdit::DropItem(const char *itemname, TClass *cl, int kind)
76{
77 if ((kind==TGo4Access::kndGo4Param) ||
78 (cl && cl->InheritsFrom(TGo4Parameter::Class())))
79 WorkWithParameter(itemname, false);
80}
81
82void TGo4ParaEdit::linkedObjectUpdated(const char *linkname, TObject *obj)
83{
84 if (strcmp(linkname,"Parameter") == 0)
85 RefreshWidget(dynamic_cast<TGo4Parameter*> (obj));
86 else
87 if (strcmp(linkname,"ParStatus") == 0)
88 RefreshWidget(dynamic_cast<TGo4ParameterStatus *> (obj));
89}
90
91void TGo4ParaEdit::linkedObjectRemoved(const char *linkname)
92{
93 // if link removed while parameter is disappear, just close parameter editor
94
95 if (strcmp(linkname,"Fitter") != 0)
96 ShootCloseWidget(true);
97}
98
99void TGo4ParaEdit::WorkWithParameter(const char *itemname, bool isrefresh)
100{
101 if (PleaseUpdateLabel->isVisible() && !isrefresh) {
102 auto par = GetLinkedCast<TGo4Parameter>("Parameter");
103 const char *previtem = GetLinkedName("Parameter");
104 if (par && previtem) {
105 QMessageBox msgBox(QMessageBox::Question, "Parameter editor",
106 QString("Current parameter %1 is modified!\nNew parameter %2 is selected.").arg(previtem).arg(itemname));
107
108 auto btnContinue = msgBox.addButton("Continue with current", QMessageBox::ActionRole);
109 /* auto btnNew = */ msgBox.addButton("Start with new", QMessageBox::ActionRole);
110 msgBox.setDefaultButton(btnContinue);
111
112 msgBox.exec();
113 if (msgBox.clickedButton() == btnContinue)
114 return;
115 }
116 }
117
118 ResetWidget();
119
120 ParamNameLbl->setText(itemname);
121
122 fItemName = itemname;
123
124 QString iconname = ":/icons/right.png";
125 QString tooltip = "Refresh parameter values from analysis";
126
127 if (BrowserItemRemote(itemname)) {
128 TGo4Slot *tgtslot = AddSlot("ParStatus");
130 if (br) br->RequestObjectStatus(itemname, tgtslot);
131 // add dummy link to be informed when parameter is disappear
132 AddLink(itemname, "ParameterLock");
133 } else {
134 iconname = ":/icons/refresh.png";
135 tooltip = "Refresh parameter values from source";
136 AddLink(itemname, "Parameter");
137 auto par = GetLinkedCast<TGo4Parameter>("Parameter", 2);
138 if (par) RefreshWidget(par);
139 }
140
141 RefreshButton->setIcon(QIcon(iconname));
142 RefreshButton->setToolTip(tooltip);
143
144 setFocus();
145}
146
148{
150
151 ParamNameLbl->setText("");
152 ParamClassLbl->setText("");
153
154 fItemName = "";
155
156 RefreshButton->setEnabled(false);
157 ApplyButton->setEnabled(false);
158
159 delete fItems;
160 fItems = nullptr;
161
163
164 PleaseUpdateLabel->setVisible(false);
165}
166
168{
169 RefreshButton->setEnabled(par != nullptr);
170 ApplyButton->setEnabled(par != nullptr);
171
172 delete fItems;
173 fItems = new TObjArray(100);
174 fItems->SetOwner(kTRUE);
175
176 if (par) {
178 ParamClassLbl->setText(QString(" - ")+par->ClassName());
179 }
180
182
183 PleaseUpdateLabel->setVisible(false);
184}
185
186
188{
189 RefreshButton->setEnabled(status != nullptr);
190
192 TGo4ServerProxy *serv = br ? br->DefineServerObject(fItemName.toLatin1().constData()) : nullptr;
193 ApplyButton->setEnabled(serv && serv->CanSubmitObjects());
194
195 delete fItems;
196 fItems = nullptr;
197
198 if (status) {
199 fItems = status->GetMemberValues(kTRUE);
200 ParamClassLbl->setText(QString(" - ") + status->GetObjectClass());
201 }
202
204
205 PleaseUpdateLabel->setVisible(false);
206}
207
209{
210 if (!fItems) {
211 MemberTable->setRowCount(0);
212 return;
213 }
214
215 fFillingTable = true;
216
217 MemberTable->hide();
218
219 MemberTable->horizontalHeaderItem(fiColType)->setText("Type");
220 MemberTable->horizontalHeaderItem(fiColName)->setText("Name");
221 MemberTable->horizontalHeaderItem(fiColValue)->setText("Value");
222 MemberTable->horizontalHeaderItem(fiColComment)->setText("Comments");
223
224 int memnum = fItems->GetLast()+1;
225 MemberTable->setRowCount(memnum);
226 // MemberTable->setLeftMargin(0);
227 MemberTable->verticalHeader()->hide();
228 TString buf;
229#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
230 int ih = QApplication::fontMetrics().height();
231#else
232 int ih = QFontMetricsF(QApplication::font()).height();
233#endif
234 for (int row = 0; row < memnum; row++) {
235 MemberTable->setRowHeight(row, ih);
237
238 QTableWidgetItem* item = new QTableWidgetItem(info->GetTypeName());
239 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
240 MemberTable->setItem(row, fiColType, item);
241
242 item = new QTableWidgetItem(info->GetFullName(buf));
243 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
244 MemberTable->setItem(row, fiColName, item);
245
246 item = new QTableWidgetItem(info->GetStrValue());
247 if (info->CanStrEdit())
248 item->setFlags(item->flags() | Qt::ItemIsEditable);
249 else
250 item->setFlags(item->flags() & ~ Qt::ItemIsEditable);
251 MemberTable->setItem(row, fiColValue, item);
252
253 item = new QTableWidgetItem(info->GetTitle());
254 item->setFlags(item->flags() & ~Qt::ItemIsEditable);
255 MemberTable->setItem(row, fiColComment, item);
256
257 MemberTable->setRowHidden(row, !info->IsVisible());
258 }
259
260 fFillingTable = false;
261
262 MemberTable->show();
263 ensurePolished();
264 update();
265 show();
266 raise();
267 MemberTable->show();
268}
269
271{
272 if (!fItems) return;
273
274 for (int n = 0; n <= fItems->GetLast(); n++) {
276 info->SetStrValue("");
277 }
278
279 PleaseUpdateLabel->setVisible(true);
280
282}
283
284void TGo4ParaEdit::ChangedTable( int row, int col )
285{
286 if ((col==fiColValue) && !fFillingTable) {
287 QString txt = MemberTable->item(row, col)->text();
289 info->SetStrValue(txt.toLatin1().constData());
290 PleaseUpdateLabel->setVisible(true);
291 }
292}
293
294void TGo4ParaEdit::TableDoubleClick( int row, int col )
295{
296 if(col != fiColName) return;
297
299
300 if (info->IsArrayItem()) {
301 fiCurrentRow = row;
303 } else if (info->IsFitterItem()) {
304 fiCurrentRow = row;
305 EditFitter();
306 }
307}
308
309void TGo4ParaEdit::TableContextMenu(const QPoint& pnt)
310{
311 QTableWidgetItem* item = MemberTable->itemAt (pnt);
312
313 if (!item || (MemberTable->column(item) != fiColName)) return;
314
315 int row = MemberTable->row(item);
316
318
319 if (info->IsArrayItem()) {
320 fiCurrentRow = row;
321 QMenu contextMenu;
322 contextMenu.addAction("Array View");
323
324 if (row<fItems->GetLast()) {
325 TGo4ParameterMember* next = (TGo4ParameterMember*) fItems->At(row+1);
326 if ((next->GetMemberId() == info->GetMemberId()) && !next->IsVisible())
327 contextMenu.addAction( "++ \t(next index)", this, &TGo4ParaEdit::IncArrayIndex);
328 }
329
330 if (row>0) {
331 TGo4ParameterMember* prev = (TGo4ParameterMember*) fItems->At(row-1);
332 if ((prev->GetMemberId() == info->GetMemberId()) && !prev->IsVisible())
333 contextMenu.addAction( "-- \t(prev index)", this, &TGo4ParaEdit::DecArrayIndex);
334 }
335
336 contextMenu.addAction( "Expand/Shrink", this, &TGo4ParaEdit::ExpandShrinkArray);
337 contextMenu.exec(QCursor::pos());
338 } else
339
340 if (info->IsFitterItem()) {
341 fiCurrentRow = row;
342 QMenu contextMenu;
343 contextMenu.addAction("Modify Fitter");
344
345 contextMenu.addAction( "Edit...", this, &TGo4ParaEdit::EditFitter);
346
347 TGo4Fitter *fitter = nullptr;
348 ServiceCall("GetFitterFromFitPanel", &fitter);
349 if (fitter && (info->GetObject() != fitter))
350 contextMenu.addAction( "Get from FitPanel", this, &TGo4ParaEdit::GetFitterFromEditor);
351 contextMenu.exec(QCursor::pos());
352 }
353}
354
356{
358
359 Int_t memberid = info->GetMemberId();
360 for (int n = 0; n <= fItems->GetLast(); n++) {
362 if (item->GetMemberId()==memberid)
363 item->SetVisible(!item->IsVisible());
364 }
365 info->SetVisible(kTRUE);
367}
368
370{
371 if (fiCurrentRow>fItems->GetLast()) return;
374 if (next->GetMemberId() == info->GetMemberId()) {
375 info->SetVisible(kFALSE);
376 next->SetVisible(kTRUE);
378 }
379}
380
382{
383 if (fiCurrentRow == 0) return;
386 if (prev->GetMemberId() == info->GetMemberId()) {
387 info->SetVisible(kFALSE);
388 prev->SetVisible(kTRUE);
390 }
391}
392
394{
396 TGo4Fitter *fitter = dynamic_cast<TGo4Fitter*> (info->GetObject());
397
398 if(!fitter) {
399 fitter = new TGo4Fitter("Fitter","Fitter from parameter editor");
400 info->SetObject(fitter, kTRUE);
401 }
402
403 TGo4Slot *fitterslot = AddSlot("Fitter");
404 fitterslot->AssignObject(fitter, kFALSE);
405 EditObjectInSlot(fitterslot);
406 PleaseUpdateLabel->setVisible(true);
407}
408
410{
412 if (!info || !info->IsFitterItem()) return;
413
414 TGo4Fitter *fitter = nullptr;
415 ServiceCall("CloneFitterFromFitPanel", &fitter);
416
417 if (fitter) info->SetObject(fitter, kTRUE);
418}
419
421{
422 TGo4LockGuard lock;
423
424 if (!fItems) return;
425
426 if (GetLinkedName("Parameter")) {
427 auto par = GetLinkedCast<TGo4Parameter>("Parameter");
428 if (!par) return;
429 if (par->SetMemberValues(fItems))
430 if (SaveItemToFile(GetLinkedName("Parameter"), "Parameters"))
431 PleaseUpdateLabel->setVisible(false);
432
433 } else if (fItemName.length() > 0) {
434
435 const char *parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
436 if (!parclass) return;
437 if (!gROOT->GetClass(parclass)) {
438 QMessageBox::warning(this, "Parameter editor",
439 QString("Parameter class ") + parclass + " not known to gui");
440 return;
441 }
442 TString foldname, parname;
443 TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
444
445 TGo4ParameterStatus status(parname, parclass, (TObjArray *)fItems->Clone());
446
447 TGo4Parameter *par = status.CreateParameter();
448
449 if (!par) {
450 QMessageBox::warning(this, "Parameter editor",
451 QString("Can not crate parameter object of class ") + parclass);
452 return;
453 }
454
455 QFileDialog fd(this, QString("Save ") + fItemName + " in root file",
456 QString(), "ROOT (*.root);;ROOT XML (*.xml)");
457 fd.setFileMode( QFileDialog::AnyFile);
458 fd.setAcceptMode(QFileDialog::AcceptSave);
459 fd.selectFile("file.root");
460 if (fd.exec() != QDialog::Accepted) return;
461
462 QStringList flst = fd.selectedFiles();
463 if (flst.isEmpty()) return;
464
465 TFile *f = TFile::Open(flst[0].toLatin1().constData(),"UPDATE");
466 if (f) {
467 f->WriteTObject(par, par->GetName(), "WriteDelete");
468 delete f;
469 }
470 }
471}
472
474{
475 WorkWithParameter(ParamNameLbl->text().toLatin1().constData(), true);
476}
477
479{
480 TGo4LockGuard lock;
481
482 if (fItemName.isEmpty() || !fItems) return;
483
484 TString foldname, parname;
485 TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
486
487 const char *parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
488 if (!parclass) return;
489
490 TGo4ParameterStatus status(parname, parclass, (TObjArray *)fItems->Clone());
491
492 if (UpdateItemInAnalysis(fItemName.toLatin1().constData(), &status)) {
493 if (BrowserItemRemote(fItemName.toLatin1().constData()))
495 else
496 PleaseUpdateLabel->setVisible(false);
497 }
498}
#define TGo4LockGuard
T * GetLinkedCast(const char *linkname, int updatelevel=0)
Definition QGo4Widget.h:157
bool SaveItemToFile(const char *itemname, const char *subfolder=nullptr)
void EditObjectInSlot(TGo4Slot *slot)
void ShootCloseWidget(bool closeparent=false)
const char * GetLinkedName(const char *linkname)
returns name of item, which was linked with linkname
virtual void ResetWidget()
TGo4Slot * AddSlot(const char *slotname)
add slot with specific name to widget top folder
QGo4Widget(QWidget *parent=nullptr, const char *name=nullptr, Qt::WindowFlags f=Qt::Widget)
void AddLink(const char *itemname, const char *linkname)
create link for item with name linkname
bool UpdateItemInAnalysis(const char *itemname, TObject *obj=nullptr)
void CloseMDIParentSlot()
bool BrowserItemRemote(const char *itemname)
void ServiceCall(const char *name, void *par=nullptr)
TGo4BrowserProxy * Browser()
const char * ItemClassName(const char *name)
TGo4ServerProxy * DefineServerObject(const char *itemname, TString *objname=nullptr, Bool_t onlyanalysis=kTRUE)
void RequestObjectStatus(const char *name, TGo4Slot *tgtslot)
Central class of Go4Fit package.
Definition TGo4Fitter.h:38
const char * GetObjectClass() const
ClassName of the described object.
virtual void saveFile()
void linkedObjectUpdated(const char *linkname, TObject *obj) override
virtual void GetFitterFromEditor()
TObjArray * fItems
TGo4ParaEdit(QWidget *parent=nullptr, const char *name=nullptr)
bool IsAcceptDrag(const char *itemname, TClass *cl, int kind) override
virtual void TableContextMenu(const QPoint &)
virtual void ChangedTable(int row, int col)
virtual ~TGo4ParaEdit()
virtual void clearTextFields()
void DropItem(const char *itemname, TClass *cl, int kind) override
virtual void ApplyClicked()
virtual void TableDoubleClick(int row, int col)
virtual void RefreshClicked()
virtual void DecArrayIndex()
virtual void RefreshWidget(TGo4Parameter *par)
virtual void ExpandShrinkArray()
void linkedObjectRemoved(const char *linkname) override
void ResetWidget() override
virtual void IncArrayIndex()
QString fItemName
virtual void EditFitter()
virtual void ShowVisibleItems()
virtual void WorkWithParameter(const char *itemname, bool isrefresh)
const char * GetTypeName() const
const char * GetFullName(TString &buf) const
void SetObject(TObject *obj, Bool_t owner)
const char * GetStrValue() const
void SetVisible(Bool_t on=kTRUE)
TObject * GetObject() const
void SetStrValue(const char *value)
Bool_t IsFitterItem() const
Status object for an analysis parameter.
TGo4Parameter * CreateParameter()
TObjArray * GetMemberValues(Bool_t takeit=kFALSE)
Base class for all parameter aggregations, e.g.
void GetMemberValues(TObjArray *fItems)
special base class for remote data servers like DABC, HTTP, hist server
virtual Bool_t CanSubmitObjects() const
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition TGo4Slot.cxx:646
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition TGo4Slot.cxx:344