Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/Go4GUI/TGo4QRootCanvas.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------
00002 //        Go4 Release Package v2.10-5 (build 21005) 
00003 //                      03-Nov-2005
00004 //---------------------------------------------------------------
00005 //       The GSI Online Offline Object Oriented (Go4) Project
00006 //       Experiment Data Processing at DVEE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 #include "TGo4QRootCanvas.h"
00017 
00018 #include <iostream.h>
00019 
00020 #include "THStack.h"
00021 #include "TCanvas.h"
00022 #include "TString.h"
00023 #include "TPad.h"
00024 #include "TIterator.h"
00025 #include "TProcessID.h"
00026 
00027 #include "qapplication.h"
00028 #include "qcursor.h"
00029 #include "qpoint.h"
00030 #include "qlistview.h"
00031 
00032 #include "Go4LockGuard/TGo4LockGuard.h"
00033 #include "Go4CommandsAnalysis/TGo4ComGetPicture.h"
00034 #include "Go4CommandsAnalysis/TGo4ComGetCanvas.h"
00035 #include "Go4CommandsAnalysis/TGo4ComGetObject.h"
00036 #include "Go4GUIRegistry/TGo4GUIRegistry.h"
00037 #include "TGo4MonitoredListStatus.h"
00038 #include "TGo4PreviewPanel.h"
00039 #include "TGo4MonitoredObject.h"
00040 #include "TGo4PadOptions.h"
00041 #include "TGo4GSIHistoClient.h"
00042 #include "Go4QtBaseWidgets/TGo4QDragDrop.h"
00043 #include "Go4QtBaseWidgets/TGo4QPicItem.h"
00044 #include "Go4QtBaseWidgets/TGo4QCanvasItem.h"
00045 #include "Go4QtBaseWidgets/TGo4QFitterItem.h"
00046 
00047 TGo4QRootCanvas::TGo4QRootCanvas(QWidget *parent, const char *name, TCanvas *c)
00048    :TQRootCanvas(parent, name, c), needMinmaxResize(true)
00049 {
00050    // TGo4LockGuard mainguard;
00051     setAcceptDrops(true);
00052     fxTGo4PreviewPanel= (dynamic_cast <TGo4PreviewPanel *>(parentWidget()));
00053     fxShowEventStatus=false;
00054 //    setWFlags(Qt::WType_TopLevel);
00055       setSizeIncrement( QSize( 100, 100 ) );
00056     setBaseSize( QSize( 100, 100 ) );
00058     Resize();
00059     Update();
00060 
00061 }
00062 
00063 TGo4QRootCanvas::~TGo4QRootCanvas(){}
00064 
00065 
00066 void TGo4QRootCanvas::SetShowEventStatus(bool s)
00067 {
00068    fxShowEventStatus=s;
00069 }
00070 void TGo4QRootCanvas::mouseDoubleClickEvent( QMouseEvent *e )
00071 {
00072    TGo4LockGuard mainguard;
00073    TQRootCanvas::mouseDoubleClickEvent(e);
00074    fxTGo4PreviewPanel->mouseDoubleClickEvent(e);
00075 }
00076 void TGo4QRootCanvas::mousePressEvent( QMouseEvent *e )
00077 {
00078    Int_t px=e->x();
00079    Int_t py=e->y();
00080    TObjLink *pickobj=0;
00081    TPad* pad=0;
00082    switch(e->button())
00083       {
00084          case LeftButton:
00085            pad=fCanvas->Pick(px, py, pickobj);
00086            emit PadClicked(pad);
00087            break;
00088          case RightButton:
00089             gROOT->cd(); // for context menu that might create new histograms (rebin, projection)
00090                          // these should be found at synchronize with root memory
00091             break;
00092          default:
00093            break;
00094       }
00095    TQRootCanvas::mousePressEvent(e);
00096    if(e->button()==RightButton)
00097       fxTGo4PreviewPanel->SyncRootMemory(); // prepare automatic sync for newly created histograms
00098 }
00099 
00100 void TGo4QRootCanvas::mouseMoveEvent(QMouseEvent *e)
00101 {
00102    TGo4LockGuard mainguard;
00103    TQRootCanvas::mouseMoveEvent(e);
00104    if(fxShowEventStatus){
00105       TObject *selected=fCanvas->GetSelected();
00106       Int_t px=fCanvas->GetEventX();
00107       Int_t py=fCanvas->GetEventY();
00108       Text_t buffer[2048];
00109       snprintf(buffer,2047,"%s  %s ", selected->GetName(), selected->GetObjectInfo(px,py) );
00110       fxTGo4PreviewPanel->DisplayEventStatus(buffer);
00111    }
00112 }
00113 
00114 void TGo4QRootCanvas::dropEvent( QDropEvent *Event )
00115 {
00116    TGo4LockGuard mainguard;
00117    QString str;
00118    TObject *object=0;
00119    QPoint Pos = Event->pos();
00120    TPad* pad = Pick(Pos.x(), Pos.y(), object);
00121    pad->cd();
00122    fxTGo4PreviewPanel->SetActivePad(pad);
00123    if ( !QTextDrag::decode( Event, str ) ) return;
00124    
00125    QListView *DragSource=dynamic_cast <QListView *> (Event->source());
00126    TGo4QDragDrop *DragedItem= dynamic_cast <TGo4QDragDrop *>(DragSource->currentItem());
00127    if(DragedItem==0) return;
00128    DragSource->clearSelection();                                // cleanup selection in case of fast drags
00129    DragSource->setSelected(DragedItem,true); // due to changed startdrag in listviews JA
00130    TObject *dragedObject = DragedItem->GetFileObj();
00131    if (dragedObject==0) dragedObject =  DragedItem->GetItemObject();
00132    if(strcmp(DragSource->name(),"ListViewRemote")==0) {
00133        TGo4GUIRegistry *fxTGo4GUIRegistry;
00134        fxTGo4GUIRegistry = TGo4GUIRegistry::Instance();
00135        if(dynamic_cast<TGo4QPicItem *> (DragedItem)) {
00136           TGo4ComGetPicture *com= new TGo4ComGetPicture(str);
00137           fxTGo4GUIRegistry->SubmitCommand(com,str,0,kFALSE,this, pad);
00138        } else 
00139        if(dynamic_cast<TGo4QCanvasItem *> (DragedItem)) {
00140           TGo4ComGetCanvas *com= new TGo4ComGetCanvas(str);
00141           fxTGo4GUIRegistry->SubmitCommand(com,str,0,kFALSE,this, pad);
00142        } else {
00143           TGo4ComGetObject *com = new TGo4ComGetObject(str);
00144           fxTGo4GUIRegistry->SubmitCommand(com,str,0,kFALSE,this, pad);
00145       }
00146       emit DropToPad(pad);
00147       
00148    } else 
00149    if (strcmp(DragSource->name(),"ClientHistListView")==0) {
00150       TGo4GSIHistoClient* client= dynamic_cast<TGo4GSIHistoClient*> (DragSource->parentWidget());
00151       if(client)
00152          client->GetSelectedItem(DragedItem, this, pad);
00153       emit DropToPad(pad);
00154    } else 
00155    if(dynamic_cast<TGo4QFitterItem*> (DragedItem)) {
00156       DragedItem->DropAction(fxTGo4PreviewPanel);
00157       fxTGo4PreviewPanel->setFocus();
00158    } else {
00159       TGo4PadOptions *fxTGo4PadOptions = 
00160           dynamic_cast <TGo4PadOptions*> (fxTGo4PreviewPanel->GetPadOptions(pad));
00161       bool PadDragAddOption=FALSE;
00162       if(fxTGo4PadOptions!=0)
00163          PadDragAddOption = fxTGo4PadOptions->DragAddOption();
00164       if(!PadDragAddOption)
00165          fxTGo4PreviewPanel->ClearPad();
00166       DragedItem->DropAction(fxTGo4PreviewPanel);
00167       emit DropToPad(pad);
00168       pad->Update();
00169       fxTGo4PreviewPanel->setFocus();
00170    } //if(strcmp(DragSource->name(),"ListViewRemote")==0)
00171 }
00172 
00173 void TGo4QRootCanvas::InsertCanvas( TCanvas* C, TPad *pad, bool createoptions)
00174 {
00175    if(C==0 || pad==0) return;
00176    TVirtualPad* padsav=gPad;
00177    //pad->cd();
00178    //C->DrawClonePad(); // this only works for already drawn canvas!
00179                         // we copy most of this code to here
00181   C->cd();
00182   TObject *obj, *clone;
00183   //copy pad attributes
00184   pad->Range(C->GetX1(),C->GetY1(),C->GetX2(),C->GetY2());
00185   pad->SetTickx(C->GetTickx());
00186   pad->SetTicky(C->GetTicky());
00187   pad->SetGridx(C->GetGridx());
00188   pad->SetGridy(C->GetGridy());
00189   pad->SetLogx(C->GetLogx());
00190   pad->SetLogy(C->GetLogy());
00191   pad->SetLogz(C->GetLogz());
00192   pad->SetBorderSize(C->GetBorderSize());
00193   pad->SetBorderMode(C->GetBorderMode());
00194   C->TAttLine::Copy((TAttLine&)*pad);
00195   C->TAttFill::Copy((TAttFill&)*pad);
00196   C->TAttPad::Copy((TAttPad&)*pad);
00197   //copy primitives
00198   TIter next(C->GetListOfPrimitives());
00199   while ((obj=next())) {
00200      pad->cd();
00201      // we must assure _before_ cloning that obj process id is
00202      // not already used in this session. This would confuse
00203      // viewpanel pad management due to the TRefArray of pads JA
00204      TProcessID* spi=TProcessID::GetSessionProcessID();
00205       //     UInt_t pid=obj->GetUniqueID() & 0xffffff;
00206       //     cout <<"discard old primitive uid: "<<pid << endl; 
00207      UInt_t objcount=TProcessID::GetSessionProcessID()->GetObjectCount(); // prevent automatic assignment
00208      while(TProcessID::GetSessionProcessID()->GetObjectWithID(objcount))
00209       {
00210          //cout<<" found previous object for id "<<objcount << endl;  
00211          // skip already used numbers    
00212          objcount++;
00213       } 
00214       obj->SetUniqueID(objcount);      
00215       //cout <<"Assigning new primitive id "<<objcount << endl;
00216       clone = obj->Clone();
00217       clone->SetBit(kIsReferenced); // otherwise, root might find another number!
00218       TProcessID::SetObjectCount(objcount); // override root TProcessID management 
00219       //UInt_t id=
00220       TProcessID::AssignID(clone); // this will put object into uid list
00221       //     cout <<"  New clone ID is "<<id << endl;
00222       //     cout << " new object count is:"<<TProcessID::GetSessionProcessID()->GetObjectCount()<<endl;
00223      pad->GetListOfPrimitives()->Add(clone,obj->GetDrawOption());
00224   }
00225   pad->ResizePad();
00226   pad->Modified();
00227   pad->Update();
00229   if(createoptions) 
00230    CreateDrawOptions(pad);
00231   padsav->cd();
00232 }
00233 
00234 
00235 
00236 void TGo4QRootCanvas::CreateDrawOptions(TPad *pad)
00237 {
00238 // TGo4LockGuard mainguard;
00239    if(pad==0) return;
00240    TH1* His=0;
00241    His=fxTGo4PreviewPanel->GetPadHistogram(pad);
00242    fxTGo4PreviewPanel->UpdatePad(pad,His,true); // first update histogram if on this pad
00243    // then scan subpads recursively:   
00244    TIterator* listiter;
00245    TObject *entry;
00246    //pad->cd();
00247    TList *TC=pad->GetListOfPrimitives();
00248    TList* primcopy=new TList;
00249    primcopy->AddAll(TC); // iterate over copy of primitives list only
00250                          // CreateDrawOptions might modifiy it (Redraw markers, etc.)
00251    listiter = primcopy->MakeIterator();
00252    //listiter->Reset();
00253    while((entry= listiter->Next())!=0) {
00254       if(entry->InheritsFrom("TPad")){
00255          TPad *fxPad=(TPad *)entry;
00256          //fxPad->Update();
00257          CreateDrawOptions(fxPad);
00258       }
00259    }
00260   delete listiter;
00261   primcopy->Clear("nodelete");
00262   delete primcopy;
00263 }
00264 
00265 void TGo4QRootCanvas::dragEnterEvent( QDragEnterEvent *e )
00266 {
00267 // TGo4LockGuard mainguard;
00268    if ( QTextDrag::canDecode( e ))   {
00269       e->accept();
00270        }
00271 }
00272 TCanvas *TGo4QRootCanvas::GetCanvas()
00273 {
00274    return fCanvas;
00275 }
00276 
00277 
00278 void TGo4QRootCanvas::resizeEvent( QResizeEvent *e )
00279 {
00280        QWidget::resizeEvent( e );
00281        needResize=true;
00282 
00283 // cout <<"resizeEvent.." << endl;
00284 //       cout << size().width() << endl;
00285 //       cout << size().height() << endl;
00286 //       cout << sizeIncrement().width() << endl;
00287 //       cout << sizeIncrement().height() << endl;
00288 
00289 }
00290 
00291 void TGo4QRootCanvas::paintEvent( QPaintEvent * )
00292 {
00293 //cout << " TGo4QRootCanvas::QPaintEvent " << endl;
00294 //Qtrootlockguard threadlock;
00295  if(fCanvas){
00296      QPainter p;
00297      p.begin( this);
00298      p.end();
00299    // in case of previous showMaximum/ showNormal operation, actual resize is
00300    // done in the next paintEvent (i.e. here).
00301    // This trick is made because showNormal after showMaximized does not always give
00302    // the fresh window values to the root canvas already in the eventFilter
00303 
00304    if (needMinmaxResize){
00305                  TGo4LockGuard threadlock;
00306                  QApplication::setOverrideCursor( Qt::WaitCursor );
00307                  Resize();
00308                  Update();
00309                  QApplication::restoreOverrideCursor();
00310                  needMinmaxResize=false;
00311                  //cout << "fCanvas->Resize() minmax in paintEvent" << endl;
00312    }
00313    Update();
00314 //   fCanvas->Flush();
00315   }
00316 }
00317 
00318 
00319 
00320 
00321 
00322 bool TGo4QRootCanvas::eventFilter( QObject *o, QEvent *e )
00323 {
00324   // Filtering of QWidget Events
00325   // for ressource management
00326   if ( e->type() == QEvent::Close) {  // close
00327         if (fCanvas && (isCanvasOwned== false) ) {
00328 
00329    delete fCanvas;
00330 
00331         #if DEBUG_LEVEL
00332    qDebug("TQRootCanvas ::eventFilter canvas Id:%i deleted \n", fCanvas->GetCanvasID()) ;
00333         #endif
00334 
00335         fCanvas=0;
00336        }
00337 
00338   if ( e->type() == QEvent::ChildRemoved ) {  // child is removed
00339 
00340         #if DEBUG_LEVEL
00341         qDebug(" TQRootCanvas:QEvent:Child removed called \n" );
00342         #endif
00343 
00344        }
00345     return FALSE;
00346   }
00347 
00348 
00349   if ( e->type() == QEvent::Destroy) {  // destroy
00350 
00351    #if DEBUG_LEVEL
00352     qDebug(" QEvent:Destroy called \n" );
00353     QKeyEvent *k = (QKeyEvent*)e;
00354    #endif
00355 
00356     return FALSE;
00357   }
00358 
00359   if( e->type() == QEvent::Paint) {  // Paint
00360 //        cout << " QPaintEvent " << endl;
00361         return FALSE;
00362   }
00363    if( e->type() == QEvent::Move) {  // Paint
00364 //        cout << " QMoveEvent " << endl;
00365      return FALSE;
00366   }
00367 
00368  if( e->type() == QEvent::MouseButtonRelease) {  // Resize on mouse release
00369         //cout << " QMouseButtonRelease Event " << endl;
00370         if (needResize){
00371                  //TGo4LockGuard threadlock;
00372                  // performance: only make a canvas resize on button release
00373                  // after changing window geometry by the size grip
00374                  // resizing without size grip is treated by enter event
00375                  QApplication::setOverrideCursor( Qt::WaitCursor );
00376                  Resize();
00377                  Update();
00378                  QApplication::restoreOverrideCursor();
00379                  needResize=false;
00380                  //cout << "fCanvas->Resize() in eventfilter" << endl;
00381      }
00382         return FALSE;
00383   }
00384 
00385 if( e->type() == QEvent::Show ||
00386       e->type() == QEvent::ShowNormal ||
00387       e->type() == QEvent::ShowFullScreen ||
00388        e->type() == QEvent::ShowMaximized ||
00389         e->type() == QEvent::ShowMinimized) {  // Resize on window show change
00390         //cout << "  Show / ShowNormal / FullScreen / Maximized / Minimized " << endl;
00391         if (needResize){
00392                  needResize=false;
00393                  needMinmaxResize=true;
00394                  // we submit the actual resize to the next paintEvent
00395                  // it seems that the root canvas can not get the true
00396                  // X-coordinates here (Resize() will not resize correctly!)
00397                  //cout << "eventfilter sets minmax resize" << endl;
00398      }
00399         return FALSE;
00400   }
00401 
00402 if( e->type() == QEvent::Enter) {
00403    // auxiliary resize for the bare rootcanvas without go4 viewpanel
00404    // resize is done on entering this widget (mousebutton release is not passed...)
00405    if (needResize)
00406             {
00407                  QApplication::setOverrideCursor( Qt::WaitCursor );
00408                  Resize();
00409                  Update();
00410                  QApplication::restoreOverrideCursor();
00411                  needResize=false;
00412             }
00413 
00414 return FALSE;
00415 }
00416 
00417 if( e->type() == QEvent::Leave) {
00418 // try: switch draw mode for crosshair back?
00419 //cout <<"QRootcanvas leave event in filter with update" << endl;
00420 fCanvas->FeedbackMode(kFALSE);
00421 Update();
00422 return FALSE;
00423 }
00424 
00425   // standard event processing
00426   return QWidget::eventFilter( o, e );
00427 }
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Tue Nov 8 10:56:02 2005 for Go4-v2.10-5 by doxygen1.2.15