GSI Object Oriented Online Offline (Go4)  GO4-6.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
QRootCanvas.cpp
Go to the documentation of this file.
1 // $Id: QRootCanvas.cpp 3332 2021-10-18 11:14:13Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 /****************************************************************************
15 ** Copyright ( C ) 2000 denis Bertini. All rights reserved.
16 *****************************************************************************/
17 
18 #include "QRootCanvas.h"
19 
20 #include <iostream>
21 
22 #include <QtCore/QSignalMapper>
23 #include <QtCore/QTimer>
24 
25 #include <QDragEnterEvent>
26 #include <QDropEvent>
27 #include <QMouseEvent>
28 #include <QCloseEvent>
29 #include <QInputDialog>
30 #include <QColorDialog>
31 #include <QMenu>
32 #include <QAction>
33 #include <QMimeData>
34 #include <QVBoxLayout>
35 #include <QStatusBar>
36 
37 #include "TCanvas.h"
38 #include "TROOT.h"
39 #include "TObjString.h"
40 #include "TObjArray.h"
41 #include "TH1.h"
42 #include "TClass.h"
43 #include "TDataType.h"
44 #include "TDataMember.h"
45 #include "TMethod.h"
46 #include "TMethodCall.h"
47 #include "TMethodArg.h"
48 #include "TColor.h"
49 #include "TLatex.h"
50 
51 #ifndef __NOGO4GED__
52 #include "TGedEditor.h"
53 #include "TVirtualPadEditor.h"
54 #endif
55 
56 #ifdef __GO4X11__
57 #include "TGo4LockGuard.h"
58 #else
59 #define TGo4LockGuard int
60 #endif
61 
62 #include "QRootDialog.h"
63 #include "QRootWindow.h"
64 #include "QRootApplication.h"
65 
66 QRootCanvas::QRootCanvas(QWidget *parent) :
67  QWidget(parent),
68  fMaskDoubleClick(false),
69  fxShowEventStatus(false),
70  fQtScalingfactor(1.0)
71 {
72  setObjectName( "QRootCanvas");
73 
74  setSizeIncrement( QSize( 100, 100 ) );
75 
76  TGo4LockGuard threadlock;
77  (void) threadlock; // suppress compiler warnings
78  // set defaults
79  setUpdatesEnabled( true );
80  setMouseTracking(true);
81 
82  setFocusPolicy( Qt::TabFocus );
83  setCursor( Qt::CrossCursor );
84 
85  // disable option that at least background is redrawn immediately
86  // and canvas content after 100 ms timeout
87  //setAttribute(Qt::WA_NoSystemBackground);
88  setAttribute(Qt::WA_PaintOnScreen);
89  setAttribute(Qt::WA_PaintUnclipped);
90 
91  // add the Qt::WinId to TGX11 interface
92  fQtWindowId = winId();
93  fRootWindowId = gVirtualX->AddWindow((ULong_t)fQtWindowId, 100, 30);
94 
95  fCanvas = new TCanvas("Canvas", width(), height(), fRootWindowId);
96 
97 #if QT_VERSION > QT_VERSION_CHECK(5,6,0)
98  // JAM the following is pure empiric. hopefully default denominator won't change in future qt?
99  fQtScalingfactor=(double) metric(QPaintDevice::PdmDevicePixelRatioScaled)/65536.;
100 #endif
101  //std::cout <<"Found Qt scaling factor:"<<fQtScalingfactor << std::endl;
102  // create the context menu
103  fMousePosX = 0;
104  fMousePosY = 0;
105  fMenuMethods = 0;
106  fMenuObj = 0;
107 
108  setAcceptDrops(true);
109 
110  fRepaintMode = 0;
111  fRepaintTimer = new QTimer;
112  fRepaintTimer->setSingleShot(true);
113  connect(fRepaintTimer, SIGNAL(timeout()), this, SLOT(processRepaintTimer()));
114 
115  fEditorFrame = 0;
116  fxPeditor = 0;
117  fxRooteditor = 0;
118  fDummyHisto = 0;
119 
120  fStatusBar = 0;
121 }
122 
124 {
125  // cannot call here, must be done before until X11 frame is exists
126  // cleanupEditor();
127 
128  if (fDummyHisto) {
129  delete fDummyHisto;
130  fDummyHisto = 0;
131  }
132 
133 #ifndef __NOGO4GED__
134  if (gTQSender == getCanvas())
135  gTQSender = 0;
136 
137  // prevent problems with root's subeditor cache
138  if (fxPeditor != 0) {
139  fxPeditor->DeleteEditors();
140  delete fxPeditor;
141  fxPeditor = 0;
142  }
143 #endif
144 
145  if(fCanvas) {
146  delete fCanvas;
147  fCanvas = 0;
148  }
149 
150  if (fMenuMethods) {
151  delete fMenuMethods;
152  fMenuMethods = 0;
153  }
154 
155  delete fRepaintTimer;
156 }
157 
158 QPoint QRootCanvas::scaledMousePoint(QMouseEvent *e)
159 {
160 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
161  int scaledX = scaledPosition(e->x());
162  int scaledY = scaledPosition(e->y());
163 #else
164  int scaledX = scaledPosition(e->position().x());
165  int scaledY = scaledPosition(e->position().y());
166 #endif
167  return QPoint(scaledX, scaledY);
168 }
169 
170 void QRootCanvas::mouseMoveEvent(QMouseEvent *e)
171 {
172  TGo4LockGuard threadlock;
173  (void) threadlock; // suppress compiler warnings
174 #if QT_VERSION > QT_VERSION_CHECK(5,0,0)
175  // JAM use event timestamp for reduction of events (qt5 bug):
176  static ulong lastprocesstime=0;
177  static ulong delta=100; // maybe ms units?
178  ulong timestamp=e->timestamp();
179  if(timestamp-delta<lastprocesstime)
180  {
181  // just eat too old events
182  e->accept();
183  // std::cout <<"----- EATING timestamp:"<<timestamp<< std::endl;
184  return;
185  }
186 
187  //std::cout <<"----- QRootCanvas::mouseMoveEvent with timestamp:"<<timestamp<<", oldstamp:"<<lastprocesstime << std::endl;
188 #endif
189 
190 
191  if (fCanvas) {
192  QPoint pnt = scaledMousePoint(e);
193 
194  if (e->buttons() & Qt::LeftButton)
195  fCanvas->HandleInput(kButton1Motion, pnt.x(), pnt.y());
196  else
197  fCanvas->HandleInput(kMouseMotion, pnt.x(), pnt.y());
198  }
199 
200  if(fxShowEventStatus) {
201  TObject* selected = fCanvas->GetSelected();
202  Int_t px = fCanvas->GetEventX();
203  Int_t py = fCanvas->GetEventY();
204  QString buffer = "";
205  if (selected!=0) {
206  buffer = selected->GetName();
207  buffer += " ";
208  buffer += selected->GetObjectInfo(px, py);
209  } else {
210  buffer = "No selected object x = ";
211  buffer += QString::number(px);
212  buffer += " y = ";
213  buffer += QString::number(py);
214  }
215 
216  emit CanvasStatusEvent(buffer.toLatin1().constData());
217 
218  if (fStatusBar) fStatusBar->showMessage(buffer.toLatin1().constData());
219  }
220  e->accept();
221 #if QT_VERSION > QT_VERSION_CHECK(5,0,0)
222  lastprocesstime=timestamp;
223 #endif
224 }
225 
226 void QRootCanvas::wheelEvent( QWheelEvent* e)
227 {
228  TGo4LockGuard threadlock;
229  (void) threadlock; // suppress compiler warnings
230 
231  if (!fCanvas) return;
232  e->accept();
233 
234 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
235  bool positive = (e->delta() > 0);
236  int ex = e->x(), ey = e->y();
237 #else
238  QPoint delta = e->pixelDelta();
239  if (delta.isNull()) delta = e->angleDelta() / 8;
240  bool positive = delta.x() > 0 || delta.y() > 0;
241  int ex = e->position().x(), ey = e->position().y();
242 #endif
243 
244  fCanvas->HandleInput(positive ? kWheelUp : kWheelDown, scaledPosition(ex), scaledPosition(ey));
245 }
246 
247 
248 void QRootCanvas::mousePressEvent( QMouseEvent *e )
249 {
250  TGo4LockGuard threadlock;
251  (void) threadlock; // suppress compiler warnings
252 
253  TObjLink* pickobj = 0;
254  // JAM2016-9 test
255 // std::cout <<"QRootCanvas::mousePressEvent at ("<<e->x()<<", "<< e->y()<<")"<< std::endl;
256 
257  QPoint scaled = scaledMousePoint(e);
258 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
259  QPoint mouse_pnt = e->globalPos();
260 #else
261  QPoint mouse_pnt = e->globalPosition().toPoint();
262 #endif
263 
264  // std::cout <<" scaledX,scaledY: ("<<scaledX<<", "<<scaledY <<") "<< std::endl;
265 // std::cout <<"global from event: ("<<e->globalX()<<", "<< e->globalY()<< std::endl;
266 // QPoint globalp=QWidget::mapToGlobal(e->pos());
267 // std::cout <<"global from map: ("<<globalp.x()<<", "<<globalp.y() <<") "<< std::endl;
268 // QPoint parentp=QWidget::mapToParent(e->pos());
269 // std::cout <<"parent: ("<<parentp.x()<<", "<<parentp.y()<<") " << std::endl;
270 // QPoint backfromglobalp=QWidget::mapFromGlobal(globalp);
271 // std::cout <<"backglobal: ("<<backfromglobalp.x()<<", "<<backfromglobalp.y()<<") " << std::endl;
272 // Int_t destx=0, desty=0;
273 // Window_t child;
274 // Window_t rootwindow=gVirtualX->GetDefaultRootWindow();
275 // gVirtualX->TranslateCoordinates(rootwindow, fQtWindowId, globalp.x(), globalp.y(), destx, desty, child);
276 // std::cout <<"TGX11 global translated: ("<<destx<<", "<<desty<<") " << std::endl;
277 // std::cout <<"TGX11 winids - default root:"<<rootwindow<<", Qt:"<<fQtWindowId<<", child:" <<child<< std::endl;
278 
279 
280  /* int themetric= metric(QPaintDevice::PdmDevicePixelRatio);
281  int scaledmetric= metric(QPaintDevice::PdmDevicePixelRatioScaled);
282  std::cout <<"metric="<<themetric<<", scaled="<<scaledmetric << std::endl;
283  int scaledX=e->x() * scaledmetric/65536; // empiric
284  int scaledY=e->y() * scaledmetric/65536; // empiric
285  std::cout <<"scaledX,scaledY: ("<<scaledX<<", "<<scaledY <<") "<< std::endl;
286  */
287 
288 
289  TPad* pad = fCanvas->Pick(scaled.x(), scaled.y(), pickobj);
290  TObject *selected = fCanvas->GetSelected();
291 
292  switch(e->button()) {
293  case Qt::LeftButton :
294  fCanvas->HandleInput(kButton1Down, scaled.x(), scaled.y());
295  emit PadClicked(pad);
296  break;
297  case Qt::RightButton : {
298  TString selectedOpt("");
299  if (pad!=0) {
300  if (pickobj==0) {
301  fCanvas->SetSelected(pad);
302  selected = pad;
303  } else
304  if(selected==0) {
305  selected = pickobj->GetObject();
306  selectedOpt = pickobj->GetOption();
307  }
308  pad->cd();
309  }
310  fCanvas->SetSelectedPad(pad);
311  gROOT->SetSelectedPrimitive(selected);
312  fMousePosX = gPad->AbsPixeltoX(gPad->GetEventX());
313  fMousePosY = gPad->AbsPixeltoY(gPad->GetEventY());
314 
315  QMenu menu(this);
316  QSignalMapper map;
317  connect(&map, SIGNAL(mapped(int)), this, SLOT(executeMenu(int)));
318 
319  fMenuObj = selected;
320  fMenuMethods = new TList;
321  TClass *cl = fMenuObj->IsA();
322  int curId = -1;
323 
324  QString buffer = Form("%s::%s", cl->GetName(), fMenuObj->GetName());
325  addMenuAction(&menu, &map, buffer, curId++);
326 
327  cl->GetMenuItems(fMenuMethods);
328  menu.addSeparator();
329 
330  if(!cl->InheritsFrom(TLatex::Class())) {
331  addMenuAction(&menu, &map, "Insert Latex", 100 );
332  menu.addSeparator();
333  }
334 
335  if(cl->InheritsFrom(TH1::Class())) {
336  addMenuAction(&menu, &map, "Qt Hist Line Color ", 101 );
337  addMenuAction(&menu, &map, "Qt Hist Fill Color ", 102 );
338  menu.addSeparator();
339  }
340 
341  TIter iter(fMenuMethods);
342  TMethod *method=0;
343  while ( (method = dynamic_cast<TMethod*>(iter())) != 0) {
344  buffer = method->GetName();
345  addMenuAction(&menu, &map, buffer, curId++);
346  }
347 
348  if (menu.exec(mouse_pnt)==0) {
349  fMenuObj = 0;
350  delete fMenuMethods;
351  fMenuMethods = 0;
352  }
353 
354  break;
355  }
356  case Qt::MiddleButton :
357  fCanvas->HandleInput(kButton2Down, scaled.x(), scaled.y());
358  emit SelectedPadChanged(pad); // that inform the Qt-world that tha pad is changed
359  // and give the pointer to the new pad as argument
360  // of the signal (M. Al-Turany)
361  break;
362  case Qt::NoButton :
363  break;
364  default:
365  break;
366  }
367  e->accept();
368 }
369 
370 void QRootCanvas::mouseReleaseEvent( QMouseEvent *e )
371 {
372  QPoint scaled = scaledMousePoint(e);
373 
374  TGo4LockGuard threadlock;
375  (void) threadlock; // suppress compiler warnings
376 
377  switch(e->button()) {
378  case Qt::LeftButton :
379  fCanvas->HandleInput(kButton1Up, scaled.x(), scaled.y());
380  break;
381  case Qt::RightButton :
382  fCanvas->HandleInput(kButton3Up, scaled.x(), scaled.y());
383  break;
384  case Qt::MiddleButton :
385  fCanvas->HandleInput(kButton2Up, scaled.x(), scaled.y());
386  break;
387  case Qt::NoButton :
388  break;
389  default:
390  break;
391  }
392  e->accept();
393 }
394 
396 {
397  QPoint scaled = scaledMousePoint(e);
398 
399  TGo4LockGuard threadlock;
400  (void) threadlock; // suppress compiler warnings
401 
402  switch(e->button()) {
403  case Qt::LeftButton : {
404  if (!fMaskDoubleClick)
405  fCanvas->HandleInput(kButton1Double, scaled.x(), scaled.y());
406  TObjLink* pickobj = 0;
407  TPad* pad = fCanvas->Pick(scaled.x(), scaled.y(), pickobj);
408  emit PadDoubleClicked(pad);
409  // prevent crash on following release event
410  // if new canvas will be created in between
411  // fCanvas->SetSelected(0);
412  break;
413  }
414  case Qt::RightButton :
415  fCanvas->HandleInput(kButton3Double, scaled.x(), scaled.y());
416  break;
417  case Qt::MiddleButton :
418  fCanvas->HandleInput(kButton2Double, scaled.x(), scaled.y());
419  break;
420  case Qt::NoButton :
421  break;
422  default:
423  break;
424  }
425  e->accept();
426 }
427 
429 {
430  fRepaintMode |= mode;
431 // if (fRepaintMode > 0) setUpdatesEnabled( false ); // JAM avoid flicker on Qt5 ?
432  fRepaintTimer->setSingleShot(true);
433  fRepaintTimer->start(100);
434 }
435 
436 void QRootCanvas::resizeEvent( QResizeEvent *)
437 {
438  //std::cout<< "QRootCanvas::resizeEvent"<<std::endl;
440 }
441 
442 void QRootCanvas::paintEvent( QPaintEvent *)
443 {
444  // this is workaround a problem, that after drawing canvas in
445  // viewpanel there is always 1 event after that
446  // therefore fRepaintMode set to -1 to ignore such first event
447  // In future behavior may change
448 
449  if (fRepaintMode<0)
450  fRepaintMode = 0;
451  else
453 }
454 
456 {
457  if (fRepaintMode == 0) return;
458  //std::cout<< " QRootCanvas::processRepaintTimer()"<<std::endl;
459  //printf("processRepaintTimer with fRepaintMode %d\n",fRepaintMode);
460  TGo4LockGuard threadlock;
461  (void) threadlock; // suppress compiler warnings
462 
463  WId newid = winId();
464  if(newid != fQtWindowId) {
465  //printf("processRepaintTimer - sees changed window id %d \n",newid);
466  // Qt has changed id for this widget (e.g. at QWorkspace::addWindow())
467  // need to adjust the ROOT X access:
468  delete fCanvas; // should also remove old x windows!
469  fRootWindowId = gVirtualX->AddWindow((ULong_t)newid, width(), height());
470  fCanvas = new TCanvas(objectName().toLatin1().constData(), width(), height(), fRootWindowId);
471  fQtWindowId = newid;
472  }
473 
474  if (fRepaintMode & act_Resize) fCanvas->Resize();
475  else fCanvas->Modified(kTRUE);
476 
477  fCanvas->Update();
478 
479  fRepaintMode = 0;
480  //std::cout<< std::endl;
481  emit CanvasUpdated();
482  //setUpdatesEnabled( true ); // JAM avoid flicker on Qt5 ?
483 }
484 
485 void QRootCanvas::leaveEvent( QEvent *e )
486 {
487  QWidget::leaveEvent(e);
488 
489  TGo4LockGuard threadlock;
490  (void) threadlock; // suppress compiler warnings
491 
492  if (fCanvas!=0)
493  fCanvas->HandleInput(kMouseLeave, 0, 0);
494 
495  emit CanvasLeaveEvent();
496 }
497 
499 {
500  fxShowEventStatus = s;
501 }
502 
504 {
505  return fxShowEventStatus;
506 }
507 
509 
510 void QRootCanvas::dragEnterEvent( QDragEnterEvent *e )
511 {
512  if (e->mimeData()->hasText())
513  e->acceptProposedAction();
514 }
515 
516 void QRootCanvas::dropEvent( QDropEvent *event )
517 {
518  TObject* obj = 0;
519 
520 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
521  QPoint pos = event->pos();
522 #else
523  QPoint pos = event->position().toPoint();
524 #endif
525 
526  TPad *pad = Pick(scaledPosition(pos.x()), scaledPosition(pos.y()), obj);
527 
528  if (pad)
529  emit CanvasDropEvent(event, pad);
530 }
531 
533 
534 void QRootCanvas::cd(Int_t subpadnumber)
535 {
536  fCanvas->cd(subpadnumber);
537 }
538 
539 void QRootCanvas::Browse(TBrowser *b)
540 {
541  fCanvas->Browse(b);
542 }
543 
544 void QRootCanvas::Clear(Option_t *option)
545 {
546  fCanvas->Clear(option);
547 }
548 
549 void QRootCanvas::Close(Option_t *option)
550 {
551  fCanvas->Close(option);
552 }
553 
554 void QRootCanvas::Draw(Option_t *option)
555 {
556  fCanvas->Draw(option);
557 }
558 
559 TObject* QRootCanvas::DrawClone(Option_t *option)
560 {
561  return fCanvas->DrawClone(option);
562 }
563 
565 {
566  return fCanvas->DrawClonePad();
567 }
568 
570 {
571  fCanvas->EditorBar();
572 }
573 
574 void QRootCanvas::EnterLeave(TPad *prevSelPad, TObject *prevSelObj)
575 {
576  fCanvas->EnterLeave(prevSelPad, prevSelObj);
577 }
578 
580 {
581  fCanvas->FeedbackMode(set);
582 }
583 
585 {
586  fCanvas->Flush();
587 }
588 
590 {
591  fCanvas->UseCurrentStyle();
592 }
593 
595 {
596  fCanvas->ForceUpdate() ;
597 }
598 
600 {
601  return fCanvas->GetDISPLAY() ;
602 }
603 
605 {
606  return fCanvas->GetContextMenu();
607 }
608 
610 {
611  return fCanvas->GetDoubleBuffer();
612 }
613 
615 {
616  return fCanvas->GetEvent();
617 }
618 
620 {
621  return fCanvas->GetEventX();
622 }
623 
625 {
626  return fCanvas->GetEventY();
627 }
628 
630 {
631  return fCanvas->GetHighLightColor() ;
632 }
633 
635 {
636  return fCanvas->GetPadSave();
637 }
638 
640 {
641  return fCanvas->GetSelected() ;
642 }
643 
645 {
646  return fCanvas->GetSelectedOpt();
647 }
648 
650 {
651  return fCanvas->GetSelectedPad();
652 }
653 
655 {
656  return fCanvas->GetShowEventStatus() ;
657 }
658 
660 {
661  return fCanvas->GetAutoExec();
662 }
663 
665 {
666  return fCanvas->GetXsizeUser();
667 }
668 
670 {
671  return fCanvas->GetYsizeUser();
672 }
673 
675 {
676  return fCanvas->GetXsizeReal();
677 }
678 
680 {
681  return fCanvas->GetYsizeReal();
682 }
683 
685 {
686  return fCanvas->GetCanvasID();
687 }
688 
690 {
691  return fCanvas->GetWindowTopX();
692 }
693 
695 {
696  return fCanvas->GetWindowTopY();
697 }
698 
700 {
701  return fCanvas->GetWindowWidth() ;
702 }
703 
705 {
706  return fCanvas->GetWindowHeight();
707 }
708 
710 {
711  return fCanvas->GetWw();
712 }
713 
715 {
716  return fCanvas->GetWh() ;
717 }
718 
719 void QRootCanvas::GetCanvasPar(Int_t &wtopx, Int_t &wtopy, UInt_t &ww, UInt_t &wh)
720 {
721  fCanvas->GetCanvasPar(wtopx, wtopy, ww, wh);
722 }
723 
724 void QRootCanvas::HandleInput(EEventType button, Int_t x, Int_t y)
725 {
726  fCanvas->HandleInput(button, scaledPosition(x), scaledPosition(y));
727 }
728 
730 {
731  return fCanvas->HasMenuBar() ;
732 }
733 
735 {
736  fCanvas->Iconify();
737 }
738 
740 {
741  return fCanvas->IsBatch() ;
742 }
743 
745 {
746  return fCanvas->IsRetained();
747 }
748 
749 void QRootCanvas::ls(Option_t *option)
750 {
751  fCanvas->ls(option);
752 }
753 
754 void QRootCanvas::Modified(Bool_t mod)
755 {
756  fCanvas->Modified(mod);
757 }
758 
759 void QRootCanvas::MoveOpaque(Int_t set)
760 {
761  fCanvas->MoveOpaque(set);
762 }
763 
765 {
766  return fCanvas->OpaqueMoving();
767 }
768 
770 {
771  return fCanvas->OpaqueResizing();
772 }
773 
774 void QRootCanvas::Paint(Option_t *option)
775 {
776  fCanvas->Paint(option);
777 }
778 
779 TPad* QRootCanvas::Pick(Int_t px, Int_t py, TObjLink *&pickobj)
780 {
781  return fCanvas->Pick(px, py, pickobj);
782 }
783 
784 TPad* QRootCanvas::Pick(Int_t px, Int_t py, TObject *prevSelObj)
785 {
786  return fCanvas->Pick(px, py, prevSelObj);
787 }
788 
789 void QRootCanvas::Resize(Option_t *option)
790 {
791  fCanvas->Resize(option);
792 }
793 
795 {
796  fCanvas->ResizeOpaque(set);
797 }
798 
799 void QRootCanvas::SaveSource(const char *filename, Option_t *option)
800 {
801  fCanvas->SaveSource(filename, option);
802 }
803 
804 void QRootCanvas::SetCursor(ECursor cursor)
805 {
806  fCanvas->SetCursor(cursor);
807 }
808 
810 {
811  fCanvas->SetDoubleBuffer(mode);
812 }
813 
814 void QRootCanvas::SetWindowPosition(Int_t x, Int_t y)
815 {
816  fCanvas->SetWindowPosition(x, y) ;
817 }
818 
819 void QRootCanvas::SetWindowSize(UInt_t ww, UInt_t wh)
820 {
821  fCanvas->SetWindowSize(ww,wh) ;
822 }
823 
824 void QRootCanvas::SetCanvasSize(UInt_t ww, UInt_t wh)
825 {
826  fCanvas->SetCanvasSize(ww, wh);
827 }
828 
830 {
831  fCanvas->SetHighLightColor(col);
832 }
833 
834 void QRootCanvas::SetSelected(TObject *obj)
835 {
836  fCanvas->SetSelected(obj);
837 }
838 
840 {
841  fCanvas->SetSelectedPad(pad);
842 }
843 
845 {
846  fCanvas->Show();
847 }
848 
849 void QRootCanvas::Size(Float_t xsizeuser, Float_t ysizeuser)
850 {
851  fCanvas->Size(xsizeuser, ysizeuser);
852 }
853 
854 void QRootCanvas::SetBatch(Bool_t batch)
855 {
856  fCanvas->SetBatch(batch);
857 }
858 
859 void QRootCanvas::SetRetained(Bool_t retained)
860 {
861  fCanvas->SetRetained(retained);
862 }
863 
864 void QRootCanvas::SetTitle(const char *title)
865 {
866  fCanvas->SetTitle(title);
867 }
868 
870 {
871  fCanvas->ToggleEventStatus();
872 }
873 
875 {
876  fCanvas->ToggleAutoExec();
877 }
878 
880 {
881  // do not call update directly, use timer instead
883 }
884 
885 void QRootCanvas::closeEvent(QCloseEvent * e)
886 {
887  if (fCanvas) {
888  delete fCanvas;
889  fCanvas = 0;
890  }
891 
892  e->accept();
893 }
894 
895 void QRootCanvas::methodDialog(TObject* object, TMethod* method)
896 {
897  if ((object==0) || (method==0)) return;
898 
899  TGo4LockGuard threadlock;
900  (void) threadlock; // suppress compiler warnings
901 
902  // Create dialog object with OK and Cancel buttons. This dialog
903  // prompts for the arguments of "method".
904 
905  QRootDialog dlg;
906 
907  dlg.setWindowTitle(Form("%s:%s", object->GetName(), method->GetName()));
908 
909  // iterate through all arguments and create apropriate input-data objects:
910  // inputlines, option menus...
911  TMethodArg *argument = 0;
912  TIter next(method->GetListOfMethodArgs());
913 
914  while ((argument = (TMethodArg *) next())) {
915  TString argTitle = TString::Format("(%s) %s", argument->GetTitle(), argument->GetName());
916  TString argDflt = argument->GetDefault() ? argument->GetDefault() : "";
917  if (argDflt.Length()>0)
918  argTitle += TString::Format(" [default: %s]", argDflt.Data());
919  TString type = argument->GetTypeName();
920  TDataType *datatype = gROOT->GetType(type);
921  TString basictype;
922 
923  if (datatype) {
924  basictype = datatype->GetTypeName();
925  } else {
926  if (type.CompareTo("enum") != 0)
927  std::cout << "*** Warning in Dialog(): data type is not basic type, assuming (int)\n";
928  basictype = "int";
929  }
930 
931  if (TString(argument->GetTitle()).Index("*")!=kNPOS) {
932  basictype += "*";
933  type = "char*";
934  }
935 
936  TDataMember *m = argument->GetDataMember();
937  if (m && m->GetterMethod()) {
938 
939  m->GetterMethod()->Init(object->IsA(), m->GetterMethod()->GetMethodName(), "");
940 
941  // Get the current value and form it as a text:
942 
943  TString val;
944 
945  if (basictype == "char*") {
946  char *tdefval(0);
947  m->GetterMethod()->Execute(object, "", &tdefval);
948  if (tdefval) val = tdefval;
949  } else
950  if ((basictype == "float") ||
951  (basictype == "double")) {
952  Double_t ddefval(0.);
953  m->GetterMethod()->Execute(object, "", ddefval);
954  val = TString::Format("%g", ddefval);
955  } else
956  if ((basictype == "char") ||
957  (basictype == "int") ||
958  (basictype == "long") ||
959  (basictype == "short")) {
960  Long_t ldefval(0);
961  m->GetterMethod()->Execute(object, "", ldefval);
962  val = TString::Format("%ld", ldefval);
963  }
964 
965  // Find out whether we have options ...
966 
967  TList *opt;
968  if ((opt = m->GetOptions()) != 0) {
969  //std::cout << "*** Warning in Dialog(): option menu not yet implemented " << opt << std::endl;
970  // should stop dialog
971  // workaround JAM: do not stop dialog, use textfield (for time display toggle)
972  dlg.addArg(argTitle.Data(), val.Data(), type.Data());
973  //return;
974  } else {
975  // we haven't got options - textfield ...
976  dlg.addArg(argTitle.Data(), val.Data(), type.Data());
977  }
978  } else { // if m not found ...
979  if ((argDflt.Length() > 1) &&
980  (argDflt[0]=='\"') && (argDflt[argDflt.Length()-1]=='\"')) {
981  // cut "" from the string argument
982  argDflt.Remove(0,1);
983  argDflt.Remove(argDflt.Length()-1,1);
984  }
985 
986  dlg.addArg(argTitle.Data(), argDflt.Data(), type.Data());
987  }
988  }
989 
990  if (dlg.exec() != QDialog::Accepted) return;
991 
992  Bool_t deletion = kFALSE;
993 
994  qDebug("DIAL executeMethod: simple version\n");
995  TVirtualPad *psave = gROOT->GetSelectedPad();
996 
997  qDebug("DIAL saved pad: %s gPad:%s \n",psave->GetName(),gPad->GetName());
998 
999  qDebug("DIAL obj:%s meth:%s \n", object->GetName(), method->GetName());
1000 
1001  //std::cout<< "executeMethod" << fCurMethod->GetName() << std::endl;
1002 
1003  TObjArray tobjlist(method->GetListOfMethodArgs()->LastIndex() + 1);
1004  for (int n=0; n<=method->GetListOfMethodArgs()->LastIndex(); n++) {
1005  QString s = dlg.getArg(n);
1006  qDebug( "** QString values (first ) :%s \n", s.toLatin1().constData() );
1007  tobjlist.AddLast(new TObjString(s.toLatin1().constData())) ;
1008  }
1009 
1010  // handle command if existing object
1011  if(strcmp(method->GetName(),"Delete") == 0) {
1012  // here call explicitly the dtor
1013  qDebug(" DIAL obj name deleted :%s \n", object->GetName());
1014  emit MenuCommandExecuted(object, "Delete");
1015  delete object;
1016  object = 0;
1017  deletion = kTRUE;
1018  qDebug(" DIAL deletion done closing ... \n");
1019  } else
1020  if (strcmp(method->GetName(), "SetCanvasSize") == 0) {
1021  int width = dlg.getArg(0).toInt();
1022  int height = dlg.getArg(1).toInt();
1023  qDebug( " do resize with %i %i \n", width, height);
1024  resize(width, height);
1025  emit MenuCommandExecuted(fCanvas, "SetCanvasSize");
1026  } else {
1027  // here call cint call
1028  qDebug("TCint::Execute called !\n");
1029 
1030  object->Execute(method, &tobjlist);
1031 
1032  if (object->TestBit(TObject::kNotDeleted))
1033  emit MenuCommandExecuted(object, method->GetName());
1034  else {
1035  deletion = true;
1036  object = 0;
1037  }
1038  }
1039 
1040  if(!deletion ) {
1041  qDebug("DIAL set saved pad: %s herit:%s gPad:%s\n",
1042  psave->GetName(), psave->ClassName(), gPad->GetName());
1043  gROOT->SetSelectedPad(psave);
1044  gROOT->GetSelectedPad()->Modified();
1045  gROOT->GetSelectedPad()->Update();
1046  qDebug("DIAL update done on %s \n", gROOT->GetSelectedPad()->GetName());
1047  } else {
1048  gROOT->SetSelectedPad( gPad );
1049  gROOT->GetSelectedPad()->Update();
1050  }
1051 }
1052 
1053 QAction* QRootCanvas::addMenuAction(QMenu* menu, QSignalMapper* map, const QString& text, int id)
1054 {
1056 
1057  QAction* act = new QAction(text, menu);
1058 
1059  if (!enabled)
1060  if ((text.compare("DrawClone")==0) ||
1061  (text.compare("DrawClass")==0) ||
1062  (text.compare("Inspect")==0) ||
1063  (text.compare("SetShowProjectionX")==0) ||
1064  (text.compare("SetShowProjectionY")==0) ||
1065  (text.compare("DrawPanel")==0) ||
1066  (text.compare("FitPanel")==0))
1067  act->setEnabled(false);
1068 
1069  map->connect (act, SIGNAL(triggered()), map, SLOT(map()));
1070  menu->addAction(act);
1071  map->setMapping(act, id);
1072 
1073 
1074  return act;
1075 }
1076 
1078 {
1079  TGo4LockGuard threadlock;
1080  (void) threadlock; // suppress compiler warnings
1081 
1082  QString text("");
1083  bool ok = false;
1084  if (id >=100) {
1085  switch (id){
1086  case 100: {
1087  TLatex *fxLatex = new TLatex();
1088  text = QInputDialog::getText(this, tr( "Qt Root" ),
1089  tr( "Please enter your text" ),
1090  QLineEdit::Normal, QString(), &ok);
1091  //if (ok && !text.isEmpty())
1092  fxLatex->DrawLatex(fMousePosX, fMousePosY, text.toLatin1().constData());
1093  emit MenuCommandExecuted(fxLatex, "DrawLatex");
1094  break;
1095  }
1096  case 101: {
1097  TH1 *h1 = dynamic_cast<TH1*> (fMenuObj);
1098  if (h1!=0) {
1099  QColor col = QColorDialog::getColor();
1100  if (col.isValid()) {
1101  short int C_new = TColor::GetColor(col.red(), col.green(), col.blue());
1102  h1->SetLineColor(C_new);
1103  emit MenuCommandExecuted(h1, "SetLineColor");
1104  }
1105  }
1106  break;
1107  }
1108  case 102 : {
1109  TH1 *h1 = dynamic_cast<TH1*> (fMenuObj);
1110  if (h1!=0) {
1111  QColor col = QColorDialog::getColor();
1112  if (col.isValid()) {
1113  short int C_new = TColor::GetColor(col.red(), col.green(), col.blue());
1114  h1->SetFillColor(C_new);
1115  emit MenuCommandExecuted(h1,"SetFillColor");
1116  }
1117  }
1118  }
1119  }
1120  gROOT->GetSelectedPad()->Update();
1121  gROOT->GetSelectedPad()->Modified();
1122  fCanvas->Modified();
1123  fCanvas->ForceUpdate();
1124  gROOT->SetFromPopUp( kFALSE );
1125  } else
1126  if (id >=0) {
1127 
1128  // save global to Pad before calling TObject::Execute()
1129 
1130  TVirtualPad* psave = gROOT->GetSelectedPad();
1131  TMethod *method = (TMethod *) fMenuMethods->At(id);
1132 
1134  fCanvas->HandleInput(kButton3Up, gPad->XtoAbsPixel(fMousePosX), gPad->YtoAbsPixel(fMousePosY));
1135 
1136  // change current dir that all new histograms appear here
1137  gROOT->cd();
1138 
1139 
1140  if (method->GetListOfMethodArgs()->First()){
1141  if (strstr(method->GetName(), "Delete")){
1142  // JAM2016: do not allow mouse menu delete in Go4
1143  //std::cout << "Supressing Delete in menu!" << std::endl;
1144  }
1145  else {
1146  methodDialog(fMenuObj, method);
1147  }
1148  }
1149  else
1150  {
1151  gROOT->SetFromPopUp(kTRUE);
1152  fMenuObj->Execute(method->GetName(), "");
1153 
1154  if (fMenuObj->TestBit(TObject::kNotDeleted)) {
1155  emit MenuCommandExecuted(fMenuObj, method->GetName());
1156  } else {
1157  fMenuObj = 0;
1158  }
1159 
1160  }
1161 
1162  #ifndef __NOGO4GED__
1163  TGedEditor* ed = dynamic_cast<TGedEditor*>(TVirtualPadEditor::GetPadEditor(kFALSE));
1164  if (fMenuObj && ed) ed->SetModel(psave, fMenuObj, kButton1Down);
1165  #endif
1166 
1167  fCanvas->GetPadSave()->Update();
1168  fCanvas->GetPadSave()->Modified();
1169 
1170  gROOT->SetSelectedPad(psave);
1171 
1172  gROOT->GetSelectedPad()->Update();
1173  gROOT->GetSelectedPad()->Modified();
1174 
1175  fCanvas->Modified();
1176  fCanvas->ForceUpdate();
1177  gROOT->SetFromPopUp(kFALSE);
1178  }
1179 
1180  fMenuObj = 0;
1181  delete fMenuMethods;
1182  fMenuMethods = 0;
1183 }
1184 
1186 {
1187  return fEditorFrame ? fEditorFrame->isVisible() : false;
1188 }
1189 
1190 
1192 {
1193 #ifdef __NOGO4GED__
1194  return false;
1195 #else
1197 #endif
1198 }
1199 
1201 {
1202  if (!fEditorFrame) return;
1203 
1204 #ifndef __NOGO4GED__
1205  bool flag = !isEditorVisible();
1206 
1207  fEditorFrame->setVisible(flag);
1208  if (flag && (fxPeditor == 0)) {
1209 #if QT_VERSION > QT_VERSION_CHECK(5,6,0)
1210  // JAM the following is pure empiric. hopefully default denominator won't change in future qt?
1211  double scalefactor=(double) metric(QPaintDevice::PdmDevicePixelRatioScaled)/65536.;
1212  fEditorFrame->setMinimumWidth( fEditorFrame->minimumWidth()/scalefactor);
1213 #endif
1214 
1215 // JAM 5-2019: this part was moved to buildEditorWindow() because of init problems with Qt 4
1216 // std::cout<< "QRootCanvas::toggleEditor() will create Rooteditor" <<std::endl;
1217 // fxRooteditor = new QRootWindow(fEditorFrame, "rootwrapperwindow");
1218 // QVBoxLayout* gedlayout = new QVBoxLayout(fEditorFrame);
1219 // gedlayout->setContentsMargins(0, 0, 0, 0);
1220 // gedlayout->addWidget(fxRooteditor);
1222  TGo4LockGuard threadlock;
1223  (void) threadlock; // suppress compiler warnings
1224 
1225  fxRooteditor->SetResizeOnPaint(kFALSE); // disable internal resize on paintEvent, we use ResizeGedEditor
1226  fxRooteditor->SetEditable(); // mainframe will adopt pad editor window
1227 
1228  fxPeditor = TVirtualPadEditor::LoadEditor();
1229  fxPeditor->SetGlobal(kFALSE);
1230  fxRooteditor->SetEditable(kFALSE); // back to window manager as root window
1231  }
1232 #endif
1233 }
1234 
1236 {
1237 #ifndef __NOGO4GED__
1238  TGedEditor* ed = dynamic_cast<TGedEditor*>(fxPeditor);
1239  if ((ed != 0) && isEditorVisible() && fxRooteditor)
1241 #endif
1242 }
1243 
1244 
1245 void QRootCanvas::activateEditor(TPad *pad, TObject *obj)
1246 {
1247 #ifndef __NOGO4GED__
1248  TGedEditor* ed = dynamic_cast<TGedEditor*>(fxPeditor);
1249  if ((ed != 0) && (obj != 0) && isEditorVisible()) {
1250  gTQSender = getCanvas();
1251  ed->SetModel(pad, obj, kButton1Down);
1252  }
1253 #endif
1254 }
1255 
1257 {
1258 #ifndef __NOGO4GED__
1259 // std::cout << "QRootCanvas::CleanupGedEditor()" << std::endl;
1260  TGedEditor* ed = dynamic_cast<TGedEditor*>(fxPeditor);
1261  if (!ed) return;
1262  if (fDummyHisto == 0) {
1263  fDummyHisto = new TH1I("dummyhisto", "dummyhisto", 100, -10., 10.);
1264  fDummyHisto->FillRandom("gaus", 1000);
1265  fDummyHisto->SetDirectory(0);
1266  fDummyHisto->SetBit(kCanDelete, kFALSE);
1267  }
1268  gTQSender = getCanvas();
1269  ed->SetModel(0, fDummyHisto, kButton1Down);
1270  ed->SetModel(0, getCanvas(), kButton1Down);
1271 #endif
1272 }
1273 
1274 
1276 {
1277  if (fStatusBar) fStatusBar->showMessage(msg);
1278 }
1279 
1281 {
1282  return fStatusBar ? fStatusBar->isVisible() : false;
1283 }
1284 
1286 {
1287  if (!fStatusBar) return;
1288 
1289  setShowEventStatus(flag);
1290  fStatusBar->setVisible(flag);
1291 }
1292 
1293 
1294 // JAM2019 test order of creation for ged parent window in qt4:
1296 {
1297  if (!fxRooteditor) {
1298  fxRooteditor = new QRootWindow(fEditorFrame, "rootwrapperwindow");
1299  QVBoxLayout* gedlayout = new QVBoxLayout(fEditorFrame);
1300  gedlayout->setContentsMargins(0, 0, 0, 0);
1301  gedlayout->addWidget(fxRooteditor);
1302  }
1303 }
void SetBatch(Bool_t batch=kTRUE)
Bool_t IsRetained()
double scaledPosition(int p)
Definition: QRootCanvas.h:201
QRootWindow * fxRooteditor
Definition: QRootCanvas.h:223
void showStatusMessage(const char *msg)
Option_t * GetSelectedOpt()
Size_t GetYsizeUser()
void Iconify()
virtual void mouseDoubleClickEvent(QMouseEvent *e)
void Modified(Bool_t=1)
Int_t GetWindowTopX()
bool isStatusBarVisible()
virtual void Draw(Option_t *option="")
virtual void Size(Float_t xsizeuser=0, Float_t ysizeuser=0)
void SetRetained(Bool_t retained=kTRUE)
TVirtualPad * GetSelectedPad()
virtual void paintEvent(QPaintEvent *e)
void activateRepaint(int act)
virtual void dropEvent(QDropEvent *Event)
TObject * fMenuObj
Definition: QRootCanvas.h:233
Bool_t IsBatch()
TList * fMenuMethods
Definition: QRootCanvas.h:234
void MenuCommandExecuted(TObject *, const char *)
void CanvasLeaveEvent()
virtual void HandleInput(EEventType button, Int_t x, Int_t y)
void SelectedPadChanged(TPad *)
double ScaledHeight()
Int_t GetEventY()
virtual void ToggleEventStatus()
Bool_t OpaqueResizing()
virtual void ToggleAutoExec()
void FeedbackMode(Bool_t set)
void SetCanvasSize(UInt_t ww, UInt_t wh)
void EnterLeave(TPad *prevSelPad, TObject *prevSelObj)
void cleanupEditor()
void SetTitle(const char *title="")
void PadClicked(TPad *)
Int_t GetWindowTopY()
double ScaledWidth()
Int_t GetEventX()
void CanvasUpdated()
Int_t GetEvent()
virtual void Browse(TBrowser *b)
void SetEditable(bool on=true)
UInt_t GetWh()
int fRepaintMode
Definition: QRootCanvas.h:219
virtual TObject * DrawClone(Option_t *option="")
QRootCanvas(QWidget *parent=0)
Definition: QRootCanvas.cpp:66
Bool_t GetAutoExec()
virtual void SetDoubleBuffer(Int_t mode=1)
void SaveSource(const char *filename="", Option_t *option="")
bool fMaskDoubleClick
Definition: QRootCanvas.h:229
double fMousePosX
Definition: QRootCanvas.h:230
TObject * GetSelected()
void methodDialog(TObject *object, TMethod *method)
Int_t GetCanvasID()
QAction * addMenuAction(QMenu *menu, QSignalMapper *map, const QString &text, int id)
Bool_t OpaqueMoving()
virtual void SetCursor(ECursor cursor)
double fMousePosY
Definition: QRootCanvas.h:231
QFrame * fEditorFrame
Definition: QRootCanvas.h:221
Color_t GetHighLightColor()
void ResizeOpaque(Int_t set=1)
TCanvas * getCanvas()
Definition: QRootCanvas.h:67
TH1 * fDummyHisto
Definition: QRootCanvas.h:224
void cd(Int_t subpadnumber=0)
void ForceUpdate()
void setShowEventStatus(bool s)
void resizeEditor()
TContextMenu * GetContextMenu()
virtual void mouseReleaseEvent(QMouseEvent *e)
void SetHighLightColor(Color_t col)
void SetSelected(TObject *obj)
virtual void mousePressEvent(QMouseEvent *e)
void SetResizeOnPaint(bool on=true)
Definition: QRootWindow.h:52
void toggleEditor()
bool fxShowEventStatus
Definition: QRootCanvas.h:235
void Clear(Option_t *option="")
virtual void leaveEvent(QEvent *e)
virtual TObject * DrawClonePad()
virtual void resizeEvent(QResizeEvent *e)
void Close(Option_t *option="")
Int_t GetDoubleBuffer()
void CanvasDropEvent(QDropEvent *, TPad *)
static bool IsRootCanvasMenuEnabled()
QString getArg(int n)
Definition: QRootDialog.cpp:77
QTimer * fRepaintTimer
Definition: QRootCanvas.h:218
void addArg(const char *argname, const char *value, const char *type)
Definition: QRootDialog.cpp:63
virtual void GetCanvasPar(Int_t &wtopx, Int_t &wtopy, UInt_t &ww, UInt_t &wh)
QStatusBar * fStatusBar
Definition: QRootCanvas.h:226
virtual void Paint(Option_t *option="")
virtual TPad * Pick(Int_t px, Int_t py, TObjLink *&pickobj)
virtual void Resize(Option_t *option="")
TVirtualPad * GetPadSave()
bool isEditorVisible()
bool isEditorAllowed()
virtual void dragEnterEvent(QDragEnterEvent *e)
void SetWindowSize(UInt_t ww, UInt_t wh)
const char * GetDISPLAY()
bool showEventStatus() const
Bool_t HasMenuBar()
Size_t GetXsizeUser()
virtual void EditorBar()
QPoint scaledMousePoint(QMouseEvent *ev)
TCanvas * fCanvas
Definition: QRootCanvas.h:215
void processRepaintTimer()
void UseCurrentStyle()
virtual void closeEvent(QCloseEvent *e)
double fQtScalingfactor
Definition: QRootCanvas.h:237
UInt_t GetWindowHeight()
virtual void mouseMoveEvent(QMouseEvent *e)
void MoveOpaque(Int_t set=1)
UInt_t GetWw()
void buildEditorWindow()
Size_t GetYsizeReal()
virtual void ls(Option_t *option="")
void CanvasStatusEvent(const char *)
Size_t GetXsizeReal()
void SetWindowPosition(Int_t x, Int_t y)
void SetSelectedPad(TPad *pad)
TVirtualPadEditor * fxPeditor
Definition: QRootCanvas.h:222
void activateEditor(TPad *pad, TObject *obj)
void setStatusBarVisible(bool flag)
void executeMenu(int id)
virtual void wheelEvent(QWheelEvent *e)
void PadDoubleClicked(TPad *)
virtual ~QRootCanvas()
Bool_t GetShowEventStatus()
UInt_t GetWindowWidth()
Int_t fRootWindowId
Definition: QRootCanvas.h:216
string msg
Definition: go4init.py:11
virtual void Update()