GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4ViewPanel.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 // JAM2016: activate this for global ROOT "escape mode" before redraw (NOT RECOMMENDED)
15 // otherwise, escape mode will reset global arrays of TGraph painter class only
16 //#define GLOBALESCAPE 1
17 
18 #include "TGo4ViewPanel.h"
19 
20 #include "TF1.h"
21 #include "TH1.h"
22 #include "TH2.h"
23 #include "TVirtualX.h"
24 #include "THStack.h"
25 #include "TGraph.h"
26 #include "TMultiGraph.h"
27 #include "TColor.h"
28 #include "TCanvas.h"
29 #include "TFrame.h"
30 #include "TArrayD.h"
31 #include "TCutG.h"
32 #include "TArrow.h"
33 #include "TList.h"
34 #include "TLatex.h"
35 #include "TPaveStats.h"
36 #include "TPaveLabel.h"
37 #include "TLegend.h"
38 #include "TStyle.h"
39 #include "TROOT.h"
40 #include "TMath.h"
41 #include "TClass.h"
42 #include "TSystem.h"
43 #include "TCanvasImp.h"
44 
45 #include <QMenu>
46 #include <QMenuBar>
47 #include <QStatusBar>
48 #include <QFileDialog>
49 #include <QTimer>
50 #include <QInputDialog>
51 #include <QTime>
52 #include <QtCore/QSignalMapper>
53 #include <QDropEvent>
54 
55 #ifdef __GO4X11__
56 #include "QRootCanvas.h"
57 #endif
58 #ifdef __GO4WEB__
59 #include "QWebCanvas.h"
60 #endif
61 
62 //#include "QRootApplication.h"
63 
64 #include "TGo4Log.h"
65 #include "TGo4Picture.h"
66 #include "TGo4Fitter.h"
67 #include "TGo4Marker.h"
68 #include "TGo4WinCond.h"
69 #include "TGo4PolyCond.h"
70 #include "TGo4CondArray.h"
71 #include "TGo4WinCondView.h"
72 #include "TGo4PolyCondView.h"
73 #include "TGo4LockGuard.h"
74 #include "TGo4MdiArea.h"
75 #include "TGo4ASImage.h"
76 #include "TGo4PrintWidget.h"
77 #include "TGo4Slot.h"
78 #include "TGo4ObjectProxy.h"
79 #include "TGo4LinkProxy.h"
80 #include "TGo4DrawObjProxy.h"
81 #include "TGo4DrawCloneProxy.h"
82 #include "TGo4Iter.h"
83 #include "TGo4BrowserProxy.h"
84 #include "TGo4QSettings.h"
85 
86 const char *NoStackDrawOption = "nostack, ";
87 
88 class TPadGuard {
89  TVirtualPad *fSave;
90 public:
91 
92  TPadGuard(TVirtualPad *repl = nullptr)
93  {
94  fSave = gPad;
95  gPad = repl;
96  }
97 
99  {
100  gPad = fSave;
101  }
102 };
103 
104 
105 TGo4ViewPanel::TGo4ViewPanel(QWidget *parent, const char *name) :
106  QGo4Widget(parent, name)
107 {
108  setupUi(this);
109 
110  QObject::connect(CursorB, &QCheckBox::toggled, this, &TGo4ViewPanel::SetCursorMode);
111  QObject::connect(RegionB, &QCheckBox::toggled, this, &TGo4ViewPanel::SetRegionMode);
112  QObject::connect(FreezeMode, &QCheckBox::toggled, this, &TGo4ViewPanel::SetFreezeMouseMode);
113  QObject::connect(LatexB, &QCheckBox::toggled, this, &TGo4ViewPanel::SetLateXMode);
114  QObject::connect(DrawB, &QCheckBox::toggled, this, &TGo4ViewPanel::SetDrawingMode);
115  QObject::connect(PrintLogB, &QPushButton::pressed, this, &TGo4ViewPanel::LogMarkerValues);
116  QObject::connect(PolyB, &QCheckBox::toggled, this, &TGo4ViewPanel::SetPolygonMode);
117  QObject::connect(SelectedMarkerCmb, QOverload<int>::of(&QComboBox::activated), this, &TGo4ViewPanel::SelectedMarkerCmb_activated);
118  QObject::connect(DelSelectedMarker, &QPushButton::clicked, this, &TGo4ViewPanel::DelSelectedMarker_clicked);
119  QObject::connect(GetConditionBtn, &QPushButton::clicked, this, &TGo4ViewPanel::GetConditionBtn_clicked);
120  QObject::connect(InfoConditionBtn, &QPushButton::clicked, this, &TGo4ViewPanel::InfoConditionBtn_clicked);
121  QObject::connect(EditConditionBtn, &QPushButton::clicked, this, &TGo4ViewPanel::EditConditionBtn_clicked);
122  QObject::connect(SetConditionBtn, &QPushButton::clicked, this, &TGo4ViewPanel::SetConditionBtn_clicked);
123 
124  // TODO: viewpanel does not closed when press close button
125  setAttribute(Qt::WA_DeleteOnClose);
126 
127  fPanelName = objectName();
128 
129  fxActivePad = nullptr;
130 
132  fxRepaintTimerPad = nullptr;
133  fxResizeTimerPad = nullptr;
134  fxDoubleClickTimerPad = nullptr;
135  fbFreezeTitle = false;
136  fFreezedTitle = "";
137  fbApplyToAllFlag = false;
138  fbAutoZoomFlag = false;
139  fbCanvasCrosshair = false;
140 
141  fbCloneFlag = true;
142  fbModifiedSignalFlag = false;
143  fbLeaveFocusAfterCondEnd = false;
144 
145  // setup of marker editor
146  fbMarkEditorVisible = false;
147  fbTypingMode = true;
148  MarkerPanel->setVisible(false);
150  fiPickCounter = 0;
151  fbPickAgain = false;
152 
153  setWindowTitle(GetPanelName());
154 
155  QSizePolicy sizePolicy3(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(7));
156  sizePolicy3.setHorizontalStretch(0);
157  sizePolicy3.setVerticalStretch(20);
158 
159  fxQCanvas = nullptr;
160  fxWCanvas = nullptr;
161 
162  CanvasStatus = nullptr;
163 
164 #ifdef __GO4WEB__
165  if (go4sett->getWebBasedCanvas()) {
166  fxWCanvas = new QWebCanvas(this);
167 
168  fxWCanvas->setMinimumSize(QSize(50, 50));
169  sizePolicy3.setHeightForWidth(fxWCanvas->sizePolicy().hasHeightForWidth());
170  fxWCanvas->setSizePolicy(sizePolicy3);
171 
172  fxGridLayout->addWidget(fxWCanvas, 1, 1, 1, 1);
173 
174  fxWCanvas->setObjectName(GetPanelName());
175  fxWCanvas->getCanvas()->SetName(GetPanelName());
176  }
177 #endif
178 
179 #ifdef __GO4X11__
180  if (!fxWCanvas) {
181  fxQCanvas = new QRootCanvas(this);
182  // fxQCanvas->setObjectName(QStringLiteral("fxQCanvas"));
183  fxQCanvas->setMinimumSize(QSize(50, 50));
184  sizePolicy3.setHeightForWidth(fxQCanvas->sizePolicy().hasHeightForWidth());
185  fxQCanvas->setSizePolicy(sizePolicy3);
186 
187  fxGridLayout->addWidget(fxQCanvas, 1, 1, 1, 1);
188 
189  fxQCanvas->setObjectName(GetPanelName());
190  fxQCanvas->getCanvas()->SetName(GetPanelName());
191  fxQCanvas->setEditorFrame(EditorFrame);
192  }
193 #endif
194 
195 // printf("Resize x %d y %d\n", go4sett->lastPanelSize().width(), go4sett->lastPanelSize().height());
196 // resize(go4sett->lastPanelSize());
197 
198  fSelectMenu = nullptr;
199  fSelectMap = nullptr;
200 
201  fMenuBar = new QMenuBar(MenuFrame);
202  fMenuBar->setMinimumWidth(50);
203  fMenuBar->setNativeMenuBar(kFALSE); // disable putting this to screen menu. for MAC style WMs
204 
205  QMenu* fileMenu = fMenuBar->addMenu("F&ile");
206  fileMenu->addAction("&Save as...", this, &TGo4ViewPanel::SaveCanvas);
207  fileMenu->addAction("Print...", this, &TGo4ViewPanel::PrintCanvas);
208  fileMenu->addAction("Produce &Picture", this, &TGo4ViewPanel::ProducePicture);
209  fileMenu->addAction("Produce &Graph from markers", this, &TGo4ViewPanel::ProduceGraphFromMarkers);
210 
211 // fileMenu->addAction("Copy to T&Canvas in Memory", this, &TGo4ViewPanel::SendToBrowser);
212 // fileMenu->addAction("&Load marker setup...", this, &TGo4ViewPanel::LoadMarkers);
213 // fileMenu->addAction("Save &marker setup...", this, &TGo4ViewPanel::SaveMarkers);
214  fileMenu->addAction("Cl&ose", this, &TGo4ViewPanel::ClosePanel);
215 
216  //Edit Menu
217  QMenu* editMenu = fMenuBar->addMenu("&Edit");
218 
219  QObject::connect(CreateChkAction(editMenu, "Show marker &editor", fbMarkEditorVisible),
220  &QAction::toggled, this, &TGo4ViewPanel::SetMarkerPanel);
221 
222  bool ed_visible = false, ed_allowed = true;
223 
224 #ifdef __GO4X11__
225  if (fxQCanvas) {
226  ed_visible = fxQCanvas->isEditorVisible();
227  ed_allowed = fxQCanvas->isEditorAllowed();
228  }
229 #endif
230 
231  fxCanvasEditorChk = CreateChkAction(editMenu, "Show &ROOT attributes editor", ed_visible, ed_allowed);
232  QObject::connect(fxCanvasEditorChk, &QAction::toggled, this, &TGo4ViewPanel::StartRootEditor);
233 
234  bool status_flag = go4sett->getPadEventStatus();
235  fxCanvasEventstatusChk = CreateChkAction(editMenu, "Show &event status", status_flag);
236  QObject::connect(fxCanvasEventstatusChk, &QAction::toggled, this, &TGo4ViewPanel::ShowEventStatus);
237 
238  editMenu->addAction("Start &condition editor", this, &TGo4ViewPanel::StartConditionEditor);
239 
240  editMenu->addSeparator();
241  editMenu->addAction("Clear &markers", this, &TGo4ViewPanel::ClearAllMarkers);
242  editMenu->addAction("Clear &pad", this, &TGo4ViewPanel::ClearActivePad);
243  editMenu->addAction("Clear c&anvas", this, &TGo4ViewPanel::ClearCanvas);
244 
245  fSelectMap = new QSignalMapper(this);
246  fSelectMenu = fMenuBar->addMenu("&Select");
247 
248  fOptionsMap = new QSignalMapper(this);
249  fOptionsMenu = fMenuBar->addMenu("&Options");
250  QObject::connect(fOptionsMenu, &QMenu::aboutToShow, this, &TGo4ViewPanel::AboutToShowOptionsMenu);
251 
252 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
253  auto signal = QOverload<int>::of(&QSignalMapper::mapped);
254 #else
255  auto signal = &QSignalMapper::mappedInt;
256 #endif
257 
258  QObject::connect(fSelectMap, signal, this, &TGo4ViewPanel::SelectMenuItemActivated);
259  QObject::connect(fOptionsMap, signal, this, &TGo4ViewPanel::OptionsMenuItemActivated);
260 
264  AddIdAction(fOptionsMenu, fOptionsMap, "Histogram &Statistics", StatisticsId);
265  AddIdAction(fOptionsMenu, fOptionsMap, "Multiplot &Legend", SetLegendId);
266 
267  fOptionsMenu->addSeparator();
268  AddIdAction(fOptionsMenu, fOptionsMap, "Histogram &Title", SetTitleId);
271  AddIdAction(fOptionsMenu, fOptionsMap, "Draw item name", DrawItemnameId);
272  fOptionsMenu->addSeparator();
273  AddIdAction(fOptionsMenu, fOptionsMap, "&1:1 Coordinate ratio", SetXYRatioOneId);
274  fOptionsMenu->addSeparator();
275  AddIdAction(fOptionsMenu, fOptionsMap, "&X-Axis displays time", AxisTimeDisplayId);
276  AddIdAction(fOptionsMenu, fOptionsMap, "Set X-Axis time format...", SetTimeFormatId);
277  fOptionsMenu->addSeparator();
278  AddIdAction(fOptionsMenu, fOptionsMap, "&Keep Viewpanel Title", FreezeTitleId);
279  AddIdAction(fOptionsMenu, fOptionsMap, "Set &Viewpanel Title...", SetTitleTextId);
280 
281  QCheckBox* box1 = new QCheckBox("Apply to all", MenuFrame);
282  box1->setObjectName("ApplyToAllCheck");
283  QObject::connect(box1, &QCheckBox::toggled, this, &TGo4ViewPanel::ApplyToAllToggled);
284 
285  fAutoScaleCheck = new QCheckBox("AutoScale", MenuFrame);
286  fAutoScaleCheck->setObjectName("AutoScaleCheck");
287  QObject::connect(fAutoScaleCheck, &QCheckBox::toggled, this, &TGo4ViewPanel::AutoScaleToggled);
288 
289  QHBoxLayout* menugrid = new QHBoxLayout(nullptr/*MenuFrame*/);
290  menugrid->setContentsMargins(0,0,0,0);
291  menugrid->setSpacing(0);
292  menugrid->addWidget(fMenuBar, 10, Qt::AlignLeft);
293  menugrid->addWidget(box1, 1, Qt::AlignRight);
294  menugrid->addWidget(fAutoScaleCheck, 1, Qt::AlignRight);
295 
296  fxGridLayout->addLayout(menugrid, 0, 0, 1, 2);
297 
298  // status widget
299 
300  if (fxWCanvas) {
301  // TODO: one can get status from webcanvas here
302 #ifdef __GO4WEB__
303  fxWCanvas->setStatusBarVisible(status_flag);
304 
310 
311 #endif
312  } else {
313 #ifdef __GO4X11__
314  CanvasStatus = new QStatusBar(this);
315  fxGridLayout->addWidget(CanvasStatus, 3, 0, 1, 2);
316  CanvasStatus->setVisible(false);
318  fxQCanvas->setStatusBarVisible(status_flag);
319 
327 #endif
328  }
329 }
330 
332 {
333  TGo4LockGuard lock;
334 
335  // we should delete all markers first, while they
336  // have internal reference on the pad, which will be
337  // deleted by the net canvas->Clear() call
339 
341 
342  GetCanvas()->Clear();
343 
344  fxRepaintTimerPad = nullptr;
345 
347 
348  if (gPad)
349  if (IsPanelPad((TPad *)gPad)) {
350  gPad = nullptr;
351  }
352 
353  if (gROOT->GetSelectedPad())
354  if (IsPanelPad((TPad *) gROOT->GetSelectedPad()))
355  gROOT->SetSelectedPad(nullptr);
356 }
357 
359 {
360  fbaPanelName = fPanelName.toLatin1();
361  return fbaPanelName.constData();
362 }
363 
364 void TGo4ViewPanel::SetPanelName(const char *newname)
365 {
366  fPanelName = newname;
367 }
368 
370 {
371  return GetTopSlot(true);
372 }
373 
374 TGo4Slot *TGo4ViewPanel::AddNewSlot(const char *name, TGo4Slot *parent)
375 {
376  if (!parent)
377  parent = GetPanelSlot();
378  return new TGo4Slot(parent, name, "title");
379 }
380 
382 {
383  // do nothing
384 }
385 
386 void TGo4ViewPanel::linkedObjectUpdated(const char *linkname, TObject *obj)
387 {
388  if (!linkname)
389  return;
390 
391  if (strcmp(linkname, "PadRangeAxisChanged") == 0) {
393  } else if (strcmp(linkname, "PadModified") == 0) {
394  if (IsRedrawBlocked())
395  return;
397  QTimer::singleShot(1, this, &TGo4ViewPanel::ProcessPadModifiedSignal);
398  fbModifiedSignalFlag = true;
399  }
400 }
401 
402 void TGo4ViewPanel::linkedUpdated(TGo4Slot *slot, TObject *obj)
403 {
404  if (!slot)
405  return;
406 
407  if (IsRedrawBlocked())
408  return;
409 
410  Int_t kind = GetDrawKind(slot);
411 
412  TGo4Slot *padslot = slot;
413  if (kind != kind_PadSlot)
414  padslot = slot->GetParent();
415 
416  if (((kind > 0) && (kind < 100)) || (kind == kind_Condition)
417  || (kind == kind_Latex) || (kind == kind_Func)) {
418  TGo4Picture *padopt = GetPadOptions(padslot);
419 
420  if (padopt) {
421  padopt->SetContentModified(true);
422  padopt->SetPadModified();
423 
424  // in this small period other objects can come,
425  // therefore only one repaint will be done
427  }
428  }
429 }
430 
431 void TGo4ViewPanel::linkedRemoved(TGo4Slot *slot, TObject *obj)
432 {
433  if (!slot)
434  return;
435 
436  if (IsRedrawBlocked())
437  return;
438 
439  int kind = GetDrawKind(slot);
440 
441  if (kind == kind_ThisPad) {
442  TPad *pad = (TPad *) obj;
443  if (pad)
444  PadDeleted(pad);
445  return;
446  }
447 
448  TGo4Slot *padslot = slot;
449  if (kind != kind_PadSlot)
450  padslot = slot->GetParent();
451 
452  CheckObjectsAssigments(GetSlotPad(padslot), padslot);
453 
454  if (((kind > 0) && (kind < 100)) || (kind == kind_Condition)
455  || (kind == kind_Latex) || (kind == kind_Func)) {
457  TGo4Picture *padopt = GetPadOptions(padslot);
458  if (padopt) {
459  padopt->SetPadModified();
461  }
462  }
463 }
464 
465 bool TGo4ViewPanel::IsAcceptDrag(const char *itemname, TClass *cl, int kind)
466 {
467  if (!cl)
468  return false;
469  int cando = Browser()->ItemCanDo(itemname);
470  return TGo4BrowserProxy::CanDrawItem(cando)
471  || cl->InheritsFrom(TGo4Condition::Class());
472 }
473 
474 void TGo4ViewPanel::DropOnPad(TPad *pad, const char *itemname, TClass *cl, int kind)
475 {
476  if (!cl) return;
477  if (!pad) pad = GetCanvas();
478 
479  if (cl->InheritsFrom(TGo4Fitter::Class())) {
480  SetActivePad(pad);
481  EditItem(itemname);
482  return;
483  }
484  int cando = Browser()->ItemCanDo(itemname);
486  && !cl->InheritsFrom(TGo4Condition::Class()))
487  return;
488 
489  if (!AddDrawObject(pad, kind_Link, itemname, nullptr, false, nullptr)) return;
490 
491  SetActivePad(pad);
492 
494 
495  Browser()->GetBrowserObject(itemname,
496  go4sett->getFetchDataWhenDraw() ? 2 : 1);
497 }
498 
499 // ****************************************************************
500 
502 {
503  TGo4LockGuard lock;
504 
505  // create appropriate entry in OM
506  UpdatePadStatus(GetCanvas(), true);
507 
508  fAutoScaleCheck->setChecked(GetPadOptions(GetCanvas())->IsAutoScale());
509 
510 #ifdef __GO4X11__
511  // JAM 5-2019 construct top window for ged editor already here, otherwise problems with Qt4
513 
514  // adjust canvas size before any drawing will be done
515  if (fxQCanvas) fxQCanvas->Resize();
516 #endif
517 
519 
520  // printf("Resize again x %d y %d\n", go4sett->lastPanelSize().width(), go4sett->lastPanelSize().height());
521  // resize(go4sett->lastPanelSize());
522 
524 
526 
528 }
529 
531 {
532  parentWidget()->close();
533 }
534 
536 {
537  fiMouseMode = mode;
538 }
539 
541 {
542  return fiMouseMode;
543 }
544 
546 {
547  TGo4Slot *padslot = GetPadSlot(pad);
548  if (!padslot) return QString();
549  return QString(padslot->GetPar("::SelMarker"));
550 }
551 
553 {
554  TGo4Slot *padslot = GetPadSlot(pad);
555  if (!padslot) return -1;
556  Int_t selindex = -1;
557  if (!padslot->GetIntPar("::SelIndex", selindex)) return -1;
558  return selindex;
559 }
560 
561 TGo4Slot *TGo4ViewPanel::GetSelectedSlot(TPad *pad, int* selkind, TObject **selobj)
562 {
563  if (selkind) *selkind = kind_None;
564  if (selobj) *selobj = nullptr;
565 
566  TGo4Slot *padslot = GetPadSlot(pad);
567  QString selname = GetSelectedMarkerName(pad);
568  int selindex = GetSelectedMarkerIndex(pad);
569 
570  if (!padslot || selname.isEmpty()) return nullptr;
571 
572  for (int n = 0; n < padslot->NumChilds(); n++) {
573  TGo4Slot *subslot = padslot->GetChild(n);
574  int drawkind = GetDrawKind(subslot);
575  TObject *obj = subslot->GetAssignedObject();
576 
577  if ((drawkind == kind_Link) && obj) {
578  if (obj->InheritsFrom(TGo4Condition::Class()))
579  drawkind = kind_Condition;
580  }
581 
582  if ((drawkind == kind_Marker) || (drawkind == kind_Window)
583  || (drawkind == kind_Poly) || (drawkind == kind_Latex)
584  || (drawkind == kind_Arrow) || (drawkind == kind_Condition)) {
585 
586  if (!obj || (selname != obj->GetName()))
587  continue;
588 
589  if (drawkind == kind_Condition) {
590  TGo4Condition *selcond = dynamic_cast<TGo4Condition *>(obj);
591  if (obj->InheritsFrom(TGo4CondArray::Class())) {
592  TGo4CondArray* arr = (TGo4CondArray*) obj;
593  selcond = nullptr;
594  if ((selindex >= 0) && (selindex < arr->GetNumber()))
595  selcond = arr->At(selindex);
596  }
597  drawkind = kind_None;
598  obj = selcond;
599  if (selcond) {
600  if (selcond->InheritsFrom(TGo4WinCond::Class()))
601  drawkind = kind_Window;
602  else if (selcond->InheritsFrom(TGo4PolyCond::Class()))
603  drawkind = kind_Poly;
604  }
605  }
606  if (selkind)
607  *selkind = drawkind;
608  if (selobj)
609  *selobj = obj;
610  return subslot;
611  }
612  }
613  return nullptr;
614 }
615 
617 {
618  TGo4Slot *slot = GetSelectedSlot(pad, nullptr, nullptr);
619  if (!slot)
620  return false;
621 
622  return GetDrawKind(slot) == kind_Condition;
623 }
624 
625 TPad *TGo4ViewPanel::FindPadWithItem(const char *itemname)
626 {
627  TGo4Iter iter(GetPanelSlot(), kTRUE);
628  while (iter.next()) {
629  TGo4Slot *subslot = iter.getslot();
630  int drawkind = GetDrawKind(subslot);
631  if ((drawkind == kind_Link) || (drawkind == kind_Condition) || (drawkind == kind_Latex) || (drawkind == kind_Func)) {
632  const char *linkname = GetLinkedName(subslot);
633  if (linkname && (strcmp(linkname, itemname) == 0))
634  return GetSlotPad(subslot->GetParent());
635  }
636  }
637  return nullptr;
638 }
639 
640 const char *TGo4ViewPanel::GetDrawItemName(int itemcnt)
641 {
642  int cnt = 0;
643 
644  TGo4Iter iter(GetPanelSlot(), kTRUE);
645  while (iter.next()) {
646  TGo4Slot *subslot = iter.getslot();
647  int drawkind = GetDrawKind(subslot);
648  if ((drawkind == kind_Link) || (drawkind == kind_Condition)) {
649  const char *linkname = GetLinkedName(subslot);
650  if (linkname) {
651  if (cnt++ == itemcnt) return linkname;
652  }
653  }
654  }
655 
656  return nullptr;
657 }
658 
659 
660 void TGo4ViewPanel::UndrawItemOnPanel(const char *itemname)
661 {
662  TGo4LockGuard lock;
663 
664  TObjArray delslots;
665 
666  TGo4Iter iter(GetPanelSlot(), kTRUE);
667  while (iter.next()) {
668  TGo4Slot *subslot = iter.getslot();
669  int drawkind = GetDrawKind(subslot);
670  if ((drawkind == kind_Link) || (drawkind == kind_Condition) || (drawkind == kind_Latex) || (drawkind == kind_Func)) {
671  const char *linkname = GetLinkedName(subslot);
672  if (linkname && (strcmp(linkname, itemname) == 0)) {
673  delslots.Add(subslot);
674  TGo4Slot *padslot = subslot->GetParent();
675  TGo4Picture *padopt = GetPadOptions(padslot);
676  if (padopt)
677  padopt->SetPadModified();
678  }
679  }
680  }
681  if (delslots.GetLast() >= 0) {
682  delslots.Delete();
684  }
685 }
686 
687 void TGo4ViewPanel::SetSelectedMarker(TPad *pad, const QString& selname,
688  int selindex)
689 {
690  TGo4LockGuard lock;
691 
692  TGo4Slot *padslot = GetPadSlot(pad);
693  if (!padslot)
694  return;
695 
696  if (selname.isEmpty())
697  selindex = -1;
698 
699  int oldselindex = GetSelectedMarkerIndex(pad);
700  QString oldselname = GetSelectedMarkerName(pad);
701 
702  TGo4Slot *oldsel = GetSelectedSlot(pad, nullptr, nullptr);
703  if (oldsel)
704  SetSpecialDrawOption(oldsel, nullptr);
705 
706  if (selname.length() > 0)
707  padslot->SetPar("::SelMarker", selname.toLatin1().constData());
708  else
709  padslot->RemovePar("::SelMarker");
710 
711  if (selindex > -1)
712  padslot->SetIntPar("::SelIndex", selindex);
713  else
714  padslot->RemovePar("::SelIndex");
715 
716  int newselkind = 0;
717  TObject *newselobj = nullptr;
718  TGo4Slot *newselslot = GetSelectedSlot(pad, &newselkind, &newselobj);
719 
720  if ((selindex >= 0) && newselslot) {
721  QString drawopt("sel=");
722  drawopt += QString::number(selindex);
723  SetSpecialDrawOption(newselslot, drawopt.toLatin1().constData());
724  }
725 
726  if (((oldselindex != selindex) || (oldselname != selname))
727  && ((oldselindex >= 0) || (selindex >= 0))) {
728  MarkPadModified(pad);
729  ShootRepaintTimer(pad);
730  } else if (newselobj) {
731  // this will bring object to the top
732  newselobj->Pop();
733  // very special case, normally one should not call pad->Update()
734  pad->Update();
735  }
736 
737 }
738 
739 void TGo4ViewPanel::SetSelectedMarkerByMouseClick(TPad *pad, const char *name)
740 {
741  TGo4LockGuard lock;
742 
743  if (!fbMarkEditorVisible) return;
744  TGo4Slot *padslot = GetPadSlot(pad);
745  if (!padslot) return;
746 
747  bool find = false;
748 
749  for (int n = 0; n < padslot->NumChilds(); n++) {
750  TGo4Slot *subslot = padslot->GetChild(n);
751  int drawkind = GetDrawKind(subslot);
752  if ((drawkind == kind_Marker) || (drawkind == kind_Window)
753  || (drawkind == kind_Poly)) {
754  TObject *obj = subslot->GetAssignedObject();
755  if (obj && (strcmp(obj->GetName(), name) == 0)) {
756  SetSelectedMarker(pad, name, -1);
757  SetActiveObj(pad, drawkind, subslot);
758  find = true;
759  break;
760  }
761  }
762  if (drawkind != kind_Condition) continue;
763  TGo4Condition *cond = dynamic_cast<TGo4Condition *>(subslot->GetAssignedObject());
764  if (!cond)
765  continue;
766 
767  if (strcmp(cond->GetName(), name) == 0) {
768  SetSelectedMarker(pad, name, -1);
769 
770  if (cond->InheritsFrom(TGo4PolyCond::Class()))
771  drawkind = kind_Poly;
772  else
773  drawkind = kind_Window;
774 
775  SetActiveObj(pad, drawkind, subslot);
776  find = true;
777  break;
778  }
779 
780  TGo4CondArray* arr = dynamic_cast<TGo4CondArray*>(cond);
781  if (!arr)
782  continue;
783 
784  for (int ncon = 0; ncon < arr->GetNumber(); ncon++)
785  if (strcmp(arr->At(ncon)->GetName(), name) == 0) {
786  SetSelectedMarker(pad, arr->GetName(), ncon);
787  if (arr->At(ncon)->InheritsFrom(TGo4PolyCond::Class()))
788  drawkind = kind_Poly;
789  else
790  drawkind = kind_Window;
791  SetActiveObj(pad, drawkind, subslot);
792  find = true;
793  break;
794  }
795  }
796  if (find)
797  RefreshButtons();
798 }
799 
801 {
802  TGo4LockGuard lock;
803 
804  int selectedkind;
805  TGo4Slot *selslot = GetSelectedSlot(GetActivePad(), &selectedkind, nullptr);
806 
807  if (!selslot)
808  return;
809 
810  if (selectedkind == kind_Window) {
811  FreezeMode->setChecked(false);
812  RegionB->setChecked(true);
814  } else if (selectedkind == kind_Poly) {
815  FreezeMode->setChecked(false);
816  PolyB->setChecked(true);
818  } else
819  return;
820 
821  MarkPadModified(pad);
822  ShootRepaintTimer(pad);
823 }
824 
825 void TGo4ViewPanel::SwitchMarkerButton(int kind, bool on)
826 {
827  if (!fbTypingMode)
828  return;
829 
831  if (!on) {
833  } else {
834  fiPickCounter = 0;
835  switch (kind) {
836  case kind_Marker:
838  break;
839  case kind_Window:
841  break;
842  case kind_Poly:
844  break;
845  case kind_Latex:
847  break;
848  case kind_Arrow:
850  break;
851  default:
853  break;
854  }
855  int selectedkind = 0;
856  /*TGo4Slot *selslot = */ GetSelectedSlot(GetActivePad(), &selectedkind, nullptr);
857  if (selectedkind != kind)
858  SetSelectedMarker(GetActivePad(), "", -1);
859  }
860 
861  RefreshButtons();
862 }
863 
865 {
867 }
868 
870 {
872 }
873 
875 {
877 }
878 
880 {
882 }
883 
885 {
887 }
888 
890 {
891  if (!fbTypingMode)
892  return;
893  fbPickAgain = on;
894  RefreshButtons();
895 }
896 
898 {
899  TGo4LockGuard lock;
900 
901  MarkerPanel->setVisible(fbMarkEditorVisible);
902 
903 #ifdef __GO4X11__
904  if (fxQCanvas)
906 #endif
907 
908 // if(!fbMarkEditorVisible) return;
909 
910  bool iscondition = IsConditionSelected(GetActivePad());
911 
912  fbTypingMode = false;
913  GetConditionBtn->setVisible(iscondition);
914  InfoConditionBtn->setVisible(iscondition);
915  EditConditionBtn->setVisible(iscondition);
916  SetConditionBtn->setVisible(iscondition);
917  if (iscondition) {
918  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
919  TGo4Condition *cond = !slot ? nullptr : dynamic_cast<TGo4Condition *>(slot->GetAssignedObject());
920  ModifyConditionBtn->setVisible(cond && (cond->IsChanged() != 0));
921 
922  QString iconname = ":/icons/right.png";
923  QString tooltip = "Refresh condition from analysis";
924  if (!BrowserItemRemote(GetLinkedName(slot))) {
925  iconname = ":/icons/refresh.png";
926  tooltip = "Refresh condition from source";
927  }
928  GetConditionBtn->setIcon(QIcon(iconname));
929  GetConditionBtn->setToolTip(tooltip);
930 
931  } else
932  ModifyConditionBtn->setVisible(false);
933 
934  switch (GetMouseMode()) {
935  case kMouseROOT:
936  CursorB->setChecked(false);
937  RegionB->setChecked(false);
938  LatexB->setChecked(false);
939  DrawB->setChecked(false);
940  PolyB->setChecked(false);
941  break;
942  case kMousePickCursor:
943  CursorB->setChecked(true);
944  RegionB->setChecked(false);
945  LatexB->setChecked(false);
946  DrawB->setChecked(false);
947  PolyB->setChecked(false);
948  break;
949  case kMousePickLimits:
950  CursorB->setChecked(false);
951  RegionB->setChecked(true);
952  LatexB->setChecked(false);
953  DrawB->setChecked(false);
954  PolyB->setChecked(false);
955  break;
956  case kMousePickPolygon:
957  CursorB->setChecked(false);
958  RegionB->setChecked(false);
959  LatexB->setChecked(false);
960  DrawB->setChecked(false);
961  PolyB->setChecked(true);
962  break;
963  case kMousePickLatex:
964  CursorB->setChecked(false);
965  RegionB->setChecked(false);
966  LatexB->setChecked(true);
967  DrawB->setChecked(false);
968  PolyB->setChecked(false);
969  break;
970  case kMouseDraw: // currently, we only draw arrows:
971  CursorB->setChecked(false);
972  RegionB->setChecked(false);
973  LatexB->setChecked(false);
974  DrawB->setChecked(true);
975  PolyB->setChecked(false);
976  break;
977  default:
978  CursorB->setChecked(false);
979  RegionB->setChecked(false);
980  LatexB->setChecked(false);
981  DrawB->setChecked(false);
982  PolyB->setChecked(false);
983  break;
984  }; // switch()
985  FreezeMode->setChecked(fbPickAgain);
986 
987  SelectedMarkerCmb->clear();
988  SelectedMarkerCmb->addItem("new");
989 
990  TGo4Slot *slot = GetPadSlot(GetActivePad());
991  int findindx = -1;
992 
993  QString selname = GetSelectedMarkerName(GetActivePad());
994  int selindex = GetSelectedMarkerIndex(GetActivePad());
995 
996  if (slot)
997  for (int n = 0; n < slot->NumChilds(); n++) {
998  TGo4Slot *subslot = slot->GetChild(n);
999  int drawkind = GetDrawKind(subslot);
1000  if ((drawkind == kind_Marker) || (drawkind == kind_Window)
1001  || (drawkind == kind_Poly) || (drawkind == kind_Condition)) {
1002  TObject *obj = subslot->GetAssignedObject();
1003  if (!obj)
1004  continue;
1005 
1006  if (obj->InheritsFrom(TGo4CondArray::Class())) {
1007  TGo4CondArray* arr = (TGo4CondArray*) obj;
1008  for (int ncon = 0; ncon < arr->GetNumber(); ncon++) {
1009  // TGo4Condition *sub = arr->At(ncon);
1010  QString fullname(arr->GetName());
1011  fullname += "/Sub";
1012  fullname += QString::number(ncon);
1013  SelectedMarkerCmb->addItem(fullname);
1014 
1015  if ((selname == obj->GetName()) && (selindex == ncon))
1016  findindx = SelectedMarkerCmb->count() - 1;
1017  }
1018  } else {
1019  SelectedMarkerCmb->addItem(obj->GetName());
1020  if (selname == obj->GetName())
1021  findindx = SelectedMarkerCmb->count() - 1;
1022  }
1023  }
1024  }
1025 
1026  if (findindx < 0) {
1027  findindx = 0;
1028  SetSelectedMarker(GetActivePad(), "", -1);
1029  }
1030 
1031  SelectedMarkerCmb->setCurrentIndex(findindx);
1032  DelSelectedMarker->setEnabled((findindx > 0) /*&& !iscondition*/);
1033 
1034  if (fbMarkEditorVisible) {
1035  MarkerPanel->ensurePolished();
1036  MarkerPanel->update();
1037  MarkerPanel->show();
1038  }
1039  fbTypingMode = true;
1040 }
1041 
1043 {
1044  if (!fbTypingMode)
1045  return;
1046  if (indx == 0) {
1047  SetSelectedMarker(GetActivePad(), "", -1);
1048  } else {
1049  QString selname = SelectedMarkerCmb->itemText(indx);
1050  int selindex = -1;
1051  int p = selname.indexOf("/Sub");
1052  if (p > 0) {
1053  selindex = selname.mid(p + 4).toInt();
1054  selname.truncate(p);
1055  } else
1056  selindex = -1;
1057  SetSelectedMarker(GetActivePad(), selname, selindex);
1058  }
1059 
1060  int drawkind = 0;
1061  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), &drawkind, nullptr);
1062 
1063  if (slot && (drawkind > 0)) {
1064  SetActiveObj(GetActivePad(), drawkind, slot);
1065  SwitchMarkerButton(drawkind, true);
1066  } else
1068 }
1069 
1071 {
1072  if (!fbTypingMode) return;
1073  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
1074  if (!slot) return;
1075  delete slot;
1076  SetSelectedMarker(GetActivePad(), "", -1);
1077  RedrawPanel(GetActivePad(), true);
1078 }
1079 
1081 {
1082  fbMarkEditorVisible = flag;
1083  if (!fbMarkEditorVisible) {
1084  // switch back to normal root mouse when editor is hidden
1087  gROOT->SetEditorMode("");
1088  fiPickCounter = 0;
1089  }
1090  RefreshButtons();
1092 }
1093 
1095 {
1096  if (!fbTypingMode)
1097  return;
1098 
1099  TGo4Slot *slot = GetPadSlot(GetActivePad());
1100  if (!slot)
1101  return;
1102 
1103  for (int n = 0; n < slot->NumChilds(); n++) {
1104  TGo4Slot *subslot = slot->GetChild(n);
1105  int drawkind = GetDrawKind(subslot);
1106  TObject *obj = subslot->GetAssignedObject();
1107  if ((drawkind < kind_Condition) || !obj)
1108  continue;
1109  switch (drawkind) {
1110  case kind_Marker:
1111  obj->Print("*");
1112  break;
1113  case kind_Latex:
1114  obj->Print("*");
1115  break;
1116  case kind_Arrow:
1117  obj->Print("go4log");
1118  break;
1119  case kind_Window:
1120  case kind_Poly:
1121  case kind_Condition:
1122  obj->Print("go4log-limits-stats");
1123  break;
1124  }
1125  }
1126 }
1127 
1129 {
1130  TGo4LockGuard lock;
1131 
1132  TPad *pad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
1133  if (!pad)
1134  pad = GetCanvas();
1135 
1137 
1138  RedrawPanel(pad, true);
1139 }
1140 
1141 void TGo4ViewPanel::ProcessMarkersClear(TPad *pad, bool withsubpads)
1142 {
1143  if (!pad) return;
1144 
1150  if (!withsubpads) return;
1151 
1152  TGo4Slot *slot = GetPadSlot(pad);
1153  if (!slot) return;
1154 
1155  TGo4Iter iter(slot, true);
1156  while (iter.next()) {
1157  TPad *subpad = GetSlotPad(iter.getslot());
1158  if (subpad)
1159  ProcessMarkersClear(subpad, false);
1160  }
1161 }
1162 
1164 {
1165  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
1166  if (GetDrawKind(slot) != kind_Condition)
1167  return;
1168  const char *itemname = GetLinkedName(slot);
1169  if (!itemname)
1170  return;
1171 
1172  Browser()->GetBrowserObject(itemname, 2);
1173 
1174  RefreshButtons();
1175 }
1176 
1178 {
1179  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
1180  if (GetDrawKind(slot) != kind_Condition)
1181  return;
1182  const char *itemname = GetLinkedName(slot);
1183  if (itemname)
1184  ShowItemInfo(itemname);
1185 }
1186 
1188 {
1189  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
1190  if (GetDrawKind(slot) != kind_Condition) return;
1191  const char *itemname = GetLinkedName(slot);
1192  if (itemname)
1193  EditItem(itemname);
1194 }
1195 
1197 {
1198  TGo4Slot *slot = GetSelectedSlot(GetActivePad(), nullptr, nullptr);
1199  if (GetDrawKind(slot) != kind_Condition) return;
1200  const char *itemname = GetLinkedName(slot);
1201  if (itemname) {
1202  UpdateItemInAnalysis(itemname);
1203  TGo4Condition *cond = dynamic_cast<TGo4Condition *>(slot->GetAssignedObject());
1204  if(cond) cond->SetChanged(kFALSE);
1205  RefreshButtons();
1206  }
1207 }
1208 
1210 {
1211  QFileDialog fd(this, "Save Markers of active pad into", QString(),
1212  "ROOT file (*.root)");
1213  fd.setFileMode(QFileDialog::AnyFile);
1214  fd.setAcceptMode(QFileDialog::AcceptSave);
1215  if (fd.exec() == QDialog::Accepted) {
1216  QStringList flst = fd.selectedFiles();
1217  if (flst.isEmpty())
1218  return;
1219 
1220  QString filename = flst[0];
1221  if (!filename.endsWith(".root"))
1222  filename.append(".root");
1223 // fxTGo4PreviewPanelSlots->SaveMarkerSetup(filename,"Markersetup");
1224  }
1225 }
1226 
1228 {
1229  QFileDialog fd(this, "Load Marker setup from:", QString(),
1230  "ROOT file (*.root)");
1231  fd.setFileMode(QFileDialog::ExistingFile);
1232  if (fd.exec() == QDialog::Accepted) {
1233  QStringList flst = fd.selectedFiles();
1234  if (flst.isEmpty())
1235  return;
1236  QString filename = flst[0];
1237  }
1238 }
1239 
1241 {
1242  TGo4LockGuard lock;
1243 
1244  if (fxActivePad != pad)
1246 
1247  raise();
1248 
1249  if (!pad) {
1250  if (!fxWCanvas) {
1251  GetCanvas()->SetSelected(nullptr);
1252  GetCanvas()->SetSelectedPad(nullptr);
1253  CanvasUpdate();
1254  }
1255  return;
1256  }
1257 
1258  fxActivePad = pad;
1259  if (!fxWCanvas) {
1260  fxActivePad->cd();
1261  GetCanvas()->SetSelectedPad(fxActivePad);
1262  }
1263 
1265 
1266  // no need for update of web canvas here
1267  if (!fxWCanvas) {
1268  BlockPanelRedraw(true);
1269  CanvasUpdate();
1270  BlockPanelRedraw(false);
1271  }
1272 
1274 
1277 }
1278 
1279 void TGo4ViewPanel::PadClickedSlot(TPad *pad, int px, int py)
1280 {
1281  TGo4LockGuard lock;
1282  SetActivePad(pad);
1283 
1284  if (!pad)
1285  return;
1286 
1287  if ((px < 0) || (py < 0)) {
1288  px = pad->GetEventX();
1289  py = pad->GetEventY();
1290  }
1291 
1292  Double_t x = pad->PadtoX(pad->AbsPixeltoX(px));
1293  Double_t y = pad->PadtoY(pad->AbsPixeltoY(py));
1294 
1295  bool docreate = GetSelectedMarkerName(pad).isEmpty(),
1296  docheck = false, iscreated = false;
1297 
1298  switch (fiMouseMode) {
1299  case kMouseROOT: {
1300  TObject *obj = GetCanvas()->GetSelected();
1301  if (obj)
1302  if (obj->InheritsFrom(TGo4Marker::Class())
1303  || obj->InheritsFrom(TGo4WinCondView::Class())
1304  || obj->InheritsFrom(TGo4PolyCondView::Class()))
1305  SetSelectedMarkerByMouseClick(pad, obj->GetName());
1306 
1307  break;
1308  }
1309 
1310  case kMousePickCursor: {
1311  // we have a click on our working pad, get coordinates:
1312  gROOT->SetEditorMode("");
1313 
1314  if (docreate) {
1315  TGo4Marker* mark = new TGo4Marker(x, y, 28);
1316  AddMarkerObj(pad, kind_Marker, mark);
1317  Int_t ix = TGo4Marker::GetInstances() - 1;
1318  mark->SetMarkerColor((ix) % 6 + 2);
1319  mark->SetHistogram(GetPadHistogram(pad));
1320  if (!fbPickAgain)
1321  fiMouseMode = kMouseROOT; // reset pick
1322  mark->Draw("");
1323  } else {
1324  TGo4Marker* mark = dynamic_cast<TGo4Marker*>(GetActiveObj(pad, kind_Marker));
1325  if(mark) {
1326  mark->SetX(x);
1327  mark->SetY(y);
1328  }
1329  if (!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
1330  }
1331  CanvasUpdate(true);
1332 
1333 // RedrawPanel(pad, true);
1334  break;
1335  }
1336 
1337  case kMousePickLimits: {
1338  gROOT->SetEditorMode("");
1339  TGo4WinCond *conny = nullptr;
1340  Double_t xmin(x), xmax(x), ymin(y), ymax(y);
1341  if (fiPickCounter == 0) {
1342  // pick the first time after enabling limits record:
1343  if (docreate) {
1344  TH1 *hist = GetPadHistogram(pad);
1345  bool fbTwoDimRegion = hist && (hist->GetDimension() > 1);
1346  int ix = GetNumMarkers(pad, kind_Window);
1347  QString name = "Region " + QString::number(ix + 1);
1348  conny = new TGo4WinCond(name.toLatin1().constData());
1349  iscreated = true;
1350  if (fbTwoDimRegion)
1351  conny->SetValues(0, 0, 0, 0);
1352  else
1353  conny->SetValues(0, 0);
1354  conny->SetLineColor(GetAutoColor(ix%9 + 1));
1355  conny->SetFillColor(GetAutoColor(ix%9 + 1));
1356  conny->SetFillStyle(3002);
1357  conny->SetWorkHistogram(hist);
1358  // adjust two dim region to one dim defaults
1359  conny->SetYRMSDraw(fbTwoDimRegion && conny->IsXRMSDraw());
1360  conny->SetYMeanDraw(fbTwoDimRegion && conny->IsXMeanDraw());
1361  conny->SetYMaxDraw(fbTwoDimRegion && conny->IsXMaxDraw());
1362  AddMarkerObj(pad, kind_Window, conny);
1363  } else
1364  conny = dynamic_cast<TGo4WinCond*>(GetActiveObj(pad, kind_Window));
1365  if(!conny) return;
1366  fiPickCounter++;
1367  } else if (fiPickCounter == 1) {
1368  conny = dynamic_cast<TGo4WinCond *>(GetActiveObj(pad, kind_Window));
1369  if (!conny) return;
1370  xmin = conny->GetXLow();
1371  ymin = conny->GetYLow();
1372  fiPickCounter = 0;
1374  docheck = true;
1375  } else {
1376  std::cout << "TGo4ViewPanel:PadClickedSlot() NEVER COME HERE" << std::endl;
1377  return;
1378  }
1379  // do not change original condition dimension
1380  if (conny->GetDimension() > 1)
1381  conny->SetValues(xmin, xmax, ymin, ymax);
1382  else
1383  conny->SetValues(xmin, xmax);
1384 
1385  TGo4Slot *condslot = GetSelectedSlot(pad, nullptr, nullptr);
1386  if (GetDrawKind(condslot) == kind_Condition) {
1387  TGo4Condition *maincond =
1388  dynamic_cast<TGo4Condition *>(condslot->GetAssignedObject());
1389  if (maincond) maincond->SetChanged();
1390  }
1391 
1392  conny->SetChanged();
1393  if (iscreated)
1394  conny->Draw("");
1395  CanvasUpdate(true);
1396 
1397  // RedrawPanel(pad, true);
1398  break;
1399  }
1400 
1401  case kMousePickPolygon: {
1402  gROOT->SetEditorMode("");
1403  TGo4PolyCond *cond = nullptr;
1404 
1405  if (fiPickCounter == 0) {
1406  // pick the first time after enabling limits record:
1407  if (docreate) {
1408  TH1 *hist = GetPadHistogram(pad);
1409  int ix = GetNumMarkers(pad, kind_Poly);
1410  QString name = "Polygon " + QString::number(ix + 1);
1411  cond = new TGo4PolyCond(name.toLatin1().constData());
1412  iscreated = true;
1413  AddMarkerObj(pad, kind_Poly, cond);
1414  cond->SetWorkHistogram(hist);
1415  } else {
1416 
1417  cond = dynamic_cast<TGo4PolyCond*>(GetActiveObj(pad, kind_Poly));
1418  // start region from the beginning
1419  if (cond) {
1420  TCutG *cut = cond->GetCut(kTRUE);
1421  delete cut;
1422  }
1423  }
1424  if(!cond) return;
1425  fiPickCounter++;
1426  } else {
1427  cond = dynamic_cast<TGo4PolyCond*> (GetActiveObj(pad, kind_Poly));
1428  if(!cond) return;
1429  fiPickCounter++;
1430  }
1431 
1432  if (cond) {
1433  TCutG *cut = cond->GetCut(kFALSE);
1434  // this insert point in last mouse position
1435  if (!cut) {
1436  cut = new TCutG(TGo4PolyCond::NextAvailableName(), 1);
1437  cut->SetPoint(0, x, y);
1438  cut->SetPoint(1, x, y); // JAM2019- otherwise we will lose first point to zero when defining next ones
1439  cond->SetValuesDirect(cut);
1440  } else {
1441  // cut->InsertPoint(); // JAM2019 - this gives ROOT6 error also without webcanvas
1442  cut->SetPoint(fiPickCounter, x, y);
1443  }
1444 
1445  cond->SetChanged();
1446 
1447  int ix = GetNumMarkers(pad, kind_Poly);
1448 
1449  cond->SetLineColor(GetAutoColor(ix % 9 + 1));
1450  cond->SetFillColor(GetAutoColor(ix % 9 + 1));
1451  cond->SetFillStyle(3002);
1452  }
1453 
1454  // mark condition
1455  TGo4Slot *condslot = GetSelectedSlot(pad, nullptr, nullptr);
1456  if (GetDrawKind(condslot) == kind_Condition) {
1457  TGo4Condition *maincond =
1458  dynamic_cast<TGo4Condition *>(condslot->GetAssignedObject());
1459  if (maincond) maincond->SetChanged();
1460  }
1461 
1462  if (iscreated)
1463  cond->Draw("");
1464  CanvasUpdate(true);
1465  break;
1466  }
1467 
1468  case kMousePickLatex: {
1469  gROOT->SetEditorMode("");
1470  if (docreate) {
1471  int ix = GetNumMarkers(pad, kind_Latex);
1472  QString name = QString("Label ") + QString::number(ix + 1);
1473  bool ok;
1474  QString txt = QInputDialog::getText(this,
1475  "Enter new LaTeX label text:", name, QLineEdit::Normal,
1476  QString(), &ok);
1477  if (ok && (txt.length() > 0)) {
1478  TLatex *latex = new TLatex(x, y, name.toLatin1().constData());
1479  latex->SetName(name.toLatin1().constData());
1480  latex->SetTitle(txt.toLatin1().constData());
1481  AddMarkerObj(pad, kind_Latex, latex);
1482  latex->Draw();
1483  } else {
1485  }
1486  } else {
1487  TLatex *latex = dynamic_cast<TLatex *>(GetActiveObj(pad, kind_Latex));
1488  if(latex) {
1489  latex->SetX(x);
1490  latex->SetY(y);
1491  }
1492  }
1493  if (!fbPickAgain)
1494  fiMouseMode = kMouseROOT; // reset pick
1495 
1496 // pad->Modified();
1497 // pad->Update();
1498 
1499  CanvasUpdate(true);
1500 
1501 // RedrawPanel(pad, true);
1502  break;
1503  }
1504 
1505  case kMouseDraw: {
1506  gROOT->SetEditorMode("");
1507  if (fiPickCounter == 0) {
1508  // pick the first time after enabling limits record:
1509  TArrow* arrow = new TArrow(x, y, x, y, 0.02);
1510  AddMarkerObj(pad, kind_Arrow, arrow);
1511  fiPickCounter++;
1512  arrow->Draw("");
1513  } else if (fiPickCounter == 1) {
1514  TArrow* arrow = dynamic_cast<TArrow*>(GetActiveObj(pad, kind_Arrow));
1515  if(arrow) {
1516  arrow->SetX2(x);
1517  arrow->SetY2(y);
1518  }
1519  if(!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
1520  fiPickCounter = 0;
1521  } else {
1522  std::cout <<"TGo4ViewPanel:MouseClick() NEVER COME HERE" << std::endl;
1523  return;
1524  }
1525  // do not change original arrow dimension
1526  // pad->Modified();
1527  // pad->Update();
1528 
1529  CanvasUpdate(true);
1530 
1531  // RedrawPanel(pad, true);
1532  break;
1533  }
1534  }
1535 
1536  if (docheck)
1537  CheckActionAtTheEnd(pad);
1538 }
1539 
1541 {
1542  bool goback = true;
1543 
1544 // uncomment this code to have loop mode for array of conditions
1545 
1546 // if(fbPickAgain) {
1547 // QString selname = GetSelectedMarkerName(pad);
1548 // int selindex = GetSelectedMarkerIndex(pad);
1549 // if (selindex >= 0) {
1550 // TGo4Slot *slot = GetSelectedSlot(pad, nullptr, nullptr);
1551 // TGo4CondArray* arr = nullptr;
1552 // if (slot)
1553 // arr = dynamic_cast<TGo4CondArray*> (slot->GetAssignedObject());
1554 // if (arr) {
1555 // if (selindex<arr->GetNumber()-1) {
1556 // SetSelectedMarker(pad, selname, selindex+1);
1557 // goback = false;
1558 // }
1559 // else
1560 // SetSelectedMarker(pad, "", -1);
1561 // }
1562 // }
1563 // }
1564  if (goback) {
1566  ServiceCall("ActivateConditionEditor");
1567  fbLeaveFocusAfterCondEnd = false;
1568 // MarkPadModified(pad);
1569 // ShootRepaintTimer(pad);
1570  }
1571 }
1572 
1574 {
1575  bool res = false,
1576  needredraw = false, // complete repaint
1577  needupdate = false, // only pad update
1578  needrefresh = true, //false; // refresh buttons
1579  docheck = false,
1580  candelete = !IsConditionSelected(pad);
1581 
1582  switch (fiMouseMode) {
1583  case kMousePickLimits: {
1584  if (fiPickCounter > 0) {
1585  TGo4WinCond *cond = dynamic_cast<TGo4WinCond*>(GetActiveObj(pad, kind_Window));
1586  if (cond) {
1587  if (candelete) DeleteDrawObject(pad, cond);
1588  needredraw = true;
1589  }
1590  fiPickCounter = 0;
1592  docheck = true;
1593  }
1594 
1595  res = true;
1596  break;
1597  }
1598 
1599  case kMousePickPolygon: {
1600  if (fiPickCounter > 0) {
1601  TGo4PolyCond *cond = dynamic_cast<TGo4PolyCond *>(GetActiveObj(pad, kind_Poly));
1602  if (cond) {
1603  bool delcond = true;
1604  TCutG *cut = cond->GetCut(kFALSE);
1605  if (cut) {
1606  int n = cut->GetN();
1607  Double_t x, y;
1608  cut->GetPoint(0, x, y);
1609  delcond = (n < 3);
1610 
1611  if (n >= 3)
1612  cut->SetPoint(n, x, y);
1613 
1614  int ix = GetNumMarkers(pad, kind_Poly);
1615  cond->SetLineColor(GetAutoColor(ix % 9 + 1));
1616  cond->SetFillColor(GetAutoColor(ix % 9 + 1));
1617  cond->SetFillStyle(3002);
1618  }
1619 
1620  if (delcond && candelete) {
1621  DeleteDrawObject(pad, cond);
1622  needredraw = true;
1623  } else {
1624  needupdate = true;
1625  }
1626  }
1627  if (!fbPickAgain)
1629  fiPickCounter = 0;
1630  docheck = true;
1631  }
1632 
1633  needrefresh = true;
1634  res = true;
1635  break;
1636  }
1637 
1638  case kMouseDraw: {
1639  if (fiPickCounter>0) {
1640  TArrow* arrow = dynamic_cast<TArrow*> (GetActiveObj(pad, kind_Arrow));
1641  if (arrow) {
1642  DeleteDrawObject(pad, arrow);
1643  needredraw = true;
1644  }
1645  fiPickCounter = 0;
1647  }
1648  res = true;
1649  break;
1650  }
1651  }
1652  if (needredraw) {
1653  RedrawPanel(pad, true);
1654  } else {
1655  if (needupdate) {
1656  CanvasUpdate(true);
1657  // pad->Modified();
1658  // pad->Update();
1659  }
1660  if (needrefresh)
1661  RefreshButtons();
1662  }
1663 
1664  if (docheck)
1665  CheckActionAtTheEnd(pad);
1666 
1667  return res;
1668 }
1669 
1670 void TGo4ViewPanel::PadDoubleClickedSlot(TPad *pad, int, int)
1671 {
1672  if (CompleteMarkerEdit(pad)) return;
1673  if (fxDoubleClickTimerPad) return;
1674 
1675  fxDoubleClickTimerPad = pad;
1676  QTimer::singleShot(100, this, &TGo4ViewPanel::ProcessPadDoubleClick);
1677 }
1678 
1679 void TGo4ViewPanel::CanvasDropEventSlot(QDropEvent* event, TPad *pad)
1680 {
1681  emit widgetService(this, service_DropEvent, (const char *) pad, event);
1682 }
1683 
1685 {
1686  if (!fxDoubleClickTimerPad) return;
1687 
1688  if (GetNumberOfPads(GetCanvas()) <= 1) {
1689  MoveScale(1,0,0,0);
1690  fxDoubleClickTimerPad = nullptr;
1691  return;
1692  }
1693 
1694  TGo4Picture pic;
1696  fxDoubleClickTimerPad = nullptr;
1697 
1698  if (pic.GetNumObjNames() == 0) return;
1699 
1700  TGo4ViewPanel *newpanel = CreateViewPanel();
1701  newpanel->ProcessPictureRedraw("", newpanel->GetCanvas(), &pic);
1702  newpanel->ShootRepaintTimer();
1703 }
1704 
1705 
1706 TH1 *TGo4ViewPanel::Get_fHistogram(TObject *obj, bool force)
1707 {
1708  // return fHistogram member of THStack, TMultiGraph, TGraph
1709  if (!obj) return nullptr;
1710 
1711  Long_t offset =obj->IsA()->GetDataMemberOffset("fHistogram");
1712  if (offset <= 0) return nullptr;
1713 
1714  TH1 **hist = (TH1 **)((char *) obj + offset);
1715 
1716  if (!force || IsWebCanvas()) return *hist;
1717 
1718  if (obj->IsA() == THStack::Class())
1719  return ((THStack *)obj)->GetHistogram();
1720 
1721  if (obj->IsA() == TMultiGraph::Class())
1722  return ((TMultiGraph *)obj)->GetHistogram();
1723 
1724  TGraph *gr = dynamic_cast<TGraph *> (obj);
1725  if (gr) return gr->GetHistogram();
1726 
1727  return *hist;
1728 }
1729 
1730 
1731 void TGo4ViewPanel::MenuCommandExecutedSlot(TObject *obj, const char *cmdname)
1732 {
1733  TPad *pad = dynamic_cast<TPad *>(obj);
1734  if (pad)
1735  UpdatePadStatus(pad, true);
1736 
1737  Browser()->Scan_gROOT();
1738 
1739  if ((strcmp(cmdname, "UnZoom") == 0) && obj->InheritsFrom(TAxis::Class())) {
1740 
1741  // this code is done specially to treat unzoom in the THStack
1742 
1743  TGo4Iter iter(GetPanelSlot(), kTRUE);
1744  TGo4Slot *subslot = nullptr;
1745 
1746  do {
1747  if (!subslot)
1748  subslot = GetPanelSlot();
1749  else
1750  subslot = iter.getslot();
1751 
1752  TPad *subpad = GetSlotPad(subslot);
1753  if (!subpad)
1754  continue;
1755 
1756  TGo4Slot *sislot = GetSuperimposeSlot(subslot);
1757  if (!sislot)
1758  continue;
1759 
1760  THStack *hs = dynamic_cast<THStack*>(sislot->GetAssignedObject());
1761 
1762  // prevent creation of histogram when not exists
1763  TH1 *framehisto = Get_fHistogram(hs);
1764  if (!framehisto) continue;
1765 
1766  if (framehisto->GetXaxis() != obj) continue;
1767 
1768  TIter next(hs->GetHists());
1769  while (auto hs_h1 = (TH1 *) next())
1770  hs_h1->GetXaxis()->UnZoom();
1771 
1772  return;
1773  } while (iter.next());
1774  }
1775 }
1776 
1778 {
1779  if (fxWCanvas) {
1780  fBlockSignals = true;
1781  TCanvasImp *imp = GetCanvas()->GetCanvasImp();
1782  fxCanvasEventstatusChk->setChecked(imp->HasStatusBar());
1783  fxCanvasEditorChk->setChecked(imp->HasEditor());
1784  fBlockSignals = false;
1785  } else {
1786  ResizeGedEditor();
1787  }
1788 }
1789 
1791 {
1792  ServiceCall("SavePanelCanvas");
1793 }
1794 
1796 {
1797  TGo4Picture *pic = new TGo4Picture(GetPanelName(), "Copy of picture");
1798 
1799  MakePictureForPad(pic, GetCanvas(), false);
1800 
1801  SaveObjectInMemory("", pic);
1802 }
1803 
1805 {
1806  // get list of markers here
1807  TObjArray markers;
1809  Int_t npts = markers.GetEntries();
1810  if (npts == 0)
1811  return;
1812  // create arrays of length
1813  TArrayD x(npts), y(npts);
1814  // copy marker values to array:
1815  for (Int_t j = 0; j < npts; ++j) {
1816  TGo4Marker* mark = dynamic_cast<TGo4Marker*>(markers[j]);
1817  if (!mark) {
1818  std::cout << "NEVER COME HERE: no marker at index " << j << std::endl;
1819  return;
1820  }
1821  x[j] = mark->GetX();
1822  y[j] = mark->GetY();
1823  }
1824 
1825  // create graph from points array:
1826  TString grname = GetPanelName() + TString("-Markergraph");
1827  TGraph *graf = new TGraph(npts, x.GetArray(), y.GetArray());
1828  graf->SetName(grname.Data());
1829  graf->SetMarkerStyle(28);
1830  SaveObjectInMemory("", graf);
1831 }
1832 
1833 void TGo4ViewPanel::MakePictureForPad(TGo4Picture *pic, TPad *pad, bool useitemname)
1834 {
1835  TGo4Picture *padopt = GetPadOptions(pad);
1836  TGo4Slot *slot = GetPadSlot(pad);
1837  if (!padopt || !slot) return;
1838 
1839  pic->CopyOptionsFrom(padopt);
1840 
1843 
1844  if (pad == GetCanvas() && fbFreezeTitle)
1845  pic->SetTitle(fFreezedTitle.toLatin1().constData());
1846 
1847  if (!padopt->IsXYRatioOne())
1848  pic->SetFrameAttr(pad);
1849 
1850  int objnamenum = 0;
1851 
1852  for (int n = 0; n < slot->NumChilds(); n++) {
1853  TGo4Slot *subslot = slot->GetChild(n);
1854  int kind = GetDrawKind(subslot);
1855 
1856  if ((kind == kind_Arrow) || (kind == kind_Latex) || (kind == kind_Marker)
1857  || (kind == kind_Window) || (kind == kind_Poly) || (kind == kind_Func)
1858  || (kind == kind_Specials)) {
1859  TObject *obj = subslot->GetAssignedObject();
1860  const char *drawopt = GetSpecialDrawOption(subslot);
1861 
1862  if (obj) {
1863  if (dynamic_cast<TLatex *>(obj) || dynamic_cast<TF1 *>(obj)) {
1864  // test here if we have local object or monitored remote one
1865  if (dynamic_cast<TGo4ObjectProxy*>(subslot->GetProxy())) {
1866  // make clone when really needed
1867  pic->AddSpecialObject(obj->Clone(), drawopt);
1868  } else if (dynamic_cast<TGo4LinkProxy*>(subslot->GetProxy())) {
1869  const char *itemname = GetLinkedName(subslot);
1870  if (itemname)
1871  pic->AddObjName(itemname, drawopt);
1872  } else {
1873  TGo4Log::Error("MakePictureForPad NEVER COME HERE, unknown proxy type");
1874  }
1875  } else {
1876  obj = obj->Clone();
1877 
1878  TGo4Marker* mark = dynamic_cast<TGo4Marker*>(obj);
1879  if (mark) mark->DeletePainter();
1880  TGo4Condition *cond = dynamic_cast<TGo4Condition *>(obj);
1881  if (cond) cond->DeletePainter();
1882 
1883  pic->AddSpecialObject(obj, drawopt);
1884  }
1885  }
1886  continue;
1887  }
1888 
1889  if ((kind != kind_Link) && (kind != kind_Condition))
1890  continue;
1891 
1892  const char *drawopt = padopt->GetDrawOption(objnamenum++);
1893 
1894  if (useitemname) {
1895  const char *itemname = GetLinkedName(subslot);
1896  if (itemname)
1897  pic->AddObjName(itemname, drawopt);
1898  } else {
1899  TNamed *nm = dynamic_cast<TNamed*>(subslot->GetAssignedObject());
1900  if (nm) pic->AddObjName(nm->GetName(), drawopt);
1901  }
1902 
1903  Int_t rebinx, rebiny;
1904  if (subslot->GetIntPar("::HasRebinX", rebinx))
1905  pic->SetRebinX(rebinx);
1906  if (subslot->GetIntPar("::HasRebinY", rebiny))
1907  pic->SetRebinY(rebiny);
1908  }
1909 
1910  TObjArray pads;
1911 
1912  for (int n = 0; n < slot->NumChilds(); n++) {
1913  TGo4Slot *subslot = slot->GetChild(n);
1914  TPad *subpad = GetSlotPad(subslot);
1915  if (subpad)
1916  pads.Add(subpad);
1917  }
1918  if (pads.GetLast() < 0)
1919  return;
1920 
1921  double lastx = -1;
1922  int xcnt = 0, sizex = 1, sizey = 1;
1923  for (int n = 0; n <= pads.GetLast(); n++) {
1924  TPad *subpad = (TPad *) pads.At(n);
1925  double mitx = subpad->GetXlowNDC() + subpad->GetWNDC() / 2.;
1926  if (mitx > lastx) {
1927  xcnt++;
1928  lastx = mitx;
1929  } else {
1930  xcnt = 0;
1931  lastx = -1;
1932  }
1933  if (xcnt > sizex)
1934  sizex = xcnt;
1935  }
1936 
1937  while (sizex * sizey <= pads.GetLast())
1938  sizey++;
1939 
1940  pic->SetDivision(sizey, sizex);
1941 
1942  for (int ny = 0; ny < sizey; ny++)
1943  for (int nx = 0; nx < sizex; nx++) {
1944  int indx = ny * sizex + nx;
1945  if (indx > pads.GetLast())
1946  break;
1947  TPad *subpad = (TPad *) pads.At(indx);
1948  MakePictureForPad(pic->Pic(ny, nx), subpad, useitemname);
1949  }
1950 }
1951 
1953 {
1954  TGo4PrintWidget dlg;
1955  if (dlg.exec() != QDialog::Accepted)
1956  return;
1957 
1959 
1960  QString outfile = "~/go4printout.ps";
1961  QString PrnCmd = dlg.GetPrintProg() + " -P " + dlg.GetPrinter() + " "
1962  + outfile;
1963  QString DelCmd = QString("rm -f ") + outfile;
1964 
1965  GetCanvas()->Print(outfile.toLatin1().constData());
1966  gSystem->Exec(PrnCmd.toLatin1().constData());
1967  gSystem->Exec(DelCmd.toLatin1().constData());
1968 }
1969 
1971 {
1972  if (fBlockSignals)
1973  return;
1974 
1975  bool visible = false;
1976  if (fxQCanvas) {
1977 #ifdef __GO4X11__
1978  if (!fxQCanvas->isEditorAllowed()) return;
1979 
1980  visible = !fxQCanvas->isEditorVisible();
1981 
1982  if (visible)
1984 
1986 #endif
1987  } else if (fxWCanvas) {
1988 
1989 #ifdef __GO4WEB__
1990 
1991  // SetActivePad(GetCanvas());
1992 
1993  visible = !fxWCanvas->isEditorVisible();
1994 
1995  fxWCanvas->setEditorVisible(visible);
1996 
1997 #endif
1998  }
1999 
2000  if (visible)
2002 
2003  show();
2004 
2005  ResizeGedEditor();
2006 }
2007 
2009 {
2010  TGo4Slot *padslot = GetPadSlot(GetActivePad());
2011  if (!padslot)
2012  return;
2013 
2014  for (int n = 0; n < padslot->NumChilds(); n++) {
2015  TGo4Slot *subslot = padslot->GetChild(n);
2016  int drawkind = GetDrawKind(subslot);
2017  if (drawkind != kind_Condition)
2018  continue;
2019  const char *itemname = GetLinkedName(subslot);
2020  if (itemname) {
2021  EditItem(itemname);
2022  return;
2023  }
2024  }
2025 }
2026 
2028 {
2029  if (!pad) return;
2030 
2031  double defleft = gStyle->GetPadLeftMargin(); // always refer to ideal margins
2032  double defright = gStyle->GetPadRightMargin();
2033  double deftop = gStyle->GetPadTopMargin();
2034  double defbottom = gStyle->GetPadBottomMargin();
2035 
2036  double dx = fabs(pad->AbsPixeltoX(1) - pad->AbsPixeltoX(0));
2037  double dy = fabs(pad->AbsPixeltoY(1) - pad->AbsPixeltoY(0));
2038  if ((dx <= 0) || (dy <= 0)) return;
2039  double ratio = dx / dy;
2040  if(fabs(1.0-ratio) < 1.0E-3) {
2041  return; // do not change margins again!
2042  }
2043 
2044 
2045  if (ratio < 1.) {
2046 
2047  double left = pad->GetLeftMargin();
2048  double right = pad->GetRightMargin();
2049  double change = (1. - left - right) * (1 - ratio);
2050  double newleft = left + change / 2.;
2051  double newright = right + change / 2.;
2052  double newtop = pad->GetTopMargin();
2053  double newbottom = pad->GetBottomMargin();
2054  double shrink=newtop- deftop; // zoom everything consistent to the default margins
2055  if(shrink>newleft-defleft) shrink = newleft-defleft; // avoid exceeding default boundaries
2056  if(shrink>newright-defright) shrink = newright-defright; // avoid exceeding default boundaries
2057 
2058  // now scale all margins up to the point that any margin reaches default margin:
2059  newtop = newtop - shrink;
2060  newbottom = newbottom - shrink;
2061  newleft = newleft - shrink;
2062  newright = newright - shrink;
2063 
2064  pad->SetLeftMargin(newleft);
2065  pad->SetRightMargin(newright);
2066  pad->SetTopMargin(newtop);
2067  pad->SetBottomMargin(newbottom);
2068  } else {
2069 
2070  double bottom = pad->GetBottomMargin();
2071  double top = pad->GetTopMargin();
2072  double change = (1. - bottom - top) * (1. - 1 / ratio);
2073  double newleft=pad->GetLeftMargin();
2074  double newright=pad->GetRightMargin();
2075  double newtop= top + change / 2.;
2076  double newbottom= bottom + change / 2.;
2077  double shrink=newleft - defleft;
2078  if(shrink>newtop-deftop) shrink=newtop-deftop; // avoid exceeding default boundaries
2079  if(shrink>newbottom-defbottom) shrink=newbottom-defbottom; // avoid exceeding default boundaries
2080  // now scale all margins up to the point that any margin reaches default margin:
2081  newtop = newtop - shrink;
2082  newbottom = newbottom -shrink;
2083  newleft = newleft- shrink;
2084  newright = newright - shrink;
2085 
2086  pad->SetTopMargin(newtop);
2087  pad->SetBottomMargin(newbottom);
2088  pad->SetLeftMargin(newleft);
2089  pad->SetRightMargin(newright);
2090  }
2091 }
2092 
2094 {
2095  if (!pad) return;
2096  pad->SetLeftMargin(gStyle->GetPadLeftMargin());
2097  pad->SetRightMargin(gStyle->GetPadRightMargin());
2098  pad->SetTopMargin(gStyle->GetPadTopMargin());
2099  pad->SetBottomMargin(gStyle->GetPadBottomMargin());
2100 }
2101 
2103 {
2104  TPad *pad = GetActivePad();
2105  if (!pad)
2106  pad = GetCanvas();
2107 
2108  ClearPad(pad, true, false);
2109 
2110  RedrawPanel(pad, true);
2111 }
2112 
2114 {
2115  // TGo4LockGuard glob;
2116 
2117  ClearPad(GetCanvas(), true, true);
2118 
2120 
2121  RedrawPanel(GetCanvas(), true);
2122 }
2123 
2125 {
2126  TPad *pad = GetActivePad();
2127  if (!pad)
2128  pad = GetCanvas();
2129 
2130  TGo4Picture *padopt = GetPadOptions(pad);
2131 
2132  SetIdAction(fOptionsMap, StatisticsId, true, padopt->IsHisStats());
2135  SetIdAction(fOptionsMap, SetTitleId, true, padopt->IsHisTitle());
2137  padopt->IsTitleTime());
2139  padopt->IsTitleDate());
2141  padopt->IsTitleItem());
2144  SetIdAction(fOptionsMap, SetLegendId, true, padopt->IsLegendDraw());
2146  padopt->IsXAxisTimeDisplay());
2148 }
2149 
2151 {
2152  TGo4LockGuard lock;
2153  if (id == BringToFrontId) {
2157  }
2158  return;
2159  }
2160 
2161  int selected = TGo4Picture::PictureIndex;
2162 
2163  if (id != MasterSelectId)
2164  selected = id - FirstSelectId;
2165 
2166  TGo4Slot *slot = GetPadSlot(GetActivePad());
2167  if (!slot)
2168  return;
2169 
2170  int wasselected = GetSelectedObjectIndex(slot);
2171 
2172  SetSelectedObjectIndex(slot, selected);
2173 
2174  if (selected != wasselected) {
2177  }
2178 
2179  if (selected != TGo4Picture::PictureIndex)
2181 }
2182 
2184 {
2185  if (fBlockSignals)
2186  return;
2187 
2188  bool flag = true;
2189  if (fxQCanvas) {
2190 #ifdef __GO4X11__
2191  flag = !fxQCanvas->isStatusBarVisible();
2193 #endif
2194  } else if (fxWCanvas) {
2195 #ifdef __GO4WEB__
2196  flag = !fxWCanvas->isStatusBarVisible();
2198 #endif
2199  }
2200 
2201  fxCanvasEventstatusChk->setChecked(flag);
2202  if (!flag)
2204 }
2205 
2206 void TGo4ViewPanel::UpdatePadStatus(TPad *pad, bool removeitems)
2207 {
2208  if (!GetPadSlot(pad))
2209  return;
2210 
2211  BlockPanelRedraw(true);
2212  ProcessPadStatusUpdate(pad, nullptr, removeitems);
2213  BlockPanelRedraw(false);
2214 }
2215 
2216 void TGo4ViewPanel::ProcessPadStatusUpdate(TPad *pad, TGo4Slot *parent, bool removeitems)
2217 {
2218  if (!pad)
2219  return;
2220 
2221  TGo4Slot *slot = nullptr;
2222 
2223  bool setdefaults = false;
2224  if (!parent) {
2225  slot = GetPadSlot(pad);
2226  if (!slot)
2227  return;
2228  } else {
2229  slot = parent->FindChild(pad->GetName());
2230  // create slot for subpad if not existing
2231  if (!slot) {
2232  slot = AddNewSlot(pad->GetName(), parent);
2233  SetDrawKind(slot, kind_PadSlot);
2234  setdefaults = true;
2235  }
2236  }
2237 
2238  SetSlotPad(slot, pad);
2239 
2240  TGo4Picture *padopt = GetPadOptions(slot);
2241 
2242  padopt->SetPadModified();
2243 
2244  bool issubpads = false;
2245 
2246  bool isdupluicate = false;
2247 
2248  // check if pads with duplicate names appears in list.
2249  // Remove first copies. Can appiar by RMB menu Divide call
2250  do {
2251  TObjArray subpads;
2252  isdupluicate = false;
2253  TIter iter(pad->GetListOfPrimitives());
2254  while (auto obj = iter()) {
2255  TPad *subpad = dynamic_cast<TPad *>(obj);
2256  if (!subpad)
2257  continue;
2258  issubpads = true;
2259  if (subpads.FindObject(subpad->GetName()))
2260  isdupluicate = true;
2261  if (!isdupluicate)
2262  subpads.Add(subpad);
2263  }
2264  if (isdupluicate) {
2265  pad->GetListOfPrimitives()->RemoveAll(&subpads);
2266  subpads.Delete();
2267  subpads.Compress();
2268  padopt->SetPadModified();
2269  }
2270 
2271  } while (isdupluicate);
2272 
2273  // remove all subslots, which are correspond to non-existing subpads
2274  for (int n = slot->NumChilds() - 1; n >= 0; n--) {
2275  TGo4Slot *subslot = slot->GetChild(n);
2276  TPad *subpad = GetSlotPad(subslot);
2277  if (subpad) {
2278  if (!pad->GetListOfPrimitives()->FindObject(subpad))
2279  delete subslot;
2280  else
2281  issubpads = true;
2282  }
2283  }
2284 
2285  if (setdefaults)
2286  SetPadDefaults(pad);
2287 
2288  if (!issubpads)
2289  return;
2290 
2291  TIter iter(pad->GetListOfPrimitives());
2292  TObjArray removedItems;
2293  while (auto obj = iter()) {
2294  TPad *subpad = dynamic_cast<TPad *>(obj);
2295  if (subpad)
2296  ProcessPadStatusUpdate(subpad, slot, removeitems);
2297  else
2298  removedItems.Add(obj);
2299  }
2300 
2301  pad->GetListOfPrimitives()->RemoveAll(&removedItems);
2302 
2303  if (removeitems)
2304  ClearPadItems(slot, nullptr);
2305 }
2306 
2307 TGo4Slot *TGo4ViewPanel::AddDrawObject(TPad *pad, int kind, const char *itemname,
2308  TObject *obj, bool owner, const char *drawopt)
2309 {
2310  TGo4Slot *padslot = GetPadSlot(pad);
2311 
2312  if (!padslot) {
2313  if (owner) delete obj;
2314  return nullptr;
2315  }
2316 
2317  // clear only if link is added
2318  if (kind < 100)
2319  ClearPad(pad, false, true);
2320 
2321  TGo4Slot *tgtslot = nullptr;
2322 
2323  if (kind == kind_Link) {
2324  TClass *cl = Browser()->ItemClass(itemname);
2325  if (cl && cl->InheritsFrom(TGo4Condition::Class()))
2326  UndrawItem(itemname);
2327 
2328  TGo4Slot *brslot = Browser()->BrowserSlot(itemname);
2329 
2330  if (brslot) {
2331  tgtslot = AddNewSlot(brslot->GetName(), padslot);
2332  SetLinkedName(tgtslot, itemname);
2333  if (fbCloneFlag)
2334  tgtslot->SetProxy(new TGo4DrawCloneProxy(brslot, this));
2335  else
2336  tgtslot->SetProxy(new TGo4LinkProxy(brslot));
2337  }
2338  } else {
2339 
2340  QString newslotname = itemname;
2341  if (newslotname.isEmpty() || padslot->FindChild(newslotname.toLatin1().constData())) {
2342  int cnt = 0;
2343  do {
2344  if (!itemname || (*itemname == 0))
2345  newslotname = "::SpecialObject_";
2346  else
2347  newslotname = itemname;
2348  newslotname += QString::number(cnt++);
2349  } while (padslot->FindChild(newslotname.toLatin1().constData()));
2350  }
2351  tgtslot = AddNewSlot(newslotname.toLatin1().constData(), padslot);
2352  tgtslot->SetProxy(new TGo4ObjectProxy(obj, owner));
2353  }
2354 
2355  if (!tgtslot) return nullptr;
2356 
2357  if (kind < 100)
2359 
2360  tgtslot->SetPar("::FirstDraw", "true");
2361  SetDrawKind(tgtslot, kind);
2362  SetSpecialDrawOption(tgtslot, drawopt);
2363 
2364  TGo4Picture *padopt = GetPadOptions(padslot);
2365  if (padopt) {
2366  padopt->SetContentModified(true);
2367  padopt->SetPadModified();
2368  if ((kind < 100) && drawopt)
2369  padopt->SetDrawOption(drawopt, TGo4Picture::PictureIndex);
2370  }
2371 
2372  return tgtslot;
2373 }
2374 
2375 TGo4Slot *TGo4ViewPanel::GetDrawObjectSlot(TPad *pad, const char *name)
2376 {
2377  TGo4Slot *slot = GetPadSlot(pad);
2378 
2379  return !slot ? nullptr : slot->FindChild(name);
2380 }
2381 
2382 TObject *TGo4ViewPanel::GetDrawObject(TPad *pad, const char *name)
2383 {
2384  TGo4Slot *subslot = GetDrawObjectSlot(pad, name);
2385 
2386  return !subslot ? nullptr : subslot->GetAssignedObject();
2387 }
2388 
2389 void TGo4ViewPanel::DeleteDrawObject(TPad *pad, const char *name)
2390 {
2391  TGo4Slot *padslot = GetPadSlot(pad);
2392 
2393  TGo4Slot *subslot = !padslot ? nullptr : padslot->FindChild(name);
2394 
2395  if (subslot) {
2396  delete subslot;
2397  TGo4Picture *padopt = GetPadOptions(padslot);
2398  if (padopt)
2399  padopt->SetPadModified();
2400  }
2401 }
2402 
2403 void TGo4ViewPanel::DeleteDrawObject(TPad *pad, TObject *obj)
2404 {
2405  TGo4Slot *padslot = GetPadSlot(pad);
2406  if (!padslot)
2407  return;
2408  for (int n = 0; n < padslot->NumChilds(); n++) {
2409  TGo4Slot *subslot = padslot->GetChild(n);
2410  if (GetDrawKind(subslot) < 0)
2411  continue;
2412  if (subslot->GetAssignedObject() == obj) {
2413  delete subslot;
2414  break;
2415  }
2416  }
2417 }
2418 
2419 void TGo4ViewPanel::CollectSpecialObjects(TPad *pad, TObjArray *objs, int selectkind)
2420 {
2421  TGo4Slot *slot = GetPadSlot(pad);
2422  if (!slot || !objs)
2423  return;
2424 
2425  for (int n = 0; n < slot->NumChilds(); n++) {
2426  TGo4Slot *subslot = slot->GetChild(n);
2427  Int_t kind = GetDrawKind(subslot);
2428  if (kind < 0)
2429  continue;
2430  if ((kind != kind_Link) && ((selectkind < 0) || (kind == selectkind))) {
2431  TObject *obj = subslot->GetAssignedObject();
2432  if (obj)
2433  objs->Add(obj);
2434  }
2435  }
2436 }
2437 
2438 bool TGo4ViewPanel::DeleteDrawObjects(TPad *pad, int kindtodelete)
2439 {
2440  TGo4Slot *slot = GetPadSlot(pad);
2441  TGo4Picture *padopt = GetPadOptions(slot);
2442 
2443  if (!slot || !padopt)
2444  return false;
2445 
2446  bool res = false;
2447 
2448  for (int n = slot->NumChilds() - 1; n >= 0; n--) {
2449  TGo4Slot *subslot = slot->GetChild(n);
2450  Int_t kind = GetDrawKind(subslot);
2451  if (kind < 0)
2452  continue;
2453  if ((kind != kind_Link)
2454  && ((kindtodelete < 0) || (kind == kindtodelete))) {
2455  res = true;
2456  delete subslot;
2457  }
2458  }
2459  if (res)
2460  padopt->SetPadModified();
2461  return true;
2462 }
2463 
2464 void TGo4ViewPanel::SetPadSuperImpose(TPad *pad, bool on)
2465 {
2466  TGo4Picture *padopt = GetPadOptions(pad);
2467  if (padopt) {
2468  padopt->SetSuperimpose(on);
2469  padopt->SetPadModified();
2470  }
2471 }
2472 
2474 {
2475  fbModifiedSignalFlag = false;
2476  if (!GetActivePad())
2477  return;
2478 
2480  GetPadOptions(GetActivePad()), true))
2482 }
2483 
2484 bool TGo4ViewPanel::ScanDrawOptions(TPad *pad, TGo4Slot *padslot,
2485  TGo4Picture *pic, bool onlyscan)
2486 {
2487  TGo4LockGuard lock;
2488 
2489  if (!pad || !pic || !padslot)
2490  return false;
2491 
2492  bool optchanged = false;
2493  TObjLink* link = pad->GetListOfPrimitives()->FirstLink();
2494 
2495  while (link) {
2496  const char *clname = link->GetObject()->ClassName();
2497  if ((strcmp(clname, "TFrame") == 0) || (strcmp(clname, "TLegend") == 0)) {
2498 
2499  // comment out, can never be working
2500  //TPaveText* titl = dynamic_cast<TPaveText*>(link->GetObject());
2501  //if (titl &&(strcmp(titl->GetName(),"title") == 0))
2502  // pic->SetTitleAttr(titl);
2503 
2504  link = link->Next();
2505  } else
2506  break;
2507  }
2508 
2509  // take draw options from first drawn object
2510  if (link) {
2511 
2512  TString newopt(link->GetOption());
2513  Int_t drawoptindx = !GetSuperimposeSlot(padslot) ? 0 : TGo4Picture::PictureIndex;
2514  TString oldopt(pic->GetDrawOption(drawoptindx));
2515 
2516  while (newopt.BeginsWith(NoStackDrawOption, TString::kIgnoreCase))
2517  newopt.Remove(0, strlen(NoStackDrawOption));
2518 
2519  if (!oldopt.Contains("asimage"))
2520  if ((newopt.Length() != oldopt.Length())
2521  || (newopt.CompareTo(oldopt, TString::kIgnoreCase) != 0)) {
2522  optchanged = true;
2523  pic->SetDrawOption(newopt.Data(), drawoptindx);
2524  }
2525 
2526  TH1 *h1 = dynamic_cast<TH1 *>(link->GetObject());
2527  // access axis properties of graphs
2528  if(!h1) {
2529  TGraph *gr = dynamic_cast<TGraph *> (link->GetObject());
2530  if(gr) h1 = Get_fHistogram(gr);
2531  }
2532 
2533  if (h1) {
2534  TPaveStats* stats =
2535  dynamic_cast<TPaveStats*>(h1->GetListOfFunctions()->FindObject("stats"));
2536  if (h1->TestBit(TH1::kNoStats)) {
2537  pic->SetHisStats(kFALSE);
2538  } else {
2539  pic->SetHisStats(kTRUE);
2540  pic->SetStatsAttr(stats);
2541  }
2542  // test: set here time display
2543  TAxis *xax = h1->GetXaxis();
2544  pic->SetXAxisAttTime(xax->GetTimeDisplay(), xax->GetTimeFormat() ,TGo4Picture::PictureIndex);
2545  }
2546 
2547  }
2548 
2549  if (pad->GetLogx() != pic->GetLogScale(0)) {
2550  pic->SetLogScale(0, pad->GetLogx());
2551  optchanged = true;
2552  }
2553 
2554  if (pad->GetLogy() != pic->GetLogScale(1)) {
2555  pic->SetLogScale(1, pad->GetLogy());
2556  optchanged = true;
2557  }
2558 
2559  if (pad->GetLogz() != pic->GetLogScale(2)) {
2560  pic->SetLogScale(2, pad->GetLogz());
2561  optchanged = true;
2562  }
2563 
2564  if (pad == GetCanvas())
2565  fbCanvasCrosshair = pad->HasCrosshair();
2566 
2567  TPaveText *titl = dynamic_cast<TPaveText *>(pad->GetListOfPrimitives()->FindObject("title"));
2568  if (titl) {
2569  pic->SetTitleAttr(titl);
2570  optchanged = true;
2571  }
2572 
2573  TObjArray objs, objslots;
2574 
2575  CollectMainDrawObjects(padslot, &objs, &objslots, 0);
2576  ScanObjectsDrawOptions(onlyscan, padslot, &objs, &objslots);
2577 
2578  return optchanged;
2579 }
2580 
2582  TObjArray *objs, TObjArray *objslots)
2583 {
2584  TGo4Picture *pic = GetPadOptions(padslot);
2585 
2586  TPad *pad = GetSlotPad(padslot);
2587  if (pad && pic) {
2588  if (padslot->GetPar("::DrawOptAssigned")) {
2590  } else if (!onlyscan) {
2592  padslot->SetPar("::DrawOptAssigned", "1");
2593  }
2594  }
2595 
2596  if (!padslot || !pic || !objs || !objslots)
2597  return;
2598 
2599  for (int n = 0; n <= objs->GetLast(); n++) {
2600  TObject *obj = objs->At(n);
2601  TGo4Slot *subslot = (TGo4Slot *) objslots->At(n);
2602 
2603  if (!obj || !subslot)
2604  continue;
2605 
2606  if (subslot->GetPar("::DrawOptAssigned")) {
2607  pic->SetDrawAttributes(obj, n);
2608  } else if (!onlyscan) {
2609  pic->GetDrawAttributes(obj, n);
2610  subslot->SetPar("::DrawOptAssigned", "1");
2611  }
2612  }
2613 }
2614 
2615 void TGo4ViewPanel::CollectMainDrawObjects(TGo4Slot *slot, TObjArray *objs, TObjArray *objslots, int modifier)
2616 {
2617  // modifier == 0 - no objects can be deleted
2618  // == 1 - objects of same types should be in the list
2619  // == 2 - only last object survive
2620  if (!slot || !objs)
2621  return;
2622 
2623  TObjArray mainslots;
2624 
2625  int lastobjtype = 0;
2626 
2627  for (int n = 0; n < slot->NumChilds(); n++) {
2628  TGo4Slot *subslot = slot->GetChild(n);
2629  Int_t kind = GetDrawKind(subslot);
2630 
2631  if ((kind <= 0) || (kind >= kind_Additional))
2632  continue;
2633 
2634  TObject *obj = subslot->GetAssignedObject();
2635 
2636  if (!obj)
2637  continue;
2638 
2639  int objtype = 0;
2640 
2641  if (obj->InheritsFrom(TH1::Class()))
2642  objtype = 1;
2643  else if (obj->InheritsFrom(TGraph::Class()))
2644  objtype = 2;
2645  else if (obj->InheritsFrom(TMultiGraph::Class()))
2646  objtype = 3;
2647  else if (obj->InheritsFrom(THStack::Class()))
2648  objtype = 4;
2649 
2650  // can happen condition here, which is add as link and not identified as condition yet
2651  // should both be recognized as "main" draw object
2652  if (objtype > 0) {
2653  lastobjtype = objtype;
2654  mainslots.Add(subslot);
2655  }
2656  }
2657 
2658  Bool_t deletesomething = kFALSE;
2659 
2660  for (int n = 0; n <= mainslots.GetLast(); n++) {
2661  TGo4Slot *subslot = (TGo4Slot *) mainslots.At(n);
2662  TObject *obj = subslot->GetAssignedObject();
2663  Int_t objtype = 0;
2664  if (obj->InheritsFrom(TH1::Class()))
2665  objtype = 1;
2666  else if (obj->InheritsFrom(TGraph::Class()))
2667  objtype = 2;
2668  else if (obj->InheritsFrom(TMultiGraph::Class()))
2669  objtype = 3;
2670  else if (obj->InheritsFrom(THStack::Class()))
2671  objtype = 4;
2672 
2673  // check if all main object correspond to type of last object
2674  // if no, delete
2675 
2676  if ((n < mainslots.GetLast()) && ((modifier == 2) || ((modifier == 1) && (lastobjtype != objtype)))) {
2677  delete subslot;
2678  deletesomething = kTRUE;
2679  } else {
2680  objs->Add(obj);
2681  if (objslots)
2682  objslots->Add(subslot);
2683  TGo4DrawCloneProxy *pr = dynamic_cast<TGo4DrawCloneProxy *>(subslot->GetProxy());
2684  if (pr) {
2685  pr->UpdateTitle();
2686  pr->PerformRebin();
2687  }
2688  }
2689  }
2690 
2691  if (deletesomething)
2692  CleanupGedEditor();
2693 
2694  for (int n = 0; n < slot->NumChilds(); n++) {
2695  TGo4Slot *subslot = slot->GetChild(n);
2696 
2697  Int_t kind = GetDrawKind(subslot);
2698  if ((kind >= kind_Additional) && (kind < kind_Specials)) {
2699  TObject *obj = subslot->GetAssignedObject();
2700  if (obj) {
2701  objs->Add(obj);
2702  if (objslots)
2703  objslots->Add(subslot);
2704  }
2705  }
2706  }
2707 }
2708 
2710 {
2711  if (indx < 0) indx = 0;
2712 
2713  switch (indx % 10) {
2714  case 0: return kBlack;
2715  case 1: return kRed;
2716  case 2: return kGreen;
2717  case 3: return kBlue;
2718  case 4: return kCyan;
2719  case 5: return kOrange;
2720  case 6: return kSpring;
2721  case 7: return kViolet;
2722  case 8: return kPink;
2723  case 9: return kAzure;
2724  }
2725 
2726  return kBlack;
2727 }
2728 
2729 
2731  TGo4Slot *sislot, TGo4Slot *legslot, TObjArray *objs,
2732  TObjArray * objslots, bool showitems)
2733 {
2734  if (!sislot || !objs || !padopt) return nullptr;
2735  TObject *oldobj = sislot->GetAssignedObject();
2736 
2737  Bool_t ishstack = kFALSE;
2738  Bool_t isgstack = kFALSE;
2739  Bool_t iserror = kFALSE;
2740  Bool_t resetcolors = kFALSE;
2741 
2742  for (int n = 0; n <= objs->GetLast(); n++) {
2743  TObject *obj = objs->At(n);
2744  if (obj->InheritsFrom(TH1::Class()))
2745  ishstack = kTRUE;
2746  else if (obj->InheritsFrom(TGraph::Class()))
2747  isgstack = kTRUE;
2748  else
2749  iserror = kTRUE;
2750  }
2751 
2752  // if error, no superimpose is allowed
2753  if (iserror || (ishstack && isgstack)) {
2754  TGo4Log::Error("Superimpose of multiple objects with different types");
2755  return nullptr;
2756  }
2757 
2758  if (ishstack) {
2759  THStack *hs = dynamic_cast<THStack*>(oldobj);
2760 
2761  if (!hs) {
2762  hs = new THStack(objs->First()->GetName(), objs->First()->GetTitle());
2763  sislot->SetProxy(new TGo4DrawObjProxy(hs, kTRUE, kTRUE));
2764  resetcolors = kTRUE;
2765  } else {
2766  if (hs->GetHists())
2767  hs->GetHists()->Clear();
2768  }
2769 
2770  for (int n = 0; n <= objs->GetLast(); n++) {
2771  TH1 *histo = (TH1 *) objs->At(n);
2772  TGo4Slot *objslot = (TGo4Slot *) objslots->At(n);
2773 
2774  Int_t kind = GetDrawKind(objslot);
2775  // Int_t objindx = padslot->GetIndexOf(objslot); // slot index for object starts from 2
2776 
2777  if (resetcolors || (kind == kind_FitModels) || objslot->GetPar("::FirstDraw")) {
2778  histo->SetLineColor(GetAutoColor(n));
2779  if ((go4sett->getDrawLineWidth() > 1) && (histo->GetLineWidth()==1))
2780  histo->SetLineWidth(go4sett->getDrawLineWidth());
2781  }
2782 
2783  histo->GetXaxis()->UnZoom();
2784 
2785  const char *drawopt = padopt->GetDrawOption(n);
2786  if (!drawopt)
2787  drawopt = GetSpecialDrawOption(objslot);
2788 
2789  objslot->RemovePar("::FirstDraw");
2790 
2791  hs->Add(histo, drawopt);
2792  }
2793  oldobj = hs;
2794  } else if (isgstack) {
2795  TMultiGraph *mgr = dynamic_cast<TMultiGraph *>(oldobj);
2796  if (!mgr) {
2797  mgr = new TMultiGraph(objs->First()->GetName(), objs->First()->GetTitle());
2798  sislot->SetProxy(new TGo4DrawObjProxy(mgr, kTRUE, kTRUE));
2799  resetcolors = kTRUE;
2800  } else if (mgr->GetListOfGraphs()) {
2801  mgr->GetListOfGraphs()->Clear();
2802  }
2803 
2804  for (int n = 0; n <= objs->GetLast(); n++) {
2805  TGraph *gr = (TGraph *) objs->At(n);
2806  TGo4Slot *objslot = (TGo4Slot *) objslots->At(n);
2807 
2808  Int_t kind = GetDrawKind(objslot);
2809 
2810  TString drawopt = padopt->GetDrawOption(n);
2811  if (drawopt.IsNull())
2812  drawopt = GetSpecialDrawOption(objslot);
2813  if (drawopt.IsNull())
2814  drawopt = go4sett->getTGraphDrawOpt().toLatin1().constData();
2815 
2816  drawopt.ToLower();
2817 
2818  // suppress multiple drawing of axis for subgraphs
2819  if (n > 0) drawopt.ReplaceAll("a", "");
2820 
2821  Bool_t first_draw = objslot->GetPar("::FirstDraw") != nullptr;
2822 
2823  Int_t objindx = padslot->GetIndexOf(objslot); // slot index for object starts from 2
2824 
2825  if (resetcolors || (kind == kind_FitModels) || first_draw) {
2826  // use only basic 9 colors
2827  Int_t nextcol = GetAutoColor(((objindx + 7) % 9));
2828  gr->SetLineColor(nextcol);
2829  gr->SetMarkerColor(nextcol);
2830  if ((go4sett->getDrawLineWidth() > 1) && (gr->GetLineWidth()==1))
2831  gr->SetLineWidth(go4sett->getDrawLineWidth());
2832  }
2833 
2834  if (first_draw && (n == 0)) {
2835  TAxis *ax = gr->GetXaxis();
2836  if (ax && ax->GetTimeDisplay()) {
2837  padopt->SetHisStats(kFALSE);
2838  padopt->SetXAxisTimeDisplay(kTRUE);
2839  padopt->SetXAxisTimeFormat(ax->GetTimeFormat());
2840  }
2841  }
2842 
2843  objslot->RemovePar("::FirstDraw");
2844 
2845  mgr->Add(gr, drawopt.Data());
2846  }
2847  oldobj = mgr;
2848  }
2849 
2850  if ((ishstack || isgstack) && legslot) {
2851  TLegend* legend = dynamic_cast<TLegend*>(legslot->GetAssignedObject());
2852 
2853  if (!legend) {
2854  double miny = 0.94 - 0.03 * objs->GetLast();
2855  if (miny < 0.6)
2856  miny = 0.6;
2857  else if (miny > 0.92)
2858  miny = 0.92;
2859  legend = new TLegend(0.6, miny, 0.95, 0.99);
2860  legend->SetBorderSize(2);
2861  legend->SetName("fitlegend");
2862  legslot->SetProxy(new TGo4ObjectProxy(legend, kTRUE));
2863  } else {
2864  legend->Clear();
2865  }
2866 
2867  for (int n = 0; n <= objs->GetLast(); n++) {
2868  TObject *stob = objs->At(n);
2869 
2870  const char *objname = stob->GetName();
2871 
2872  if (showitems && objslots) {
2873  const char *itemname = GetLinkedName((TGo4Slot *) objslots->At(n));
2874  if (itemname) objname = itemname;
2875  }
2876 
2877  TString ldrawopt = "l";
2878 
2879  if (!ishstack) {
2880  ldrawopt = "";
2881  TString drawopt = padopt->GetDrawOption(n);
2882  drawopt.ToLower();
2883  if (drawopt.Contains("l")) ldrawopt+="l";
2884  if (drawopt.Contains("p")) ldrawopt+="p";
2885  }
2886 
2887  if (ldrawopt.IsNull()) ldrawopt = "l";
2888 
2889  legend->AddEntry(stob, objname, ldrawopt.Data());
2890  }
2891  }
2892 
2893  return oldobj;
2894 }
2895 
2896 void TGo4ViewPanel::Divide(int numX, int numY)
2897 {
2898  TPad *pad = GetActivePad();
2899 
2900  TGo4Slot *padslot = GetPadSlot(pad);
2901  if (!pad || !padslot) return;
2902 
2903  ClearPad(pad, true, true);
2904  RedrawPanel(pad, true);
2905 
2906  if ((numX > 1) || (numY > 1)) {
2907  pad->Divide(numX, numY);
2908 
2909  UpdatePadStatus(pad, true);
2910 
2911  RedrawPanel(pad, true);
2912  }
2913 
2914  // note: number of pads will be changed in list of previewpanelstatus by InitPad
2915 // RefreshButtons();
2916 }
2917 
2918 void TGo4ViewPanel::SetSlotPad(TGo4Slot *padslot, TPad *pad)
2919 {
2920  TGo4Slot *tgtslot = padslot->FindChild("::ThisPad");
2921  if (!tgtslot)
2922  tgtslot = new TGo4Slot(padslot, "::ThisPad", "Special object");
2923  tgtslot->SetProxy(new TGo4ObjectProxy(pad, kFALSE));
2924  SetDrawKind(tgtslot, kind_ThisPad);
2925  ConnectPad(pad);
2926 
2927  AllocatePadOptions(pad);
2928 }
2929 
2931 {
2932  if (pad == GetCanvas())
2933  return GetPanelSlot();
2934 
2935  TGo4Iter iter(GetPanelSlot(), kTRUE);
2936  while (iter.next()) {
2937  TGo4Slot *subslot = iter.getslot();
2938  if (GetDrawKind(subslot) == kind_PadSlot)
2939  if (GetSlotPad(subslot) == pad)
2940  return subslot;
2941  }
2942  return nullptr;
2943 }
2944 
2946 {
2947  if (!slot)
2948  return nullptr;
2949 
2950  TGo4Slot *tgtslot = slot->FindChild("::ThisPad");
2951 
2952  return !tgtslot ? nullptr : (TPad *) tgtslot->GetAssignedObject();
2953 }
2954 
2956 {
2957  if (!padslot)
2958  return false;
2959  for (int n = 0; n < padslot->NumChilds(); n++)
2960  if (GetSlotPad(padslot->GetChild(n)))
2961  return true;
2962  return false;
2963 }
2964 
2966 {
2967  return IsPadHasSubPads(GetPadSlot(pad));
2968 }
2969 
2971 {
2972  TGo4Picture *padopt = GetPadOptions(pad);
2973  if (padopt)
2974  padopt->SetPadModified();
2975 }
2976 
2978 {
2979  return GetPadSlot(pad) != nullptr;
2980 }
2981 
2983 {
2984  if (!toppad)
2985  toppad = GetCanvas();
2986  int number = 1;
2987  TGo4Iter iter(GetPadSlot(toppad), kTRUE);
2988  while (iter.next()) {
2989  TPad *pad = GetSlotPad(iter.getslot());
2990  if (pad)
2991  number++;
2992  }
2993  return number;
2994 }
2995 
2996 TPad *TGo4ViewPanel::GetSubPad(TPad *toppad, int num, bool onlytoplevel)
2997 {
2998  if (!toppad)
2999  toppad = GetCanvas();
3000  TGo4Slot *slot = GetPadSlot(toppad);
3001  if (!slot)
3002  return nullptr;
3003 
3004  int cnt = -1;
3005  if (!onlytoplevel || !IsPadHasSubPads(slot))
3006  cnt++;
3007 
3008  if (num == cnt)
3009  return toppad;
3010 
3011  TGo4Iter iter(slot, kTRUE);
3012  while (iter.next()) {
3013  TGo4Slot *subslot = iter.getslot();
3014  TPad *pad = GetSlotPad(subslot);
3015  if (!pad)
3016  continue;
3017  if (!onlytoplevel || !IsPadHasSubPads(subslot))
3018  cnt++;
3019  if (num == cnt)
3020  return pad;
3021  }
3022  return nullptr;
3023 }
3024 
3025 void TGo4ViewPanel::ProducePadsList(TObjArray *arr, TPad *toppad)
3026 {
3027  if (!arr)
3028  return;
3029  if (!toppad)
3030  toppad = GetCanvas();
3031 
3032  arr->Add(toppad);
3033 
3034  TGo4Iter iter(GetPadSlot(toppad), kTRUE);
3035  while (iter.next()) {
3036  TPad *pad = GetSlotPad(iter.getslot());
3037  if (pad)
3038  arr->Add(pad);
3039  }
3040 }
3041 
3042 const char *TGo4ViewPanel::GetDrawObjectLinkName(TPad *pad, TObject *obj)
3043 {
3044  TGo4Slot *slot = GetPadSlot(pad);
3045  if (!pad || !slot || !obj)
3046  return nullptr;
3047 
3048  for (int n = 0; n < slot->NumChilds(); n++) {
3049  TGo4Slot *subslot = slot->GetChild(n);
3050  if (subslot->GetAssignedObject() == obj)
3051  return GetLinkedName(subslot);
3052  }
3053  return nullptr;
3054 }
3055 
3057 {
3058  return !padslot ? nullptr : padslot->FindChild("::Superimpose");
3059 }
3060 
3062 {
3063  TGo4Slot *slot = GetPadSlot(pad);
3064  if (!pad || !slot)
3065  return nullptr;
3066 
3067  for (int n = 0; n < slot->NumChilds(); n++) {
3068  TGo4Slot *subslot = slot->GetChild(n);
3069  Int_t kind = GetDrawKind(subslot);
3070  if ((kind <= 0) || (kind >= kind_Additional))
3071  continue;
3072  TObject *obj = subslot->GetAssignedObject();
3073  if (obj)
3074  return subslot;
3075  }
3076  return nullptr;
3077 }
3078 
3080 {
3081  TGo4Slot *slot = GetPadMainObjectSlot(pad);
3082  return !slot ? nullptr : slot->GetAssignedObject();
3083 }
3084 
3086 {
3087 #ifdef __GO4X11__
3088  if (fxQCanvas)
3089  return fxQCanvas->getCanvas();
3090 #endif
3091 
3092 #ifdef __GO4WEB__
3093  if (fxWCanvas)
3094  return fxWCanvas->getCanvas();
3095 #endif
3096 
3097  return nullptr;
3098 }
3099 
3101 {
3102  if (fxQCanvas) {
3103 #ifdef __GO4X11__
3104  if (modify) fxQCanvas->Modified();
3105  fxQCanvas->Update();
3106 #endif
3107  } else if (fxWCanvas) {
3108 #ifdef __GO4WEB__
3109  if (modify) fxWCanvas->Modified();
3110  fxWCanvas->Update();
3111 #endif
3112  }
3113 }
3114 
3116 {
3117  return fxActivePad;
3118 }
3119 
3121 {
3122  TGo4Slot *padslot = GetPadSlot(pad);
3123  if (!padslot)
3124  return;
3125 
3126  TGo4Slot *tgtslot = padslot->FindChild("::PadOptions");
3127  if (!tgtslot) {
3128  tgtslot = new TGo4Slot(padslot, "::PadOptions", "Pad options slot");
3129  TGo4Picture *opt = new TGo4Picture;
3131  tgtslot->SetProxy(new TGo4ObjectProxy(opt, kTRUE));
3132  SetDrawKind(tgtslot, kind_PadOptions);
3133  }
3134 }
3135 
3137 {
3138  return GetPadOptions(GetPadSlot(pad));
3139 }
3140 
3142 {
3143  if (!padslot)
3144  return nullptr;
3145  TGo4Slot *tgtslot = padslot->FindChild("::PadOptions");
3146  return !tgtslot ? nullptr : (TGo4Picture *) tgtslot->GetAssignedObject();
3147 }
3148 
3150 {
3151  TGo4Slot *padslot = GetPadSlot(pad);
3152 
3153  if (!pad || !padslot)
3154  return nullptr;
3155 
3156  TObject *obj = nullptr;
3157 
3158  TGo4Slot *sislot = GetSuperimposeSlot(padslot);
3159  if (sislot)
3160  obj = sislot->GetAssignedObject();
3161 
3162  if (!obj)
3163  obj = GetPadMainObject(pad);
3164  if (!obj)
3165  return nullptr;
3166 
3167  if (obj->InheritsFrom(TH1::Class()))
3168  return (TH1 *) obj;
3169 
3170  TPadGuard lock(fxWCanvas ? nullptr : gPad); // replace gPad to avoid redrawing of canvas
3171 
3172  if (obj->InheritsFrom(TGraph::Class()))
3173  // return graph histogram - if need create them in not web case
3174  return Get_fHistogram(obj, true);
3175 
3176  if (obj->InheritsFrom(THStack::Class()))
3177  return Get_fHistogram(obj, true);
3178 
3179  if (obj->InheritsFrom(TMultiGraph::Class())) {
3180  TMultiGraph *mg = dynamic_cast<TMultiGraph *>(obj);
3181  if (mg) {
3182  // do not force here, otherwise never come to the TGraph
3183  TH1 *h = Get_fHistogram(mg);
3184  if (h) return h;
3185 
3186  TIter iter(mg->GetListOfGraphs());
3187  while (auto gr = (TGraph *) iter()) {
3188  h = Get_fHistogram(gr, true);
3189  if (h) return h;
3190  }
3191  }
3192  }
3193 
3194  return nullptr;
3195 }
3196 
3198 {
3199  if (on)
3201  else
3203 }
3204 
3206 {
3207  return fiSkipRedrawCounter > 0;
3208 }
3209 
3211 {
3212  TGo4Slot *slot = GetPadSlot(GetActivePad());
3213  if (!slot)
3214  return;
3215 
3216  fSelectMenu->clear();
3217 
3218  TGo4Slot *sislot = GetSuperimposeSlot(slot);
3219 
3220  TObjArray objs, objslots;
3221  CollectMainDrawObjects(slot, &objs, &objslots, 0);
3222 
3223  Int_t nselectitem = 0;
3224 
3225  int selected = GetSelectedObjectIndex(slot);
3226 
3227  if ((selected > objs.GetLast()) || ((selected == TGo4Picture::PictureIndex) && !sislot)) {
3228  SetSelectedObjectIndex(slot, 0);
3229  selected = 0;
3230  }
3231 
3232  if (sislot) {
3233  AddIdAction(fSelectMenu, fSelectMap, "Master object", MasterSelectId);
3234  fSelectMenu->addSeparator();
3235  nselectitem++;
3236  }
3237 
3238  QString capt = GetPanelName();
3239  QString fulllist = "";
3240  QString selslotname = "";
3241 
3242  for (int n = 0; n <= objslots.GetLast(); n++) {
3243  TGo4Slot *subslot = (TGo4Slot *) objslots.At(n);
3244  AddIdAction(fSelectMenu, fSelectMap, objs.At(n)->GetName(),
3245  FirstSelectId + n);
3246  nselectitem++;
3247 
3248  QString subslotname = subslot->GetName();
3249  if (n == selected) {
3250  subslotname = QString("[") + subslotname + QString("]");
3251  selslotname = subslotname;
3252  }
3253  if (n > 0) fulllist += ", ";
3254  fulllist += subslotname;
3255  }
3256 
3257  if ((selected != TGo4Picture::PictureIndex) && (objslots.GetLast() > 0)
3258  && (selected < objslots.GetLast())) {
3259  fSelectMenu->addSeparator();
3261  QString("Show ") + selslotname + QString(" on top"),
3262  BringToFrontId);
3263  }
3264 
3265  if ((selected == TGo4Picture::PictureIndex) && (fulllist.length() > 0))
3266  fulllist = QString("[") + fulllist + QString("]");
3267 
3268  fSelectMenu->setEnabled(nselectitem > 0);
3269 
3270  if (nselectitem > 0) {
3271  if (selected == TGo4Picture::PictureIndex)
3272  SetIdAction(fSelectMap, MasterSelectId, true, true);
3273  else
3274  SetIdAction(fSelectMap, FirstSelectId + selected, true, true);
3275  }
3276 
3277  if (fulllist.length() > 0) {
3278  capt += ": ";
3279  capt += fulllist;
3280  }
3281 
3282  if (capt.length() > 60) {
3283  capt.truncate(58);
3284  capt += "...";
3285  }
3286 
3287  if (!fbFreezeTitle)
3288  setWindowTitle(capt);
3289 }
3290 
3292 {
3293  if (!slot)
3294  return;
3295  if (kind <= 0)
3296  slot->RemovePar("::DrawKind");
3297  else
3298  slot->SetIntPar("::DrawKind", kind);
3299 }
3300 
3301 void TGo4ViewPanel::SetSpecialDrawOption(TGo4Slot *slot, const char *drawopt)
3302 {
3303  if (!slot)
3304  return;
3305  if (drawopt)
3306  slot->SetPar("::DrawOpt", drawopt);
3307  else
3308  slot->RemovePar("::DrawOpt");
3309 }
3310 
3312 {
3313  if (!slot)
3314  return -1;
3315  Int_t kind;
3316  if (!slot->GetIntPar("::DrawKind", kind))
3317  return -1;
3318  return kind;
3319 }
3320 
3322 {
3323  return !slot ? nullptr : slot->GetPar("::DrawOpt");
3324 }
3325 
3327 {
3328  if (slot)
3329  slot->SetIntPar("::SelectedObject", indx);
3330 }
3331 
3333 {
3334  if (!slot)
3335  return 0;
3336  Int_t indx = 0;
3337  if (!slot->GetIntPar("::SelectedObject", indx))
3338  indx = 0;
3339  return indx;
3340 }
3341 
3342 TObject *TGo4ViewPanel::GetSelectedObject(TPad *pad, const char **drawopt)
3343 {
3344  TGo4Slot *slot = GetPadSlot(pad);
3345  TGo4Picture *padopt = GetPadOptions(slot);
3346  if (!slot || !padopt)
3347  return nullptr;
3348 
3349  int indx = GetSelectedObjectIndex(slot);
3350 
3351  TGo4Slot *sislot = GetSuperimposeSlot(slot);
3352  if (sislot && (indx == TGo4Picture::PictureIndex)) {
3353  if (drawopt)
3354  *drawopt = padopt->GetDrawOption(TGo4Picture::PictureIndex);
3355  return sislot->GetAssignedObject();
3356  }
3357 
3358  TObjArray objs, objslots;
3359  CollectMainDrawObjects(slot, &objs, &objslots, 0);
3360 
3361  if (objs.GetLast() < 0)
3362  return nullptr;
3363 
3364  if ((indx > objs.GetLast()) || (indx < 0))
3365  indx = 0;
3366 
3367  if (drawopt) {
3368  const char *resopt = padopt->GetDrawOption(indx);
3369  if (!resopt)
3370  resopt = GetSpecialDrawOption((TGo4Slot *) objslots.At(indx));
3371 
3372  *drawopt = resopt;
3373  }
3374 
3375  return objs.At(indx);
3376 }
3377 
3379 {
3380  TGo4Slot *slot = GetPadSlot(pad);
3381  TGo4Picture *padopt = GetPadOptions(slot);
3382  if (!slot || !padopt)
3383  return false;
3384 
3385  int indx = GetSelectedObjectIndex(slot);
3386 
3387  TObjArray objs, objslots;
3388  CollectMainDrawObjects(slot, &objs, &objslots, 0);
3389 
3390  // no sense to shift object which is already at the end
3391  if ((objs.GetLast() <= 0) || (indx == objs.GetLast()))
3392  return false;
3393 
3394  TGo4Slot *selslot = (TGo4Slot *) objslots.At(indx);
3395  TGo4Slot *lastslot = (TGo4Slot *) objslots.Last();
3396 
3397  if (!slot->ShiftSlotAfter(selslot, lastslot))
3398  return false;
3399 
3400  SetSelectedObjectIndex(slot, objs.GetLast());
3401 
3402  return true;
3403 }
3404 
3406 {
3407  if (!pad || !padslot) return;
3408 
3409  TObjArray objs, objslots;
3410  CollectMainDrawObjects(padslot, &objs, &objslots, 0);
3411 
3412  int indx = GetSelectedObjectIndex(padslot);
3413  if (indx < 0) indx = 0;
3414 
3415  TH1 *selhisto = dynamic_cast<TH1 *>((indx <= objs.GetLast()) ? objs.At(indx) : nullptr);
3416  if (!selhisto)
3417  selhisto = GetPadHistogram(pad);
3418 
3419  for (int n = 0; n < padslot->NumChilds(); n++) {
3420  TGo4Slot *subslot = padslot->GetChild(n);
3421  Int_t kind = GetDrawKind(subslot);
3422  TObject *obj = subslot->GetAssignedObject();
3423  if (!obj) continue;
3424 
3425  TGo4Marker* mark = nullptr;
3426  TGo4Condition *cond = nullptr;
3427 
3428  // reset condition and marker histogram
3429  if ((kind >= kind_Specials) && (kind < kind_Other)) {
3430  if (obj->InheritsFrom(TGo4Condition::Class()))
3431  cond = (TGo4Condition *) obj;
3432  else if (obj->InheritsFrom(TGo4Marker::Class()))
3433  mark = (TGo4Marker*) obj;
3434  } else if (kind == kind_Condition)
3435  cond = dynamic_cast<TGo4Condition *>(obj);
3436 
3437  TH1 *oldhisto = nullptr;
3438 
3439  if (cond)
3440  oldhisto = cond->GetWorkHistogram();
3441  else if (mark)
3442  oldhisto = mark->GetHistogram();
3443 
3444  if (oldhisto)
3445  if (!objs.FindObject(oldhisto))
3446  oldhisto = nullptr;
3447 
3448  if (!oldhisto) {
3449  if (cond) {
3450  cond->SetWorkHistogram(selhisto);
3451  } else if (mark) {
3452  mark->SetHistogram(selhisto);
3453  }
3454  }
3455  }
3456 }
3457 
3458 void TGo4ViewPanel::SetFreezedTitle(const QString& title)
3459 {
3460  QString mycaption = GetPanelName();
3461  mycaption += ": ";
3462  mycaption += title;
3463  setWindowTitle(mycaption);
3464  fbFreezeTitle = true;
3465  fFreezedTitle = title;
3466 }
3467 
3469 {
3470  if (!pad || !padslot)
3471  return;
3472 
3473  TGo4Picture *pic = nullptr;
3474  TGo4Slot *picslot = nullptr;
3475  TCanvas *canv = nullptr;
3476  TGo4Slot *canvslot = nullptr;
3477 
3478  int numcond = 0;
3479 
3480  for (int n = 0; n < padslot->NumChilds(); n++) {
3481  TGo4Slot *subslot = padslot->GetChild(n);
3482  Int_t kind = GetDrawKind(subslot);
3483  if (kind == kind_Condition)
3484  numcond++;
3485 
3486  TObject *obj = subslot->GetAssignedObject();
3487  if (!obj)
3488  continue;
3489 
3490  if ((kind < 0) || (kind >= 100))
3491  continue;
3492 
3493  // change drawkind of condition which is drawn as normal object
3494  if (obj->InheritsFrom(TGo4Condition::Class())) {
3495  numcond++;
3496  TGo4Condition *cond = static_cast<TGo4Condition *>(obj);
3497  cond->SetLineColor(GetAutoColor(numcond));
3498  cond->SetFillColor(GetAutoColor(numcond));
3499  cond->SetFillStyle(3444);
3500  SetDrawKind(subslot, kind_Condition);
3501  continue;
3502  }
3503 
3504  if (obj->InheritsFrom(TLatex::Class())) {
3505  SetDrawKind(subslot, kind_Latex);
3506  continue;
3507  }
3508  // JAM test
3509  if (obj->InheritsFrom(TF1::Class())) {
3510  SetDrawKind(subslot, kind_Func);
3511  continue;
3512  }
3513  if (!pic) {
3514  pic = dynamic_cast<TGo4Picture *>(obj);
3515  if (pic)
3516  picslot = subslot;
3517  }
3518 
3519  if (!canv) {
3520  canv = dynamic_cast<TCanvas *>(obj);
3521  if (canv)
3522  canvslot = subslot;
3523  }
3524  }
3525 
3526  if (pic) {
3527 
3528  ClearPadItems(padslot, picslot);
3529 
3530  // remove all subpads if any but do not remove items while picture is there
3531  ClearPad(pad, false, true);
3532 
3533  ProcessPictureRedraw(GetLinkedName(picslot), pad, pic);
3534 
3535  if (pad == GetCanvas())
3536  SetFreezedTitle(pic->GetTitle());
3537 
3538  // remove picture from the pad
3539  delete picslot;
3540 
3541  return;
3542  }
3543 
3544  if (canv) {
3545  // remove all other
3546  ClearPadItems(padslot, canvslot);
3547 
3548  // remove all subpads if any but do not remove items while picture is there
3549  ClearPad(pad, false, true);
3550 
3551  TVirtualPad *padsav = gPad;
3552 
3553  ProcessCanvasAdopt(pad, canv, GetLinkedName(canvslot));
3554 
3555  if (padsav)
3556  padsav->cd();
3557 
3558  delete canvslot;
3559  }
3560 }
3561 
3562 void TGo4ViewPanel::ProcessPictureRedraw(const char *picitemname, TPad *pad, TGo4Picture *pic)
3563 {
3564  if (!pad || !pic) return;
3565 
3566  if (pic->IsDivided()) {
3567  pad->Divide(pic->GetDivX(), pic->GetDivY());
3568 
3569  // this create appropriate entries in the OM
3570  UpdatePadStatus(pad, false);
3571 
3572  for (Int_t posy = 0; posy < pic->GetDivY(); posy++)
3573  for (Int_t posx = 0; posx < pic->GetDivX(); posx++) {
3574  TGo4Picture *sub = pic->FindPic(posy, posx);
3575  if (sub)
3576  ProcessPictureRedraw(picitemname, (TPad *)pad->GetPad(posy * pic->GetDivX() + posx + 1), sub);
3577  }
3578 
3579  return;
3580  }
3581 
3582  TGo4Picture *padopt = GetPadOptions(pad);
3583  if (!padopt) {
3584  TGo4Log::Error("Internal problem in view panel redraw");
3585  return;
3586  }
3587 
3588  pic->GetFrameAttr(pad); // do it only once, pad preserves automatically
3589 
3591 
3592  SetAutoZoomFlag(pic->IsAutoZoom());
3593 
3594  padopt->CopyOptionsFrom(pic);
3595 
3597 
3598  TGo4BrowserProxy *brcont = Browser();
3599 
3600  Option_t *drawopt = pic->GetDrawOption(TGo4Picture::PictureIndex);
3601  if (drawopt)
3603 
3604  Int_t ndraw = 0;
3605 
3606  for (Int_t n = 0; n < pic->GetNumObjNames(); n++) {
3607  Option_t *drawopt = pic->GetDrawOption(n);
3608  if (drawopt)
3609  pic->SetDrawOption(drawopt, n);
3610 
3611  const char *objname = pic->GetObjName(n);
3612 
3613  TString drawname;
3614 
3615  if (brcont->DefineRelatedObject(picitemname, objname, drawname)) {
3616 
3617  TGo4Slot *slot = AddDrawObject(pad, kind_Link, drawname.Data(), nullptr, false, nullptr);
3618 
3619  brcont->GetBrowserObject(drawname.Data(), go4sett->getFetchDataWhenDraw() ? 2 : 1);
3620  ndraw++;
3621 
3622  if (pic->GetRebinX(n) > 1) {
3623  slot->SetIntPar("::DoRebinX", pic->GetRebinX(n));
3624  slot->SetIntPar("::HasRebinX", pic->GetRebinX(n));
3625  }
3626 
3627  if (pic->GetRebinY(n) > 1) {
3628  slot->SetIntPar("::DoRebinY", pic->GetRebinY(n));
3629  slot->SetIntPar("::HasRebinY", pic->GetRebinY(n));
3630  }
3631  }
3632  }
3633 
3634  if (ndraw > 1)
3635  padopt->SetSuperimpose(kTRUE);
3636 
3637  TListIter iter(pic->GetSpecialObjects());
3638  while (auto obj = iter()) {
3639  Option_t *drawopt = iter.GetOption();
3640  if (dynamic_cast<TArrow *>(obj))
3641  AddMarkerObj(pad, kind_Arrow, obj->Clone());
3642  else if (dynamic_cast<TLatex *>(obj))
3643  AddMarkerObj(pad, kind_Latex, obj->Clone());
3644  else if (dynamic_cast<TGo4Marker *>(obj))
3645  AddMarkerObj(pad, kind_Marker, obj->Clone());
3646  else if (dynamic_cast<TGo4WinCond *>(obj))
3647  AddMarkerObj(pad, kind_Window, obj->Clone());
3648  else if (dynamic_cast<TGo4PolyCond *>(obj))
3649  AddMarkerObj(pad, kind_Poly, obj->Clone());
3650  else if (dynamic_cast<TPaveLabel *>(obj))
3651  AddDrawObject(pad, kind_Specials, obj->GetName(), obj->Clone(), kTRUE, drawopt ? drawopt : "br");
3652  else
3653  AddDrawObject(pad, kind_Specials, obj->GetName(), obj->Clone(), kTRUE, drawopt);
3654  }
3655 
3656  padopt->SetPadModified();
3657 }
3658 
3659 void TGo4ViewPanel::ProcessCanvasAdopt(TPad *tgtpad, TPad *srcpad, const char *srcpaditemname)
3660 {
3661  if (!tgtpad || !srcpad) return;
3662 
3663  TGo4Slot *padslot = GetPadSlot(tgtpad);
3664 
3665  TGo4Picture *padopt = GetPadOptions(tgtpad);
3666 
3667  if (!padopt || !padslot) return;
3668 
3669  tgtpad->SetTickx(srcpad->GetTickx());
3670  tgtpad->SetTicky(srcpad->GetTicky());
3671  tgtpad->SetGridx(srcpad->GetGridx());
3672  tgtpad->SetGridy(srcpad->GetGridy());
3673  tgtpad->SetBorderSize(srcpad->GetBorderSize());
3674  tgtpad->SetBorderMode(srcpad->GetBorderMode());
3675  srcpad->TAttLine::Copy(*tgtpad);
3676  srcpad->TAttFill::Copy(*tgtpad);
3677  srcpad->TAttPad::Copy(*tgtpad);
3678 
3679  tgtpad->SetPhi(srcpad->GetPhi());
3680  tgtpad->SetTheta(srcpad->GetTheta());
3681 
3682  int nsubpads = 0, nmain = 0, mainkind = 0;
3683  TObjLink* link = srcpad->GetListOfPrimitives()->FirstLink();
3684  while (link) {
3685  TObject *obj = link->GetObject();
3686  const char *drawopt = link->GetOption();
3687 
3688  TH1 *h1 = nullptr;
3689 
3690  int kind = 0;
3691 
3692  TPad *srcsubpad = dynamic_cast<TPad *>(obj);
3693 
3694  TString itemname = TString::Format("%s/%s", srcpaditemname, obj->GetName());
3695 
3696  if (srcsubpad) {
3697  nsubpads++;
3698  QString subpadname = tgtpad->GetName();
3699  subpadname += "_";
3700  subpadname += QString::number(nsubpads);
3701 
3702  Double_t xlow, ylow, xup, yup;
3703 
3704  srcsubpad->GetPadPar(xlow, ylow, xup, yup);
3705 
3706  tgtpad->cd();
3707  TPad *tgtsubpad = new TPad(subpadname.toLatin1().constData(),
3708  srcsubpad->GetName(), xlow, ylow, xup, yup);
3709  tgtsubpad->SetNumber(nsubpads);
3710  tgtsubpad->Draw();
3711 
3712  TGo4Slot *subpadslot = AddNewSlot(tgtsubpad->GetName(), padslot);
3713  SetDrawKind(subpadslot, kind_PadSlot);
3714  SetSlotPad(subpadslot, tgtsubpad);
3715 
3716  ProcessCanvasAdopt(tgtsubpad, srcsubpad, itemname.Data());
3717  } else if (dynamic_cast<TGo4Condition *>(obj)) {
3718  TGo4Condition *cond = (TGo4Condition *) obj->Clone();
3719  cond->SetWorkHistogram(nullptr);
3720  AddDrawObject(tgtpad, kind_Condition, cond->GetName(), cond, kTRUE, nullptr);
3721  } else if (dynamic_cast<TGo4Marker*>(obj)) {
3722  TGo4Marker* mark = (TGo4Marker*) obj->Clone();
3723  mark->SetHistogram(nullptr);
3724  AddDrawObject(tgtpad, kind_Marker, mark->GetName(), mark, kTRUE, nullptr);
3725  } else if (dynamic_cast<TLatex *>(obj)) {
3726  AddDrawObject(tgtpad, kind_Latex, obj->GetName(), obj->Clone(), kTRUE, nullptr);
3727  } else if (dynamic_cast<TPaveLabel *>(obj)) {
3728  AddDrawObject(tgtpad, kind_Specials, obj->GetName(), obj->Clone(), kTRUE, drawopt ? drawopt : "br");
3729  } else if (dynamic_cast<TArrow *>(obj)) {
3730  AddDrawObject(tgtpad, kind_Arrow, obj->GetName(), obj->Clone(), kTRUE, nullptr);
3731  } else if (dynamic_cast<TH1 *>(obj)) {
3732  kind = 1;
3733  h1 = (TH1 *)obj;
3734  } else if (dynamic_cast<TGraph *>(obj)) {
3735  kind = 2;
3736  h1 = Get_fHistogram(obj);
3737  } else if (dynamic_cast<THStack *>(obj)) {
3738  kind = 3;
3739  h1 = Get_fHistogram(obj);
3740  } else if (dynamic_cast<TMultiGraph *>(obj)) {
3741  kind = 4;
3742  h1 = Get_fHistogram(obj);
3743  } else {
3744  // Add other object ???
3745  }
3746 
3747  // only first object is added,
3748  // make superimpose only for histos and graphs
3749  if ((kind > 0) && ((mainkind == 0) || ((kind == mainkind) && (kind < 3)))) {
3750 
3751  if (drawopt)
3752  padopt->SetDrawOption(drawopt, nmain);
3753 
3754  AddDrawObject(tgtpad, knd_Reference, obj->GetName(), obj, false, nullptr);
3755 
3756  mainkind = kind;
3757 
3758  if (h1 && (nmain == 0)) {
3759  TakeFullRangeFromHisto(h1, padopt, nmain == 0);
3760  Int_t ndim = h1->GetDimension();
3761  TakeSelectedAxisRange(0, padopt, h1->GetXaxis());
3762  if (ndim > 1)
3763  TakeSelectedAxisRange(1, padopt, h1->GetYaxis());
3764  if (ndim > 2)
3765  TakeSelectedAxisRange(2, padopt, h1->GetZaxis());
3766  if (ndim < 3) {
3767  Double_t selmin = h1->GetMinimum();
3768  Double_t selmax = h1->GetMaximum();
3769 
3770  if (selmin < selmax)
3771  padopt->SetRange(ndim, selmin, selmax);
3772 
3773  padopt->SetAutoScale(
3774  !h1->TestBit(TH1::kIsZoomed) || (selmin >= selmax));
3775  }
3776  }
3777 
3778  nmain++;
3779  }
3780 
3781  link = link->Next();
3782  }
3783 
3784  if (nmain > 1)
3785  padopt->SetSuperimpose(kTRUE);
3786 
3787  if (nsubpads == 0)
3788  ScanDrawOptions(srcpad, padslot, padopt, false);
3789 }
3790 
3791 void TGo4ViewPanel::RedrawPanel(TPad *pad, bool force)
3792 {
3793  if (IsRedrawBlocked()) return;
3794 
3795  TGo4LockGuard lock;
3796 
3797  BlockPanelRedraw(true);
3798 
3799 #ifdef __GO4X11__
3800 
3801  // JAM2016: does this help for some array conflicts in TGraph painter? YES!
3802  // must be done once before pad->Clear in ProcessPadRedraw, so we do it here instead for each subpad
3803 #ifdef GLOBALESCAPE
3804  if (fxQCanvas) {
3805  gROOT->SetEscape();
3806  fxQCanvas->HandleInput(kButton1Up, 0, 0);
3807  fxQCanvas->HandleInput(kMouseMotion, 0, 0); // stolen from TRootEmbeddedCanvas::HandleContainerKey
3808  // SL2016 - one need to reset escape status back, some other functionality (like zooming) may not work
3809  gROOT->SetEscape(kFALSE);
3810  }
3811 
3812 #else
3813  // JAM 2016: only reset crucial static arrays in TGraph subclasses, do not escape complete root...
3814  // turned out to have strange side effects with TBox which also has static variables reacting on escape flag :(
3815  if(fxQCanvas) { // just for the scope to delete dummy graph on stack
3816  gPad = pad;
3817  Bool_t oldmodified = gPad->IsModified();
3818  TGraph dummy(1);
3819  gROOT->SetEscape();
3820  dummy.ExecuteEvent(kButton1Up, 0, 0); // will reset escape flag internally
3821  gPad->Modified(oldmodified); // probably not necessary, since we only use escape mode in event handler. But who knows what future root brings?
3822  }
3823 #endif
3824 #endif
3825 
3826  bool isanychildmodified = false;
3827  bool ispadupdatecalled = false;
3828 
3829  QTime starttm = QTime::currentTime();
3830  bool intime = true;
3831 
3832 
3833  // this loop done to allow consequent update of multi-pad canvas
3834  // each subpad separately redrawn in ProcessPadRedraw() method and
3835  // than pad->Update() is called. If it takes too long,
3836  // loop is finishing and via paint timer will be activated later
3837 
3838  do {
3839  TPad *selpad = TGo4MdiArea::Instance()->GetSelectedPad();
3840 
3841  isanychildmodified = ProcessPadRedraw(pad, force);
3842 
3844 
3845  // here pad->Update should redraw only modified subpad
3846  if (isanychildmodified) {
3847  CanvasUpdate();
3848  ispadupdatecalled = true;
3849  }
3850 
3851  int delay = starttm.msecsTo(QTime::currentTime());
3852  intime = (delay >= 0) && (delay < 100);
3853 
3854  } while (!force && isanychildmodified && intime);
3855 
3856  if (GetActivePad())
3858 
3859  RefreshButtons();
3860 
3861  // to correctly select active pad, one should call canvas->Update()
3862  if (!ispadupdatecalled)
3863  CanvasUpdate();
3864 
3866 
3867  BlockPanelRedraw(false);
3868 
3869  if (!force && isanychildmodified)
3870  ShootRepaintTimer(pad);
3871 }
3872 
3873 bool TGo4ViewPanel::ProcessPadRedraw(TPad *pad, bool force)
3874 {
3875  TGo4Slot *slot = GetPadSlot(pad);
3876  if (!slot) return false;
3877 
3878  TGo4Picture *padopt = GetPadOptions(slot);
3879  if (!padopt) return false;
3880 
3881  bool ischilds = false;
3882  bool ischildmodified = false;
3883 
3884  CheckObjectsAssigments(pad, slot);
3885 
3886  CheckForSpecialObjects(pad, slot);
3887 
3888  // this parameter ensure that all pads will be scanned one after another
3889  Int_t lastdrawnpad = 0;
3890  if (!force)
3891  if (!slot->GetIntPar("::LastDrawnPad", lastdrawnpad))
3892  lastdrawnpad = 0;
3893 
3894  Int_t subpadindx = 0, numchilds = slot->NumChilds();
3895 
3896  // first redraw all subpads
3897  for (int n = 0; n < numchilds; n++) {
3898  subpadindx = (n + lastdrawnpad);
3899  if (numchilds > 0) subpadindx = subpadindx % numchilds;
3900  TPad *subpad = GetSlotPad(slot->GetChild(subpadindx));
3901  if (!subpad) continue;
3902  ischilds = true;
3903  if (ProcessPadRedraw(subpad, force)) {
3904  ischildmodified = true;
3905  if (!force) break; // break if any of child is modified
3906  }
3907  }
3908 
3909  if (!force && ischildmodified)
3910  slot->SetIntPar("::LastDrawnPad", subpadindx);
3911  else
3912  slot->RemovePar("::LastDrawnPad");
3913 
3914  if (!force && !padopt->IsPadModified())
3915  return ischildmodified;
3916 
3917  bool updatecontent = padopt->IsContentModified();
3918 
3919  padopt->SetPadModified(false);
3920  padopt->SetContentModified(false);
3921 
3922  // do not draw anything else if subpads are there
3923  if (ischilds) return ischildmodified;
3924 
3925  pad->Clear();
3926 
3927  pad->SetCrosshair(fbCanvasCrosshair);
3928  pad->SetLogx(padopt->GetLogScale(0));
3929  pad->SetLogy(padopt->GetLogScale(1));
3930  pad->SetLogz(padopt->GetLogScale(2));
3931 
3932  TObjArray objs, objslots;
3933  CollectMainDrawObjects(slot, &objs, &objslots, padopt->IsSuperimpose() ? 1 : 2);
3934 
3935  ScanObjectsDrawOptions(false, slot, &objs, &objslots);
3936 
3937  TGo4Slot *sislot = GetSuperimposeSlot(slot);
3938  TGo4Slot *legslot = slot->FindChild("::Legend");
3939  TGo4Slot *asislot = slot->FindChild("::ASImage");
3940 
3941  // if nothing to draw, delete all additional slots and exit
3942  if (objs.GetLast() < 0) {
3943  delete sislot;
3944  delete legslot;
3945  delete asislot;
3946 
3947  RedrawSpecialObjects(pad, slot);
3948 
3950 
3951  // indicate that nothing is happen
3952  return true;
3953  }
3954 
3955  TH2 *asihisto = nullptr;
3956 
3957  TObject *drawobj = nullptr;
3958 
3959  // Bool_t dosuperimpose = padopt->IsSuperimpose() && (objs.GetLast()>0);
3960  Bool_t dosuperimpose = objs.GetLast() > 0;
3961 
3962  const char *drawopt = padopt->GetDrawOption(0);
3963 
3964  Bool_t doasiimage = !dosuperimpose && !fxWCanvas && objs.Last()->InheritsFrom(TH2::Class());
3965 
3966  if (drawopt && TString(drawopt).Contains("asimage")) {
3967  if (!doasiimage) { drawopt = "col"; padopt->SetDrawOption("col", 0); }
3968  } else {
3969  doasiimage = kFALSE;
3970  }
3971 
3972  if (dosuperimpose) {
3973  if (!sislot)
3974  sislot = new TGo4Slot(slot, "::Superimpose", "place for superimpose object");
3975  if (padopt->IsLegendDraw()) {
3976  if (!legslot)
3977  legslot = new TGo4Slot(slot, "::Legend", "place for legends object");
3978  } else if (legslot) {
3979  delete legslot;
3980  legslot = nullptr;
3981  }
3982 
3983  drawobj = ProduceSuperimposeObject(slot, padopt, sislot, legslot, &objs,
3984  &objslots, padopt->IsTitleItem());
3985  if (!drawobj)
3986  dosuperimpose = kFALSE;
3987  }
3988 
3989  if (!dosuperimpose) {
3990  if (sislot) {
3991  delete sislot;
3992  sislot = nullptr;
3993  }
3994  if (legslot) {
3995  delete legslot;
3996  legslot = nullptr;
3997  }
3998  drawobj = objs.Last();
3999  }
4000 
4001  if (doasiimage) {
4002  asihisto = dynamic_cast<TH2 *>(drawobj);
4003  if (!asihisto)
4004  doasiimage = false;
4005  else {
4006  if (!asislot)
4007  asislot = new TGo4Slot(slot, "::ASImage", "place for Go4 ASI image");
4008  TGo4ASImage *image = dynamic_cast<TGo4ASImage *>(asislot->GetAssignedObject());
4009  if(!image) {
4010  image = new TGo4ASImage;
4011  asislot->SetProxy(new TGo4ObjectProxy(image, kTRUE));
4012  updatecontent = true;
4013  }
4014  if (updatecontent)
4015  image->SetHistogramContent(asihisto);
4016 
4017  drawobj = image;
4018  }
4019  }
4020 
4021  if (!doasiimage && asislot) {
4022  delete asislot;
4023  asislot = nullptr;
4024  }
4025 
4026  gPad = pad; // instead of pad->cd(), while it is redraw frame
4027  if (drawobj) {
4028  bool first_draw = (slot->GetPar("::PadFirstDraw") == nullptr);
4029  if (first_draw) slot->SetPar("::PadFirstDraw", "true");
4030 
4031  if (drawobj->InheritsFrom(TH1::Class())) {
4032  TH1 *h1 = (TH1 *) drawobj;
4033  h1->SetBit(kCanDelete, kFALSE);
4034  RedrawHistogram(pad, padopt, h1, updatecontent, first_draw);
4035  } else if (drawobj->InheritsFrom(THStack::Class())) {
4036  THStack *hs = (THStack*) drawobj;
4037  RedrawStack(pad, padopt, hs, dosuperimpose, updatecontent);
4038  } else if (drawobj->InheritsFrom(TGraph::Class())) {
4039  TGraph *gr = (TGraph *)drawobj;
4040  RedrawGraph(pad, padopt, gr, updatecontent, first_draw);
4041  } else if (drawobj->InheritsFrom(TMultiGraph::Class())) {
4042  TMultiGraph *mg = (TMultiGraph *)drawobj;
4043  RedrawMultiGraph(pad, padopt, mg, dosuperimpose, updatecontent);
4044  } else if (dynamic_cast<TGo4ASImage*>(drawobj)) {
4045  TGo4ASImage *ai = (TGo4ASImage *) drawobj;
4046  RedrawImage(pad, padopt, ai, asihisto, updatecontent);
4047  }
4048  }
4049 
4050  if (legslot)
4051  RedrawLegend(pad, padopt, legslot);
4052 
4053  if (!doasiimage)
4054  RedrawSpecialObjects(pad, slot);
4055 
4057 
4058  return true;
4059 }
4060 
4061 void TGo4ViewPanel::RedrawHistogram(TPad *pad, TGo4Picture *padopt, TH1 *his, bool scancontent, bool first_draw)
4062 {
4063  if (!pad || !padopt || !his) return;
4064 
4065  if (scancontent)
4066  TakeFullRangeFromHisto(his, padopt, true);
4067 
4068  TString drawopt(padopt->GetDrawOption(0));
4069  if (drawopt.IsNull()) {
4070  if (his->GetDimension() == 1)
4071  drawopt = go4sett->getTH1DrawOpt().toLatin1().constData();
4072  else if (his->GetDimension() == 2)
4073  drawopt = go4sett->getTH2DrawOpt().toLatin1().constData();
4074  else if (his->GetDimension() == 3)
4075  drawopt = go4sett->getTH3DrawOpt().toLatin1().constData();
4076  }
4077 
4078  drawopt.ToUpper();
4079 
4080  if (first_draw && (go4sett->getDrawLineWidth() > 1) && (his->GetLineWidth()==1))
4081  his->SetLineWidth(go4sett->getDrawLineWidth());
4082 
4083  // only activate panel defaults if no fill color set by user:
4084  if (first_draw && (go4sett->getDrawFillColor() > 0) && (his->GetFillColor() == 0))
4085  his->SetFillColor(go4sett->getDrawFillColor());
4086  if (first_draw && (go4sett->getDrawFillStyle()!=1001) && (his->GetFillStyle()==1001))
4087  his->SetFillStyle(go4sett->getDrawFillStyle());
4088 
4089  Int_t nlvl = padopt->GetHisContour();
4090  if (nlvl > 0) his->SetContour(nlvl);
4091 
4092  his->SetStats(padopt->IsHisStats());
4093  his->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
4094  his->Draw(drawopt.Data());
4095 
4096  SetSelectedRangeToHisto(pad, his, nullptr, padopt, true);
4097 }
4098 
4099 void TGo4ViewPanel::RedrawStack(TPad *pad, TGo4Picture *padopt, THStack *hs,
4100  bool dosuperimpose, bool scancontent)
4101 {
4102  if (!pad || !padopt || !hs) return;
4103 
4104  if (scancontent) {
4105  TIter iter(hs->GetHists());
4106  bool first = true;
4107  while (auto h1 = (TH1 *) iter()) {
4108  TakeFullRangeFromHisto(h1, padopt, first);
4109  first = false;
4110  }
4111  }
4112 
4113  // never draw statistics with stack
4114 
4115  Int_t drawoptindx = dosuperimpose ? TGo4Picture::PictureIndex : 0;
4116  TString drawopt(padopt->GetDrawOption(drawoptindx));
4117  if (drawopt.IsNull())
4118  drawopt = "hist";
4119  if (!drawopt.Contains(NoStackDrawOption, TString::kIgnoreCase))
4120  drawopt.Prepend(NoStackDrawOption);
4121 
4122  hs->Draw(drawopt.Data());
4123  // do not access histogram in web canvas - causes redraw of the complete canvas
4124  TH1 *framehisto = Get_fHistogram(hs, true);
4125  if (!framehisto) return;
4126 
4127  framehisto->SetStats(false);
4128  framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
4129  TH1 *h1 = hs->GetHists() ? dynamic_cast<TH1 *>(hs->GetHists()->First()) : nullptr;
4130  if (h1) {
4131  hs->SetTitle(h1->GetTitle());
4132  framehisto->SetTitle(h1->GetTitle());
4133  framehisto->GetXaxis()->SetTitle(h1->GetXaxis()->GetTitle());
4134  framehisto->GetYaxis()->SetTitle(h1->GetYaxis()->GetTitle());
4135  framehisto->GetZaxis()->SetTitle(h1->GetZaxis()->GetTitle());
4136  }
4137 
4138  SetSelectedRangeToHisto(pad, framehisto, hs, padopt, false);
4139 }
4140 
4141 void TGo4ViewPanel::RedrawGraph(TPad *pad, TGo4Picture *padopt, TGraph * gr, bool scancontent, bool first_draw)
4142 {
4143  if (!pad || !padopt || !gr) return;
4144 
4145  if (scancontent) {
4146  TakeFullRangeFromGraph(gr, padopt, true);
4147  gr->SetEditable(kFALSE);
4148  }
4149 
4150  TString drawopt = padopt->GetDrawOption(0);
4151 
4152  // when graph drawn for the first time, check if time units used in axis
4153  if (first_draw) {
4154  TAxis *ax = gr->GetXaxis();
4155  if (ax && ax->GetTimeDisplay()) {
4156  padopt->SetHisStats(kFALSE);
4157  padopt->SetXAxisTimeDisplay(kTRUE);
4158  padopt->SetXAxisTimeFormat(ax->GetTimeFormat());
4159  if (drawopt.IsNull()) {
4160  drawopt = go4sett->getTGraphDrawOpt().toLatin1().constData();
4161  padopt->SetDrawOption(drawopt);
4162  }
4163  }
4164  if ((go4sett->getDrawLineWidth() > 1) && (gr->GetLineWidth()==1))
4165  gr->SetLineWidth(go4sett->getDrawLineWidth());
4166 
4167 
4168  // only activate panel defaults if no fill color set by user:
4169  if ((go4sett->getDrawFillColor() > 0) && (gr->GetFillColor() == 0))
4170  gr->SetFillColor(go4sett->getDrawFillColor());
4171  if ((go4sett->getDrawFillStyle() != 1001) && (gr->GetFillStyle() == 1001))
4172  gr->SetFillStyle(go4sett->getDrawFillStyle());
4173  }
4174 
4175  if (drawopt.IsNull())
4176  drawopt = go4sett->getTGraphDrawOpt().toLatin1().constData();
4177 
4178  TH1 *framehisto = Get_fHistogram(gr);
4179  if (framehisto) {
4180  framehisto->SetStats(padopt->IsHisStats());
4181  framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
4182  }
4183 
4184  gr->Draw(drawopt.Data());
4185 
4186  if (!framehisto && !IsWebCanvas()) {
4187  framehisto = gr->GetHistogram();
4188  if (framehisto && ((framehisto->TestBit(TH1::kNoStats) == padopt->IsHisStats()) || (framehisto->TestBit(TH1::kNoTitle) == padopt->IsHisTitle()))) {
4189  framehisto->SetStats(padopt->IsHisStats());
4190  framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
4191  gr->Draw(drawopt.Data());
4192  }
4193  }
4194 
4195  SetSelectedRangeToHisto(pad, framehisto, nullptr, padopt, false);
4196 }
4197 
4198 void TGo4ViewPanel::RedrawMultiGraph(TPad *pad, TGo4Picture *padopt, TMultiGraph *mg, bool dosuperimpose,
4199  bool scancontent)
4200 {
4201  if (!pad || !padopt || !mg) return;
4202 
4203  TIter iter(mg->GetListOfGraphs());
4204  TGraph *firstgr = nullptr;
4205  bool first = true;
4206  while (auto gr = (TGraph *) iter()) {
4207  if (scancontent) {
4208  gr->SetEditable(kFALSE);
4209  TakeFullRangeFromGraph(gr, padopt, first);
4210  }
4211  if (first)
4212  firstgr = gr;
4213  first = false;
4214  }
4215 
4216  Int_t drawoptindx = dosuperimpose ? TGo4Picture::PictureIndex : 0;
4217  TString drawopt(padopt->GetDrawOption(drawoptindx));
4218  if (drawopt.IsNull())
4219  drawopt = go4sett->getTGraphDrawOpt().toLatin1().constData();
4220  if (dosuperimpose)
4221  drawopt = "";
4222 
4223  if (IsWebCanvas()) {
4224  mg->Draw(drawopt.Data());
4225  return;
4226  }
4227 
4228  TH1 *framehisto = (dosuperimpose && firstgr) ? firstgr->GetHistogram() : mg->GetHistogram();
4229 
4230  if (!framehisto) {
4231  // this is workaround to prevent recreation of framehistogram in TMultiGraph::Paint
4232  mg->Draw(drawopt.Data());
4233  framehisto = (dosuperimpose && firstgr) ? firstgr->GetHistogram() : mg->GetHistogram();
4234  }
4235 
4236  if (!framehisto) {
4237  TGo4Log::Error("Internal problem with MultiGraph drawing - cannot access frame histo");
4238  return;
4239  }
4240 
4241  SetSelectedRangeToHisto(pad, framehisto, nullptr, padopt, false);
4242 
4243  // try to avoid flicker of range when in fullscale: set range before and after draw
4244  Double_t miny, maxy, selmin, selmax;
4245  if (padopt->GetFullRange(1, miny, maxy) && !padopt->GetRangeY(selmin, selmax)) {
4246  if (padopt->GetLogScale(1)) {
4247  if (maxy <= 0) maxy = 1.;
4248  if ((miny <= 0) || (miny >= maxy)) {
4249  miny = maxy * 1e-4;
4250  if (miny > 1.) miny = 1.;
4251  }
4252  } else {
4253  maxy *= ((maxy>0) ? 1.1 : 0.9);
4254  miny *= ((miny>0) ? 0.9 : 1.1);
4255  }
4256  framehisto->SetMaximum(maxy);
4257  framehisto->SetMinimum(miny);
4258  }
4259 
4260  framehisto->SetStats(kFALSE); // never draw statistics with multigraph
4261  framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
4262 
4263  // set title of first TGraph to TMultiGraph and frame histo
4264  if (firstgr) {
4265  mg->SetTitle(firstgr->GetTitle());
4266  framehisto->SetTitle(firstgr->GetTitle());
4267  framehisto->GetXaxis()->SetTitle(firstgr->GetXaxis()->GetTitle());
4268  framehisto->GetYaxis()->SetTitle(firstgr->GetYaxis()->GetTitle());
4269  }
4270 
4271  mg->Draw(drawopt.Data());
4272 }
4273 
4275  TH2 *asihisto, bool scancontent)
4276 {
4277  if (!pad || !padopt || !im) return;
4278 
4279  im->SetDrawData(asihisto, this, pad);
4280 
4281  if (scancontent)
4282  TakeFullRangeFromHisto(asihisto, padopt, true);
4283 
4284  TString drawopt(padopt->GetDrawOption(0));
4285 
4286  double uminx, umaxx, uminy, umaxy;
4287  padopt->GetRange(0, uminx, umaxx);
4288  padopt->GetRange(1, uminy, umaxy);
4289  im->SetSelectedRange(uminx, umaxx, uminy, umaxy);
4290 
4291  im->SetPaletteEnabled(drawopt.Contains("Z"));
4292 
4293  im->Draw();
4294 }
4295 
4296 void TGo4ViewPanel::RedrawLegend(TPad *pad, TGo4Picture *padopt, TGo4Slot *legslot)
4297 {
4298  if (!legslot) return;
4299  TLegend* legend = dynamic_cast<TLegend*>(legslot->GetAssignedObject());
4300  //legend->SetBit(kCanDelete, kFALSE); // jam2016
4301  if(legend) legend->Draw();
4302 }
4303 
4305 {
4306  if (!pad || !padslot) return;
4307 
4308  CheckObjectsAssigments(pad, padslot);
4309 
4310  QString selname = GetSelectedMarkerName(pad);
4311  TObject *selectedobj = nullptr;
4312  const char *selectdrawopt = nullptr;
4313  for (int n = 0; n < padslot->NumChilds(); n++) {
4314  TGo4Slot *subslot = padslot->GetChild(n);
4315 
4316  Int_t kind = GetDrawKind(subslot);
4317 
4318  if ((kind < kind_Specials) || (kind >= kind_Other))
4319  continue;
4320 
4321  TObject *obj = subslot->GetAssignedObject();
4322  if (!obj)
4323  continue;
4324 
4325  TString drawopt = GetSpecialDrawOption(subslot);
4326  if(obj->InheritsFrom(TF1::Class())){
4327  if(!pad->GetListOfPrimitives()->IsEmpty())
4328  drawopt.Append("LSAME"); // for correct overlay of TF1 objects JAM
4329  TF1 *func = dynamic_cast<TF1 *>(obj);
4330  Int_t objindx = padslot->GetIndexOf(subslot);
4331  func->SetLineColor(GetAutoColor(((objindx+7) % 9) + 1)); // 9 basic colors for superimpose of tf1, like for other superimpose
4332  }
4333 
4334  if ((selname == obj->GetName()) && !selectedobj) {
4335  selectedobj = obj;
4336  selectdrawopt = drawopt.Data();
4337  } else {
4338  //obj->SetBit(kCanDelete, kFALSE); // jam2016
4339  obj->Draw(drawopt.Data());
4340  }
4341  }
4342 
4343  // if one has selected object on the pad, one should
4344  // draw it as last to bring it to the front of other
4345  if (selectedobj) {
4346  //selectedobj->SetBit(kCanDelete, kFALSE); // jam2016
4347  selectedobj->Draw(selectdrawopt ? selectdrawopt : "");
4348  }
4349 }
4350 
4352 {
4353  return fbAutoZoomFlag;
4354 }
4355 
4357 {
4358  fbAutoZoomFlag = on;
4359 }
4360 
4362 {
4363  return fbApplyToAllFlag;
4364 }
4365 
4367 {
4368  return fbFreezeTitle;
4369 }
4370 
4372  int value, const char *drawopt)
4373 {
4374  TGo4LockGuard lock;
4375  TGo4Picture *subopt = GetPadOptions(padslot);
4376  if (!subopt) return;
4377  switch (kind) {
4378  case 0:
4379  case 1:
4380  case 2: {
4381  int selindx = GetSelectedObjectIndex(padslot);
4382  subopt->SetDrawOption(drawopt, selindx);
4383  subopt->SetPadModified();
4384  break;
4385  }
4386  case 100: {
4387  subopt->SetPadModified();
4388  break;
4389  }
4390  case 101: {
4391  TPad *subpad = GetSlotPad(padslot);
4392  if (subpad) {
4393  subpad->SetFillColor(value);
4394  if (subpad->GetFrame())
4395  subpad->GetFrame()->SetFillColor(value);
4396  }
4397  subopt->SetPadModified();
4398  break;
4399  }
4400  case 16: {
4401  // this is for setting time axis format:
4402  subopt->SetXAxisTimeFormat(drawopt);
4403  subopt->SetPadModified();
4404  break;
4405  }
4406 
4407  default:
4408  subopt->ChangeDrawOption(kind, value);
4409  break;
4410  }
4411 }
4412 
4413 void TGo4ViewPanel::ChangeDrawOption(int kind, int value, const char *drawopt)
4414 {
4415  TGo4LockGuard lock;
4416 
4417  bool scanall = IsApplyToAllFlag();
4418 
4419  if (kind == 100) {
4420  gStyle->SetPalette(value);
4421  scanall = true;
4422  }
4423 
4424  TPad *pad = scanall ? GetCanvas() : GetActivePad();
4425 
4426  if (!pad)
4427  pad = GetCanvas();
4428 
4429  TGo4Slot *slot = GetPadSlot(pad);
4430  if (!slot) return;
4431 
4432  ChangeDrawOptionForPad(slot, kind, value, drawopt);
4433 
4434  TGo4Iter iter(slot, true);
4435  while (iter.next())
4436  ChangeDrawOptionForPad(iter.getslot(), kind, value, drawopt);
4437 
4438  RedrawPanel(pad, false);
4439 }
4440 
4441 void TGo4ViewPanel::ResetPadFillColors(TPad *pad, int col, TPad *backup)
4442 {
4443  TGo4LockGuard lock;
4444  if (!pad)
4445  return;
4446  if(backup) col=backup->GetFillColor();
4447  pad->SetFillColor((Color_t) col);
4448  //pad->Modified(); // for image formats, display window bitmap has to change
4449  TIter iter(pad->GetListOfPrimitives());
4450  while (auto obj = iter()) {
4451  TPad *subpad = dynamic_cast<TPad *>(obj);
4452  TFrame *fram = dynamic_cast<TFrame *>(obj);
4453  if (subpad) {
4454  TPad *backpad = nullptr;
4455  if (backup)
4456  backpad = dynamic_cast<TPad *>(backup->GetListOfPrimitives()->FindObject(subpad->GetName()));
4457  ResetPadFillColors(subpad, col, backpad);
4458  } else if (fram) {
4459  if (backup) {
4460  TFrame *backframe = dynamic_cast<TFrame *>(backup->GetListOfPrimitives()->FindObject(fram->GetName()));
4461  if (backframe) {
4462  col = backframe->GetFillColor();
4463  }
4464  }
4465  fram->SetFillColor((Color_t)col);
4466  }
4467  }
4468 }
4469 
4470 void TGo4ViewPanel::ClearPad(TPad *pad, bool removeitems, bool removesubpads)
4471 {
4472  TGo4LockGuard lock;
4473 
4474  BlockPanelRedraw(true);
4475  CleanupGedEditor();
4476  ProcessPadClear(pad, removeitems, removesubpads);
4477  if (!GetActivePad())
4479  GetCanvas()->SetSelected(nullptr);
4480  BlockPanelRedraw(false);
4481 }
4482 
4484 {
4485  if (!padslot) return;
4486 
4487  for (int n = padslot->NumChilds() - 1; n >= 0; n--) {
4488  TGo4Slot *subslot = padslot->GetChild(n);
4489  int kind = GetDrawKind(subslot);
4490  if ((kind < kind_Permanet) && (subslot != remain)) {
4491  delete subslot;
4492  }
4493  }
4494 }
4495 
4496 void TGo4ViewPanel::ProcessPadClear(TPad *pad, bool removeitems, bool removesubpads)
4497 {
4498  TGo4Slot *slot = GetPadSlot(pad);
4499  TGo4Picture *padopt = GetPadOptions(slot);
4500  if (!slot || !padopt)
4501  return;
4502 
4503 // padopt->Clear(""); // remove all settings completely
4504  padopt->SetPadModified();
4505 
4506  if (removeitems)
4507  ClearPadItems(slot, nullptr);
4508 
4509  CheckObjectsAssigments(pad, slot);
4510 
4511  for (int n = slot->NumChilds() - 1; n >= 0; n--) {
4512  TGo4Slot *subslot = slot->GetChild(n);
4513 
4514  TPad *subpad = GetSlotPad(subslot);
4515  if (!subpad)
4516  continue;
4517  ProcessPadClear(subpad, removeitems || removesubpads, removesubpads);
4518  if (!removesubpads)
4519  continue;
4520  if (fxActivePad == subpad)
4521  fxActivePad = nullptr;
4522 
4523  delete subslot;
4524 
4525  pad->GetListOfPrimitives()->Remove(subpad);
4526 
4528 
4529  if (GetCanvas()->GetSelectedPad() == subpad)
4530  GetCanvas()->SetSelectedPad(nullptr);
4531 
4532  delete subpad;
4533  }
4534 
4536 }
4537 
4539 {
4540  TGo4LockGuard lock;
4541 
4542  if (!pad) return;
4543 
4544  {
4545  TPadGuard lock; // workaround to avoid canvas update
4546  gStyle->SetOptStat(go4sett->getOptStat());
4547  }
4548 
4549  if (go4sett->getOptStatW()>0) gStyle->SetStatW(go4sett->getOptStatW()*0.01);
4550  if (go4sett->getOptStatH()>0) gStyle->SetStatH(go4sett->getOptStatH()*0.01);
4551 
4553  bool show_status = go4sett->getPadEventStatus();
4554 
4555  int fiPadcolorR, fiPadcolorG, fiPadcolorB;
4556  go4sett->getCanvasColor(fiPadcolorR, fiPadcolorG, fiPadcolorB);
4557  int padfillcolor = TColor::GetColor(fiPadcolorR, fiPadcolorG, fiPadcolorB);
4558 
4559  if (padfillcolor != 0) {
4560  // now define associated colors for WBOX shading
4561  // note: root restricts this mechanism to number<50
4562  // we extend it since TGX11ttf expects the shadow color
4563  // the following are copies from TColor code:
4564  Int_t nplanes = 16;
4565  if (gVirtualX)
4566  gVirtualX->GetPlanes(nplanes);
4567  if (nplanes == 0)
4568  nplanes = 16;
4569  TColor *normal = gROOT->GetColor(padfillcolor);
4570  if (normal) {
4571  Float_t h, l, s;
4572  normal->GetHLS(h, l, s);
4573  const char *cname = normal->GetName();
4574  // assign the color numbers and names for shading:
4575  Float_t dr, dg, db, lr, lg, lb;
4576  TColor *dark = gROOT->GetColor(100 + padfillcolor);
4577  if (!dark) {
4578  new TColor(100 + padfillcolor, -1, -1, -1, TString::Format("%s%s", cname, "_dark").Data());
4579  dark = gROOT->GetColor(100 + padfillcolor);
4580  }
4581  TColor *light = gROOT->GetColor(150 + padfillcolor);
4582  if (!light) {
4583  new TColor(150 + padfillcolor, -1, -1, -1, TString::Format("%s%s", cname, "_bright").Data());
4584  light = gROOT->GetColor(150 + padfillcolor);
4585  }
4586 
4587  // set dark color
4588  TColor::HLStoRGB(h, 0.7 * l, s, dr, dg, db);
4589  if (dark) {
4590  if (nplanes > 8)
4591  dark->SetRGB(dr, dg, db);
4592  else
4593  dark->SetRGB(0.3, 0.3, 0.3);
4594  }
4595 
4596  // set light color
4597  TColor::HLStoRGB(h, 1.2 * l, s, lr, lg, lb);
4598  if (light) {
4599  if (nplanes > 8)
4600  light->SetRGB(lr, lg, lb);
4601  else
4602  light->SetRGB(0.8, 0.8, 0.8);
4603  }
4604  } else { // if(normal)
4605  TGo4Log::Error("Internal problem in view panel: Could not assign root shadow colors for number %d", padfillcolor);
4606  }
4607  }
4608 
4609  pad->SetCrosshair(fbCanvasCrosshair);
4610  pad->SetFillColor(padfillcolor);
4611 
4612 #ifdef __GO4X11__
4613  if (fxQCanvas)
4614  if (show_status != fxQCanvas->isStatusBarVisible())
4615  ShowEventStatus(show_status);
4616 #endif
4617 
4618  TGo4Picture *padopt = GetPadOptions(pad);
4619  if (padopt) {
4620  padopt->SetDrawOption(nullptr, TGo4Picture::PictureIndex);
4621  padopt->SetDrawOption(nullptr, 0);
4622  padopt->SetTitleTime(go4sett->getDrawTimeFlag());
4623  padopt->SetTitleDate(go4sett->getDrawDateFlag());
4624  padopt->SetTitleItem(go4sett->getDrawItemFlag());
4626  }
4627 }
4628 
4630 {
4631  if (!pad)
4632  return;
4633  TString output = pad->GetName();
4634  output.Append(": ");
4635  TGo4Picture *padopt = GetPadOptions(pad);
4636  if (padopt)
4637  if (padopt->IsSuperimpose())
4638  output.Append(" SuperImpose:");
4639 
4640  if (IsApplyToAllFlag())
4641  output.Append(" All Pads:");
4642  output.Append(" Ready");
4643 
4644  if (fxQCanvas) {
4645 #ifdef __GO4X11__
4646  fxQCanvas->showStatusMessage(output.Data());
4647 #endif
4648  } else if (fxWCanvas) {
4649  printf("Implement display pad status in web canvas\n");
4650  }
4651 }
4652 
4653 void TGo4ViewPanel::MoveScale(int expandfactor, int xaction, int yaction, int zaction)
4654 {
4655  TPad *selpad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
4656  if (!selpad)
4657  return;
4658 
4659  TGo4Picture *padopt = GetPadOptions(selpad);
4660  if (padopt) {
4661  TObject *padhist = GetPadMainObject(selpad);
4662 
4663  MoveSingleScale(expandfactor, xaction, 0, padopt, padhist);
4664  MoveSingleScale(expandfactor, yaction, 1, padopt, padhist);
4665  MoveSingleScale(expandfactor, zaction, 2, padopt, padhist);
4666  if ((xaction == 0) && (yaction == 0) && (zaction == 0)) {
4667  padopt->ClearRange();
4668  padopt->SetAutoScale(true);
4669  }
4670  padopt->SetPadModified();
4671  }
4672 
4673  if (IsApplyToAllFlag()) {
4674  TGo4Iter iter(GetPadSlot(selpad), kTRUE);
4675  while (iter.next()) {
4676  TPad *subpad = GetSlotPad(iter.getslot());
4677  padopt = GetPadOptions(subpad);
4678  if (!padopt) continue;
4679 
4680  TObject *padhist = GetPadMainObject(subpad);
4681 
4682  MoveSingleScale(expandfactor, xaction, 0, padopt, padhist);
4683  MoveSingleScale(expandfactor, yaction, 1, padopt, padhist);
4684  MoveSingleScale(expandfactor, zaction, 2, padopt, padhist);
4685  if ((xaction == 0) && (yaction == 0) && (zaction == 0)) {
4686  padopt->ClearRange();
4687  padopt->SetAutoScale(true);
4688  }
4689  padopt->SetPadModified();
4690  }
4691  }
4692 
4693  RedrawPanel(selpad, false);
4694 }
4695 
4696 void TGo4ViewPanel::MoveSingleScale(int expandfactor, int action, int naxis,
4697  TGo4Picture *padopt, TObject *padobj)
4698 {
4699  if (action <= 0) return;
4700 
4701  double new_umin, new_umax, fmin, fmax, tmin, tmax;
4702  double fact = expandfactor / 100.;
4703 
4704  bool sel = padopt->GetRange(naxis, new_umin, new_umax) && (action!=6);
4705 
4706  padopt->GetFullRange(naxis, fmin, fmax);
4707 
4708  // we use number of dimensions to determine if we have contents
4709  int ndim = padopt->GetFullRangeDim();
4710 
4711  if (!sel || (new_umin >= new_umax)) { new_umin = fmin; new_umax = fmax; }
4712 
4713  double shift = (new_umax - new_umin) * fact;
4714  // protect if changes is out of full axis ranges
4715  if (shift <= 0) return;
4716 
4717  switch (action) {
4718  case 1:
4719  if ((new_umax + shift) > fmax) // SlotShiftL
4720  shift = fmax - new_umax;
4721  new_umin += shift;
4722  new_umax += shift;
4723  break;
4724  case 2:
4725  if (new_umin - shift < fmin) // SlotShiftR
4726  shift = new_umin - fmin;
4727  new_umin -= shift;
4728  new_umax -= shift;
4729  break;
4730  case 3:
4731  if (ndim == 1) {
4732  new_umax -= shift; // Expand 1d upper
4733  if (naxis < 1) // lower only for X
4734  new_umin += shift; // Expand 1d lower X
4735  }
4736  if (ndim == 2) {
4737  new_umax -= shift; // Expand 2d upper
4738  if (naxis < 2) // lower only for X,Y
4739  new_umin += shift; // Expand 1d lower X,Y
4740  }
4741  break;
4742  case 4:
4743  if (ndim == 1) { // Shrink 1d upper
4744  if (naxis < 1) { // X axis
4745  tmax = (-fact * new_umin + (1. - fact) * new_umax)
4746  / (1. - 2. * fact);
4747  tmin = (-fact * new_umax + (1. - fact) * new_umin)
4748  / (1. - 2. * fact); // Shrink 1d X
4749  } else { // content, lower has not been expanded
4750  tmax = (-fact * new_umin + new_umax) / (1. - fact);
4751  tmin = (-fact * new_umax + (1. - fact) * new_umin)
4752  / (1. - 2. * fact); // Shrink 1d X
4753  }
4754  }
4755  if (ndim == 2) {
4756  if (naxis < 2) { // X,Y axis
4757  tmax = (-fact * new_umin + (1. - fact) * new_umax)
4758  / (1. - 2. * fact);
4759  tmin = (-fact * new_umax + (1. - fact) * new_umin)
4760  / (1. - 2. * fact); // Shrink 1d X
4761  } else { // content, lower has not been expanded
4762  tmax = (-fact * new_umin + new_umax) / (1. - fact);
4763  tmin = (-fact * new_umax + (1. - fact) * new_umin)
4764  / (1. - 2. * fact); // Shrink 1d X
4765  }
4766  }
4767  new_umin = tmin;
4768  new_umax = tmax;
4769  if (new_umin < fmin)
4770  new_umin = fmin;
4771  if (new_umax > fmax)
4772  new_umax = fmax;
4773  break;
4774 
4775  case 5: // Auto-zoom
4776  case 6: { // Auto zoom, but ignore selected range
4777  TH1 *padhist = dynamic_cast<TH1 *>(padobj);
4778 
4779  if (!padhist) break;
4780 
4781  if (naxis >= ndim) break;
4782 
4783  TAxis *axis = padhist->GetXaxis();
4784  if (naxis==1) axis = padhist->GetYaxis();
4785  if (naxis==2) axis = padhist->GetZaxis();
4786 
4787  // keep selected bins
4788  Int_t sel_l = sel ? axis->GetFirst() : 0;
4789  Int_t sel_r = sel ? axis->GetLast() : axis->GetNbins();
4790 
4791  Int_t firstbin = 0, lastbin = 0;
4792 
4793  // X axis in case of 1-dim histogram
4794  if ((ndim==1) && (naxis == 0)) {
4795  for (Int_t n1 = 1; n1<=padhist->GetNbinsX(); n1++) {
4796  Double_t v = padhist->GetBinContent(n1);
4797  if (TMath::Abs(v)<1e-10) continue;
4798  if ((n1<sel_l) || (n1>sel_r)) continue;
4799  lastbin = n1;
4800  if (firstbin == 0) firstbin = n1;
4801  }
4802  }
4803 
4804  // X,Y axis in case of 2-dim histogram
4805  if ((ndim == 2) && (naxis < 2))
4806  for (Int_t n1 = 1; n1<=padhist->GetNbinsX(); n1++)
4807  for (Int_t n2 = 1; n2<=padhist->GetNbinsY(); n2++) {
4808  Double_t v = padhist->GetBinContent(n1,n2);
4809  if (TMath::Abs(v)<1e-10) continue;
4810  Int_t bin = naxis == 0 ? n1 : n2;
4811  if ((bin<sel_l) || (bin>sel_r)) continue;
4812  if ((lastbin == 0) || (bin > lastbin)) lastbin = bin;
4813  if ((firstbin == 0) || (bin < firstbin)) firstbin = bin;
4814  }
4815 
4816  // X,Y,Z axis in case of 3-dim histogram
4817  if ((ndim == 3) && (naxis < 3))
4818  for (Int_t n1 = 1; n1<=padhist->GetNbinsX(); n1++)
4819  for (Int_t n2 = 1; n2<=padhist->GetNbinsY(); n2++)
4820  for (Int_t n3 = 1; n3<=padhist->GetNbinsZ(); n3++) {
4821  Double_t v = padhist->GetBinContent(n1,n2,n3);
4822  if (TMath::Abs(v)<1e-10) continue;
4823  Int_t bin = naxis == 0 ? n1 : ((naxis==1) ? n2 : n3);
4824  if ((bin<sel_l) || (bin>sel_r)) continue;
4825  if ((lastbin == 0) || (bin > lastbin)) lastbin = bin;
4826  if ((firstbin == 0) || (bin < firstbin)) firstbin = bin;
4827  }
4828 
4829  if (firstbin > 0) {
4830 
4831  if (firstbin >= lastbin) { firstbin--; lastbin++; }
4832 
4833  if (firstbin<=3) firstbin = 1;
4834  if (lastbin >=axis->GetNbins()-3) lastbin = axis->GetNbins();
4835 
4836  Double_t left = axis->GetBinLowEdge(firstbin);
4837  Double_t right = axis->GetBinUpEdge(lastbin);
4838 
4839  Double_t margin = (right - left) * fact;
4840  left -= margin; right += margin;
4841 
4842  if ((left <= new_umin) && (right >= new_umax)) return;
4843 
4844  if (left > new_umin) new_umin = left;
4845  if (right < new_umax) new_umax = right;
4846 
4847  if (action==6) axis->SetRange(firstbin,lastbin);
4848  }
4849 
4850  break;
4851  }
4852 
4853  default:
4854  return;
4855  }
4856 
4857  TakeSelectedAxisRange(naxis, padopt, new_umin, new_umax, false);
4858 
4859  if (naxis == ndim)
4860  if (padopt->GetRange(naxis, new_umin, new_umax))
4861  padopt->SetAutoScale(kFALSE);
4862 }
4863 
4864 void TGo4ViewPanel::TakeFullRangeFromHisto(TH1 *h1, TGo4Picture *padopt, bool isfirsthisto)
4865 {
4866  if (!h1 || !padopt) return;
4867 
4868  TAxis *xax = h1->GetXaxis();
4869  TAxis *yax = h1->GetYaxis();
4870  TAxis *zax = h1->GetZaxis();
4871  int ndim = h1->GetDimension();
4872 
4873  if (isfirsthisto) {
4874  padopt->SetFullRangeDim(ndim);
4875  padopt->SetFullRange(0, xax->GetBinLowEdge(1),
4876  xax->GetBinUpEdge(xax->GetNbins()));
4877  if (ndim > 1)
4878  padopt->SetFullRange(1, yax->GetBinLowEdge(1),
4879  yax->GetBinUpEdge(yax->GetNbins()));
4880  else
4881  padopt->ClearFullRange(2);
4882 
4883  if (ndim > 2)
4884  padopt->SetFullRange(2, zax->GetBinLowEdge(1),
4885  zax->GetBinUpEdge(zax->GetNbins()));
4886  } else
4887  ndim = padopt->GetFullRangeDim();
4888 
4889  if (ndim >= 3)
4890  return;
4891 
4892  Int_t dimindx = (ndim == 1) ? 1 : 2;
4893 
4894  Double_t minimum = 0, maximum = 0;
4895  Bool_t first = kTRUE;
4896  if (!isfirsthisto) {
4897  padopt->GetFullRange(dimindx, minimum, maximum);
4898  first = kFALSE;
4899  }
4900 
4901  for (Int_t biny = 1; biny <= yax->GetNbins(); biny++)
4902  for (Int_t binx = 1; binx <= xax->GetNbins(); binx++) {
4903  Int_t bin = h1->GetBin(binx, biny);
4904  Double_t value = h1->GetBinContent(bin);
4905  if (first) {
4906  minimum = value;
4907  maximum = value;
4908  first = kFALSE;
4909  }
4910  if (value < minimum)
4911  minimum = value;
4912  else if (value > maximum)
4913  maximum = value;
4914  }
4915 
4916  padopt->SetFullRange(dimindx, minimum, maximum);
4917 }
4918 
4919 void TGo4ViewPanel::TakeFullRangeFromGraph(TGraph *gr, TGo4Picture *padopt, bool isfirst)
4920 {
4921  if (!gr || !padopt) return;
4922 
4923  Double_t minx = 0, maxx = 0, miny = 0, maxy = 0, xx, yy;
4924  if (isfirst) {
4925  if (gr->GetN() > 0) {
4926  gr->GetPoint(0, minx, miny);
4927  maxx = minx;
4928  maxy = miny;
4929  }
4930  } else {
4931  padopt->GetFullRange(0, minx, maxx);
4932  padopt->GetFullRange(1, miny, maxy);
4933  }
4934 
4935  for (Int_t n = 0; n < gr->GetN(); n++) {
4936  gr->GetPoint(n, xx, yy);
4937  if (xx < minx)
4938  minx = xx;
4939  else if (xx > maxx)
4940  maxx = xx;
4941  if (yy < miny)
4942  miny = yy;
4943  else if (yy > maxy)
4944  maxy = yy;
4945  }
4946 
4947  padopt->SetFullRangeDim(1);
4948  padopt->SetFullRange(0, minx, maxx);
4949  padopt->SetFullRange(1, miny, maxy);
4950  padopt->ClearFullRange(2);
4951 }
4952 
4953 void TGo4ViewPanel::SetSelectedRangeToHisto(TPad *pad, TH1 *h1, THStack *hs,
4954  TGo4Picture *padopt, bool isthishisto)
4955 {
4956  // set selected range, stats and title position for histogram
4957 
4958  if (!h1 || !padopt || !pad) return;
4959 
4960  int ndim = padopt->GetFullRangeDim();
4961 
4962  bool autoscale = padopt->IsAutoScale();
4963 
4964  double hmin = 0., hmax = 0., umin, umax;
4965 
4966  TAxis *ax = h1->GetXaxis();
4967 
4968  if (IsAutoZoomFlag() && isthishisto) {
4969  MoveSingleScale(1., 6, 0, padopt, h1);
4970  if (ndim>1) MoveSingleScale(1., 6, 1, padopt, h1);
4971  if (ndim>2) MoveSingleScale(1., 6, 2, padopt, h1);
4972  } else if (padopt->GetRange(0, umin, umax)) {
4973  // note: go4 range was full visible range of histogram
4974  // in new ROOT automatic shift of ranges can appear,
4975  // to prevent this, center of each bin should be used
4976 
4977  Int_t i1 = ax->FindFixBin(umin);
4978  Int_t i2 = ax->FindFixBin(umax);
4979  if (i1 < i2) ax->SetRange(i1,i2);
4980  else { ax->UnZoom(); padopt->ClearRange(0); }
4981  } else {
4982  ax->UnZoom();
4983  }
4984 
4985  TAxis *ay = h1->GetYaxis();
4986 
4987  if (padopt->GetRange(1, umin, umax)) {
4988  if (!autoscale && (ndim == 1)) {
4989  hmin = umin;
4990  hmax = umax;
4991  ay = nullptr;
4992  }
4993 
4994  // note: go4 range was full visible range of histogram
4995  // in new ROOT automatic shift of ranges can appear,
4996  // to prevent this, center of each bin should be used
4997 
4998  if (ndim>1) {
4999  Int_t i1 = ay->FindFixBin(umin);
5000  Int_t i2 = ay->FindFixBin(umax);
5001  if (i1 < i2) { ay->SetRange(i1,i2); ay = nullptr; }
5002  }
5003  }
5004 
5005  if (ay) {
5006  ay->UnZoom();
5007  padopt->ClearRange(1);
5008  // workaround for the 5.34/11 version
5009  if ((ndim == 1) && (h1->GetMinimum() == 0) && (h1->GetMaximum() == 1)) {
5010  h1->SetMinimum();
5011  h1->SetMaximum();
5012  }
5013  }
5014 
5015  TAxis *az = h1->GetZaxis();
5016 
5017  if (padopt->GetRange(2, umin, umax) && (ndim > 1)) {
5018  if (!autoscale && (ndim == 2)) {
5019  hmin = umin;
5020  hmax = umax;
5021  az = nullptr;
5022  }
5023  // note: go4 range was full visible range of histogram
5024  // in new ROOT automatic shift of ranges can appear,
5025  // to prevent this, center of each bin should be used
5026 
5027  if (ndim>2) {
5028  Int_t i1 = az->FindFixBin(umin);
5029  Int_t i2 = az->FindFixBin(umax);
5030  if (i1<i2) { az->SetRange(i1,i2); az = nullptr; }
5031  }
5032  }
5033 
5034  if (az) {
5035  az->UnZoom();
5036  padopt->ClearRange(2);
5037  }
5038 
5039  if (hmin != hmax) {
5040  // if scale axis is log, prevent negative values, otherwise
5041  // histogram will not be displayed
5042  if (padopt->GetLogScale(ndim)) {
5043  if (hmax <= 0) hmax = 1.;
5044  if ((hmin <= 0) || (hmin >= hmax)) {
5045  hmin = hmax * 1e-4;
5046  if (hmin > 1.) hmin = 1;
5047  }
5048  }
5049 
5050  h1->SetMinimum(hmin);
5051  h1->SetMaximum(hmax);
5052  h1->SetBit(TH1::kIsZoomed);
5053  if (hs) {
5054  hs->SetMinimum(hmin);
5055  hs->SetMaximum(hmax);
5056  }
5057  } else {
5058  // this is autoscale mode
5059 
5060  if (hs) {
5061  if (ndim == 1) {
5062  TIter next(hs->GetHists());
5063  while (auto hs_h1 = (TH1 *) next()) {
5064  if (padopt->GetRange(0, umin, umax)) {
5065  // note: go4 range was full visible range of histogram
5066  // in new ROOT automatic shift of ranges can appear,
5067  // to prevent this, center of each bin should be used
5068  TAxis *ax = hs_h1->GetXaxis();
5069  Int_t i1 = ax->FindFixBin(umin);
5070  Int_t i2 = ax->FindFixBin(umax);
5071  if (i1<i2) { ax->SetRange(i1,i2); }
5072  else { ax->UnZoom(); padopt->ClearRange(0); }
5073  } else {
5074  hs_h1->GetXaxis()->UnZoom();
5075  }
5076 
5077  hs_h1->GetYaxis()->UnZoom();
5078  hs_h1->SetMinimum();
5079  hs_h1->SetMaximum();
5080  }
5081  }
5082 
5083  hs->SetMinimum();
5084  hs->SetMaximum();
5085  }
5086 
5087  h1->SetMinimum();
5088  h1->SetMaximum();
5089  h1->ResetBit(TH1::kIsZoomed);
5090 
5091  // here one can estimate actual range which will be displayed on canvas
5092 
5093  if (ndim < 3) {
5094 
5095  Double_t selmin = h1->GetMinimum();
5096  Double_t selmax = h1->GetMaximum();
5097 
5098  if (selmin >= selmax) {
5099  padopt->ClearRange(ndim);
5100  } else {
5101  bool islogscale = (ndim == 1) && (padopt->GetLogScale(1) > 0);
5102 
5103  if (islogscale) {
5104  if ((selmin > 0) && (selmax > 0)) {
5105  selmin = TMath::Log10(selmin) + TMath::Log10(0.5);
5106  selmin = TMath::Power(10, selmin);
5107  selmax = TMath::Log10(selmax)
5108  + TMath::Log10(2 * (0.9 / 0.95));
5109  selmax = TMath::Power(10, selmax);
5110  }
5111 
5112  } else {
5113  Double_t yMARGIN = gStyle->GetHistTopMargin();
5114  Double_t dymin = yMARGIN * (selmax - selmin);
5115  if ((selmin >= 0) && (selmin - dymin < 0))
5116  selmin = 0;
5117  else
5118  selmin -= dymin;
5119  selmax += yMARGIN * (selmax - selmin);
5120  }
5121 
5122  padopt->SetRange(ndim, selmin, selmax);
5123  }
5124  }
5125  }
5126 
5127  if (padopt->IsHisStats() && isthishisto) {
5128  TPaveStats* stats =
5129  dynamic_cast<TPaveStats*>(h1->GetListOfFunctions()->FindObject("stats"));
5130  if (!stats) {
5131  stats = new TPaveStats(
5132  gStyle->GetStatX()-gStyle->GetStatW(),
5133  gStyle->GetStatY()-gStyle->GetStatH(),
5134  gStyle->GetStatX(),
5135  gStyle->GetStatY(),"brNDC");
5136  stats->SetParent(h1);
5137  stats->UseCurrentStyle();
5138  stats->SetName("stats");
5139  h1->GetListOfFunctions()->Add(stats);
5140  stats->ConvertNDCtoPad(); // need to bypass TPave init problem
5141  }
5142  padopt->GetStatsAttr(stats);
5143  }
5144 
5145  if (padopt->IsHisTitle() && padopt->HasTitleAttr()) {
5146  TPaveText* titl =
5147  dynamic_cast<TPaveText*>(pad->GetListOfPrimitives()->FindObject("title"));
5148 
5149  if (!titl) {
5150  titl = new TPaveText(gStyle->GetTitleX()-gStyle->GetTitleW(),
5151  gStyle->GetTitleY()-gStyle->GetTitleH(),
5152  gStyle->GetTitleX(),
5153  gStyle->GetTitleY(),"blNDC");
5154  titl->UseCurrentStyle();
5155  titl->SetFillColor(gStyle->GetTitleFillColor());
5156  titl->SetFillStyle(gStyle->GetTitleStyle());
5157  titl->SetName("title");
5158  titl->SetBorderSize(gStyle->GetTitleBorderSize());
5159  titl->SetTextColor(gStyle->GetTitleTextColor());
5160  titl->SetTextFont(gStyle->GetTitleFont(""));
5161  if (gStyle->GetTitleFont("")%10 > 2)
5162  titl->SetTextSize(gStyle->GetTitleFontSize());
5163  titl->AddText(h1->GetTitle());
5164  titl->SetBit(kCanDelete);
5165  pad->GetListOfPrimitives()->Add(titl);
5166  titl->ConvertNDCtoPad(); // need to bypass TPave init problem
5167  }
5168  padopt->GetTitleAttr(titl);
5169  }
5170 
5171  // add here setting the time format properties:
5172  TAxis *xax = h1->GetXaxis();
5173  xax->SetTimeDisplay(padopt->IsXAxisTimeDisplay());
5174  xax->SetTimeFormat(padopt->GetXAxisTimeFormat());
5175 
5176  // JAM 2016 finally we evaluate the rectangular axis scale property:
5177  if (padopt->IsXYRatioOne()) {
5178  RectangularRatio(pad);
5179  } else {
5180  DefaultPadMargin(pad);
5181  }
5182 }
5183 
5184 bool TGo4ViewPanel::GetVisibleRange(TPad *pad, int naxis, double& min, double& max)
5185 {
5186  TGo4Picture *padopt = GetPadOptions(pad);
5187  if (!padopt) return false;
5188 
5189  int NumDim = padopt->GetFullRangeDim();
5190 
5191  if ((naxis < 0) || (naxis > NumDim)) return false;
5192 
5193  bool res = padopt->GetRange(naxis, min, max);
5194  if (!res || (min >= max))
5195  res = padopt->GetFullRange(naxis, min, max);
5196  return res;
5197 }
5198 
5200  double selmin, double selmax, bool force)
5201 {
5202  if ((selmin == -1.) && (selmax == -1.)) return false;
5203 
5204  double min, max, umin, umax;
5205 
5206  bool full = padopt->GetFullRange(naxis, min, max);
5207  /*bool sel = */ padopt->GetRange(naxis, umin, umax);
5208 
5209  if (!full || (min >= max) || (selmin >= selmax)) {
5210  padopt->ClearRange(naxis);
5211  return true;
5212  }
5213 
5214  double delta = (max - min) / 100000.;
5215  bool changed = false;
5216 
5217  if (umin < umax) {
5218  if (fabs(umin - selmin) > delta) {
5219  umin = selmin;
5220  changed = true;
5221  }
5222  if (fabs(umax - selmax) > delta) {
5223  umax = selmax;
5224  changed = true;
5225  }
5226  } else {
5227  umin = selmin;
5228  umax = selmax;
5229  changed = true;
5230  }
5231 
5232  if ((selmin < min + delta) && (selmax > max - delta) && !force) {
5233  padopt->ClearRange(naxis);
5234  } else {
5235  padopt->SetRange(naxis, umin, umax);
5236  }
5237 
5238  return changed;
5239 }
5240 
5241 bool TGo4ViewPanel::TakeSelectedAxisRange(int naxis, TGo4Picture *padopt, TAxis *ax)
5242 {
5243  Double_t selmin, selmax;
5244 
5245  // check if something selected on axis
5246  if (((ax->GetFirst() <= 0) && (ax->GetLast() >= ax->GetNbins() - 1))
5247  || (ax->GetFirst() >= ax->GetLast())) {
5248  selmin = -1111;
5249  selmax = -1111;
5250  } else {
5251  selmin = ax->GetBinCenter(ax->GetFirst());
5252  selmax = ax->GetBinCenter(ax->GetLast());
5253  }
5254 
5255  return TakeSelectedAxisRange(naxis, padopt, selmin, selmax, false);
5256 }
5257 
5259 {
5260  TGo4LockGuard lock;
5261 
5262  TGo4Picture *padopt = GetPadOptions(pad);
5263 
5264  if (IsRedrawBlocked() || !pad || !padopt) return;
5265 
5266  // check if we have histogram and can take range from it
5267  TH1 *h1 = GetPadHistogram(pad);
5268 
5269  if (h1) {
5270  Int_t ndim = padopt->GetFullRangeDim();
5271 
5272  TakeSelectedAxisRange(0, padopt, h1->GetXaxis());
5273  if (ndim > 1)
5274  TakeSelectedAxisRange(1, padopt, h1->GetYaxis());
5275  if (ndim > 2)
5276  TakeSelectedAxisRange(2, padopt, h1->GetZaxis());
5277  if (ndim < 3) {
5278 
5279  bool iszoomed = h1->TestBit(TH1::kIsZoomed);
5280 
5281  padopt->SetAutoScale(!iszoomed);
5282  //h1->SetMinimum();
5283  //h1->SetMaximum();
5284 
5285  Double_t selmin = h1->GetMinimum();
5286  Double_t selmax = h1->GetMaximum();
5287 
5288  if (iszoomed) {
5289  padopt->SetRange(ndim, selmin, selmax);
5290  } else if (selmin >= selmax) {
5291  padopt->ClearRange(ndim);
5292  } else {
5293 
5294  bool islogscale = (ndim == 1) && (pad->GetLogy() > 0);
5295 
5296  if (islogscale) {
5297  if ((selmin > 0) && (selmax > 0)) {
5298  selmin = TMath::Log10(selmin) + TMath::Log10(0.5);
5299  selmin = TMath::Power(10, selmin);
5300  selmax = TMath::Log10(selmax)
5301  + TMath::Log10(2 * (0.9 / 0.95));
5302  selmax = TMath::Power(10, selmax);
5303  }
5304 
5305  } else {
5306  Double_t yMARGIN = gStyle->GetHistTopMargin();
5307  Double_t dymin = yMARGIN * (selmax - selmin);
5308  if ((selmin >= 0) && (selmin - dymin < 0))
5309  selmin = 0;
5310  else
5311  selmin -= dymin;
5312  selmax += yMARGIN * (selmax - selmin);
5313  }
5314 
5315  padopt->SetRange(ndim, selmin, selmax);
5316  }
5317  }
5318 
5319  // inform that options were changed in panel
5321  return;
5322  }
5323 
5324  Double_t rxmin, rxmax, rymin, rymax;
5325  pad->GetRangeAxis(rxmin, rymin, rxmax, rymax);
5326 
5327  if (pad->GetLogx() > 0) {
5328  rxmin = TMath::Power(10., rxmin);
5329  rxmax = TMath::Power(10., rxmax);
5330  }
5331 
5332  if (pad->GetLogy() > 0) {
5333  rymin = TMath::Power(10., rymin);
5334  rymax = TMath::Power(10., rymax);
5335  }
5336 
5337  PadRangeAxisChanged(pad, rxmin, rxmax, rymin, rymax);
5338 }
5339 
5340 void TGo4ViewPanel::PadRangeAxisChanged(TPad *pad, double rxmin, double rxmax,
5341  double rymin, double rymax)
5342 {
5343  TGo4LockGuard lock;
5344 
5345  if (IsRedrawBlocked() || !pad) return;
5346 
5347  TGo4Picture *padopt = GetPadOptions(pad);
5348  if (!padopt) return;
5349 
5350  TakeSelectedAxisRange(0, padopt, rxmin, rxmax, false);
5351  TakeSelectedAxisRange(1, padopt, rymin, rymax, false);
5352 
5354 }
5355 
5356 void TGo4ViewPanel::GetSelectedRange(int& ndim, bool& autoscale, double& xmin,
5357  double& xmax, double& ymin, double& ymax, double& zmin, double& zmax)
5358 {
5359  ndim = 0;
5360  TGo4Picture *padopt = GetPadOptions(GetActivePad());
5361  if (!padopt) return;
5362 
5363  ndim = padopt->GetFullRangeDim();
5364  autoscale = padopt->IsAutoScale();
5365 
5366  GetVisibleRange(GetActivePad(), 0, xmin, xmax);
5367  GetVisibleRange(GetActivePad(), 1, ymin, ymax);
5368  GetVisibleRange(GetActivePad(), 2, zmin, zmax);
5369 }
5370 
5372 {
5373  fbApplyToAllFlag = on;
5374 
5375  QCheckBox* box1 = findChild<QCheckBox*>("ApplyToAllCheck");
5376  if (box1) box1->setChecked(on);
5377 }
5378 
5379 void TGo4ViewPanel::SetAutoScale(bool on, TPad *selpad)
5380 {
5381  TGo4LockGuard lock;
5382 
5383  bool modified = false;
5384  bool applytoall = false;
5385  bool redraw_immediately = !selpad;
5386 
5387  if (!selpad) {
5388  applytoall = IsApplyToAllFlag();
5389  selpad = applytoall ? GetCanvas() : GetActivePad();
5390  }
5391  if (!selpad)
5392  return;
5393 
5394  TGo4Picture *padopt = GetPadOptions(selpad);
5395  if (padopt) {
5396  if (on != padopt->IsAutoScale())
5397  padopt->SetPadModified();
5398  padopt->SetAutoScale(on);
5399  modified = modified || padopt->IsPadModified();
5400  }
5401 
5402  if (applytoall) {
5403  TGo4Iter iter(GetPadSlot(selpad), kTRUE);
5404  while (iter.next()) {
5405  TPad *subpad = GetSlotPad(iter.getslot());
5406  padopt = GetPadOptions(subpad);
5407  if (!padopt)
5408  continue;
5409  if (on != padopt->IsAutoScale())
5410  padopt->SetPadModified();
5411  padopt->SetAutoScale(on);
5412  modified = modified || padopt->IsPadModified();
5413  }
5414  }
5415 
5416  if (modified && redraw_immediately)
5417  RedrawPanel(selpad, false);
5418 }
5419 
5420 void TGo4ViewPanel::SetSelectedRange(double xmin, double xmax, double ymin,
5421  double ymax, double zmin, double zmax)
5422 {
5423  TGo4LockGuard lock;
5424 
5425  TPad *selpad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
5426  if (!selpad)
5427  return;
5428 
5429  TGo4Picture *padopt = GetPadOptions(selpad);
5430  if (padopt) {
5431  Int_t ndim = padopt->GetFullRangeDim();
5432 
5433  TakeSelectedAxisRange(0, padopt, xmin, xmax, true);
5434  if (ndim > 1)
5435  TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
5436  if (ndim > 2)
5437  TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
5438  if (!padopt->IsAutoScale()) {
5439  if (ndim == 1)
5440  TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
5441  if (ndim == 2)
5442  TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
5443  }
5444  padopt->SetPadModified();
5445  }
5446 
5447  if (IsApplyToAllFlag()) {
5448  TGo4Iter iter(GetPadSlot(selpad), kTRUE);
5449  while (iter.next()) {
5450  TPad *subpad = GetSlotPad(iter.getslot());
5451  padopt = GetPadOptions(subpad);
5452  if (!padopt)
5453  continue;
5454  Int_t ndim = padopt->GetFullRangeDim();
5455  TakeSelectedAxisRange(0, padopt, xmin, xmax, true);
5456  if (ndim > 1)
5457  TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
5458  if (ndim > 2)
5459  TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
5460  if (!padopt->IsAutoScale()) {
5461  if (ndim == 1)
5462  TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
5463  if (ndim == 2)
5464  TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
5465  }
5466 
5467  padopt->SetPadModified();
5468  }
5469  }
5470 
5471  RedrawPanel(selpad, false);
5472 }
5473 
5474 void TGo4ViewPanel::resizeEvent(QResizeEvent *e)
5475 {
5476  // store size of top widget -
5477  // size of top widget will be restored when new panel is created
5478  go4sett->storePanelSize(parentWidget(), "ViewPanel");
5479  TPad *selpad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
5480  if (!selpad)
5481  return;
5482  // only if we are in 1:1 aspect ratio, we might need a redraw here:
5483  TGo4Slot *slot = GetPadSlot(selpad);
5484  if (!slot)
5485  return;
5486  TGo4Picture *padopt = GetPadOptions(slot);
5487  if (!padopt)
5488  return;
5489 
5490  if (padopt->IsXYRatioOne()) {
5491  // note: we need to delay execution of redraw, since resize Event in QtROOT canvas will
5492  // also happen in timer 100ms after us -> new coordinates are not refreshed here!
5493  fxResizeTimerPad = selpad;
5494  QTimer::singleShot(1000, this, &TGo4ViewPanel::checkResizeSlot);
5495  }
5496 }
5497 
5499 {
5500 #ifdef __GO4X11__
5502 #endif
5503 }
5504 
5506 {
5507  if (obj && !obj->InheritsFrom(THStack::Class()) && !obj->InheritsFrom(TMultiGraph::Class())) {
5508  if (fxQCanvas) {
5509 #ifdef __GO4X11__
5511 #endif
5512  } else if (fxWCanvas) {
5513 #ifdef __GO4WEB__
5515 #endif
5516  }
5517  }
5518 }
5519 
5521 {
5522 #ifdef __GO4X11__
5523  if (fxQCanvas)
5525 #endif
5526 }
5527 
5529 {
5531 }
5532 
5534 {
5535  if (IsRepaintTimerActive()) return;
5536 
5537  if (!pad) pad = GetCanvas();
5538 
5539  fxRepaintTimerPad = pad;
5541 }
5542 
5544 {
5545  return fxRepaintTimerPad != nullptr;
5546 }
5547 
5549 {
5550  TPad *pad = fxRepaintTimerPad;
5551  fxRepaintTimerPad = nullptr;
5552  if (pad)
5553  RedrawPanel(pad, false);
5554 }
5555 
5557 {
5558  TPad *pad = fxResizeTimerPad;
5559  fxResizeTimerPad = nullptr;
5560  if (pad)
5561  RedrawPanel(pad, true);
5562 }
5563 
5565 {
5566  TGo4Slot *slot = GetPadSlot(pad);
5567  if (slot)
5568  delete slot;
5569 
5570  GetCanvas()->SetSelectedPad(GetCanvas());
5571  GetCanvas()->SetSelected(GetCanvas());
5573 }
5574 
5575 // marker functions
5576 
5577 int TGo4ViewPanel::GetNumMarkers(TPad *pad, int kind)
5578 {
5579  TGo4Slot *slot = GetPadSlot(pad);
5580  if (!slot)
5581  return 0;
5582 
5583  int res = 0;
5584 
5585  for (int n = 0; n < slot->NumChilds(); n++) {
5586  TGo4Slot *subslot = slot->GetChild(n);
5587  if (GetDrawKind(subslot) == kind)
5588  res++;
5589  }
5590  return res;
5591 }
5592 
5593 void TGo4ViewPanel::AddMarkerObj(TPad *pad, int kind, TObject *obj)
5594 {
5595  TGo4Slot *padslot = GetPadSlot(pad);
5596  if (!padslot) {
5597  delete obj;
5598  return;
5599  }
5600 
5601  QString basename;
5602  switch (kind) {
5603  case kind_Marker:
5604  basename = "Marker";
5605  break;
5606  case kind_Window:
5607  basename = "Window";
5608  break;
5609  case kind_Poly:
5610  basename = "Polygon";
5611  break;
5612  case kind_Latex:
5613  basename = "Latex";
5614  break;
5615  case kind_Arrow:
5616  basename = "Arrow";
5617  break;
5618  default:
5619  basename = "Something";
5620  break;
5621  }
5622 
5623  QString slotname;
5624  int cnt = 0;
5625  do {
5626  slotname = basename + QString::number(cnt++);
5627  } while (padslot->FindChild(slotname.toLatin1().constData()));
5628 
5629  TGo4Slot *objslot = AddDrawObject(pad, kind, slotname.toLatin1().constData(), obj, true, nullptr);
5630 
5631  SetActiveObj(pad, kind, objslot);
5632 }
5633 
5634 void TGo4ViewPanel::SetActiveObj(TPad *pad, int kind, TGo4Slot *activeslot)
5635 {
5636  TGo4Slot *slot = GetPadSlot(pad);
5637  if (!slot)
5638  return;
5639 
5640  for (int n = 0; n < slot->NumChilds(); n++) {
5641  TGo4Slot *subslot = slot->GetChild(n);
5642  int drawkind = GetDrawKind(subslot);
5643  if (drawkind != kind)
5644  continue;
5645 
5646  if (subslot != activeslot)
5647  subslot->RemovePar("::ActiveMarker");
5648  else
5649  subslot->SetPar("::ActiveMarker", "1");
5650  }
5651 }
5652 
5653 TObject *TGo4ViewPanel::GetActiveObj(TPad *pad, int kind)
5654 {
5655  int selkind;
5656  TObject *selobj;
5657  /* TGo4Slot *selslot = */ GetSelectedSlot(pad, &selkind, &selobj);
5658  if ((kind == selkind) && selobj)
5659  return selobj;
5660 
5661  TGo4Slot *slot = GetPadSlot(pad);
5662  if (!slot) return nullptr;
5663 
5664  TObject *lastobj = nullptr;
5665 
5666  for (int n = 0; n < slot->NumChilds(); n++) {
5667  TGo4Slot *subslot = slot->GetChild(n);
5668  int drawkind = GetDrawKind(subslot);
5669  if (drawkind != kind)
5670  continue;
5671 
5672  lastobj = subslot->GetAssignedObject();
5673  if (subslot->GetPar("::ActiveMarker"))
5674  return lastobj;
5675  }
5676 
5677  return lastobj;
5678 }
5679 
5680 QString TGo4ViewPanel::GetActiveObjName(TPad *pad, int kind)
5681 {
5682  TObject *obj = GetActiveObj(pad, kind);
5683  return !obj ? QString("null") : QString(obj->GetName());
5684 }
5685 
5687 {
5688  TGo4LockGuard lock;
5689  switch (id) {
5690  case CrosshairId: {
5692  GetCanvas()->SetCrosshair(fbCanvasCrosshair);
5693  CanvasUpdate(true);
5695  break;
5696  }
5697 
5698  case FreezeTitleId: {
5700  break;
5701  }
5702 
5703  case AutoZoomId: {
5705  if (fbAutoZoomFlag) RedrawPanel(GetCanvas(), true);
5706  break;
5707  }
5708 
5709  case SetTitleTextId: {
5710  bool ok = false;
5711  QString mycaption = windowTitle();
5712  QString oldtitle = mycaption.remove(fPanelName + ": ");
5713  QString text = QInputDialog::getText(this, GetPanelName(),
5714  "Enter Viewpanel Title:", QLineEdit::Normal, oldtitle, &ok);
5715  if (ok && !text.isEmpty())
5716  SetFreezedTitle(text);
5717  break;
5718  }
5719 
5720  case SetTimeFormatId: {
5721  bool ok = false;
5722  TPad *pad = GetActivePad();
5723  if (!pad) pad = GetCanvas();
5724  TGo4Picture *padopt = GetPadOptions(pad);
5725  QString oldfmt = padopt->GetXAxisTimeFormat();
5726  QString text = QInputDialog::getText(this, GetPanelName(),
5727  "Enter Axis time format:", QLineEdit::Normal, oldfmt, &ok);
5728  if (ok && !text.isEmpty()) {
5729  //padopt->SetXAxisTimeFormat(text.toLatin1());
5730  //padopt->SetPadModified();
5731  ChangeDrawOption(id - 1000, 0, text.toLatin1());
5732  }
5733  break;
5734  }
5735 
5736  default:
5737  if (id > 1000) {
5738  QAction* act = SetIdAction(fOptionsMap, id);
5739  bool s = act ? act->isChecked() : false;
5740  ChangeDrawOption(id - 1000, s, nullptr);
5741  }
5742  break;
5743  }
5744 }
5745 
5747 {
5748 // if (IsRedrawBlocked()) return;
5749 
5750  fbApplyToAllFlag = on;
5751 }
5752 
5754 {
5755  if (IsRedrawBlocked())
5756  return;
5757 
5758  SetAutoScale(on, nullptr);
5759 }
5760 
5761 void TGo4ViewPanel::panelSlot(TGo4ViewPanel * panel, TPad *pad, int signalid)
5762 {
5763  if (panel != this)
5764  return;
5765 
5766  BlockPanelRedraw(true);
5767 
5768  TGo4Picture *padopt = GetPadOptions(GetActivePad());
5769  if (padopt)
5770  fAutoScaleCheck->setChecked(padopt->IsAutoScale());
5771 
5772  BlockPanelRedraw(false);
5773 }
5774 
5776 {
5777  if (IsRedrawBlocked())
5778  return;
5779 
5780  ChangeDrawOption(11, on, "");
5781 }
bool IsApplyToAll() const
virtual void SetMouseMode(int mode)
virtual void ShootRepaintTimer()
void CanvasUpdate(bool modify=false)
bool fbCanvasCrosshair
virtual TObject * GetDrawObject(TPad *pad, const char *name)
virtual void CheckActionAtTheEnd(TPad *pad)
TPad * fxActivePad
virtual bool IsPadHasSubPads(TGo4Slot *padslot)
void showStatusMessage(const char *msg)
virtual void SwitchMarkerButton(int kind, bool on)
virtual void RectangularRatio(TPad *pad)
virtual void PrintCanvas()
void SetRange(Int_t naxis, Double_t min, Double_t max)
void SetTitleTime(Bool_t on=kTRUE)
bool IsAutoScale() const
void Modified(Bool_t=1)
TGo4Slot * GetChild(Int_t n) const
Definition: TGo4Slot.h:77
Bool_t GetIntPar(const char *name, Int_t &value) const
Definition: TGo4Slot.cxx:624
TPadGuard(TVirtualPad *repl=nullptr)
bool IsPadModified() const
virtual void SetPadDefaults(TPad *pad)
QString getTGraphDrawOpt()
bool isStatusBarVisible()
Int_t NumChilds() const
Definition: TGo4Slot.h:76
virtual void TakeFullRangeFromHisto(TH1 *h1, TGo4Picture *padopt, bool isfirsthisto)
void setPrinterSett(const QString &name, const QString &cmd)
virtual TGo4Slot * GetSuperimposeSlot(TGo4Slot *slot)
virtual void ApplyToAllToggled(bool)
QSignalMapper * fOptionsMap
Bool_t IsXAxisTimeDisplay() const
virtual void RedrawImage(TPad *pad, TGo4Picture *padopt, TGo4ASImage *im, TH2 *asihisto, bool scancontent)
bool isStatusBarVisible()
Definition: QWebCanvas.cpp:232
void SetAutoZoom(bool on)
TCutG * GetCut(Bool_t changeowner) override
void SetIntPar(const char *name, Int_t value)
Definition: TGo4Slot.cxx:617
void Draw(Option_t *opt="") override
virtual void StartConditionEditor()
virtual const char * GetDrawObjectLinkName(TPad *pad, TObject *obj)
Bool_t IsHisTitle() const
bool getStatBoxVisible()
virtual void SetFreezeMouseMode(bool on)
virtual void MakePictureForPad(TGo4Picture *pic, TPad *pad, bool useitemname)
void MenuCommandExecuted(TObject *, const char *)
TObject * GetBrowserObject(const char *name, Int_t update=0)
QAction * fxCanvasEventstatusChk
virtual void ActivateInGedEditor(TObject *obj)
virtual void SetDrawKind(TGo4Slot *slot, int kind)
virtual int GetAutoColor(int indx)
virtual void SetYMaxDraw(Bool_t on)
void CanvasLeaveEvent()
virtual void SetActivePad(TPad *pad)
bool fbModifiedSignalFlag
virtual bool IsRedrawBlocked()
void SetProxy(TGo4Proxy *cont)
Definition: TGo4Slot.cxx:296
virtual bool ProcessPadRedraw(TPad *pad, bool force)
void SetDrawData(TH2 *histo, TGo4ViewPanel *panel, TPad *pad)
Definition: TGo4ASImage.cpp:51
virtual void EditConditionBtn_clicked()
TPad * GetSelectedPad()
Definition: TGo4MdiArea.cpp:48
QWebCanvas * fxWCanvas
web canvas
virtual void RedrawMultiGraph(TPad *pad, TGo4Picture *padopt, TMultiGraph *mg, bool dosuperimpose, bool scancontent)
Bool_t IsTitleTime() const
virtual void HandleInput(EEventType button, Int_t x, Int_t y)
QMenu * fSelectMenu
virtual void RedrawStack(TPad *pad, TGo4Picture *padopt, THStack *hs, bool dosuperimpose, bool scancontent)
void SelectedPadChanged(TPad *)
Int_t GetDivX() const
Definition: TGo4Picture.h:53
void getCanvasColor(int &red, int &green, int &blue)
virtual QString GetSelectedMarkerName(TPad *pad)
void SelectedPadChanged(TPad *)
virtual void StartConditionEditing(TPad *pad)
bool UpdateItemInAnalysis(const char *itemname, TObject *obj=nullptr)
Definition: QGo4Widget.cpp:379
static TString NextAvailableName()
void SetValues(Double_t low1, Double_t up1) override
void CopyOptionsFrom(TGo4Picture *source)
bool fbMarkEditorVisible
virtual bool GetVisibleRange(TPad *pad, int naxis, double &min, double &max)
static bool CanDrawItem(int cando)
static TGo4MdiArea * Instance()
Definition: TGo4MdiArea.cpp:26
virtual TGo4Slot * GetDrawObjectSlot(TPad *pad, const char *name)
QString GetPrintProg()
static Int_t GetInstances()
Definition: TGo4Marker.cxx:36
void ConnectPad(TPad *pad)
Definition: QGo4Widget.cpp:229
const char * NoStackDrawOption
bool IsAcceptDrag(const char *itemname, TClass *cl, int kind) override
TGo4Slot * FindChild(const char *name) const
Definition: TGo4Slot.cxx:245
void CallPanelFunc(int id, TPad *pad=nullptr)
Definition: QGo4Widget.cpp:234
virtual const char * GetPanelName()
virtual Bool_t IsXMeanDraw() const
virtual bool IsAutoZoomFlag()
virtual bool ScanDrawOptions(TPad *pad, TGo4Slot *padslot, TGo4Picture *pic, bool onlyscan)
bool getDrawItemFlag()
virtual TObject * GetActiveObj(TPad *pad, int kind)
virtual void ShowEventStatus(bool)
void storePanelSize(QWidget *w, const QString &kind="ViewPanel")
void ResetWidget() override
void SetLinkedName(TGo4Slot *slot, const char *itemname)
Definition: QGo4Widget.cpp:148
Int_t GetNumObjNames() const
virtual void ResizeGedEditor()
void resizeEvent(QResizeEvent *e) override
void cleanupEditor()
TVirtualPad * fSave
Int_t ItemCanDo(const char *name)
void SetHistogram(TH1 *histo)
Definition: TGo4Marker.cxx:74
virtual void SetYRMSDraw(Bool_t on)
Int_t GetLogScale(Int_t nscale=0) const
void SetValuesDirect(TCutG *newcut)
virtual void SaveCanvas()
void linkedUpdated(TGo4Slot *slot, TObject *obj) override
virtual void ProcessMarkersClear(TPad *pad, bool withsubpads)
virtual void StartRootEditor(bool)
void ServiceCall(const char *name, void *par=nullptr)
Definition: QGo4Widget.cpp:398
virtual void ProduceGraphFromMarkers()
bool IsContentModified() const
void UndrawItem(const char *itemname)
Definition: QGo4Widget.cpp:323
TGo4Proxy * GetProxy() const
Definition: TGo4Slot.h:93
virtual void GetConditionBtn_clicked()
void widgetService(QGo4Widget *editor, int serviceid, const char *str, void *par)
virtual TGo4Slot * GetPanelSlot()
TClass * ItemClass(const char *name)
TGo4Slot * GetTopSlot(bool force=false)
Definition: QGo4Widget.cpp:134
virtual void PadDoubleClickedSlot(TPad *pad, int evx=-1, int evy=-1)
void PadClicked(TPad *, int, int)
void Update()
Definition: QWebCanvas.cpp:270
void CanvasUpdated()
virtual void InfoConditionBtn_clicked()
virtual void AutoScaleToggled(bool)
bool getWebBasedCanvas()
int l
Definition: f_mbs_status.c:31
Int_t GetIndexOf(const TGo4Slot *child) const
Definition: TGo4Slot.cxx:226
Graphic Qt Widget based Canvas.
Definition: QRootCanvas.h:57
virtual void ClosePanel()
void linkedObjectUpdated(const char *linkname, TObject *obj) override
virtual void ProducePicture()
virtual const char * GetDrawItemName(int itemcnt=0)
TH1 * GetWorkHistogram() const
virtual void SetAutoZoomFlag(bool on)
const char * GetLinkedName(const char *linkname)
Definition: QGo4Widget.cpp:153
bool fbLeaveFocusAfterCondEnd
virtual TGo4Slot * GetPadMainObjectSlot(TPad *pad)
TGo4Slot * BrowserSlot(const char *item=nullptr)
virtual void CompleteInitialization()
bool getPadCrosshair()
virtual void ProcessPadDoubleClick()
Double_t GetYLow() const override
Definition: TGo4WinCond.h:59
virtual void RedrawPanel(TPad *pad, bool force)
virtual void MoveScale(int expandfactor, int xaction, int yaction, int zaction)
void SetTitleItem(Bool_t on=kTRUE)
TGo4BrowserProxy * Browser()
Definition: QGo4Widget.cpp:219
virtual void ClearCanvas()
void CanvasUpdated()
virtual void DelSelectedMarker_clicked()
void EditItem(const QString &itemname)
Definition: QGo4Widget.cpp:345
virtual void Divide(int numX, int numY)
void SetXAxisTimeFormat(const char *format)
TGo4Slot * getslot() const
Definition: TGo4Iter.cxx:166
Int_t GetRebinY(Int_t index=UndefIndex) const
TGo4ViewPanel * CreateViewPanel(int ndiv=0)
Definition: QGo4Widget.cpp:297
void ChangeDrawOption(Int_t kind, Int_t value)
QString getTH2DrawOpt()
TGo4Picture * Pic(Int_t posy, Int_t posx)
virtual void LogMarkerValues()
virtual void SetCursorMode(bool on)
Bool_t GetStatsAttr(TPaveStats *stats) const
virtual void CheckForSpecialObjects(TPad *pad, TGo4Slot *padslot)
virtual void TakeFullRangeFromGraph(TGraph *gr, TGo4Picture *padopt, bool isfirst)
virtual void UpdatePanelCaption()
virtual QString GetActiveObjName(TPad *pad, int kind)
virtual void SetConditionBtn_clicked()
virtual void UndrawItemOnPanel(const char *itemname)
virtual void DeleteDrawObject(TPad *pad, const char *name)
bool getPadSuperimpose()
bool getDrawTimeFlag()
static QAction * SetIdAction(QSignalMapper *map, int id, int enabled=-1, int checked=-1)
Definition: QGo4Widget.cpp:440
TObject * GetAssignedObject()
Definition: TGo4Slot.cxx:356
virtual TPad * GetSlotPad(TGo4Slot *slot)
virtual TPad * GetSubPad(TPad *toppad, int num, bool onlytoplevel)
virtual TObject * GetPadMainObject(TPad *pad)
virtual void AboutToShowOptionsMenu()
virtual void ProducePadsList(TObjArray *arr, TPad *toppad)
virtual void SetApplyToAllFlag(bool on)
virtual void AllocatePadOptions(TPad *pad)
bool BrowserItemRemote(const char *itemname)
Definition: QGo4Widget.cpp:212
void SetApplyToAll(bool on)
TCanvas * getCanvas()
Definition: QRootCanvas.h:67
virtual bool IsConditionSelected(TPad *pad)
virtual bool IsRepaintTimerActive()
Bool_t GetFrameAttr(TPad *pad) const
virtual const char * GetSpecialDrawOption(TGo4Slot *slot)
void ShowItemInfo(const QString &itemname)
Definition: QGo4Widget.cpp:292
virtual void SetSelectedRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
QMenu * fOptionsMenu
virtual void DisplayPadStatus(TPad *pad)
void SetFullRangeDim(Int_t ndim)
Bool_t HasTitleAttr()
virtual void CheckObjectsAssigments(TPad *pad, TGo4Slot *padslot)
virtual void RedrawLegend(TPad *pad, TGo4Picture *padopt, TGo4Slot *legslot)
void SetDivision(Int_t ndivy, Int_t ndivx)
virtual TGo4Slot * AddNewSlot(const char *name, TGo4Slot *parent)
const char * GetName() const override
Definition: TGo4Marker.h:101
virtual void SaveMarkers()
virtual Bool_t IsXRMSDraw() const
virtual void ProcessCanvasAdopt(TPad *tgtpad, TPad *srcpad, const char *srcitemname)
TH1D * GetHistogram(const char *HistogramName)
Definition: Example1.cxx:43
void resizeEditor()
void PadClicked(TPad *, int, int)
TGo4Slot * GetParent() const
Definition: TGo4Slot.h:58
virtual void SetSelectedMarker(TPad *pad, const QString &selname, int selindex)
void AddObjName(const char *name, Option_t *DrawOption=nullptr)
void SetStatsAttr(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Int_t optstat=1111, const char *statformat="6.4g", Int_t optfit=1111, const char *fitformat="5.4g")
virtual bool ShiftSelectedObjectToEnd(TPad *pad)
void SetXAxisTimeDisplay(Bool_t on)
virtual void checkRepaintSlot()
void SetRebinY(Int_t ngroupy, Int_t index=UndefIndex)
void DeletePainter()
Definition: TGo4Marker.cxx:293
virtual void RedrawHistogram(TPad *pad, TGo4Picture *padopt, TH1 *his, bool scancontent, bool first_draw)
virtual void PadRangeAxisChanged(TPad *pad)
TPad * fxResizeTimerPad
virtual void MarkPadModified(TPad *pad)
Int_t GetRebinX(Int_t index=UndefIndex) const
bool isEditorVisible()
Definition: QWebCanvas.cpp:237
void toggleEditor()
virtual void DropOnPad(TPad *pad, const char *itemname, TClass *cl, int kind)
TList * GetSpecialObjects() const
Definition: TGo4Picture.h:237
virtual void UpdatePadStatus(TPad *pad, bool removeitems)
QStatusBar * CanvasStatus
virtual void SetPolygonMode(bool on)
virtual void CleanupGedEditor()
Bool_t ShiftSlotAfter(TGo4Slot *slot, TGo4Slot *after)
Definition: TGo4Slot.cxx:521
virtual void MoveSingleScale(int expandfactor, int action, int naxis, TGo4Picture *opt, TObject *padhist)
virtual void SelectMenuItemActivated(int)
void SetLogScale(Int_t nscale=0, Int_t zn=1)
virtual TGo4Slot * GetPadSlot(TPad *pad)
virtual void ResetPadFillColors(TPad *pad, int col, TPad *backup=nullptr)
virtual void SelectedMarkerCmb_activated(int indx)
virtual void ClearPad(TPad *pad, bool removeitems, bool removesubpads)
Int_t GetNumber() const
bool IsLegendDraw() const
bool IsSuperimpose() const
virtual TPad * FindPadWithItem(const char *itemname)
const char * GetObjName(Int_t n) const
virtual int GetNumMarkers(TPad *pad, int kind)
virtual void PadDeleted(TPad *pad)
TGo4QSettings * go4sett
void RemovePar(const char *name)
Definition: TGo4Slot.cxx:606
void CanvasDropEvent(QDropEvent *, TPad *)
virtual void SetMarkerPanel(bool)
void linkedRemoved(TGo4Slot *slot, TObject *obj) override
virtual void SetRegionMode(bool on)
Bool_t IsHisStats() const
virtual void SetSpecialDrawOption(TGo4Slot *slot, const char *drawopt)
virtual void SetWorkHistogram(TH1 *histo)
virtual ~TGo4ViewPanel()
void setMaskDoubleClick(bool on=true)
Definition: QRootCanvas.h:69
virtual void ClearAllMarkers()
virtual void ClearActivePad()
virtual void GetSelectedRange(int &ndim, bool &autoscale, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax)
Bool_t IsTitleItem() const
virtual void RedrawGraph(TPad *pad, TGo4Picture *padopt, TGraph *gr, bool scancontent, bool first_draw)
virtual void OptionsMenuItemActivated(int)
bool getPadEventStatus()
static QAction * CreateChkAction(QMenu *menu, const QString &text, bool checked, bool enabled=true)
Definition: QGo4Widget.cpp:403
Bool_t GetRangeY(Double_t &min, Double_t &max) const
void setEditorVisible(bool flag=true)
Definition: QWebCanvas.cpp:248
virtual void Resize(Option_t *option="")
virtual void SetSelectedObjectIndex(TGo4Slot *slot, int indx)
virtual TGo4Picture * GetPadOptions(TPad *pad)
Bool_t DefineRelatedObject(const char *itemname, const char *objectname, TString &objectitem, Int_t mask=3)
Bool_t GetRange(Int_t naxis, Double_t &min, Double_t &max) const
QString getTH1DrawOpt()
void PadDblClicked(TPad *, int, int)
TCanvas * getCanvas()
returns canvas shown in the widget
Definition: QWebCanvas.h:34
TGo4Picture * FindPic(Int_t posy, Int_t posx)
virtual int GetSelectedMarkerIndex(TPad *pad)
void SetHisStats(Bool_t on)
QSignalMapper * fSelectMap
virtual void AddMarkerObj(TPad *pad, int kind, TObject *obj)
bool isEditorVisible()
bool getFetchDataWhenDraw()
virtual int GetDrawKind(TGo4Slot *slot)
bool isEditorAllowed()
virtual void panelSlot(TGo4ViewPanel *panel, TPad *pad, int signalid)
TGo4ViewPanel(QWidget *parent=nullptr, const char *name=nullptr)
virtual TObject * ProduceSuperimposeObject(TGo4Slot *padslot, TGo4Picture *padopt, TGo4Slot *sislot, TGo4Slot *legslot, TObjArray *objs, TObjArray *objslots, bool showitems)
void SetSelectedRange(double rxmin, double rxmax, double rymin, double rymax)
Definition: TGo4ASImage.cpp:64
virtual void SetSlotPad(TGo4Slot *padslot, TPad *pad)
static void Error(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:320
QMenuBar * fMenuBar
void SetDrawOption(Option_t *option="") override
Definition: TGo4Picture.h:138
virtual void SetSelectedMarkerByMouseClick(TPad *pad, const char *name)
const char * GetPar(const char *name) const
Definition: TGo4Slot.cxx:598
TH1 * Get_fHistogram(TObject *obj, bool force=false)
Int_t GetHisContour() const
QByteArray fbaPanelName
virtual void ProcessPadModifiedSignal()
virtual void CollectMainDrawObjects(TGo4Slot *slot, TObjArray *objs, TObjArray *objslots, int modifier)
static QAction * AddIdAction(QMenu *menu, QSignalMapper *map, const QString &text, int id, int enabled=-1, int checked=-1)
Definition: QGo4Widget.cpp:413
void SetFullRange(Int_t naxis, Double_t min, Double_t max)
bool getDrawDateFlag()
virtual void ScanObjectsDrawOptions(bool onlyscan, TGo4Slot *padslot, TObjArray *objs, TObjArray *objslots)
virtual void ProcessPadStatusUpdate(TPad *pad, TGo4Slot *parent, bool removeitems)
void SetFrameAttr(Double_t left, Double_t top, Double_t right, Double_t bottom)
virtual void PadClickedSlot(TPad *pad, int evx=-1, int evy=-1)
virtual void SetChanged(Bool_t on=kTRUE)
virtual TH1 * GetPadHistogram(TPad *pad)
TH1 * GetHistogram() const
Definition: TGo4Marker.h:98
virtual void SetPadSuperImpose(TPad *pad, bool on)
QString fPanelName
virtual bool TakeSelectedAxisRange(int naxis, TGo4Picture *padopt, double selmin, double selmax, bool force)
virtual Int_t IsChanged() const
virtual void ClearPadItems(TGo4Slot *padslot, TGo4Slot *remain)
QCheckBox * fAutoScaleCheck
virtual void SetLateXMode(bool on)
Bool_t IsXYRatioOne() const
virtual bool IsWebCanvas() const
Int_t GetFullRangeDim() const
virtual void RefreshButtons()
QString fFreezedTitle
void SetSuperimpose(bool on)
void PadDoubleClicked(TPad *, int, int)
void SetWorkHistogram(TH1 *histo) override
void SetDrawAttributes(TObject *obj, Int_t index=UndefIndex)
void setStatusBar(QStatusBar *bar)
Definition: QRootCanvas.h:82
QString getTH3DrawOpt()
Double_t GetXLow() const override
Definition: TGo4WinCond.h:57
void SetPadModified(bool on=true)
bool IsAutoZoom() const
virtual bool IsPanelPad(TPad *pad)
virtual TGo4Slot * GetSelectedSlot(TPad *pad, int *selkind, TObject **selobj)
void buildEditorWindow()
virtual void BlockPanelRedraw(bool on)
void ClearFullRange(Int_t naxis=-1)
virtual void CanvasDropEventSlot(QDropEvent *event, TPad *pad)
TPad * fxRepaintTimerPad
Int_t GetDimension() const
TPad * fxDoubleClickTimerPad
virtual void SetActiveObj(TPad *pad, int kind, TGo4Slot *activeslot)
virtual void CollectSpecialObjects(TPad *pad, TObjArray *objs, int selectkind)
virtual void LoadMarkers()
void Modified()
Definition: QWebCanvas.cpp:265
virtual Bool_t IsXMaxDraw() const
virtual void RedrawSpecialObjects(TPad *pad, TGo4Slot *padslot)
virtual void SetPanelName(const char *newname)
virtual bool IsApplyToAllFlag()
QString SaveObjectInMemory(const char *foldername, TObject *obj)
Definition: QGo4Widget.cpp:355
virtual void SetYMeanDraw(Bool_t on)
void SetAutoScale(bool on)
virtual void ChangeDrawOption(int kind, int value, const char *drawopt)
void CanvasDropEvent(QDropEvent *, TPad *)
Int_t GetDivY() const
Definition: TGo4Picture.h:54
virtual int GetNumberOfPads(TPad *toppad)
void SetPar(const char *name, const char *value)
Definition: TGo4Slot.cxx:586
virtual TPad * GetActivePad()
void Draw(Option_t *opt="") override
Definition: TGo4Marker.cxx:101
void SetSelectedPad(TPad *pad)
Definition: TGo4MdiArea.cpp:53
Bool_t GetTitleAttr(TPaveText *title) const
void SetContentModified(bool on=true)
const char * GetXAxisTimeFormat() const
virtual void SuperImposeToggled(bool)
virtual void DefaultPadMargin(TPad *pad)
void SetTitleDate(Bool_t on=kTRUE)
QRootCanvas * fxQCanvas
qtroot canvas
virtual void ProcessPictureRedraw(const char *picitemname, TPad *pad, TGo4Picture *pic)
void AddSpecialObject(TObject *obj, Option_t *drawopt=nullptr)
virtual void SetDrawingMode(bool on)
void SetRebinX(Int_t ngroupx, Int_t index=UndefIndex)
virtual bool DeleteDrawObjects(TPad *pad, int kindtodelete)
virtual TObject * GetSelectedObject(TPad *pad, const char **drawopt)
TGo4Condition * At(Int_t i) const
virtual void checkResizeSlot()
Option_t * GetDrawOption() const override
Definition: TGo4Picture.h:145
virtual TCanvas * GetCanvas()
void setEditorFrame(QFrame *fr)
Definition: QRootCanvas.h:74
void activateEditor(TPad *pad, TObject *obj)
void setStatusBarVisible(bool flag)
Bool_t GetFullRange(Int_t naxis, Double_t &min, Double_t &max) const
virtual bool IsFreezeTitle()
virtual TGo4Slot * AddDrawObject(TPad *pad, int kind, const char *itemname, TObject *obj, bool owner, const char *drawopt)
virtual void ProcessPadClear(TPad *pad, bool removeitems, bool removesubpads)
void setStatusBarVisible(bool flag=true)
Definition: QWebCanvas.cpp:242
void ClearRange(Int_t naxis=-1)
virtual void SetFreezedTitle(const QString &title)
virtual bool CompleteMarkerEdit(TPad *pad)
virtual void SetSelectedRangeToHisto(TPad *pad, TH1 *h1, THStack *hs0, TGo4Picture *padopt, bool ishisto)
void SetXAxisAttTime(Bool_t timedisplay, const char *format, Int_t index=UndefIndex)
QAction * fxCanvasEditorChk
void SetHistogramContent(TH2 *histo)
Definition: TGo4ASImage.cpp:32
void SetTitleAttr(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t textsize=0.)
virtual int GetMouseMode()
virtual void MenuCommandExecutedSlot(TObject *obj, const char *cmdname)
Bool_t next(Bool_t goesinto=kTRUE)
Definition: TGo4Iter.cxx:44
void panelSignal(TGo4ViewPanel *, TPad *, int)
virtual int GetSelectedObjectIndex(TGo4Slot *slot)
virtual void CanvasUpdatedSlot()
void activateEditor(TPad *pad=nullptr, TObject *obj=nullptr)
Definition: QWebCanvas.cpp:223
virtual void ChangeDrawOptionForPad(TGo4Slot *padslot, int kind, int value, const char *drawopt)
void GetDrawAttributes(TObject *obj, Int_t index=UndefIndex) const
Bool_t IsTitleDate() const
void CallServiceFunc(int id, const char *str=nullptr, void *par=nullptr)
Definition: QGo4Widget.cpp:393
virtual void SetAutoScale(bool on, TPad *selpad)
Bool_t IsDivided() const
Definition: TGo4Picture.h:55
virtual void Update()