GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4Browser.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 "TGo4Browser.h"
15 
16 #include <iostream>
17 
18 #include <QFileDialog>
19 #include <QInputDialog>
20 #include <QTimer>
21 #include <QApplication>
22 #include <QMenu>
23 #include <QHeaderView>
24 #include <QDrag>
25 #include <QMimeData>
26 
27 #include "TClass.h"
28 #include "TClassTable.h"
29 #include "TROOT.h"
30 #include "TObjString.h"
31 #include "TCanvas.h"
32 #include "TGo4LockGuard.h"
33 #include "TGo4Slot.h"
34 #include "TGo4Iter.h"
35 #include "TGo4BrowserProxy.h"
36 #include "TGo4ServerProxy.h"
37 #include "TGo4QSettings.h"
38 #include "TGo4ViewPanel.h"
39 
40 const int ColumnWidths[TGo4Browser::NColumns] = { 150, 40, 120, 90, 60, 100, 50 };
41 const char *ColumnNames[TGo4Browser::NColumns] = { "Name", "Flags", "Info", "Date", "Time", "Class", "Size" };
42 
43 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
44 const int
45 #else
46 const Qt::Alignment
47 #endif
48  ColumnAllign[TGo4Browser::NColumns] = { Qt::AlignLeft, Qt::AlignLeft, Qt::AlignLeft, Qt::AlignLeft, Qt::AlignLeft, Qt::AlignLeft, Qt::AlignRight };
49 
50 QTreeWidgetItem* nextSibling(QTreeWidgetItem* item)
51 {
52  if (!item) return nullptr;
53 
54  QTreeWidgetItem* prnt = item->parent();
55  if (!prnt) prnt = item->treeWidget()->invisibleRootItem();
56  if (!prnt) return nullptr;
57 
58  int indx = prnt->indexOfChild(item) + 1;
59  if (indx >= prnt->childCount()) return nullptr;
60  return prnt->child(indx);
61 }
62 
63 
64 TGo4Browser::TGo4Browser(QWidget *parent, const char *name) :
65  QGo4Widget(parent,name)
66 {
67  setupUi(this);
68 
69  QObject::connect(ListView, &QGo4BrowserTreeWidget::itemDoubleClicked, this, &TGo4Browser::ListView_doubleClicked);
70  QObject::connect(ListView, &QGo4BrowserTreeWidget::customContextMenuRequested, this, &TGo4Browser::ListView_customContextMenuRequested);
71 
72  setAcceptDrops(false);
73  setCanDestroyWidget(false);
74 
75  fbUpdateTimerActive = false;
76 
77  ListView->setSortingEnabled(false);
78  ListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
79  ListView->setAcceptDrops(false);
80  ListView->viewport()->setAcceptDrops(true);
81 
82  ListView->setRootIsDecorated(false);
83 
84  // ListView->setDragEnabled(true);
85 
86  for(int indx = 0; indx < NColumns; indx++) {
87  int width = -1;
88  if ((indx == 0) || (indx == 2)) width = ColumnWidths[indx];
89  width = go4sett->getBrowserColumn(ColumnNames[indx], width);
90  fVisibleColumns[indx] = width > 0;
91 
92  ListView->headerItem()->setText(indx, ColumnNames[indx]);
93 
94  ListView->header()->setSectionHidden(indx, ! fVisibleColumns[indx]);
95  ListView->headerItem()->setTextAlignment(indx, ColumnAllign[indx]);
96 
97  ListView->header()->resizeSection(indx, width>0 ? width : ColumnWidths[indx]);
98  }
99 
100  // not in .ui file while designer brakes this connection
102 
103 // QObject::connect(ListView, &QGo4BrowserTreeWidget::ItemDropAccept, this, &TGo4Browser::ItemDropAcceptSlot);
104 
106 
107  QObject::connect(ListView->header(), &QHeaderView::sectionResized, this, &TGo4Browser::HeaderSectionResizedSlot);
108 
109  QObject::connect(ListView->header(), &QHeaderView::customContextMenuRequested, this, &TGo4Browser::Header_customContextMenuRequested);
110 
111  ListView->header()->setToolTip(
112  "You can change selected browser columns\n"
113  "by activating RMB. Flags has following meaning:\n"
114  "m - monitored,\n"
115  "s - static,\n"
116  "d - can be deleted,\n"
117  "p - protected against delete,\n"
118  "r - can not be reset (read only),\n"
119  "w - can be reset");
120 
121  ListView->setContextMenuPolicy(Qt::CustomContextMenu);
122  ListView->header()->setContextMenuPolicy(Qt::CustomContextMenu);
123 }
124 
125 
127 {
128  AddLink("","Browser");
130 }
131 
132 void TGo4Browser::linkedObjectUpdated(const char *linkname, TObject *obj)
133 {
134  if (strcmp(linkname,"Browser") == 0) {
136  } else if (strcmp(linkname,"TGo4Slot::evSubslotUpdated") == 0) {
137  TGo4Slot *itemslot = dynamic_cast<TGo4Slot *> (obj);
138  if (itemslot)
139  SetViewItemProperties(itemslot, FindItemFor(itemslot));
140  }
141 }
142 
143 
145 {
146  *res = nullptr;
147 
148  if (!ListView->currentItem()) return;
149 
150  QString fullname = FullItemName(ListView->currentItem());
151 
152  *res = new QDrag(this);
153  QMimeData *mimeData = new QMimeData;
154  mimeData->setText(fullname);
155 
156  (*res)->setMimeData(mimeData);
157 }
158 
159 void TGo4Browser::ItemDropAcceptSlot(void *item, void *d, bool* res)
160 {
161  *res = false;
162  QString tgtname = FullItemName((QTreeWidgetItem*) item);
163  const QMimeData* mime = (const QMimeData*) d;
164  if (!mime->hasText()) return;
165 
166  QString dropname = mime->text();
167 
168  TGo4Slot *tgtslot = Browser()->ItemSlot(tgtname.toLatin1().constData());
169  TGo4Slot *dropslot = Browser()->ItemSlot(dropname.toLatin1().constData());
170 
171  if (!tgtslot || !dropslot) return;
172  if (Browser()->ItemKind(tgtslot) != TGo4Access::kndFolder) return;
173 
174  if (dropslot->GetParent() == tgtslot) return;
175 
176  *res = true;
177 }
178 
179 void TGo4Browser::ItemDropProcessSlot(void *item, void *d)
180 {
181  QString tgtname = FullItemName((QTreeWidgetItem*) item);
182  const QMimeData* mime = (const QMimeData*) d;
183  if (!mime->hasText()) return;
184  Browser()->ProduceExplicitCopy(mime->text().toLatin1().constData(), tgtname.toLatin1().constData(), go4sett->getFetchDataWhenCopy());
185 }
186 
188 {
189 }
190 
192 {
193  return GetLinkedCast<TGo4BrowserProxy>("Browser");
194 }
195 
196 QString TGo4Browser::FullItemName(QTreeWidgetItem* item)
197 {
198  QString name;
199  if (item) {
200  name = item->text(0);
201  while (item->parent()) {
202  item = item->parent();
203  name = item->text(0) + "/" + name;
204  }
205  }
206  return name;
207 }
208 
209 QTreeWidgetItem* TGo4Browser::FindItemFor(TGo4Slot *slot)
210 {
212  if (!br) return nullptr;
213 
214  TString itemname;
215  if (!br->BrowserItemName(slot, itemname)) return nullptr;
216  QString iname = itemname.Data();
217 
218  QTreeWidgetItemIterator it(ListView);
219  for ( ; *it; ++it ) {
220  QString fullname = FullItemName(*it);
221  if (fullname == iname) return *it;
222  }
223  return nullptr;
224 }
225 
226 void TGo4Browser::SetViewItemProperties(TGo4Slot *itemslot, QTreeWidgetItem* item)
227 {
228  if (!itemslot || !item) return;
229 
231 
232  bool mon = br->IsItemMonitored(itemslot);
233  bool remote = br->IsItemRemote(itemslot);
234  int kind = br->ItemKind(itemslot);
235  int cando = br->ItemCanDo(itemslot);
236  const char *iteminfo = TGo4BrowserProxy::ItemInfo(itemslot);
237  const char *classname = TGo4BrowserProxy::ItemClassName(itemslot);
238 
239  bool visible = false;
240 
241  switch (br->GetItemFilter()) {
242  case 1: visible = (itemslot->GetAssignedObject() != nullptr); break;
243  case 2: visible = mon; break;
244  default: visible = true;
245  }
246 
248  item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
249  else
250  item->setFlags(item->flags() & ~Qt::ItemIsDragEnabled);
251 
252  item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
253  if (kind==TGo4Access::kndFolder) {
254  TGo4Slot *memslot = br->BrowserMemorySlot();
255  if (itemslot->IsParent(memslot) || (itemslot==memslot))
256  item->setFlags(item->flags() | Qt::ItemIsDropEnabled);
257  }
258 
259  if (visible)
260  item->setText(NColumns,"visible");
261  else
262  item->setText(NColumns,"hidden");
263 
264  // make visible all folders, where item is located
265  if (visible && (br->GetItemFilter()>0)) {
266  QTreeWidgetItem* parent = item->parent();
267  while (parent) {
268  parent->setText(NColumns, "visible");
269  parent = parent->parent();
270  }
271  }
272 
273  QString flags;
274 
275 // if (kind == TGo4Access::kndObject)
276 // if (itemslot->GetAssignedObject())
277 // flags += "c";
278 // else
279 // flags += "a";
280 
281  if (remote && (kind == TGo4Access::kndObject)) {
282  if (mon)
283  flags += "m";
284  else
285  flags += "s";
286  Int_t delprot, clearprot;
287  br->GetProtectionBits(itemslot, delprot, clearprot);
288 
289  switch (delprot) {
290  case 0: flags+="d"; break;
291  case 1: flags+="p"; break;
292  default: flags+="-"; break;
293  }
294 
295  switch (clearprot) {
296  case 0: flags+="w"; break;
297  case 1: flags+="r"; break;
298  default: flags+="-"; break;
299  }
300  }
301  item->setText(1, flags);
302  item->setText(2, iteminfo);
303  item->setText(3, br->ItemDate(itemslot));
304  item->setText(4, br->ItemTime(itemslot));
305  item->setText(5, classname);
306  QString sizelbl = "";
307  int sizeinfo = br->ItemSizeInfo(itemslot);
308  int calcsize = br->GetCalcSize(itemslot);
309  if (sizeinfo>0) sizelbl = QString::number(sizeinfo); else
310  if (calcsize>0) sizelbl = QString("= ") + QString::number(calcsize);
311  item->setText(6, sizelbl);
312 }
313 
315 {
316  TGo4LockGuard lock;
317 
318  fbUpdateTimerActive = false;
319 
320  // first update list of visible columns
321 
322  for (int indx = 0; indx < NColumns; indx++)
323  ListView->header()->setSectionHidden(indx, !fVisibleColumns[indx]);
324 
326  if (!br) return;
327 
328  ServiceCall("UpdateGuiLayout");
329 
330  TGo4Slot *topslot = br->BrowserTopSlot();
331  if (!topslot) return;
332 
333  checkVisisbilityFlags(true);
334 
335 // slot->Print("");
336 
337  QTreeWidgetItem* curfold = nullptr;
338  QTreeWidgetItem* curitem = ListView->topLevelItem(0);
339  QTreeWidgetItem* previtem = nullptr;
340 
341  TGo4Iter iter(topslot, kTRUE);
342 
343  TObjArray testedClasses;
344 
345  while (true) {
346  Bool_t res = iter.next();
347 
348  // go to top folders and remove rest items
349  Int_t levelchange = iter.levelchange();
350  while (levelchange++ < 0) {
351 
352  while (curitem) {
353  QTreeWidgetItem* next = nextSibling(curitem);
354  delete curitem;
355  curitem = next;
356  }
357 
358  if (!curfold) break;
359 
360  curitem = nextSibling(curfold);
361  previtem = curfold;
362  curfold = curfold->parent();
363  }
364 
365  if (!res) break;
366 
367  // delete all slots in folder, which has another name
368  while (curitem && (strcmp(iter.getname(), curitem->text(0).toLatin1().constData()) != 0)) {
369  QTreeWidgetItem* next = nextSibling(curitem);
370  delete curitem;
371  curitem = next;
372  }
373 
374  TGo4Slot *curslot = iter.getslot();
375  if (!curslot) {
376  std::cerr << "************* ERROR in gui slots ****************** " << std::endl;
377  return;
378  }
379 
380  const char *classname = br->ItemClassName(curslot);
381  Int_t itemkind = br->ItemKind(curslot);
382  TClass *itemclass = nullptr;
383 
384  if (classname && (strlen(classname) > 0) && (testedClasses.FindObject(classname) == nullptr)) {
385 
386  itemclass = gROOT->GetClass(classname, kFALSE);
387 
388  // if dictionary existing (library is loaded) force creation of TClass object
389  if (!itemclass && TClassTable::GetDict(classname))
390  itemclass = gROOT->LoadClass(classname);
391 
392  if (!itemclass)
393  testedClasses.Add(new TNamed(classname,""));
394  }
395 
396  TString pixmap;
397  int cando = TGo4BrowserProxy::DefineItemProperties(itemkind, itemclass, pixmap);
398  if (pixmap.Length()>0) pixmap = TString(":/icons/") + pixmap;
399  TGo4BrowserProxy::SetItemCanDo(curslot, cando);
400 
401  if (!curitem) {
402  if (!curfold)
403  curitem = new QTreeWidgetItem(ListView, previtem);
404  else
405  curitem = new QTreeWidgetItem(curfold, previtem);
406  }
407 
408  curitem->setText(0, iter.getname());
409 
410  if ((pixmap.Length()>0) && curitem->icon(0).isNull())
411  curitem->setIcon(0, QIcon(pixmap.Data()));
412 
413  if ((curitem->text(0).contains(".TGo4EventElement") && (itemkind==TGo4Access::kndTreeBranch)) ||
414  ((curitem->text(0)=="TGo4EventElement") && (itemkind==TGo4Access::kndFolder))) {
415  curitem->setHidden(go4sett->getHideTGo4EventElement());
416  }
417 
418  SetViewItemProperties(curslot, curitem);
419 
420  if (iter.isfolder()) {
421  curfold = curitem;
422  curitem = curfold->child(0);
423  previtem = nullptr;
424  } else {
425  // remove any substructures if any
426  while (curitem->child(0))
427  delete curitem->child(0);
428  previtem = curitem;
429  curitem = nextSibling(curitem);
430  }
431  }
432 
433  while (curitem) {
434  QTreeWidgetItem* next = nextSibling(curitem);
435  delete curitem;
436  curitem = next;
437  }
438 
439  if (br->GetItemFilter() > 0)
440  checkVisisbilityFlags(false);
441 
442  ListView->update();
443  ListView->viewport()->update();
444 
445  testedClasses.Delete();
446 }
447 
449 {
450  QTreeWidgetItemIterator it(ListView);
451  for ( ; *it; ++it ) {
452  QTreeWidgetItem* item = *it;
453  if (showall || !item->parent())
454  item->setHidden(false);
455  else
456  item->setHidden(item->text(NColumns)!="visible");
457  }
458 }
459 
461 {
462  int npads = 0;
463 
464  {
465  QTreeWidgetItemIterator it(ListView);
466  for ( ; *it; ++it )
467  if ((*it)->isSelected() &&
468  canDrawItem(*it)) npads++;
469  }
470 
471  if (npads == 0) return;
472 
473  TGo4ViewPanel *newpanel = CreateViewPanel(npads);
474  TPad *subpad = nullptr;
475 
476  int cnt = 0;
477  QTreeWidgetItemIterator it(ListView);
478  for ( ; *it; ++it )
479  if ( (*it)->isSelected() && canDrawItem(*it)) {
480  QString itemname = FullItemName(*it);
481 
482  subpad = newpanel->GetSubPad(newpanel->GetCanvas(), cnt++, true);
483 
484  DrawItem(itemname, newpanel, subpad, false);
485  }
486  newpanel->ShootRepaintTimer();
487 }
488 
489 
491 {
492  TGo4ViewPanel *newpanel = nullptr;
493 
494  QTreeWidgetItemIterator it(ListView);
495  for ( ; *it; ++it )
496  if ( (*it)->isSelected() && canDrawItem(*it)) {
497  if (!newpanel) {
498  newpanel = CreateViewPanel();
499  newpanel->SetPadSuperImpose(newpanel->GetCanvas(), true);
500  }
501 
502  QString itemname = FullItemName(*it);
503 
504  DrawItem(itemname, newpanel, newpanel->GetCanvas(), false);
505  }
506  if (newpanel)
507  newpanel->ShootRepaintTimer();
508 }
509 
510 void TGo4Browser::ListView_doubleClicked(QTreeWidgetItem* item, int ncol)
511 {
512  if (!item) return;
513 
514  QString fullname = FullItemName(item);
515 
517 
518  int cando = br->ItemCanDo(fullname.toLatin1().constData());
519 
520  if (go4sett->getDrawOnceFlag()) {
521  TGo4ViewPanel *panel = WhereItemDrawn(fullname.toLatin1().constData());
522 
523  QWidget *mdi = panel ? panel->parentWidget() : nullptr;
524 
525  if (mdi) {
526  if (mdi->isMinimized()) mdi->showNormal();
527  mdi->activateWindow();
528  mdi->raise();
529  mdi->show();
530  mdi->setFocus();
531  }
532 
533  if (panel) return;
534  }
535 
536  if (TGo4BrowserProxy::CanDrawItem(cando)) {
537  DrawItem(fullname, nullptr, nullptr, true);
538  } else if (TGo4BrowserProxy::CanEditItem(cando)) {
539  EditItem(fullname);
540  } else if (TGo4BrowserProxy::CanExpandItem(cando)) {
541  item->setExpanded(true);
542  ExpandItem(fullname);
543  } else if (TGo4BrowserProxy::CanExecuteItem(cando)) {
544  ExecuteItem(fullname);
545  }
546 }
547 
549 {
550  QMenu menu;
551 
552  for(int indx = 1; indx < NColumns; indx++)
553  QObject::connect(CreateChkAction(&menu, ColumnNames[indx], fVisibleColumns[indx]),
554  &QAction::toggled, [this,indx]() { ColumnToggled(indx); });
555 
556  menu.exec(ListView->header()->mapToGlobal(pos));
557 }
558 
559 
561 {
562  if (ListView->header()->logicalIndexAt(pos) != 0) {
564  return;
565  }
566 
567  QMenu menu;
568 
570  TGo4Slot *memslot = br->BrowserMemorySlot();
571  TGo4Slot *analslot = br->FindServerSlot(false, 1);
572 
573  bool istopmemory = false;
574 
575  int nitems = 0, nmemory = 0, nclose = 0, ndraw = 0, nsuperimpose = 0, si_kind = -1,
576  nremote = 0, nanalysis = 0, nmonitor = 0, nclear = 0, nclearlocal = 0, nclearproton = 0,
577  nclearprotoff = 0, ndelprotoff = 0, nobjects = 0, nfolders = 0, nedits = 0, ninfo = 0,
578  nexport = 0, ndelete = 0, nassigned = 0, nexpand = 0, nexecute = 0;
579 
580  QTreeWidgetItemIterator it(ListView);
581  for ( ; *it; ++it )
582  if ((*it)->isSelected()) {
583  QString fullname = FullItemName(*it);
584  TGo4Slot *itemslot = br->ItemSlot(fullname.toLatin1().constData());
585  if (!itemslot) continue;
586  nitems++;
587 
588  int cando = br->ItemCanDo(itemslot);
589  int kind = br->ItemKind(itemslot);
590  const char *itemclassname = br->ItemClassName(itemslot);
591 
592  bool ismemitem = itemslot->IsParent(memslot);
593 
594  if (br->IsCanDelete(itemslot) || ismemitem)
595  ndelete++;
596 
597  if (kind==TGo4Access::kndObject)
598  nobjects++;
599 
600  if (kind==TGo4Access::kndFolder)
601  nfolders++;
602 
603  if (TGo4BrowserProxy::CanExpandItem(cando)) nexpand++;
604 
605  if (TGo4BrowserProxy::CanExecuteItem(cando)) nexecute++;
606 
607  if (TGo4BrowserProxy::CanDrawItem(cando)) {
608  ndraw++;
609  TClass *cl = gROOT->GetClass(itemclassname);
610  if (cl) {
611  if (cl->InheritsFrom("TH1")) {
612  if (!cl->InheritsFrom("TH2") && !cl->InheritsFrom("TH3")) {
613  if ((si_kind < 0) || (si_kind == 1)) {
614  si_kind=1;
615  nsuperimpose++;
616  }
617  }
618  } else
619  if (cl->InheritsFrom("TGraph")) {
620  if ((si_kind<0) || (si_kind==2)) {
621  si_kind=2;
622  nsuperimpose++;
623  }
624  }
625  // JAM test for TF1:
626  else
627  if (cl->InheritsFrom("TF1")) {
628  if ((si_kind<0) || (si_kind==3)) {
629  si_kind=3;
630  nsuperimpose++;
631  }
632  }
633  }
634  }
635 
637  nedits++;
638 
640  nclose++;
641 
643  ninfo++;
644 
645  istopmemory = (itemslot==memslot);
646 
647  if (ismemitem || istopmemory)
648  nmemory++;
649 
650  if (ismemitem && TGo4BrowserProxy::CanClearItem(cando))
651  nclearlocal++;
652 
653  if ((kind==TGo4Access::kndObject) && itemslot->GetAssignedObject()) {
654  nassigned++;
656  nexport++;
657  }
658 
659  bool isanalysisitem = (itemslot==analslot) || itemslot->IsParent(analslot);
660 
661  if (isanalysisitem) nanalysis++;
662 
663  if (itemclassname && (strcmp(itemclassname,"TGo4DabcProxy") == 0)) nremote++;
664 
665  if (itemclassname && (strcmp(itemclassname,"TGo4ServerProxy") == 0)) nremote++;
666 
667  if (br->IsItemRemote(itemslot)) {
668  nremote++;
669 
670  if (isanalysisitem) {
671 
672  if (kind==TGo4Access::kndObject) {
673  Int_t delprot, clearprot;
674  br->GetProtectionBits(itemslot, delprot, clearprot);
675  if (clearprot == 1)
676  nclearproton++;
677  else if (clearprot == 0)
678  nclearprotoff++;
679  if (delprot == 0)
680  ndelprotoff++;
681  }
682 
684  nclear++;
685  }
686  }
687 
688  if (br->IsItemMonitored(itemslot)) nmonitor++;
689  }
690 
691  auto addAct = [this, &menu](const QString& iconname, const QString& text, int id, bool enabled = true, QMenu *submenu = nullptr) {
692  auto act = iconname.isEmpty() ? new QAction(text, &menu)
693  : new QAction(QIcon(QString(":/icons/") + iconname), text, &menu);
694  act->setEnabled(enabled);
695  if (submenu)
696  submenu->addAction(act);
697  else
698  menu.addAction(act);
699  QObject::connect(act, &QAction::triggered, [this, id]() { ContextMenuActivated(id); });
700  };
701 
702  addAct("chart.png", "Plot", 11, ndraw > 0);
703 
704  addAct("superimpose.png", "Superimpose", 12, (ndraw>1) && (nsuperimpose==ndraw));
705 
706  if (nexpand > 0)
707  addAct("zoomlim.png", "Expand", 28);
708 
709  if (nexecute == 1)
710  addAct("zoomlim.png", "Execute", 29);
711 
712  addAct("right.png", "Fetch item(s)", 18, (nfolders > 0) || (nobjects > 0));
713 
714  addAct("saveall.png", "Save selected...", 13, (nobjects > 0) || ((nfolders == 1) && (nitems == 1)));
715 
716  // organize export submenu
717  if (nexport > 0) {
718 
719  QMenu* expmenu = menu.addMenu(QIcon(":/icons/export.png"), "Export to");
720 
721  addAct("", "ASCII", 141, true, expmenu);
722  addAct("", "Radware", 142, true, expmenu);
723 
724  } else {
725  addAct("export.png", "Export to", 14, false);
726  }
727 
728  addAct("info.png", "Info...", 15, (ninfo > 0));
729 
730  addAct("control.png", "Edit...", 16, (nedits > 0));
731 
732  QString dellabel = "Delete item";
733  QString delbutton = "delete.png";
734  if ((nclose > 0) && (ndelete == 0)) {
735  dellabel = "Close item";
736  if (nclose > 1)
737  dellabel += "s";
738  delbutton = "close.png";
739  } else if ((nclose == 0) && (ndelete > 0)) {
740  dellabel = "Delete item";
741  if (ndelete > 1)
742  dellabel += "s";
743  } else if ((nclose > 0) && (ndelete > 0)) {
744  dellabel = "Close/delete items";
745  }
746 
747  addAct(delbutton, dellabel, 17, (nclose > 0) || (ndelete > 0));
748 
749  addAct("copyws.png", "Copy to Workspace", 19, (nobjects > 0) || ((nfolders == 1) && (nitems == 1)));
750 
751  addAct("editcopy.png", "Copy to clipboard", 20, (nobjects>0) || (nfolders>0));
752 
753  if ((nremote > 0) || (nanalysis > 0)) {
754 
755  menu.addSeparator();
756 
757  addAct("monitor.png", "Monitor item(s)", 21, ((nobjects>0) && (nremote>0) && (nmonitor<nremote)) || ((nfolders==1) && (nitems==1)));
758 
759  addAct("Stop.png", "Stop item(s) monitoring", 22, ((nobjects>0) && (nremote>0) && (nmonitor>0)) || ((nfolders==1) && (nitems==1)));
760 
761  addAct("clear.png", "Clear (Reset to 0)", 23, (nclear > 0));
762 
763  addAct("clear_nok.png", "Set Clear protection", 24, (nclearprotoff > 0));
764 
765  addAct("clear_ok.png", "Unset Clear protection", 25, (nclearproton > 0));
766 
767  addAct("delete.png", "Delete from analysis", 26, (ndelprotoff > 0));
768 
769  addAct("refresh.png", "Refresh namelist", 27);
770  }
771 
772  if ((nmemory > 0) && (nmemory == nitems)) {
773  menu.addSeparator();
774 
775  addAct("crefolder.png", "Create folder", 41, (nmemory==1) && (nfolders==1));
776 
777  addAct("rename.png", "Rename object", 42, (nmemory==1) && !istopmemory);
778 
779  addAct("clear.png", "Clear object(s)", 44, (nclearlocal > 0));
780 
781  addAct(":/icons/editpaste.png", "Paste from clipboard", 43, br->IsClipboard() && (nmemory==1) && (nfolders==1));
782  }
783 
784  menu.exec(ListView->viewport()->mapToGlobal(pos));
785 }
786 
788 {
789  if ((indx <= 0) || (indx >= NColumns)) return;
790  fVisibleColumns[indx] = !fVisibleColumns[indx];
791 
792  HeaderSectionResizedSlot(0, 0, 0);
793 
795 }
796 
798 {
799  int ncolumn = 0;
800  for (int indx = 0; indx < NColumns; indx++) {
801  int width = -1;
802  if (fVisibleColumns[indx]) {
803  width = ListView->columnWidth(ncolumn++);
804  if (width == 0) width = ColumnWidths[indx];
805  }
806  go4sett->setBrowserColumn(ColumnNames[indx], width);
807  }
808 }
809 
811 {
812  switch (id) {
813  case 11: DisplaySelectedItems(); return;
814  case 12: SuperImposeSelectedItems(); return;
815  case 13: SaveSelectedItems(); return;
816  case 141: ExportSelectedItems("ASCII format"); return;
817  case 142: ExportSelectedItems("Radware format"); return;
818  }
819 
821 
822  TGo4ServerProxy *anrefresh = nullptr;
823  TGo4ServerProxy *servrefresh = nullptr;
824 
825  if (id == 20) br->ClearClipboard();
826 
827  if (id == 19)
828  QApplication::setOverrideCursor(Qt::WaitCursor);
829 
830  QTreeWidgetItemIterator it(ListView);
831  for ( ; *it; ++it )
832  if ((*it)->isSelected()) {
833  QString itemname = FullItemName(*it);
834  TGo4Slot *itemslot = br->ItemSlot(itemname.toLatin1().constData());
835  if (!itemslot) continue;
836  int cando = br->ItemCanDo(itemslot);
837  int kind = br->ItemKind(itemslot);
838 
839  switch(id) {
840  case 15: {
841  if (TGo4BrowserProxy::CanInfoItem(cando)) {
842  ShowItemInfo(itemname);
843  return;
844  }
845  break;
846  }
847 
848  case 16: {
849  if (TGo4BrowserProxy::CanEditItem(cando)) {
850  EditItem(itemname);
851  return;
852  }
853  break;
854  }
855 
856  case 17: {
857  br->DeleteDataSource(itemslot);
858  break;
859  }
860 
861  case 18: { // fetch item from the data source
862  br->FetchItem(itemname.toLatin1().constData());
863  break;
864  }
865 
866  case 19: {
867  br->ProduceExplicitCopy(itemname.toLatin1().constData(), nullptr, go4sett->getFetchDataWhenCopy());
868  break;
869  }
870 
871  case 20: {
872  br->AddToClipboard(itemname.toLatin1().constData());
873  break;
874  }
875 
876  case 21: // toggle monitor on
877  case 22: { // toggle monitor off
878  br->SetItemMonitored(itemslot, id==21);
880  break;
881  }
882 
883  case 23: { // clear
884  TString objname;
885  TGo4ServerProxy *an = br->DefineAnalysisObject(itemname.toLatin1().constData(), objname);
886  if (an) {
887  an->ClearAnalysisObject(objname.Data());
888  // if clear folder, request all objects which were requested before
889  if (kind==TGo4Access::kndFolder) {
890  TGo4Iter iter(itemslot, kTRUE);
891  while (iter.next()) {
892  TGo4Slot *subslot = iter.getslot();
893  if (subslot->GetAssignedObject())
894  subslot->Update(kFALSE);
895  }
896  } else
897  if (itemslot->GetAssignedObject())
898  itemslot->Update(kFALSE);
899  }
900  break;
901  }
902 
903  case 24: // set clear protect
904  case 25: { // unset clear protect
905  TString objname;
906  TGo4ServerProxy *an = br->DefineAnalysisObject(itemname.toLatin1().constData(), objname);
907  if (an) {
908  an->ChageObjectProtection(objname.Data(), (id == 24 ? "+C" : "-C"));
909  anrefresh = an;
910  }
911  break;
912  }
913 
914  case 26: { // delete remote object
915  TString objname;
916  TGo4ServerProxy *an = br->DefineAnalysisObject(itemname.toLatin1().constData(), objname);
917  if (an) {
918  an->RemoveObjectFromAnalysis(objname.Data());
919  anrefresh = an;
920  }
921  break;
922  }
923 
924  case 27: { // refresh
925  TString objname;
926  TGo4ServerProxy *an = br->DefineAnalysisObject(itemname.toLatin1().constData(), objname);
927  if (an) anrefresh = an;
928  TGo4ServerProxy *serv = br->DefineServerProxy(itemname.toLatin1().constData());
929  if (serv) servrefresh = serv;
930  break;
931  }
932 
933  case 28: { // expand
934  if (TGo4BrowserProxy::CanExpandItem(cando)) {
935  (*it)->setExpanded(true);
936  ExpandItem(itemname);
937  }
938  break;
939  }
940 
941  case 29: { // execute
943  ExecuteItem(itemname);
944  break;
945  }
946 
947  case 41: { // create folder in memory
948  bool ok = false;
949  QString folder =
950  QInputDialog::getText(this,
951  "Create folder in workspace",
952  "Input folder name",
953  QLineEdit::Normal,
954  QString(),
955  &ok);
956  if (ok) br->CreateMemorySubfolder(itemname.toLatin1().constData(), folder.toLatin1().constData());
957  break;
958  }
959 
960  case 42: { // rename memory item
961  bool ok = false;
962  QString shortitemname=itemname.section("/",-1);
963  QString newname =
964  QInputDialog::getText(this,
965  "Rename item in workspace",
966  "Input new item name",
967  QLineEdit::Normal,
968  shortitemname,
969  &ok);
970  if (ok) br->RenameMemoryItem(itemname.toLatin1().constData(), newname.toLatin1().constData());
971  break;
972  }
973 
974  case 43: { // paste items from clipboard
975  br->CopyClipboard(itemname.toLatin1().constData(), go4sett->getFetchDataWhenCopy());
976  br->ClearClipboard();
977  break;
978  }
979 
980  case 44: { // clear memory item
981  br->ClearMemoryItem(itemname.toLatin1().constData());
982  break;
983  }
984  }
985  }
986 
987  if (anrefresh)
988  anrefresh->RefreshNamesList();
989 
990  if (servrefresh)
991  servrefresh->RefreshNamesList();
992 
993  if (id == 19)
994  QApplication::restoreOverrideCursor();
995 }
996 
997 bool TGo4Browser::canDrawItem(QTreeWidgetItem* item)
998 {
999  if (!item) return false;
1000  int cando = BrowserProxy()->ItemCanDo(FullItemName(item).toLatin1().constData());
1001  return TGo4BrowserProxy::CanDrawItem(cando);
1002 }
1003 
1005 {
1006  if (fbUpdateTimerActive) return;
1007 
1008  fbUpdateTimerActive = true;
1009 
1010  QTimer::singleShot(1, this, &TGo4Browser::updateListViewItems);
1011 }
1012 
1014 {
1015  QFileDialog fd(this, "Save selected objects to file", QString(),
1016  "ROOT (*.root);;ROOT XML (*.xml)");
1017  fd.setFileMode( QFileDialog::AnyFile);
1018  fd.setAcceptMode(QFileDialog::AcceptSave);
1019 
1020  if (fd.exec() != QDialog::Accepted) return;
1021 
1022  QStringList flst = fd.selectedFiles();
1023  if (flst.isEmpty()) return;
1024 
1025  QString fname = flst[0];
1026  QString title;
1027 
1028  if (fd.selectedNameFilter() == "ROOT (*.root)") {
1029  bool ok = false;
1030  title = QInputDialog::getText(this,
1031  "Save slected objects to file", "Provide file title",
1032  QLineEdit::Normal, QString(), &ok);
1033  if (!ok) return;
1034  if (fname.indexOf(".root", 0, Qt::CaseInsensitive)<0) fname+=".root";
1035  } else {
1036  if (fname.indexOf(".xml", 0, Qt::CaseInsensitive)<0) fname+=".xml";
1037  }
1038 
1039  ExportSelectedItems(fname.toLatin1().constData(),
1040  QFileInfo(fname).absolutePath().toLatin1().constData(),
1041  fd.selectedNameFilter().toLatin1().constData(),
1042  title.toLatin1().constData());
1043 }
1044 
1045 void TGo4Browser::ExportSelectedItems(const char *filtername)
1046 {
1047  QFileDialog fd(this, QString("Select directory to export to ") + filtername);
1048  fd.setOption(QFileDialog::ShowDirsOnly, true);
1049 
1050  if (fd.exec() != QDialog::Accepted) return;
1051 
1052  QStringList flst = fd.selectedFiles();
1053  if (flst.isEmpty()) return;
1054 
1055  ExportSelectedItems("null",
1056  flst[0].toLatin1().constData(),
1057  filtername,
1058  "Export of selected items");
1059 }
1060 
1061 void TGo4Browser::ExportSelectedItems(const char *filename, const char *filedir, const char *format, const char *description)
1062 {
1063  TObjArray items;
1064  QTreeWidgetItemIterator it(ListView);
1065  for ( ; *it; ++it )
1066  if ((*it)->isSelected()) {
1067  QString fullname = FullItemName(*it);
1068  items.Add(new TObjString(fullname.toLatin1().constData()));
1069  }
1070 
1071  BrowserProxy()->ExportItemsTo(&items, go4sett->getFetchDataWhenSave(), filename, filedir, format, description);
1072 
1073  items.Delete();
1074 }
1075 
1076 void TGo4Browser::ExpandItem(const QString& itemname)
1077 {
1078  BrowserProxy()->GetBrowserObject(itemname.toLatin1().constData(), 100);
1079 }
1080 
1081 void TGo4Browser::ExecuteItem(const QString& itemname)
1082 {
1083  TString objname, arg1, arg2, arg3;
1084 
1085  TGo4ServerProxy *serv = BrowserProxy()->DefineServerObject(itemname.toLatin1().constData(), &objname, kFALSE);
1086 
1087  if (!serv || objname.IsNull()) return;
1088 
1089  Int_t nargs = serv->NumCommandArgs(objname);
1090  if (nargs < 0) return;
1091 
1092  for (Int_t n = 0; n < nargs; n++) {
1093  bool ok = false;
1094  QString value =
1095  QInputDialog::getText(nullptr, "Input command arguments",
1096  QString("Arg%1:").arg(n+1), QLineEdit::Normal, "", &ok);
1097  if (!ok) return;
1098  if (n == 0)
1099  arg1 = value.toLatin1().constData();
1100  else if (n == 1)
1101  arg2 = value.toLatin1().constData();
1102  else if (n == 2)
1103  arg3 = value.toLatin1().constData();
1104  }
1105 
1106  Bool_t res = serv->SubmitCommand(objname, 3, (arg1.Length() > 0 ? arg1.Data() : nullptr), (arg2.Length() > 0 ? arg2.Data() : nullptr), (arg3.Length() > 0 ? arg3.Data() : nullptr));
1107 
1108  StatusMessage(QString(" Command execution:") + objname + QString(" result = ") + (res ? "TRUE" : "FALSE"));
1109 }
static bool CanClearItem(int cando)
virtual void ShootRepaintTimer()
void SuperImposeSelectedItems()
void ItemDropProcess(void *, void *)
void ExecuteItem(const QString &itemname)
void ContextMenuActivated(int id)
Bool_t IsParent(const TGo4Slot *slot) const
Definition: TGo4Slot.cxx:178
void ListView_doubleClicked(QTreeWidgetItem *item, int ncol)
bool getDrawOnceFlag()
TObject * GetBrowserObject(const char *name, Int_t update=0)
virtual void ChageObjectProtection(const char *fullpath, const char *flags)
void ExportItemsTo(TObjArray *items, Bool_t fetchitems, const char *filename, const char *filedir, const char *format, const char *description)
TGo4ServerProxy * DefineServerObject(const char *itemname, TString *objname=nullptr, Bool_t onlyanalysis=kTRUE)
Bool_t IsItemMonitored(TGo4Slot *slot) const
Int_t ItemKind(const char *name)
bool getFetchDataWhenCopy()
Bool_t isfolder()
Definition: TGo4Iter.cxx:109
virtual Int_t NumCommandArgs(const char *name)
Bool_t IsItemRemote(const char *name)
void SaveSelectedItems()
static bool CanDrawItem(int cando)
virtual void RemoveObjectFromAnalysis(const char *fullpath)
void ColumnToggled(int indx)
void RenameMemoryItem(const char *itemname, const char *newname)
Int_t ItemCanDo(const char *name)
void checkVisisbilityFlags(bool showall)
const Qt::Alignment ColumnAllign[TGo4Browser::NColumns]
Definition: TGo4Browser.cpp:48
Bool_t DeleteDataSource(TGo4Slot *itemslot)
void ServiceCall(const char *name, void *par=nullptr)
Definition: QGo4Widget.cpp:398
void setCanDestroyWidget(bool on=true)
Definition: QGo4Widget.h:201
static bool CanExecuteItem(int cando)
void ShootUpdateTimer()
static bool CanExpandItem(int cando)
const char * ColumnNames[TGo4Browser::NColumns]
Definition: TGo4Browser.cpp:41
void DisplaySelectedItems()
virtual Bool_t RefreshNamesList()
TGo4ViewPanel * DrawItem(const QString &itemname, TGo4ViewPanel *panel=nullptr, TPad *pad=nullptr, bool activate=true, int updatelevel=-1)
Definition: QGo4Widget.cpp:305
TGo4Slot * FindServerSlot(Bool_t databranch, Int_t kind=0)
TGo4BrowserProxy * Browser()
Definition: QGo4Widget.cpp:219
void EditItem(const QString &itemname)
Definition: QGo4Widget.cpp:345
void CreateMemorySubfolder(const char *itemname, const char *newfoldername)
TGo4Browser(QWidget *parent=nullptr, const char *name=nullptr)
Definition: TGo4Browser.cpp:64
TGo4Slot * getslot() const
Definition: TGo4Iter.cxx:166
virtual Bool_t SubmitCommand(const char *name, Int_t waitres=-1, const char *arg1=nullptr, const char *arg2=nullptr, const char *arg3=nullptr)
QTreeWidgetItem * nextSibling(QTreeWidgetItem *item)
Definition: TGo4Browser.cpp:50
virtual void ClearAnalysisObject(const char *fullpath)
TGo4ViewPanel * CreateViewPanel(int ndiv=0)
Definition: QGo4Widget.cpp:297
void updateListViewItems()
static const char * ItemInfo(TGo4Slot *slot)
static bool CanDragItem(int cando)
TObject * GetAssignedObject()
Definition: TGo4Slot.cxx:356
virtual TPad * GetSubPad(TPad *toppad, int num, bool onlytoplevel)
void CopyClipboard(const char *tgtpath, Bool_t forcerequest=kFALSE)
static bool CanExportItem(int cando)
void ShowItemInfo(const QString &itemname)
Definition: QGo4Widget.cpp:292
void StatusMessage(const QString &message)
Definition: QGo4Widget.cpp:239
void SetViewItemProperties(TGo4Slot *itemslot, QTreeWidgetItem *item)
bool canDrawItem(QTreeWidgetItem *item)
TGo4Slot * GetParent() const
Definition: TGo4Slot.h:58
void setBrowserColumn(const char *name, int width)
Bool_t IsClipboard() const
void ItemDropAcceptSlot(void *item, void *mime, bool *res)
void HeaderSectionResizedSlot(int, int, int)
void ClearMemoryItem(const char *itemname)
Int_t ItemSizeInfo(TGo4Slot *slot)
virtual void Update(Bool_t strong=kFALSE)
Definition: TGo4Slot.cxx:361
static const char * ItemDate(TGo4Slot *slot)
QString FullItemName(QTreeWidgetItem *item)
void ResetWidget() override
Bool_t IsCanDelete(TGo4Slot *slot) const
void RequestDragObject(QDrag **)
void StartWorking()
TGo4QSettings * go4sett
const char * ItemClassName(const char *name)
bool getFetchDataWhenSave()
void AddToClipboard(const char *itemname)
const char * getname()
Definition: TGo4Iter.cxx:115
static QAction * CreateChkAction(QMenu *menu, const QString &text, bool checked, bool enabled=true)
Definition: QGo4Widget.cpp:403
void FetchItem(const char *itemname, Int_t wait_time=0)
Int_t GetCalcSize(TGo4Slot *slot)
void SetItemMonitored(TGo4Slot *slot, Bool_t on=kTRUE)
TGo4Slot * BrowserMemorySlot()
void ItemDropProcessSlot(void *item, void *e)
void ExpandItem(const QString &itemname)
bool fVisibleColumns[NColumns]
Definition: TGo4Browser.h:91
static bool CanCloseItem(int cando)
void GetProtectionBits(TGo4Slot *slot, Int_t &delprot, Int_t &clearprot)
TGo4ServerProxy * DefineServerProxy(const char *itemname)
static void SetItemCanDo(TGo4Slot *slot, Int_t cando)
void Header_customContextMenuRequested(const QPoint &)
void ListView_customContextMenuRequested(const QPoint &)
const int ColumnWidths[TGo4Browser::NColumns]
Definition: TGo4Browser.cpp:40
TGo4ViewPanel * WhereItemDrawn(const char *itemname)
Definition: QGo4Widget.cpp:316
TGo4Slot * BrowserTopSlot()
virtual void SetPadSuperImpose(TPad *pad, bool on)
void ExportSelectedItems(const char *filtername)
void RequestDragObjectSlot(QDrag **)
static bool CanInfoItem(int cando)
QTreeWidgetItem * FindItemFor(TGo4Slot *slot)
TGo4ServerProxy * DefineAnalysisObject(const char *itemname, TString &analysisname)
void AddLink(const char *itemname, const char *linkname)
Definition: QGo4Widget.cpp:117
int getBrowserColumn(const char *name, int defwidth)
Bool_t ProduceExplicitCopy(const char *itemname, const char *tgtpath=nullptr, Bool_t forcerequest=kFALSE)
bool getHideTGo4EventElement()
static const char * ItemTime(TGo4Slot *slot)
virtual TCanvas * GetCanvas()
TGo4BrowserProxy * BrowserProxy()
void linkedObjectUpdated(const char *linkname, TObject *obj) override
static bool CanEditItem(int cando)
Bool_t BrowserItemName(TGo4Slot *itemslot, TString &res)
TGo4Slot * ItemSlot(const char *itemname)
static Int_t DefineItemProperties(Int_t kind, TClass *cl, TString &pixmap)
bool fbUpdateTimerActive
Definition: TGo4Browser.h:90
Bool_t next(Bool_t goesinto=kTRUE)
Definition: TGo4Iter.cxx:44
Int_t levelchange() const
Definition: TGo4Iter.h:41
Int_t GetItemFilter() const