GSI Object Oriented Online Offline (Go4)  GO4-6.1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4ParaEdit.cpp
Go to the documentation of this file.
1 // $Id: TGo4ParaEdit.cpp 3146 2021-03-30 14:43:35Z linev $
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, SIGNAL(cellChanged(int,int)), this, SLOT(ChangedTable(int,int)));
39  QObject::connect(CancelButton, SIGNAL(pressed()), this, SLOT(CloseMDIParentSlot()));
40  QObject::connect(ApplyButton, SIGNAL(pressed()), this, SLOT(ApplyClicked()));
41  QObject::connect(RefreshButton, SIGNAL(pressed()), this, SLOT(RefreshClicked()));
42  QObject::connect(ClearButton, SIGNAL(pressed()), this, SLOT(clearTextFields()));
43  QObject::connect(MemberTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(TableDoubleClick(int,int)));
44  QObject::connect(MemberTable, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ContextMenu(const QPoint &)));
45  QObject::connect(SavePar, SIGNAL(clicked()), this, SLOT(saveFile()));
46 
47  fItems = 0;
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!=0) {
63  delete fItems;
64  fItems = 0;
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==0) ? 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!=0) && 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  TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",0));
103  const char* previtem = GetLinkedName("Parameter");
104  if ((par!=0) && (previtem!=0)) {
105  int res = QMessageBox::warning(this, "Parameter editor",
106  QString("Current parameter %1 is modified!\n"
107  "New parameter %2 is selected.").arg(previtem).arg(itemname),
108  QString("Continue with current"),
109  QString("Start with new"), QString(), 0);
110 // (BrowserItemRemote(previtem) ? QString("Update current in analysis and start with new") : QString()), 0);
111  if (res==0) return;
112 // if (res==2) UpdateItemInAnalysis(previtem);
113  }
114  }
115 
116  ResetWidget();
117 
118  ParamNameLbl->setText(itemname);
119 
120  fItemName = itemname;
121 
122  QString iconname = ":/icons/right.png";
123  QString tooltip = "Refresh parameter values from analysis";
124 
125  if (BrowserItemRemote(itemname)) {
126  TGo4Slot* tgtslot = AddSlot("ParStatus");
127  TGo4BrowserProxy* br = Browser();
128  if (br!=0) br->RequestObjectStatus(itemname, tgtslot);
129  // add dummy link to be informed when parameter is disappear
130  AddLink(itemname, "ParameterLock");
131  } else {
132  iconname = ":/icons/refresh.png";
133  tooltip = "Refresh parameter values from source";
134  AddLink(itemname, "Parameter");
135  TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",2));
136  if (par!=0) RefreshWidget(par);
137  }
138 
139  RefreshButton->setIcon(QIcon(iconname));
140  RefreshButton->setToolTip(tooltip);
141 
142  setFocus();
143 }
144 
146 {
148 
149  ParamNameLbl->setText("");
150  ParamClassLbl->setText("");
151 
152  fItemName = "";
153 
154  RefreshButton->setEnabled(false);
155  ApplyButton->setEnabled(false);
156 
157  delete fItems;
158  fItems = 0;
159 
161 
162  PleaseUpdateLabel->setVisible(false);
163 }
164 
166 {
167  RefreshButton->setEnabled(par!=0);
168  ApplyButton->setEnabled(par!=0);
169 
170  delete fItems;
171  fItems = new TObjArray(100);
172  fItems->SetOwner(kTRUE);
173 
174  if (par!=0) {
175  par->GetMemberValues(fItems);
176  ParamClassLbl->setText(QString(" - ")+par->ClassName());
177  }
178 
180 
181  PleaseUpdateLabel->setVisible(false);
182 }
183 
184 
186 {
187  RefreshButton->setEnabled(status!=0);
188 
189  TGo4BrowserProxy* br = Browser();
190  TGo4ServerProxy* serv = br ? br->DefineServerObject(fItemName.toLatin1().constData()) : 0;
191  ApplyButton->setEnabled(serv && serv->CanSubmitObjects());
192 
193  delete fItems;
194  fItems = 0;
195 
196  if (status!=0) {
197  fItems = status->GetMemberValues(kTRUE);
198  ParamClassLbl->setText(QString(" - ") + status->GetObjectClass());
199  }
200 
202 
203  PleaseUpdateLabel->setVisible(false);
204 }
205 
207 {
208  if (fItems==0) {
209  MemberTable->setRowCount(0);
210  return;
211  }
212 
213  fFillingTable = true;
214 
215  MemberTable->hide();
216 
217  MemberTable->horizontalHeaderItem(fiColType)->setText("Type");
218  MemberTable->horizontalHeaderItem(fiColName)->setText("Name");
219  MemberTable->horizontalHeaderItem(fiColValue)->setText("Value");
220  MemberTable->horizontalHeaderItem(fiColComment)->setText("Comments");
221 
222  int memnum = fItems->GetLast()+1;
223  MemberTable->setRowCount(memnum);
224  // MemberTable->setLeftMargin(0);
225  MemberTable->verticalHeader()->hide();
226  TString buf;
227 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
228  int ih = QApplication::fontMetrics().height();
229 #else
230  int ih = QFontMetricsF(QApplication::font()).height();
231 #endif
232  for(int row=0; row<memnum; row++) {
233  MemberTable->setRowHeight(row, ih);
234  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
235 
236  QTableWidgetItem* item = new QTableWidgetItem(info->GetTypeName());
237  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
238  MemberTable->setItem(row, fiColType, item);
239 
240  item = new QTableWidgetItem(info->GetFullName(buf));
241  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
242  MemberTable->setItem(row, fiColName, item);
243 
244  item = new QTableWidgetItem(info->GetStrValue());
245  if (info->CanStrEdit())
246  item->setFlags(item->flags() | Qt::ItemIsEditable);
247  else
248  item->setFlags(item->flags() & ~ Qt::ItemIsEditable);
249  MemberTable->setItem(row, fiColValue, item);
250 
251  item = new QTableWidgetItem(info->GetTitle());
252  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
253  MemberTable->setItem(row, fiColComment, item);
254 
255  MemberTable->setRowHidden(row, !info->IsVisible());
256  }
257 
258  fFillingTable = false;
259 
260  MemberTable->show();
261  ensurePolished();
262  update();
263  show();
264  raise();
265  MemberTable->show();
266 }
267 
269 {
270  if (fItems==0) return;
271 
272  for(int n=0;n<=fItems->GetLast();n++) {
274  info->SetStrValue("");
275  }
276 
277  PleaseUpdateLabel->setVisible(true);
278 
280 }
281 
282 void TGo4ParaEdit::ChangedTable( int row, int col )
283 {
284  if ((col==fiColValue) && !fFillingTable) {
285  QString txt = MemberTable->item(row, col)->text();
286  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
287  info->SetStrValue(txt.toLatin1().constData());
288  PleaseUpdateLabel->setVisible(true);
289  }
290 }
291 
292 void TGo4ParaEdit::TableDoubleClick( int row, int col )
293 {
294  if(col!=fiColName) return;
295 
296  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
297 
298  if (info->IsArrayItem()) {
299  fiCurrentRow = row;
301  } else
302  if (info->IsFitterItem()) {
303  fiCurrentRow = row;
304  EditFitter();
305  }
306 }
307 
308 void TGo4ParaEdit::ContextMenu(const QPoint& pnt)
309 {
310  QTableWidgetItem* item = MemberTable->itemAt (pnt);
311 
312  if ((item==0) || (MemberTable->column(item) != fiColName)) return;
313 
314  int row = MemberTable->row(item);
315 
316  TGo4ParameterMember* info = (TGo4ParameterMember*) fItems->At(row);
317 
318  if (info->IsArrayItem()) {
319  fiCurrentRow = row;
320  QMenu contextMenu(this );
321  contextMenu.addAction("Array View");
322 
323  if (row<fItems->GetLast()) {
324  TGo4ParameterMember* next = (TGo4ParameterMember*) fItems->At(row+1);
325  if ((next->GetMemberId() == info->GetMemberId()) && !next->IsVisible())
326  contextMenu.addAction( "++ \t(next index)", this, SLOT(IncArrayIndex()));
327  }
328 
329  if (row>0) {
330  TGo4ParameterMember* prev = (TGo4ParameterMember*) fItems->At(row-1);
331  if ((prev->GetMemberId() == info->GetMemberId()) && !prev->IsVisible())
332  contextMenu.addAction( "-- \t(prev index)", this, SLOT(DecArrayIndex()));
333  }
334 
335  contextMenu.addAction( "Expand/Shrink", this, SLOT(ExpandShrinkArray()));
336  contextMenu.exec(QCursor::pos());
337  } else
338 
339  if (info->IsFitterItem()) {
340  fiCurrentRow = row;
341  QMenu contextMenu(this );
342  contextMenu.addAction("Modify Fitter");
343 
344  contextMenu.addAction( "Edit...", this, SLOT(EditFitter()));
345 
346  TGo4Fitter* fitter = 0;
347  ServiceCall("GetFitterFromFitPanel", &fitter);
348  if ((fitter!=0) && (info->GetObject()!=fitter))
349  contextMenu.addAction( "Get from FitPanel", this, SLOT(GetFitterFromEditor()));
350  contextMenu.exec(QCursor::pos());
351  }
352 }
353 
355 {
357 
358  Int_t memberid = info->GetMemberId();
359  for(int n=0;n<=fItems->GetLast();n++) {
361  if (item->GetMemberId()==memberid)
362  item->SetVisible(!item->IsVisible());
363  }
364  info->SetVisible(kTRUE);
366 }
367 
369 {
370  if (fiCurrentRow>fItems->GetLast()) return;
373  if (next->GetMemberId() == info->GetMemberId()) {
374  info->SetVisible(kFALSE);
375  next->SetVisible(kTRUE);
377  }
378 }
379 
381 {
382  if (fiCurrentRow==0) return;
385  if (prev->GetMemberId() == info->GetMemberId()) {
386  info->SetVisible(kFALSE);
387  prev->SetVisible(kTRUE);
389  }
390 }
391 
393 {
395  TGo4Fitter* fitter = dynamic_cast<TGo4Fitter*> (info->GetObject());
396 
397  if(fitter==0) {
398  fitter= new TGo4Fitter("Fitter","Fitter from parameter editor");
399  info->SetObject(fitter, kTRUE);
400  }
401 
402  TGo4Slot* fitterslot = AddSlot("Fitter");
403  fitterslot->AssignObject(fitter, kFALSE);
404  EditObjectInSlot(fitterslot);
405  PleaseUpdateLabel->setVisible(true);
406 }
407 
409 {
411  if ((info==0) || !info->IsFitterItem()) return;
412 
413  TGo4Fitter* fitter = 0;
414  ServiceCall("CloneFitterFromFitPanel", &fitter);
415 
416  if (fitter!=0) info->SetObject(fitter, kTRUE);
417 }
418 
420 {
421  TGo4LockGuard lock;
422 
423  if (fItems==0) return;
424 
425  if (GetLinkedName("Parameter")!=0) {
426  TGo4Parameter* par = dynamic_cast<TGo4Parameter*> (GetLinked("Parameter",0));
427  if (par==0) return;
428  if (par->SetMemberValues(fItems))
429  if (SaveItemToFile(GetLinkedName("Parameter"), "Parameters"))
430  PleaseUpdateLabel->setVisible(false);
431  } else
432  if (fItemName.length()>0) {
433  const char* parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
434  if (parclass==0) return;
435  if (gROOT->GetClass(parclass)==0) {
436  QMessageBox::warning(this, "Parameter editor",
437  QString("Parameter class ") + parclass + " not known to gui");
438  return;
439  }
440  TString foldname, parname;
441  TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
442 
443  TGo4ParameterStatus status(parname, parclass, (TObjArray*)fItems->Clone());
444 
445  TGo4Parameter* par = status.CreateParameter();
446 
447  if (par==0) {
448  QMessageBox::warning(this, "Parameter editor",
449  QString("Can not crate parameter object of class ") + parclass);
450  return;
451  }
452 
453  QFileDialog fd(this, QString("Save ") + fItemName + " in root file",
454  QString(), "ROOT (*.root);;ROOT XML (*.xml)");
455  fd.setFileMode( QFileDialog::AnyFile);
456  fd.setAcceptMode(QFileDialog::AcceptSave);
457  fd.selectFile("file.root");
458  if (fd.exec() != QDialog::Accepted) return;
459 
460  QStringList flst = fd.selectedFiles();
461  if (flst.isEmpty()) return;
462 
463  TFile* f = TFile::Open(flst[0].toLatin1().constData(),"UPDATE");
464  if (f!=0) {
465  f->WriteTObject(par, par->GetName(), "WriteDelete");
466  delete f;
467  }
468  }
469 }
470 
472 {
473  WorkWithParameter(ParamNameLbl->text().toLatin1().constData(), true);
474 }
475 
477 {
478  TGo4LockGuard lock;
479 
480  if ((fItemName.length()==0) || (fItems==0)) return;
481 
482  TString foldname, parname;
483  TGo4Slot::ProduceFolderAndName(fItemName.toLatin1().constData(), foldname, parname);
484 
485  const char* parclass = Browser()->ItemClassName(fItemName.toLatin1().constData());
486  if (parclass==0) return;
487 
488  TGo4ParameterStatus status(parname, parclass, (TObjArray*)fItems->Clone());
489 
490  if (UpdateItemInAnalysis(fItemName.toLatin1().constData(), &status)) {
491  if (BrowserItemRemote(fItemName.toLatin1().constData()))
492  RefreshClicked();
493  else
494  PleaseUpdateLabel->setVisible(false);
495  }
496 }
virtual void ResetWidget()
Definition: QGo4Widget.cpp:52
TObject * GetObject() const
virtual ~TGo4ParaEdit()
virtual void linkedObjectRemoved(const char *linkname)
bool UpdateItemInAnalysis(const char *itemname, TObject *obj=0)
Definition: QGo4Widget.cpp:386
void EditObjectInSlot(TGo4Slot *slot)
Definition: QGo4Widget.cpp:357
void ShootCloseWidget(bool closeparent=false)
Definition: QGo4Widget.cpp:70
virtual void DropItem(const char *itemname, TClass *cl, int kind)
const char * GetFullName(TString &buf)
virtual void ChangedTable(int row, int col)
TObject * GetLinked(const char *linkname, int updatelevel)
Definition: QGo4Widget.cpp:177
virtual void GetFitterFromEditor()
TGo4ServerProxy * DefineServerObject(const char *itemname, TString *objname=0, Bool_t onlyanalysis=kTRUE)
virtual void ApplyClicked()
Bool_t IsVisible() const
virtual void WorkWithParameter(const char *itemname, bool isrefresh)
Bool_t CanStrEdit() const
virtual void RefreshWidget(TGo4Parameter *par)
void SetStrValue(const char *value)
const char * GetLinkedName(const char *linkname)
Definition: QGo4Widget.cpp:158
TGo4BrowserProxy * Browser()
Definition: QGo4Widget.cpp:224
TObjArray * GetMemberValues(Bool_t takeit=kFALSE)
QString fItemName
Definition: TGo4ParaEdit.h:68
virtual void linkedObjectUpdated(const char *linkname, TObject *obj)
bool BrowserItemRemote(const char *itemname)
Definition: QGo4Widget.cpp:217
void SetObject(TObject *obj, Bool_t owner)
Bool_t IsArrayItem() const
TGo4ParaEdit(QWidget *parent=0, const char *name=0)
bool fFillingTable
Definition: TGo4ParaEdit.h:69
void ServiceCall(const char *name, void *par=0)
Definition: QGo4Widget.cpp:405
void RequestObjectStatus(const char *name, TGo4Slot *tgtslot)
const char * ItemClassName(const char *name)
TObjArray * fItems
Definition: TGo4ParaEdit.h:67
virtual Bool_t CanSubmitObjects()
virtual void clearTextFields()
Bool_t SetMemberValues(TObjArray *fItems)
virtual void ExpandShrinkArray()
const char * GetObjectClass() const
const char * GetStrValue() const
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition: TGo4Slot.cxx:664
virtual void saveFile()
virtual void EditFitter()
virtual void IncArrayIndex()
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition: TGo4Slot.cxx:358
bool SaveItemToFile(const char *itemname, const char *subfolder=0)
Definition: QGo4Widget.cpp:375
void AddLink(const char *itemname, const char *linkname)
Definition: QGo4Widget.cpp:122
const char * GetTypeName() const
void SetVisible(Bool_t on=kTRUE)
virtual void TableDoubleClick(int row, int col)
virtual bool IsAcceptDrag(const char *itemname, TClass *cl, int kind)
Int_t GetMemberId() const
virtual void DecArrayIndex()
virtual void ShowVisibleItems()
virtual void RefreshClicked()
Bool_t IsFitterItem() const
virtual void ResetWidget()
virtual void ContextMenu(const QPoint &)
void GetMemberValues(TObjArray *fItems)
TGo4Slot * AddSlot(const char *slotname)
Definition: QGo4Widget.cpp:146
void CloseMDIParentSlot()
Definition: QGo4Widget.cpp:79