GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
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 
33 TGo4ParaEdit::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 
68 bool 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 
75 void 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 
82 void 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 
91 void 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 
99 void 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");
129  TGo4BrowserProxy *br = Browser();
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) {
177  par->GetMemberValues(fItems);
178  ParamClassLbl->setText(QString(" - ")+par->ClassName());
179  }
180 
182 
183  PleaseUpdateLabel->setVisible(false);
184 }
185 
186 
188 {
189  RefreshButton->setEnabled(status != nullptr);
190 
191  TGo4BrowserProxy *br = Browser();
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);
236  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
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 
284 void TGo4ParaEdit::ChangedTable( int row, int col )
285 {
286  if ((col==fiColValue) && !fFillingTable) {
287  QString txt = MemberTable->item(row, col)->text();
288  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
289  info->SetStrValue(txt.toLatin1().constData());
290  PleaseUpdateLabel->setVisible(true);
291  }
292 }
293 
294 void TGo4ParaEdit::TableDoubleClick( int row, int col )
295 {
296  if(col != fiColName) return;
297 
298  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
299 
300  if (info->IsArrayItem()) {
301  fiCurrentRow = row;
303  } else if (info->IsFitterItem()) {
304  fiCurrentRow = row;
305  EditFitter();
306  }
307 }
308 
309 void 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 
317  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
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()))
494  RefreshClicked();
495  else
496  PleaseUpdateLabel->setVisible(false);
497  }
498 }
virtual void ResetWidget()
Definition: QGo4Widget.cpp:52
virtual ~TGo4ParaEdit()
void ResetWidget() override
Bool_t IsFitterItem() const
void EditObjectInSlot(TGo4Slot *slot)
Definition: QGo4Widget.cpp:350
virtual void TableContextMenu(const QPoint &)
TGo4ServerProxy * DefineServerObject(const char *itemname, TString *objname=nullptr, Bool_t onlyanalysis=kTRUE)
void ShootCloseWidget(bool closeparent=false)
Definition: QGo4Widget.cpp:70
bool SaveItemToFile(const char *itemname, const char *subfolder=nullptr)
Definition: QGo4Widget.cpp:368
bool UpdateItemInAnalysis(const char *itemname, TObject *obj=nullptr)
Definition: QGo4Widget.cpp:379
virtual void ChangedTable(int row, int col)
Bool_t CanStrEdit() const
virtual void GetFitterFromEditor()
Bool_t IsVisible() const
virtual void ApplyClicked()
void ServiceCall(const char *name, void *par=nullptr)
Definition: QGo4Widget.cpp:398
virtual void WorkWithParameter(const char *itemname, bool isrefresh)
virtual void RefreshWidget(TGo4Parameter *par)
virtual Bool_t CanSubmitObjects() const
void SetStrValue(const char *value)
TObject * GetObject() const
const char * GetLinkedName(const char *linkname)
Definition: QGo4Widget.cpp:153
TGo4BrowserProxy * Browser()
Definition: QGo4Widget.cpp:219
TObjArray * GetMemberValues(Bool_t takeit=kFALSE)
const char * GetStrValue() const
const char * GetFullName(TString &buf) const
QString fItemName
Definition: TGo4ParaEdit.h:68
const char * GetObjectClass() const
bool BrowserItemRemote(const char *itemname)
Definition: QGo4Widget.cpp:212
const char * GetTypeName() const
void SetObject(TObject *obj, Bool_t owner)
Bool_t IsArrayItem() const
bool fFillingTable
Definition: TGo4ParaEdit.h:69
void RequestObjectStatus(const char *name, TGo4Slot *tgtslot)
void linkedObjectUpdated(const char *linkname, TObject *obj) override
const char * ItemClassName(const char *name)
TObjArray * fItems
Definition: TGo4ParaEdit.h:67
virtual void clearTextFields()
virtual void ExpandShrinkArray()
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition: TGo4Slot.cxx:646
virtual void saveFile()
virtual void EditFitter()
void linkedObjectRemoved(const char *linkname) override
virtual void IncArrayIndex()
void DropItem(const char *itemname, TClass *cl, int kind) override
TGo4ParaEdit(QWidget *parent=nullptr, const char *name=nullptr)
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition: TGo4Slot.cxx:344
void AddLink(const char *itemname, const char *linkname)
Definition: QGo4Widget.cpp:117
void SetVisible(Bool_t on=kTRUE)
virtual void TableDoubleClick(int row, int col)
virtual void DecArrayIndex()
virtual void ShowVisibleItems()
bool IsAcceptDrag(const char *itemname, TClass *cl, int kind) override
virtual void RefreshClicked()
void GetMemberValues(TObjArray *fItems)
TGo4Slot * AddSlot(const char *slotname)
Definition: QGo4Widget.cpp:141
void CloseMDIParentSlot()
Definition: QGo4Widget.cpp:79