Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4ViewPanel.ui.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //        Go4 Release Package v3.04-01 (build 30401)
00003 //                      28-November-2008
00004 //---------------------------------------------------------------
00005 //   The GSI Online Offline Object Oriented (Go4) Project
00006 //   Experiment Data Processing at EE 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 const char* NoStackDrawOption = "nostack, ";
00017 
00018 #ifdef __GO4GED__
00019 #include "TGedEditor.h"
00020 #endif
00021 
00022 enum Go4ViewPanelMenuesId {
00023     ShowMarkEditorId = 201,
00024     ShowRootEditorId = 202,
00025     EventStatusId    = 301,
00026     CrosshairId      = 302,
00027     FreezeTitleId    = 309,
00028     SetTitleTextId   = 310,
00029     SelectObjectId   = 501,
00030     SuperimposeId    = 1011,
00031     StatisticsId     = 1006,
00032     SetTitleId       = 1007,
00033     SetLegendId      = 1008,
00034     DrawTimeId       = 1012,
00035     DrawDateId       = 1013,
00036     DrawItemnameId   = 1014,
00037     BringToFrontId   = 4998,
00038     MasterSelectId   = 4999,
00039     FirstSelectId    = 5000 };
00040 
00041 enum Go4MouseMode_t {
00042    kMouseROOT ,   // normal root mouse
00043    kMousePickCursor,  // click sets cursor / marker
00044    kMousePickLimits,  // click sets region limit / window condition
00045    kMousePickPolygon, // click sets polygon condition
00046    kMousePickLatex,   // click sets latex label
00047    kMouseDraw        // draw on mouse press
00048 };
00049 
00050 const char*  TGo4ViewPanel::GetPanelName()
00051 {
00052    return fPanelName.latin1();
00053 }
00054 
00055 void TGo4ViewPanel::SetPanelName(const char* newname)
00056 {
00057    fPanelName = newname;
00058 }
00059 
00060 
00061 TGo4Slot* TGo4ViewPanel::GetPanelSlot()
00062 {
00063    return GetTopSlot(true);
00064 }
00065 
00066 TGo4Slot* TGo4ViewPanel::AddNewSlot(const char* name, TGo4Slot* parent)
00067 {
00068    if (parent==0) parent = GetPanelSlot();
00069    return new TGo4Slot(parent, name, "title");
00070 }
00071 
00072 void TGo4ViewPanel::ResetWidget()
00073 {
00074    // do nothing
00075 }
00076 
00077 void TGo4ViewPanel::linkedObjectUpdated(const char* linkname, TObject* obj)
00078 {
00079    if (linkname==0) return;
00080 
00081    if (strcmp(linkname,"PadRangeAxisChanged")==0) {
00082       PadRangeAxisChanged(GetActivePad());
00083    } else
00084    if (strcmp(linkname,"PadModified")==0) {
00085       if (IsRedrawBlocked()) return;
00086       if (!fbModifiedSignalFlag)
00087         QTimer::singleShot(1, this, SLOT(ProcessPadModifiedSignal()));
00088       fbModifiedSignalFlag = true;
00089    }
00090 }
00091 
00092 void TGo4ViewPanel::linkedUpdated(TGo4Slot* slot, TObject* obj)
00093 {
00094    if (slot==0) return;
00095 
00096    if (IsRedrawBlocked()) return;
00097 
00098    Int_t kind = GetDrawKind(slot);
00099 
00100    TGo4Slot* padslot = slot;
00101    if (kind!=kind_PadSlot) padslot = slot->GetParent();
00102 
00103    if (((kind>0) && (kind<100)) || (kind==kind_Condition)) {
00104       TGo4Picture* padopt = GetPadOptions(padslot);
00105 
00106       if (padopt!=0) {
00107          padopt->SetContentModified(true);
00108          padopt->SetPadModified();
00109 
00110          // in this small period other objects can come,
00111          // therefore only one repain will be done
00112          ShootRepaintTimer();
00113       }
00114    }
00115 }
00116 
00117 void TGo4ViewPanel::linkedRemoved(TGo4Slot* slot, TObject* obj)
00118 {
00119    if (slot==0) return;
00120 
00121    if (IsRedrawBlocked()) return;
00122 
00123    int kind = GetDrawKind(slot);
00124 
00125    if (kind==kind_ThisPad) {
00126       TPad* pad = (TPad*) obj;
00127       if (pad!=0) PadDeleted(pad);
00128       return;
00129    }
00130 
00131    TGo4Slot* padslot = slot;
00132    if (kind!=kind_PadSlot) padslot = slot->GetParent();
00133 
00134    CheckObjectsAssigments(GetSlotPad(padslot), padslot);
00135 
00136    if (((kind>0) && (kind<100)) || (kind==kind_Condition)) {
00137       CleanupGedEditor();
00138       TGo4Picture* padopt = GetPadOptions(padslot);
00139       if (padopt!=0) {
00140          padopt->SetPadModified();
00141          ShootRepaintTimer();
00142       }
00143    }
00144 }
00145 
00146 bool TGo4ViewPanel::IsAcceptDrag( const char * itemname, TClass * cl, int kind )
00147 {
00148     if (cl==0) return false;
00149 
00150     int cando = Browser()->ItemCanDo(itemname);
00151     return TGo4BrowserProxy::CanDrawItem(cando) || cl->InheritsFrom(TGo4Condition::Class());
00152 }
00153 
00154 void TGo4ViewPanel::DropOnPad(TPad* pad,  const char * itemname, TClass * cl, int kind )
00155 {
00156    if (cl==0) return;
00157    if (pad==0) pad = GetCanvas();
00158 
00159    if (cl->InheritsFrom(TGo4Fitter::Class())) {
00160       SetActivePad(pad);
00161       EditItem(itemname);
00162       return;
00163    }
00164    int cando = Browser()->ItemCanDo(itemname);
00165    if (!TGo4BrowserProxy::CanDrawItem(cando) && !cl->InheritsFrom(TGo4Condition::Class())) return;
00166 
00167    if (AddDrawObject(pad, kind_Link, itemname, 0, false, 0)==0) return;
00168 
00169    SetActivePad(pad);
00170 
00171    ShootRepaintTimer();
00172 
00173    Browser()->GetBrowserObject(itemname, 2);
00174 }
00175 
00176 // ****************************************************************
00177 
00178 void TGo4ViewPanel::init()
00179 {
00180    fPanelName = name();
00181 
00182    ActivePad = 0;
00183 
00184    fbEditorFrameVisible = false;
00185    fiSkipRedrawCounter = 0;
00186    fxRepaintTimerPad = 0;
00187    fxDoubleClickTimerPad = 0;
00188    fbFreezeTitle = false;
00189    fbApplyToAllFlag = false;
00190    fbCanvasCrosshair = false;
00191    fbCanvasEventstatus = false;
00192 
00193    fbCloneFlag = true;
00194    fbModifiedSignalFlag = false;
00195    fbLeaveFocusAfterCondEnd = false;
00196 
00197    // setup of marker editor
00198    fbMarkEditorVisible = false;
00199    fbTypingMode = true;
00200    MarkerPanel->setShown(false);
00201    MarkerPanel->setRadioButtonExclusive(false);
00202    MarkerPanel->setExclusive(false);
00203    fiMouseMode = kMouseROOT;
00204    fiPickCounter = 0;
00205    fbPickAgain = false;
00206 
00207    setCaption(GetPanelName());
00208    fxGo4QRootCanvas->setName(GetPanelName());
00209    fxGo4QRootCanvas->getCanvas()->SetName(GetPanelName());
00210 
00211    fSelectMenu = 0;
00212    fxPeditor = 0;
00213    fDummyHisto = 0;
00214 
00215    connect(fxGo4QRootCanvas, SIGNAL(SelectedPadChanged(TPad*)),
00216            this, SLOT(SetActivePad(TPad*)));
00217    connect(fxGo4QRootCanvas, SIGNAL(PadClicked(TPad*)),
00218            this, SLOT(PadClickedSlot(TPad*)));
00219    connect(fxGo4QRootCanvas, SIGNAL(PadDoubleClicked(TPad*)),
00220            this, SLOT(PadDoubleClickedSlot(TPad*)));
00221    connect(fxGo4QRootCanvas->getContextMenu(), SIGNAL(MenuCommandExecuted(TObject*, const char*)),
00222            this, SLOT(MenuCommandExecutedSlot(TObject*, const char*)));
00223    connect(fxGo4QRootCanvas, SIGNAL(CanvasLeaveEvent()),
00224            this, SLOT(RefreshButtons()));
00225 }
00226 
00227 void TGo4ViewPanel::CompleteInitialization()
00228 {
00229    TGo4LockGuard lock;
00230 
00231    // create apropriate entry in OM
00232    UpdatePadStatus(GetCanvas(), true);
00233 
00234    //    fMenuBar
00235    fMenuBar = new QMenuBar( MenuFrame, "MenuBar" );
00236    fMenuBar->setMinimumWidth(50);
00237    fMenuBar->setFrameShape(QFrame::NoFrame);
00238     //File Menu
00239    QPopupMenu* FileMenu = new QPopupMenu( fMenuBar );
00240    fMenuBar->insertItem( "F&ile",FileMenu); // avoid conflict with mainwindow shortcut!
00241    FileMenu->insertItem("&Save as...", this, SLOT(SaveCanvas()));
00242    FileMenu->insertItem("Print...", this, SLOT(PrintCanvas()));
00243    FileMenu->insertItem("Produce &Picture", this, SLOT(ProducePicture()));
00244    FileMenu->insertItem("Produce &Graph from markers", this, SLOT(ProduceGraphFromMarkers()));
00245  
00246 //   FileMenu->insertItem("Copy to T&Canvas in Memory", this, SLOT(SendToBrowser()));
00247 //   FileMenu->insertItem("&Load marker setup...", this, SLOT(LoadMarkers()));
00248 //   FileMenu->insertItem("Save &marker setup...", this, SLOT(SaveMarkers()));
00249    FileMenu->insertItem("Cl&ose", this, SLOT(close()));
00250 
00251     //Edit Menu
00252    QPopupMenu* EditMenu = new QPopupMenu( fMenuBar );
00253    fMenuBar->insertItem("&Edit", EditMenu);
00254 
00255    EditMenu->insertItem("Show Marker &editor", this, SLOT(SetMarkerPanel()), 0, ShowMarkEditorId);
00256    EditMenu->setItemChecked(ShowMarkEditorId, fbMarkEditorVisible);
00257    EditMenu->insertItem("Show &ROOT Attributes Editor", this, SLOT(StartRootEditor()), 0, ShowRootEditorId);
00258    EditMenu->setItemChecked(ShowRootEditorId, false);
00259    EditMenu->insertItem("Show &Event Status", this, SLOT(ShowEventStatus()), 0, EventStatusId);
00260    EditMenu->setItemChecked(EventStatusId, false);
00261    EditMenu->insertItem("Start &condition editor", this, SLOT(StartConditionEditor()));
00262    EditMenu->insertSeparator();
00263    EditMenu->insertItem("&1:1 coordinates ratio", this, SLOT(RectangularRatio()));
00264    EditMenu->insertItem("&Default pad margins", this, SLOT(DefaultPadMargin()));
00265    EditMenu->insertSeparator();
00266    EditMenu->insertItem("Clear &Markers", this, SLOT(ClearAllMarkers()));
00267    EditMenu->insertItem("Clear &Pad", this, SLOT(ClearActivePad()));
00268    EditMenu->insertItem("Clear C&anvas", this, SLOT(ClearCanvas()));
00269 
00270    fSelectMenu = new QPopupMenu( fMenuBar );
00271    fMenuBar->insertItem("&Select", fSelectMenu, SelectObjectId);
00272    connect(fSelectMenu, SIGNAL(activated(int)), this, SLOT(SelectMenuItemActivated(int)));
00273 
00274    QPopupMenu* OptionsMenu = new QPopupMenu( fMenuBar );
00275    fMenuBar->insertItem( "&Options",OptionsMenu);
00276    connect(OptionsMenu, SIGNAL(aboutToShow()), this, SLOT(AboutToShowOptionsMenu()));
00277 
00278    OptionsMenu->insertItem("&Crosshair", CrosshairId);
00279    OptionsMenu->insertItem("Super&impose", SuperimposeId);
00280    OptionsMenu->insertItem("Histogram &Statistics", StatisticsId);
00281    OptionsMenu->insertItem("Multiplot &Legend", SetLegendId);
00282 
00283    OptionsMenu->insertSeparator();
00284    OptionsMenu->insertItem("Histogram &Title", SetTitleId);
00285    OptionsMenu->insertItem("Draw Time", DrawTimeId);
00286    OptionsMenu->insertItem("Draw Date", DrawDateId);
00287    OptionsMenu->insertItem("Draw item name", DrawItemnameId);
00288    OptionsMenu->insertSeparator();
00289    OptionsMenu->insertItem("&Keep Viewpanel Title", FreezeTitleId);
00290    OptionsMenu->insertItem("Set &Viewpanel Title...", SetTitleTextId);
00291    connect(OptionsMenu, SIGNAL(activated(int)), this, SLOT(OptionsMenuItemActivated(int)));
00292 
00293    QCheckBox* box1 = new QCheckBox(MenuFrame, "ApplyToAllCheck");
00294    box1->setText("Apply to all");
00295    connect(box1, SIGNAL(toggled(bool)), this, SLOT(ApplyToAllToggled(bool)));
00296 
00297    fAutoScaleCheck = new QCheckBox(MenuFrame, "AutoScaleCheck");
00298    fAutoScaleCheck->setText("AutoScale");
00299    fAutoScaleCheck->setChecked(GetPadOptions(GetCanvas())->IsAutoScale());
00300    connect(fAutoScaleCheck, SIGNAL(toggled(bool)), this, SLOT(AutoScaleToggled(bool)));
00301 
00302    QHBoxLayout* menugrid = new QHBoxLayout(MenuFrame, 0, -1, "MenuLayout");
00303    menugrid->addWidget(fMenuBar, 10, Qt::AlignLeft);
00304    menugrid->addWidget(box1, 1, Qt::AlignRight);
00305    menugrid->addWidget(fAutoScaleCheck, 1, Qt::AlignRight);
00306    TGo4ViewPanelLayout->addMultiCellLayout(menugrid, 0, 0, 0, 1);
00307 
00308    connect(TGo4WorkSpace::Instance(), SIGNAL(panelSignal(TGo4ViewPanel*, TPad*, int)),
00309            this, SLOT(panelSlot(TGo4ViewPanel*, TPad*, int)));
00310 
00311    // status widget
00312    CanvasStatus = new QStatusBar(this, "Canvas Status");
00313    TGo4ViewPanelLayout->addMultiCellWidget( CanvasStatus, 3, 3, 0, 1 );
00314    CanvasStatus->setShown(false);
00315 
00316    // setup of root editor
00317    fxRooteditor = new TQRootWindow(EditorFrame,"rootwrapperwindow");
00318    QVBoxLayout* gedlayout = new QVBoxLayout(EditorFrame);
00319    if (fxRooteditor) gedlayout->addWidget(fxRooteditor);
00320    EditorFrame->polish();
00321    EditorFrame->update();
00322    EditorFrame->show();
00323    EditorFrame->setShown(fbEditorFrameVisible);
00324 
00325    //RefreshButtons();
00326 
00327    SetActivePad(GetCanvas());
00328 
00329    SetPadDefaults(GetCanvas());
00330 
00331    go4sett->restorePanelSize(this);
00332    fbCloneFlag = go4sett->getCloneFlag();
00333 }
00334 
00335 void TGo4ViewPanel::destroy()
00336 {
00337    TGo4LockGuard lock;
00338 
00339   // prevent problems with root's subeditor cache
00340    if(fxPeditor!=0) {
00341       fxPeditor->DeleteEditors();
00342       delete fxPeditor;
00343       fxPeditor = 0;
00344    }
00345 
00346    if (fDummyHisto!=0) {
00347       delete fDummyHisto;
00348       fDummyHisto = 0;
00349    }
00350 
00351    // we should delete all markers first, while they
00352    // have internal reference on the pad, which will be
00353    // deleted by the net canvas->Clear() call
00354    ProcessMarkersClear(GetCanvas(), true);
00355 
00356    GetCanvas()->Clear();
00357 
00358    fxRepaintTimerPad = 0;
00359 
00360    CallPanelFunc(panel_Deleted);
00361 
00362    if (gPad!=0)
00363       if (IsPanelPad((TPad*)gPad))
00364           gPad = 0;
00365 
00366    if (gROOT->GetSelectedPad()!=0)
00367       if (IsPanelPad((TPad*)gROOT->GetSelectedPad()))
00368          gROOT->SetSelectedPad(0);
00369 }
00370 
00371 void TGo4ViewPanel::SetMouseMode(int mode)
00372 {
00373    fiMouseMode = mode;
00374 }
00375 
00376 int TGo4ViewPanel::GetMouseMode()
00377 {
00378    return fiMouseMode;
00379 }
00380 
00381 QString TGo4ViewPanel::GetSelectedMarkerName(TPad* pad)
00382 {
00383    TGo4Slot* padslot = GetPadSlot(pad);
00384    if (padslot==0) return QString::null;
00385    return QString(padslot->GetPar("::SelMarker"));
00386 }
00387 
00388 int TGo4ViewPanel::GetSelectedMarkerIndex(TPad* pad)
00389 {
00390    TGo4Slot* padslot = GetPadSlot(pad);
00391    if (padslot==0) return -1;
00392    Int_t selindex = -1;
00393    if (!padslot->GetIntPar("::SelIndex",selindex)) return -1;
00394    return selindex;
00395 }
00396 
00397 TGo4Slot* TGo4ViewPanel::GetSelectedSlot(TPad* pad, int* selkind, TObject** selobj)
00398 {
00399    if (selkind!=0) *selkind = kind_None;
00400    if (selobj!=0) *selobj = 0;
00401 
00402    TGo4Slot* padslot = GetPadSlot(pad);
00403    QString selname = GetSelectedMarkerName(pad);
00404    int selindex = GetSelectedMarkerIndex(pad);
00405 
00406    if ((padslot==0) || (selname.length()==0)) return 0;
00407 
00408    for (int n=0; n<padslot->NumChilds();n++) {
00409       TGo4Slot* subslot = padslot->GetChild(n);
00410       int drawkind = GetDrawKind(subslot);
00411       TObject* obj = subslot->GetAssignedObject();
00412 
00413       if (drawkind==kind_Link) {
00414          if ((obj!=0) && (dynamic_cast<TGo4Condition*> (obj)!=0))
00415             drawkind = kind_Condition;
00416       }
00417 
00418       if ((drawkind==kind_Marker) || (drawkind==kind_Window) ||
00419           (drawkind==kind_Poly) || (drawkind==kind_Latex) ||
00420           (drawkind==kind_Arrow) || (drawkind==kind_Condition)) {
00421 
00422         if ((obj==0) || (selname!=obj->GetName())) continue;
00423 
00424         if (drawkind==kind_Condition) {
00425            TGo4Condition* selcond = dynamic_cast<TGo4Condition*> (obj);
00426            if (obj->InheritsFrom(TGo4CondArray::Class())) {
00427               TGo4CondArray* arr = (TGo4CondArray*) obj;
00428               selcond = 0;
00429               if ((selindex>=0) &&
00430                   (selindex<arr->GetNumber()))
00431                      selcond = arr->At(selindex);
00432            }
00433            drawkind = kind_None;
00434            obj = selcond;
00435            if (selcond!=0)
00436              if (selcond->InheritsFrom(TGo4WinCond::Class())) drawkind = kind_Window; else
00437              if (selcond->InheritsFrom(TGo4PolyCond::Class())) drawkind = kind_Poly;
00438         }
00439         if (selkind!=0) *selkind = drawkind;
00440         if (selobj!=0) *selobj = obj;
00441         return subslot;
00442       }
00443    }
00444    return 0;
00445 }
00446 
00447 bool TGo4ViewPanel::IsConditionSelected(TPad* pad)
00448 {
00449    TGo4Slot* slot = GetSelectedSlot(pad, 0, 0);
00450    if (slot==0) return false;
00451 
00452    return (GetDrawKind(slot)==kind_Condition);
00453 }
00454 
00455 TPad* TGo4ViewPanel::FindPadWithItem(const char* itemname)
00456 {
00457    TGo4Iter iter(GetPanelSlot(), kTRUE);
00458    while (iter.next()) {
00459       TGo4Slot* subslot = iter.getslot();
00460       int drawkind = GetDrawKind(subslot);
00461       if ((drawkind==kind_Link) || (drawkind==kind_Condition)) {
00462          const char* linkname = GetLinkedName(subslot);
00463          if (linkname!=0)
00464             if (strcmp(linkname, itemname)==0) return GetSlotPad(subslot->GetParent());
00465       }
00466    }
00467    return 0;
00468 }
00469 
00470 void TGo4ViewPanel::UndrawItemOnPanel(const char* itemname)
00471 {
00472    TGo4LockGuard lock;
00473 
00474    TObjArray delslots;
00475 
00476    TGo4Iter iter(GetPanelSlot(), kTRUE);
00477    while (iter.next()) {
00478       TGo4Slot* subslot = iter.getslot();
00479       int drawkind = GetDrawKind(subslot);
00480       if ((drawkind==kind_Link) || (drawkind==kind_Condition)) {
00481          const char* linkname = GetLinkedName(subslot);
00482          if ((linkname!=0) && (strcmp(linkname, itemname)==0)) {
00483             delslots.Add(subslot);
00484             TGo4Slot* padslot = subslot->GetParent();
00485             TGo4Picture* padopt = GetPadOptions(padslot);
00486             if (padopt!=0) padopt->SetPadModified();
00487         }
00488       }
00489    }
00490    if (delslots.GetLast()>=0) {
00491      delslots.Delete();
00492      ShootRepaintTimer();
00493    }
00494 }
00495 
00496 void TGo4ViewPanel::SetSelectedMarker(TPad* pad, const QString& selname, int selindex)
00497 {
00498    TGo4LockGuard lock;
00499 
00500    TGo4Slot* padslot = GetPadSlot(pad);
00501    if (padslot==0) return;
00502 
00503    if (selname.length()==0) selindex = -1;
00504 
00505    int oldselindex = GetSelectedMarkerIndex(pad);
00506    QString oldselname = GetSelectedMarkerName(pad);
00507 
00508    TGo4Slot* oldsel = GetSelectedSlot(pad, 0, 0);
00509    if (oldsel!=0)
00510       SetSpecialDrawOption(oldsel, 0);
00511 
00512    if (selname.length()>0)
00513       padslot->SetPar("::SelMarker", selname.latin1());
00514    else
00515       padslot->RemovePar("::SelMarker");
00516 
00517    if (selindex>-1)
00518       padslot->SetIntPar("::SelIndex", selindex);
00519    else
00520       padslot->RemovePar("::SelIndex");
00521 
00522    int newselkind = 0;
00523    TObject* newselobj = 0;
00524    TGo4Slot* newselslot = GetSelectedSlot(pad, &newselkind, &newselobj);
00525 
00526    if ((selindex>=0) && (newselslot!=0)) {
00527       QString drawopt("sel=");
00528       drawopt += QString::number(selindex);
00529       SetSpecialDrawOption(newselslot, drawopt.latin1());
00530    }
00531 
00532    if (((oldselindex!=selindex) || (oldselname!=selname)) &&
00533        ((oldselindex>=0) || (selindex>=0))) {
00534          MarkPadModified(pad);
00535          ShootRepaintTimer(pad);
00536       } else
00537       if (newselobj!=0) {
00538           // this will bring object to the top
00539           newselobj->Pop();
00540           // very special case, normally one should not call pad->Update()
00541           pad->Update();
00542       }
00543 
00544 }
00545 
00546 void TGo4ViewPanel::SetSelectedMarkerByMouseClick(TPad* pad, const char* name)
00547 {
00548    TGo4LockGuard lock;
00549 
00550    if (!fbMarkEditorVisible) return;
00551 
00552    TGo4Slot* padslot = GetPadSlot(pad);
00553    if (padslot==0) return;
00554 
00555    bool find = false;
00556 
00557    for(int n=0;n<padslot->NumChilds();n++) {
00558       TGo4Slot* subslot = padslot->GetChild(n);
00559       int drawkind = GetDrawKind(subslot);
00560       if ((drawkind==kind_Marker) ||
00561           (drawkind==kind_Window) ||
00562           (drawkind==kind_Poly)) {
00563              TObject* obj = subslot->GetAssignedObject();
00564              if ((obj!=0) && (strcmp(obj->GetName(),name)==0)) {
00565                 SetSelectedMarker(pad, name, -1);
00566                 SetActiveObj(pad, drawkind, subslot);
00567                 find = true;
00568                 break;
00569              }
00570           }
00571       if (drawkind!=kind_Condition) continue;
00572       TGo4Condition* cond = dynamic_cast<TGo4Condition*>
00573          (subslot->GetAssignedObject());
00574       if (cond==0) continue;
00575 
00576       if (strcmp(cond->GetName(),name)==0) {
00577          SetSelectedMarker(pad, name, -1);
00578 
00579          if (cond->InheritsFrom(TGo4PolyCond::Class()))
00580            drawkind=kind_Poly;
00581          else
00582            drawkind=kind_Window;
00583 
00584          SetActiveObj(pad, drawkind, subslot);
00585          find = true;
00586          break;
00587       }
00588 
00589       TGo4CondArray* arr = dynamic_cast<TGo4CondArray*> (cond);
00590       if (arr==0) continue;
00591 
00592       for(int ncon=0;ncon<arr->GetNumber();ncon++)
00593         if (strcmp(arr->At(ncon)->GetName(),name)==0) {
00594            SetSelectedMarker(pad, arr->GetName(), ncon);
00595            if (arr->At(ncon)->InheritsFrom(TGo4PolyCond::Class()))
00596              drawkind=kind_Poly;
00597            else
00598              drawkind=kind_Window;
00599            SetActiveObj(pad, drawkind, subslot);
00600            find = true;
00601            break;
00602         }
00603    }
00604    if (find) RefreshButtons();
00605 }
00606 
00607 void TGo4ViewPanel::StartConditionEditing(TPad* pad)
00608 {
00609    TGo4LockGuard lock;
00610 
00611    int selectedkind;
00612    TGo4Slot* selslot = GetSelectedSlot(GetActivePad(), &selectedkind, 0);
00613 
00614    if (selslot==0) return;
00615 
00616    if (selectedkind==kind_Window) {
00617       FreezeMode->setChecked(false);
00618       RegionB->setOn(true);
00619       fbLeaveFocusAfterCondEnd = true;
00620    } else
00621    if (selectedkind==kind_Poly) {
00622       FreezeMode->setChecked(false);
00623       PolyB->setOn(true);
00624       fbLeaveFocusAfterCondEnd = true;
00625    } else
00626      return;
00627 
00628    MarkPadModified(pad);
00629    ShootRepaintTimer(pad);
00630 }
00631 
00632 void TGo4ViewPanel::SwitchMarkerButton(int kind, bool on)
00633 {
00634    if(!fbTypingMode) return;
00635    CompleteMarkerEdit(GetActivePad());
00636    if (!on) {
00637       SetMouseMode(kMouseROOT);
00638    } else {
00639      fiPickCounter = 0;
00640      switch(kind) {
00641         case kind_Marker: SetMouseMode(kMousePickCursor); break;
00642         case kind_Window: SetMouseMode(kMousePickLimits); break;
00643         case kind_Poly: SetMouseMode(kMousePickPolygon); break;
00644         case kind_Latex: SetMouseMode(kMousePickLatex); break;
00645         case kind_Arrow: SetMouseMode(kMouseDraw); break;
00646         default: SetMouseMode(kMousePickCursor); break;
00647      }
00648      int selectedkind;
00649      TGo4Slot* selslot = GetSelectedSlot(GetActivePad(), &selectedkind, 0);
00650      if (selectedkind!=kind)
00651         SetSelectedMarker(GetActivePad(), "", -1);
00652    }
00653 
00654    RefreshButtons();
00655 }
00656 
00657 void TGo4ViewPanel::SetCursorMode( bool on )
00658 {
00659    SwitchMarkerButton(kind_Marker, on);
00660 }
00661 
00662 void TGo4ViewPanel::SetRegionMode( bool on )
00663 {
00664    SwitchMarkerButton(kind_Window, on);
00665 }
00666 
00667 void TGo4ViewPanel::SetPolygonMode( bool on )
00668 {
00669    SwitchMarkerButton(kind_Poly, on);
00670 }
00671 
00672 void TGo4ViewPanel::SetLateXMode( bool on )
00673 {
00674    SwitchMarkerButton(kind_Latex, on);
00675 }
00676 
00677 void TGo4ViewPanel::SetDrawingMode( bool on )
00678 {
00679    SwitchMarkerButton(kind_Arrow, on);
00680 }
00681 
00682 void TGo4ViewPanel::SetFreezeMouseMode( bool on )
00683 {
00684    if(!fbTypingMode) return;
00685    fbPickAgain = on;
00686    RefreshButtons();
00687 }
00688 
00689 void TGo4ViewPanel::RefreshButtons()
00690 {
00691    TGo4LockGuard lock;
00692 
00693    MarkerPanel->setShown(fbMarkEditorVisible);
00694    fxGo4QRootCanvas->setMaskDoubleClick(fbMarkEditorVisible);
00695 
00696 //   if(!fbMarkEditorVisible) return;
00697 
00698    bool iscondition = IsConditionSelected(GetActivePad());
00699 
00700    fbTypingMode=false;
00701    GetConditionBtn->setShown(iscondition);
00702    InfoConditionBtn->setShown(iscondition);
00703    EditConditionBtn->setShown(iscondition);
00704    SetConditionBtn->setShown(iscondition);
00705    if (iscondition) {
00706       TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0, 0);
00707       TGo4Condition* cond = slot==0 ? 0 :
00708         dynamic_cast<TGo4Condition*> (slot->GetAssignedObject());
00709       ModifyConditionBtn->setShown((cond!=0) && (cond->IsChanged()!=0));
00710 
00711       QString iconname = "right.png";
00712       QString tooltip = "Refresh condition from analysis";
00713       if (!BrowserItemRemote(GetLinkedName(slot))) {
00714          iconname = "refresh.png";
00715          tooltip = "Refresh condition from source";
00716       }
00717       GetConditionBtn->setIconSet( QIconSet( QPixmap::fromMimeSource(iconname) ) );
00718       QToolTip::remove(GetConditionBtn);
00719       QToolTip::add(GetConditionBtn, tooltip);
00720 
00721    } else
00722       ModifyConditionBtn->setShown(false);
00723 
00724    switch(GetMouseMode()) {
00725       case kMouseROOT:
00726          CursorB->setOn(false);
00727          RegionB->setOn(false);
00728          LatexB->setOn(false);
00729          DrawB->setOn(false);
00730          PolyB->setOn(false);
00731          break;
00732       case kMousePickCursor:
00733          CursorB->setOn(true);
00734          RegionB->setOn(false);
00735          LatexB->setOn(false);
00736          DrawB->setOn(false);
00737          PolyB->setOn(false);
00738          break;
00739       case kMousePickLimits:
00740          CursorB->setOn(false);
00741          RegionB->setOn(true);
00742          LatexB->setOn(false);
00743          DrawB->setOn(false);
00744          PolyB->setOn(false);
00745          break;
00746       case kMousePickPolygon:
00747          CursorB->setOn(false);
00748          RegionB->setOn(false);
00749          LatexB->setOn(false);
00750          DrawB->setOn(false);
00751          PolyB->setOn(true);
00752          break;
00753       case kMousePickLatex:
00754          CursorB->setOn(false);
00755          RegionB->setOn(false);
00756          LatexB->setOn(true);
00757          DrawB->setOn(false);
00758          PolyB->setOn(false);
00759          break;
00760       case kMouseDraw:   // currently, we only draw arrows:
00761          CursorB->setOn(false);
00762          RegionB->setOn(false);
00763          LatexB->setOn(false);
00764          DrawB->setOn(true);
00765          PolyB->setOn(false);
00766          break;
00767       default:
00768          CursorB->setOn(false);
00769          RegionB->setOn(false);
00770          LatexB->setOn(false);
00771          DrawB->setOn(false);
00772          PolyB->setOn(false);
00773          break;
00774    }; // switch()
00775    FreezeMode->setChecked(fbPickAgain);
00776 
00777    SelectedMarkerCmb->clear();
00778    SelectedMarkerCmb->insertItem("new");
00779 
00780    TGo4Slot* slot = GetPadSlot(GetActivePad());
00781    int findindx = -1;
00782 
00783    QString selname = GetSelectedMarkerName(GetActivePad());
00784    int selindex = GetSelectedMarkerIndex(GetActivePad());
00785 
00786    if (slot!=0)
00787      for (int n=0; n<slot->NumChilds();n++) {
00788        TGo4Slot* subslot = slot->GetChild(n);
00789        int drawkind = GetDrawKind(subslot);
00790        if ((drawkind==kind_Marker) || (drawkind==kind_Window) ||
00791            (drawkind==kind_Poly) || (drawkind==kind_Condition)) {
00792           TObject* obj = subslot->GetAssignedObject();
00793           if (obj==0) continue;
00794 
00795           if (obj->InheritsFrom(TGo4CondArray::Class())) {
00796              TGo4CondArray* arr = (TGo4CondArray*) obj;
00797              for(int ncon=0;ncon<arr->GetNumber();ncon++) {
00798                 TGo4Condition* sub = arr->At(ncon);
00799                 QString fullname(arr->GetName());
00800                 fullname+="/Sub";
00801                 fullname+=QString::number(ncon);
00802                 SelectedMarkerCmb->insertItem(fullname);
00803 
00804                 if ((selname==obj->GetName()) &&
00805                     (selindex==ncon))
00806                        findindx = SelectedMarkerCmb->count()-1;
00807              }
00808           } else {
00809              SelectedMarkerCmb->insertItem(obj->GetName());
00810              if (selname==obj->GetName())
00811                findindx = SelectedMarkerCmb->count()-1;
00812           }
00813         }
00814      }
00815 
00816    if (findindx<0) {
00817       findindx = 0;
00818       SetSelectedMarker(GetActivePad(), "", -1);
00819    }
00820 
00821    SelectedMarkerCmb->setCurrentItem(findindx);
00822    DelSelectedMarker->setEnabled((findindx>0) /*&& !iscondition*/);
00823 
00824    if (fbMarkEditorVisible) {
00825       MarkerPanel->polish();
00826       MarkerPanel->update();
00827       MarkerPanel->show();
00828    }
00829    fbTypingMode=true;
00830 }
00831 
00832 void TGo4ViewPanel::SelectedMarkerCmb_activated(int indx)
00833 {
00834    if (!fbTypingMode) return;
00835    if (indx==0)
00836       SetSelectedMarker(GetActivePad(), "", -1);
00837    else {
00838      QString selname = SelectedMarkerCmb->text(indx);
00839      int selindex = -1;
00840      int p = selname.find("/Sub");
00841      if (p>0) {
00842         selindex = atoi(selname.latin1()+p+4);
00843         selname.truncate(p);
00844      } else
00845         selindex = -1;
00846      SetSelectedMarker(GetActivePad(), selname, selindex);
00847    }
00848 
00849    int drawkind = 0;
00850    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), &drawkind, 0);
00851 
00852    if ((slot!=0) && (drawkind>0)) {
00853       SetActiveObj(GetActivePad(), drawkind, slot);
00854       SwitchMarkerButton(drawkind, true);
00855    } else
00856       SwitchMarkerButton(kind_Marker, false);
00857 }
00858 
00859 void TGo4ViewPanel::DelSelectedMarker_clicked()
00860 {
00861    if (!fbTypingMode) return;
00862    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0,0);
00863    if (slot==0) return;
00864    delete slot;
00865    SetSelectedMarker(GetActivePad(), "", -1);
00866    RedrawPanel(GetActivePad(), true);
00867 }
00868 
00869 void TGo4ViewPanel::SetMarkerPanel()
00870 {
00871     fbMarkEditorVisible= !fMenuBar->isItemChecked(ShowMarkEditorId);
00872     fMenuBar->setItemChecked(ShowMarkEditorId, fbMarkEditorVisible);
00873     if(!fbMarkEditorVisible) {
00874        // switch back to normal root mouse when editor is hidden
00875        CompleteMarkerEdit(GetActivePad());
00876        SetMouseMode(kMouseROOT);
00877        gROOT->SetEditorMode("");
00878        fiPickCounter = 0;
00879     }
00880     RefreshButtons();
00881     ShootRepaintTimer();
00882 }
00883 
00884 
00885 void TGo4ViewPanel::LogMarkerValues()
00886 {
00887     if (!fbTypingMode) return;
00888 
00889     TGo4Slot* slot = GetPadSlot(GetActivePad());
00890     if (slot==0) return;
00891 
00892     for (int n=0; n<slot->NumChilds();n++) {
00893        TGo4Slot* subslot = slot->GetChild(n);
00894        int drawkind = GetDrawKind(subslot);
00895        TObject* obj = subslot->GetAssignedObject();
00896        if ((drawkind<kind_Condition) || (obj==0)) continue;
00897        switch (drawkind) {
00898           case kind_Marker: obj->Print("*"); break;
00899           case kind_Latex: obj->Print("*"); break;
00900           case kind_Arrow: obj->Print("go4log"); break;
00901           case kind_Window:
00902           case kind_Poly:
00903           case kind_Condition:
00904              obj->Print("go4log-limits-stats"); break;
00905        }
00906     }
00907 }
00908 
00909 void TGo4ViewPanel::ClearAllMarkers()
00910 {
00911    TGo4LockGuard lock;
00912 
00913    TPad* pad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
00914    if (pad==0) pad = GetCanvas();
00915 
00916    ProcessMarkersClear(pad, IsApplyToAllFlag());
00917 
00918    RedrawPanel(pad, true);
00919 }
00920 
00921 void TGo4ViewPanel::ProcessMarkersClear(TPad *pad, bool withsubpads)
00922 {
00923    if (pad==0) return;
00924 
00925    DeleteDrawObjects(pad, kind_Marker);
00926    DeleteDrawObjects(pad, kind_Window);
00927    DeleteDrawObjects(pad, kind_Poly);
00928    DeleteDrawObjects(pad, kind_Latex);
00929    DeleteDrawObjects(pad, kind_Arrow);
00930    if (!withsubpads) return;
00931 
00932    TGo4Slot* slot = GetPadSlot(pad);
00933    if (slot==0) return;
00934    TGo4Iter iter(slot, true);
00935    while (iter.next()) {
00936       TPad* subpad = GetSlotPad(iter.getslot());
00937       if (subpad!=0) ProcessMarkersClear(subpad, false);
00938    }
00939 }
00940 
00941 
00942 void TGo4ViewPanel::GetConditionBtn_clicked()
00943 {
00944    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0, 0);
00945    if (GetDrawKind(slot)!=kind_Condition) return;
00946    const char* itemname = GetLinkedName(slot);
00947    if (itemname==0) return;
00948 
00949    Browser()->GetBrowserObject(itemname, 2);
00950 
00951    RefreshButtons();
00952 }
00953 
00954 void TGo4ViewPanel::InfoConditionBtn_clicked()
00955 {
00956    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0, 0);
00957    if (GetDrawKind(slot)!=kind_Condition) return;
00958    const char* itemname = GetLinkedName(slot);
00959    if (itemname!=0) ShowItemInfo(itemname);
00960 }
00961 
00962 void TGo4ViewPanel::EditConditionBtn_clicked()
00963 {
00964    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0, 0);
00965    if (GetDrawKind(slot)!=kind_Condition) return;
00966    const char* itemname = GetLinkedName(slot);
00967    if (itemname!=0) EditItem(itemname);
00968 }
00969 
00970 void TGo4ViewPanel::SetConditionBtn_clicked()
00971 {
00972    TGo4Slot* slot = GetSelectedSlot(GetActivePad(), 0, 0);
00973    if (GetDrawKind(slot)!=kind_Condition) return;
00974    const char* itemname = GetLinkedName(slot);
00975    if (itemname!=0) {
00976       UpdateItemInAnalysis(itemname);
00977       TGo4Condition* cond = dynamic_cast<TGo4Condition*> (slot->GetAssignedObject());
00978       if (cond!=0) cond->SetChanged(kFALSE);
00979       RefreshButtons();
00980    }
00981 }
00982 
00983 void TGo4ViewPanel::SaveMarkers()
00984 {
00985     QFileDialog* fd = new QFileDialog( this, "Save Markers", TRUE );
00986     fd->setCaption("Save Markers of active pad into ");
00987     fd->setMode( QFileDialog::AnyFile);
00988     fd->setName( "Save to file: ");
00989     fd->setFilter( "ROOT file (*.root)");
00990     if ( fd->exec() == QDialog::Accepted ) {
00991        QString filename = fd->selectedFile();
00992        if (!filename.endsWith(".root")) filename.append(".root");
00993 //       fxTGo4PreviewPanelSlots->SaveMarkerSetup(filename,"Markersetup");
00994     }
00995     delete fd;
00996 }
00997 
00998 void TGo4ViewPanel::LoadMarkers()
00999 {
01000     QFileDialog* fd = new QFileDialog( this, "Load Markers", TRUE );
01001     fd->setCaption("Load Marker setup from:");
01002     fd->setMode( QFileDialog::ExistingFile );
01003     fd->setName( "Load from file: ");
01004     fd->setFilter( "ROOT file (*.root)");
01005     if ( fd->exec() == QDialog::Accepted ) {
01006         QString filename = fd->selectedFile();
01007 //        fxTGo4PreviewPanelSlots->LoadMarkerSetup(filename,"Markersetup");
01008     }
01009     delete fd;
01010 }
01011 
01012 
01013 void TGo4ViewPanel::SetActivePad(TPad* pad)
01014 {
01015    TGo4LockGuard lock;
01016 
01017    if (ActivePad!=pad)
01018      CompleteMarkerEdit(ActivePad);
01019 
01020    if (pad==0) {
01021       GetCanvas()->SetSelected(0);
01022       GetCanvas()->SetSelectedPad(0);
01023       GetCanvas()->Update();
01024       return;
01025    }
01026 
01027    ActivePad = pad;
01028    ActivePad->cd();
01029    GetCanvas()->SetSelectedPad(ActivePad);
01030 
01031    TGo4WorkSpace::Instance()->SetSelectedPad(ActivePad);
01032 
01033    BlockPanelRedraw(true);
01034    ActivePad->Update();
01035    BlockPanelRedraw(false);
01036 
01037    DisplayPadStatus(ActivePad);
01038 
01039    UpdatePanelCaption();
01040    CallPanelFunc(panel_Activated, ActivePad);
01041 }
01042 
01043 void TGo4ViewPanel::PadClickedSlot(TPad* pad)
01044 {
01045    TGo4LockGuard lock;
01046 
01047    SetActivePad(pad);
01048 
01049    if (pad==0) return;
01050 
01051    Int_t px = pad->GetEventX();
01052    Int_t py = pad->GetEventY();
01053    Double_t x = pad->PadtoX(pad->AbsPixeltoX(px));
01054    Double_t y = pad->PadtoY(pad->AbsPixeltoY(py));
01055    bool docreate = GetSelectedMarkerName(pad).length()==0;
01056    bool docheck = false;
01057 
01058 //   cout << "PadClickedSlot( px = " << px << " py = " << py << endl;
01059 
01060    switch(fiMouseMode) {
01061      case kMouseROOT: {
01062         TObject *obj = GetCanvas()->GetSelected();
01063 //        if (obj!=0)
01064 //           cout << "  obj = " << obj->GetName()
01065 //                << "  class = " << obj->ClassName() << endl;
01066 
01067         if (obj!=0)
01068         if (obj->InheritsFrom(TGo4Marker::Class()) ||
01069             obj->InheritsFrom(TGo4WinCondView::Class()) ||
01070             obj->InheritsFrom(TGo4PolyCondView::Class()))
01071               SetSelectedMarkerByMouseClick(pad, obj->GetName());
01072 
01073         break;
01074      }
01075 
01076 
01077      case kMousePickCursor: {
01078        // we have a click on our working pad, get coordinates:
01079        gROOT->SetEditorMode("");
01080 
01081        if(docreate) {
01082           TGo4Marker* mark = new TGo4Marker(x,y,28);
01083           AddMarkerObj(pad, kind_Marker, mark);
01084           Int_t ix = TGo4Marker::GetInstances()-1;
01085           mark->SetMarkerColor((ix)%6 +2);
01086           mark->SetHistogram(GetPadHistogram(pad));
01087           if (!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
01088         } else {
01089           TGo4Marker* mark = dynamic_cast<TGo4Marker*> (GetActiveObj(pad, kind_Marker));
01090           if(mark!=0) {
01091              mark->SetX(x);
01092              mark->SetY(y);
01093           }
01094           if (!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
01095         }
01096 
01097         RedrawPanel(pad, true);
01098         break;
01099      }
01100 
01101      case kMousePickLimits: {
01102         gROOT->SetEditorMode("");
01103         TGo4WinCond* conny = 0;
01104         Double_t xmin(x), xmax(x), ymin(y), ymax(y);
01105         if(fiPickCounter==0) {
01106            // pick the first time after enabling limits record:
01107            if(docreate) {
01108               TH1* hist = GetPadHistogram(pad);
01109               bool fbTwoDimRegion=(hist!=0) && (hist->GetDimension()>1);
01110               int ix = GetNumMarkers(pad, kind_Window);
01111               QString name = "Region " + QString::number(ix+1);
01112               conny = new TGo4WinCond(name.latin1());
01113               if(fbTwoDimRegion)
01114                  conny->SetValues(0,0,0,0);
01115               else
01116                  conny->SetValues(0,0);
01117               conny->SetLineColor(ix%6 +2);
01118               conny->SetFillColor(ix%6 +2);
01119               conny->SetFillStyle(3002);
01120               conny->SetWorkHistogram(hist);
01121               // adjust two dim region to one dim defaults
01122               conny->SetYRMSDraw(fbTwoDimRegion  && conny->IsXRMSDraw());
01123               conny->SetYMeanDraw(fbTwoDimRegion && conny->IsXMeanDraw());
01124               conny->SetYMaxDraw(fbTwoDimRegion && conny->IsXMaxDraw());
01125               AddMarkerObj(pad, kind_Window, conny);
01126            } else
01127               conny = dynamic_cast<TGo4WinCond*> (GetActiveObj(pad, kind_Window));
01128 //           cout << "Start wincond = " << (conny ? conny->GetName() : "null") << endl;
01129            if(conny==0) return;
01130            fiPickCounter++;
01131         } else
01132         if (fiPickCounter==1) {
01133            conny = dynamic_cast<TGo4WinCond*> (GetActiveObj(pad, kind_Window));
01134 //           cout << "Stop wincond = " << (conny ? conny->GetName() : "null") << endl;
01135            if(conny==0) return;
01136            xmin = conny->GetXLow();
01137            ymin = conny->GetYLow();
01138            fiPickCounter=0;
01139            if(!fbPickAgain)  fiMouseMode=kMouseROOT;
01140            docheck = true;
01141         } else {
01142            cout <<"TGo4ViewPanel:MouseClick() NEVER COME HERE" << endl;
01143            return;
01144         }
01145         // do not change original condition dimension
01146         if(conny->GetDimension()>1)
01147            conny->SetValues(xmin,xmax,ymin,ymax);
01148         else
01149            conny->SetValues(xmin, xmax);
01150 
01151 //        cout << "XUP = " << conny->GetXUp() << endl;
01152 //        cout << "YUP = " << conny->GetYUp() << endl;
01153 
01154         TGo4Slot* condslot = GetSelectedSlot(pad, 0, 0);
01155         if (GetDrawKind(condslot)==kind_Condition) {
01156            TGo4Condition* maincond = dynamic_cast<TGo4Condition*> (condslot->GetAssignedObject());
01157            if (maincond!=0) maincond->SetChanged(kTRUE);
01158         }
01159 
01160         conny->SetChanged(kTRUE);
01161 
01162         RedrawPanel(pad, true);
01163         break;
01164      }
01165 
01166      case kMousePickPolygon: {
01167         gROOT->SetEditorMode("");
01168         TGo4PolyCond* cond = 0;
01169 
01170         if(fiPickCounter==0) {
01171            // pick the first time after enabling limits record:
01172            if(docreate) {
01173               TH1* hist = GetPadHistogram(pad);
01174               int ix = GetNumMarkers(pad, kind_Poly);
01175               QString name = "Polygon " + QString::number(ix+1);
01176               cond = new TGo4PolyCond(name.latin1());
01177               AddMarkerObj(pad, kind_Poly, cond);
01178               cond->SetWorkHistogram(hist);
01179            } else {
01180               cond = dynamic_cast<TGo4PolyCond*> (GetActiveObj(pad, kind_Poly));
01181               // start region from the beginning
01182               if (cond!=0) {
01183                  TCutG* cut = cond->GetCut(kTRUE);
01184                  delete cut;
01185               }
01186            }
01187            if(cond==0) return;
01188            fiPickCounter++;
01189         } else {
01190            cond = dynamic_cast<TGo4PolyCond*> (GetActiveObj(pad, kind_Poly));
01191            if(cond==0) return;
01192            fiPickCounter++;
01193         }
01194 
01195         if (cond!=0) {
01196            TCutG* cut = cond->GetCut(kFALSE);
01197 
01198            // this insert point in last mouse position
01199            if (cut==0) {
01200               cut = new TCutG(TGo4PolyCond::NextAvailableName(), 1);
01201               cut->SetPoint(0, x, y);
01202               cond->SetValuesDirect(cut);
01203            } else {
01204               cut->InsertPoint();
01205            }
01206 
01207            cond->SetChanged(kTRUE);
01208 
01209            int ix = GetNumMarkers(pad, kind_Poly);
01210 
01211            cond->SetLineColor(ix%6 +2);
01212            cond->SetFillColor(ix%6 +2);
01213            cond->SetFillStyle(3002);
01214         }
01215 
01216         // mark condition
01217         TGo4Slot* condslot = GetSelectedSlot(pad, 0, 0);
01218         if (GetDrawKind(condslot)==kind_Condition) {
01219            TGo4Condition* maincond = dynamic_cast<TGo4Condition*> (condslot->GetAssignedObject());
01220            if (maincond!=0) maincond->SetChanged(kTRUE);
01221         }
01222 
01223         RedrawPanel(pad, true);
01224         break;
01225      }
01226 
01227      case kMousePickLatex: {
01228         gROOT->SetEditorMode("");
01229         if(docreate) {
01230            int ix = GetNumMarkers(pad, kind_Latex);
01231            QString name = QString("Label ") + QString::number(ix+1);
01232            bool ok;
01233            QString txt = QInputDialog::getText("Enter new LaTeX label text:",
01234                          name, QLineEdit::Normal, QString::null, &ok);
01235            if (ok && (txt.length()>0)) {
01236               TLatex* latex = new TLatex(x,y, name.latin1());
01237               latex->SetName(name.latin1());
01238               latex->SetTitle(txt.latin1());
01239               AddMarkerObj(pad, kind_Latex, latex);
01240            } else {
01241               fiMouseMode=kMouseROOT;
01242            }
01243         } else {
01244            TLatex* latex = dynamic_cast<TLatex*> (GetActiveObj(pad, kind_Latex));
01245            if(latex!=0) {
01246               latex->SetX(x);
01247               latex->SetY(y);
01248            }
01249         }
01250         if(!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
01251         RedrawPanel(pad, true);
01252         break;
01253      }
01254 
01255      case kMouseDraw: {
01256         gROOT->SetEditorMode("");
01257         if(fiPickCounter==0) {
01258            // pick the first time after enabling limits record:
01259            TArrow* arrow = new TArrow(x,y,x,y);
01260            AddMarkerObj(pad, kind_Arrow, arrow);
01261            fiPickCounter++;
01262         } else
01263         if (fiPickCounter==1) {
01264            TArrow* arrow = dynamic_cast<TArrow*> (GetActiveObj(pad, kind_Arrow));
01265            if(arrow!=0) {
01266               arrow->SetX2(x);
01267               arrow->SetY2(y);
01268            }
01269            if(!fbPickAgain) fiMouseMode=kMouseROOT; // reset pick
01270            fiPickCounter=0;
01271         } else {
01272            cout <<"TGo4ViewPanel:MouseClick() NEVER COME HERE" << endl;
01273            return;
01274         }
01275         // do not change original condition dimension
01276         RedrawPanel(pad, true);
01277         break;
01278      }
01279    }
01280 
01281    if (docheck) CheckActionAtTheEnd(pad);
01282 }
01283 
01284 void TGo4ViewPanel::CheckActionAtTheEnd(TPad* pad)
01285 {
01286    bool goback = true;
01287 
01288 // uncomment this code to have loop mode for array of conditions
01289 
01290 //   if(fbPickAgain) {
01291 //      QString selname = GetSelectedMarkerName(pad);
01292 //      int selindex = GetSelectedMarkerIndex(pad);
01293 //      if (selindex>=0) {
01294 //         TGo4Slot* slot = GetSelectedSlot(pad, 0, 0);
01295 //         TGo4CondArray* arr = 0;
01296 //         if (slot!=0)
01297 //           arr = dynamic_cast<TGo4CondArray*> (slot->GetAssignedObject());
01298 //         if (arr!=0) {
01299 //           if (selindex<arr->GetNumber()-1) {
01300 //              SetSelectedMarker(pad, selname, selindex+1);
01301 //              goback = false;
01302 //           }
01303 //           else
01304 //             SetSelectedMarker(pad, "", -1);
01305 //         }
01306 //      }
01307 //   }
01308    if (goback) {
01309       if (fbLeaveFocusAfterCondEnd)
01310          ServiceCall("ActivateConditionEditor");
01311       fbLeaveFocusAfterCondEnd = false;
01312 //      MarkPadModified(pad);
01313 //      ShootRepaintTimer(pad);
01314    }
01315 }
01316 
01317 bool TGo4ViewPanel::CompleteMarkerEdit(TPad* pad)
01318 {
01319    bool res = false;
01320    bool needredraw = false;
01321    bool needrefresh = false;
01322    bool docheck = false;
01323    bool candelete = !IsConditionSelected(pad);
01324 
01325    switch(fiMouseMode) {
01326      case kMousePickLimits: {
01327         if (fiPickCounter>0) {
01328            TGo4WinCond* cond = dynamic_cast<TGo4WinCond*> (GetActiveObj(pad, kind_Window));
01329            if (cond!=0) {
01330               if (candelete) DeleteDrawObject(pad, cond);
01331               needredraw = true;
01332            }
01333            fiPickCounter = 0;
01334            if(!fbPickAgain) fiMouseMode=kMouseROOT;
01335            docheck = true;
01336         }
01337 
01338         res = true;
01339         break;
01340      }
01341 
01342      case kMousePickPolygon: {
01343        if (fiPickCounter>0) {
01344          TGo4PolyCond* cond = dynamic_cast<TGo4PolyCond*> (GetActiveObj(pad, kind_Poly));
01345          if (cond!=0) {
01346             bool delcond = true;
01347             TCutG* cut = cond->GetCut(kFALSE);
01348             if (cut!=0) {
01349                int n = cut->GetN();
01350                Double_t x, y;
01351                cut->GetPoint(0, x, y);
01352                delcond = (n<3);
01353 
01354                if (n>=3)
01355                   cut->SetPoint(n, x, y);
01356 
01357                int ix = GetNumMarkers(pad, kind_Poly);
01358                cond->SetLineColor(ix%6 +2);
01359                cond->SetFillColor(ix%6 +2);
01360                cond->SetFillStyle(3002);
01361             }
01362 
01363             if (delcond && candelete)
01364               DeleteDrawObject(pad, cond);
01365 
01366             needredraw = true;
01367          }
01368          if(!fbPickAgain) fiMouseMode=kMouseROOT;
01369          fiPickCounter = 0;
01370          docheck = true;
01371        }
01372 
01373        needrefresh = true;
01374        res = true;
01375        break;
01376      }
01377 
01378      case kMouseDraw: {
01379         if (fiPickCounter>0) {
01380            TArrow* arrow = dynamic_cast<TArrow*> (GetActiveObj(pad, kind_Arrow));
01381            if (arrow!=0) {
01382              DeleteDrawObject(pad, arrow);
01383              needredraw = true;
01384            }
01385            fiPickCounter = 0;
01386            if(!fbPickAgain) fiMouseMode=kMouseROOT;
01387         }
01388         res = true;
01389         break;
01390      }
01391    }
01392    if (needredraw) RedrawPanel(pad, true); else
01393    if (needrefresh) RefreshButtons();
01394 
01395    if (docheck) CheckActionAtTheEnd(pad);
01396 
01397    return res;
01398 }
01399 
01400 void TGo4ViewPanel::PadDoubleClickedSlot(TPad* pad)
01401 {
01402    if (CompleteMarkerEdit(pad)) return;
01403 
01404    if (GetNumberOfPads(GetCanvas())<=1) return;
01405 
01406    if (fxDoubleClickTimerPad!=0) return;
01407    fxDoubleClickTimerPad = pad;
01408    QTimer::singleShot(100, this, SLOT(ProcessPadDoubleClick()));
01409 }
01410 
01411 void TGo4ViewPanel::CanvasDropEventSlot(QDropEvent* event, TPad* pad)
01412 {
01413    emit widgetService(this, service_DropEvent, (const char*) pad, event);
01414 }
01415 
01416 void TGo4ViewPanel::CanvasStatusEventSlot(const char* message)
01417 {
01418    if (CanvasStatus!=0)
01419      CanvasStatus->message(message);
01420 }
01421 
01422 void TGo4ViewPanel::ProcessPadDoubleClick()
01423 {
01424    if (fxDoubleClickTimerPad==0) return;
01425 
01426    TGo4Picture pic;
01427    MakePictureForPad(&pic, fxDoubleClickTimerPad, true);
01428    fxDoubleClickTimerPad = 0;
01429 
01430    if (pic.GetNumObjNames()==0) return;
01431 
01432    TGo4ViewPanel* newpanel = CreateViewPanel();
01433    newpanel->ProcessPictureRedraw("", newpanel->GetCanvas(), &pic);
01434    newpanel->ShootRepaintTimer();
01435 }
01436 
01437 void TGo4ViewPanel::MenuCommandExecutedSlot(TObject* obj, const char* cmdname)
01438 {
01439    TPad* pad = dynamic_cast<TPad*> (obj);
01440    if (pad!=0)
01441       UpdatePadStatus(pad, true);
01442 
01443    Browser()->Scan_gROOT();
01444 }
01445 
01446 void TGo4ViewPanel::DoCanvasResizeSlot()
01447 {
01448    ResizeGedEditor();
01449 }
01450 
01451 void TGo4ViewPanel::SaveCanvas()
01452 {
01453    ServiceCall("SavePanelCanvas");
01454 }
01455 
01456 void TGo4ViewPanel::ProduceGraphFromMarkers()
01457 {
01458    // get list of markers here
01459    TObjArray markers;
01460    CollectSpecialObjects(GetActivePad(), &markers, kind_Marker);
01461    Int_t npts=markers.GetEntries();
01462    //cout <<"Found "<<npts<<" markers in pad" <<endl; 
01463    if(npts==0) return;
01464    // create arrays of length 
01465    Double_t x[npts];
01466    Double_t y[npts];
01467    // copy marker values to array:
01468    for(Int_t j=0;j<npts;++j)
01469     {
01470         TGo4Marker* mark=dynamic_cast<TGo4Marker*>(markers[j]);
01471         if(mark==0)
01472             {
01473                 cout <<"NEVER COME HERE: no marker at index "<<j << endl;   
01474                 return;
01475             }
01476         x[j]=mark->GetX();
01477         y[j]=mark->GetY();
01478         //cout <<"Set point "<<j <<" to x="<<x[j]<<", y="<<y[j]<<endl;    
01479     }
01480    
01481    // create graph from points array: 
01482    TString grname=GetPanelName()+TString("-Markergraph");
01483    TGraph* graf = new TGraph(npts,x,y);
01484    graf->SetName(grname.Data());
01485    graf->SetMarkerStyle(28);   
01486    SaveObjectInMemory("", graf);
01487 }
01488 
01489 
01490 void TGo4ViewPanel::ProducePicture()
01491 {
01492    TGo4Picture* pic = new TGo4Picture(GetPanelName(), "Copy of picture");
01493 
01494    MakePictureForPad(pic, GetCanvas(), false);
01495 
01496    SaveObjectInMemory("", pic);
01497 }
01498 
01499 void TGo4ViewPanel::MakePictureForPad(TGo4Picture* pic, TPad* pad, bool useitemname)
01500 {
01501    TGo4Picture* padopt = GetPadOptions(pad);
01502    TGo4Slot* slot = GetPadSlot(pad);
01503    if ((padopt==0) || (slot==0)) return;
01504 
01505    pic->CopyOptionsFrom(padopt);
01506    
01507    int objnamenum = 0;
01508 
01509    for(int n=0;n<slot->NumChilds();n++) {
01510        
01511       TGo4Slot* subslot = slot->GetChild(n);
01512       int kind = GetDrawKind(subslot);
01513 
01514       if ((kind==kind_Arrow) || (kind==kind_Latex) ||
01515           (kind==kind_Marker) || (kind==kind_Window) ||
01516           (kind==kind_Poly) || (kind==kind_Specials)) {
01517          TObject* obj = subslot->GetAssignedObject();
01518          const char* drawopt = GetSpecialDrawOption(subslot);
01519          if (obj!=0) {
01520             obj = obj->Clone();
01521             TGo4Marker* mark = dynamic_cast<TGo4Marker*> (obj);
01522             if (mark!=0) mark->DeletePainter();
01523             TGo4Condition* cond = dynamic_cast<TGo4Condition*> (obj);
01524             if (cond!=0) cond->DeletePainter();
01525             pic->AddSpecialObject(obj, drawopt);
01526          }
01527          continue;
01528       }
01529 
01530       if ((kind!=kind_Link) && (kind!=kind_Condition)) continue;
01531       
01532       const char* drawopt = padopt->GetDrawOption(objnamenum++);
01533 
01534       if (useitemname) {
01535          const char* itemname = GetLinkedName(subslot);
01536          if (itemname!=0) pic->AddObjName(itemname, drawopt);
01537       } else {
01538          TNamed* nm = dynamic_cast<TNamed*> (subslot->GetAssignedObject());
01539          if (nm!=0) pic->AddObjName(nm->GetName(), drawopt);
01540       }
01541 
01542       Int_t rebinx, rebiny;
01543       if (subslot->GetIntPar("::HasRebinX", rebinx))
01544          pic->SetRebinX(rebinx);
01545       if (subslot->GetIntPar("::HasRebinY", rebiny))
01546          pic->SetRebinY(rebiny);
01547    }
01548 
01549    TObjArray pads;
01550 
01551    for (int n=0;n<slot->NumChilds();n++) {
01552       TGo4Slot* subslot = slot->GetChild(n);
01553       TPad* subpad = GetSlotPad(subslot);
01554       if (subpad!=0)
01555         pads.Add(subpad);
01556    }
01557 
01558    if (pads.GetLast()<0) return;
01559 
01560    double lastx = -1;
01561    int xcnt = 0, sizex = 1, sizey = 1;
01562    for (int n=0;n<=pads.GetLast();n++) {
01563       TPad* subpad = (TPad*) pads.At(n);
01564       double mitx = subpad->GetXlowNDC()+subpad->GetWNDC()/2.;
01565       if (mitx>lastx) { xcnt++; lastx = mitx; }
01566                  else { xcnt = 0; lastx = -1; }
01567       if (xcnt>sizex) sizex = xcnt;
01568    }
01569 
01570    while (sizex*sizey<=pads.GetLast()) sizey++;
01571 
01572    pic->SetDivision(sizey, sizex);
01573 
01574    for(int ny=0;ny<sizey;ny++)
01575      for(int nx=0;nx<sizex;nx++) {
01576         int indx = ny*sizex + nx;
01577         if (indx>pads.GetLast()) break;
01578         TPad* subpad = (TPad*) pads.At(indx);
01579         MakePictureForPad(pic->Pic(ny,nx), subpad, useitemname);
01580      }
01581 }
01582 
01583 void TGo4ViewPanel::PrintCanvas()
01584 {
01585    TGo4PrintWidget dlg;
01586    if (dlg.exec() != QDialog::Accepted) return;
01587 
01588    go4sett->setPrinterSett(dlg.GetPrinter(), dlg.GetPrintProg());
01589 
01590    QString outfile = "~/go4printout.ps";
01591    QString PrnCmd = dlg.GetPrintProg() +
01592                     " -P " + dlg.GetPrinter() +
01593                     " " + outfile;
01594    QString DelCmd = QString("rm -f ") + outfile;
01595 
01596    GetCanvas()->Print(outfile.latin1());
01597    gSystem->Exec(PrnCmd.latin1());
01598    gSystem->Exec(DelCmd.latin1());
01599 }
01600 
01601 void TGo4ViewPanel::StartRootEditor()
01602 {
01603    TGo4LockGuard lock;
01604 
01605    fbEditorFrameVisible = !fMenuBar->isItemChecked(ShowRootEditorId);
01606    fMenuBar->setItemChecked(ShowRootEditorId, fbEditorFrameVisible);
01607    EditorFrame->setShown(fbEditorFrameVisible);
01608 
01609    if(fbEditorFrameVisible && (fxPeditor==0)) {
01610       SetActivePad(GetCanvas());
01611       fxRooteditor->SetEditable();      // mainframe will adopt pad editor window
01612       fxPeditor = TVirtualPadEditor::LoadEditor();
01613       fxRooteditor->SetEditable(kFALSE); // back to window manager as root window
01614    }
01615 
01616    ActivateInGedEditor(GetSelectedObject(GetActivePad(), 0));
01617 
01618    show();
01619 
01620    if (fbEditorFrameVisible)
01621      QTimer::singleShot(100, this, SLOT(ResizeGedEditorSlot()));
01622 }
01623 
01624 void TGo4ViewPanel::StartConditionEditor()
01625 {
01626    TGo4Slot* padslot = GetPadSlot(GetActivePad());
01627    if (padslot==0) return;
01628 
01629    for (int n=0; n<padslot->NumChilds();n++) {
01630       TGo4Slot* subslot = padslot->GetChild(n);
01631       int drawkind = GetDrawKind(subslot);
01632       if (drawkind!=kind_Condition) continue;
01633       const char* itemname = GetLinkedName(subslot);
01634       if (itemname!=0) {
01635          EditItem(itemname);
01636          return;
01637       }
01638    }
01639 }
01640 
01641 void TGo4ViewPanel::RectangularRatio()
01642 {
01643    TPad *pad = GetActivePad();
01644    if (pad==0) return;
01645 
01646    double dx = fabs(pad->AbsPixeltoX(1) - pad->AbsPixeltoX(0));
01647    double dy = fabs(pad->AbsPixeltoY(1) - pad->AbsPixeltoY(0));
01648 
01649    if ((dx<=0) || (dy<=0)) return;
01650 
01651    double ratio = dx / dy;
01652 
01653    if (ratio<1.) {
01654      double left = pad->GetLeftMargin();
01655      double right = pad->GetRightMargin();
01656      double change = (1.-left-right)*(1-ratio);
01657      pad->SetLeftMargin(left+change/2.);
01658      pad->SetRightMargin(right+change/2.);
01659    } else {
01660      double bottom = pad->GetBottomMargin();
01661      double top = pad->GetTopMargin();
01662      double change = (1.-bottom-top)*(1.-1/ratio);
01663      pad->SetTopMargin(top + change/2.);
01664      pad->SetBottomMargin(bottom + change/2.);
01665    }
01666 
01667    RedrawPanel(pad, true);
01668 }
01669 
01670 void TGo4ViewPanel::DefaultPadMargin()
01671 {
01672    TPad *pad = GetActivePad();
01673    if (pad==0) return;
01674 
01675    pad->SetLeftMargin(gStyle->GetPadLeftMargin());
01676    pad->SetRightMargin(gStyle->GetPadRightMargin());
01677    pad->SetTopMargin(gStyle->GetPadTopMargin());
01678    pad->SetBottomMargin(gStyle->GetPadBottomMargin());
01679 
01680    RedrawPanel(pad, true);
01681 }
01682 
01683 void TGo4ViewPanel::ClearActivePad()
01684 {
01685    TPad* pad = GetActivePad();
01686    if (pad==0) pad = GetCanvas();
01687 
01688    ClearPad(pad, true, false);
01689 
01690    RedrawPanel(pad, true);
01691 }
01692 
01693 void TGo4ViewPanel::ClearCanvas()
01694 {
01695    // TGo4LockGuard glob;
01696 
01697    ClearPad(GetCanvas(), true, true);
01698 
01699    SetPadDefaults(GetCanvas());
01700 
01701    RedrawPanel(GetCanvas(), true);
01702 }
01703 
01704 
01705 void TGo4ViewPanel::AboutToShowOptionsMenu()
01706 {
01707    TPad* pad = GetActivePad();
01708    if (pad==0) pad = GetCanvas();
01709 
01710    TGo4Picture *padopt = GetPadOptions(pad);
01711 
01712    fMenuBar->setItemChecked(StatisticsId, padopt->IsHisStats());
01713    fMenuBar->setItemChecked(SuperimposeId, padopt->IsSuperimpose());
01714    fMenuBar->setItemChecked(SetTitleId, padopt->IsHisTitle());
01715    fMenuBar->setItemChecked(DrawTimeId, padopt->IsTitleTime());
01716    fMenuBar->setItemEnabled(DrawTimeId, padopt->IsHisTitle() && fbCloneFlag);
01717    fMenuBar->setItemChecked(DrawDateId, padopt->IsTitleDate());
01718    fMenuBar->setItemEnabled(DrawDateId, padopt->IsHisTitle() && fbCloneFlag);
01719    fMenuBar->setItemChecked(DrawItemnameId, padopt->IsTitleItem());
01720    fMenuBar->setItemEnabled(DrawItemnameId, padopt->IsHisTitle() && fbCloneFlag);
01721 
01722    fMenuBar->setItemChecked(FreezeTitleId, fbFreezeTitle);
01723 
01724    fMenuBar->setItemChecked(CrosshairId, fbCanvasCrosshair);
01725    fMenuBar->setItemChecked(SetLegendId, padopt->IsLegendDraw());
01726 }
01727 
01728 void TGo4ViewPanel::SelectMenuItemActivated(int id)
01729 {
01730    TGo4LockGuard lock;
01731 
01732    if (id==BringToFrontId) {
01733       if (ShiftSelectedObjectToEnd(GetActivePad())) {
01734          MarkPadModified(GetActivePad());
01735          ShootRepaintTimer(GetActivePad());
01736       }
01737       return;
01738    }
01739 
01740    int selected = TGo4Picture::PictureIndex;
01741 
01742    if (id!=MasterSelectId) selected = id - FirstSelectId;
01743 
01744    TGo4Slot* slot = GetPadSlot(GetActivePad());
01745    if (slot==0) return;
01746 
01747    int wasselected = GetSelectedObjectIndex(slot);
01748 
01749    SetSelectedObjectIndex(slot, selected);
01750 
01751    if (selected!=wasselected) {
01752       CallPanelFunc(panel_Updated, GetActivePad());
01753       UpdatePanelCaption();
01754    }
01755 
01756    if (selected!=TGo4Picture::PictureIndex)
01757       ActivateInGedEditor(GetSelectedObject(GetActivePad(), 0));
01758 }
01759 
01760 void TGo4ViewPanel::ShowEventStatus()
01761 {
01762    // TGo4LockGuard glob;
01763    bool s = !fMenuBar->isItemChecked(EventStatusId);
01764    fMenuBar->setItemChecked(EventStatusId, s);
01765    fbCanvasEventstatus = s;
01766    fxGo4QRootCanvas->setShowEventStatus(s);
01767    CanvasStatus->setShown(s);
01768    if(!s) DisplayPadStatus(ActivePad);
01769 }
01770 
01771 void TGo4ViewPanel::UpdatePadStatus(TPad* pad, bool removeitems)
01772 {
01773    if (GetPadSlot(pad)==0) return;
01774 
01775    BlockPanelRedraw(true);
01776    ProcessPadStatusUpdate(pad, 0, removeitems);
01777    BlockPanelRedraw(false);
01778 }
01779 
01780 void TGo4ViewPanel::ProcessPadStatusUpdate(TPad* pad, TGo4Slot* parent, bool removeitems)
01781 {
01782    if (pad==0) return;
01783 
01784    TGo4Slot* slot = 0;
01785 
01786    bool setdefaults = false;
01787    if (parent==0) {
01788       slot = GetPadSlot(pad);
01789       if (slot==0) return;
01790    } else {
01791       slot = parent->FindChild(pad->GetName());
01792       // create slot for subpad if not existing
01793       if (slot==0) {
01794          slot = AddNewSlot(pad->GetName(), parent);
01795          SetDrawKind(slot, kind_PadSlot);
01796          setdefaults = true;
01797       }
01798    }
01799 
01800    SetSlotPad(slot, pad);
01801 
01802    TGo4Picture* padopt = GetPadOptions(slot);
01803 
01804    padopt->SetPadModified();
01805 
01806    bool issubpads = false;
01807 
01808    bool isdupluicate = false;
01809 
01810    // check if pads with duplicate names appears in list.
01811    // Remove first copies. Can appiar by RMB menu Divide call
01812    do {
01813      TObjArray subpads;
01814      isdupluicate = false;
01815      TIter iter(pad->GetListOfPrimitives());
01816      TObject* obj = 0;
01817      while ((obj = iter()) != 0) {
01818         TPad* subpad = dynamic_cast<TPad*> (obj);
01819         if (subpad==0) continue;
01820         issubpads = true;
01821         if (subpads.FindObject(subpad->GetName())!=0)
01822            isdupluicate = true;
01823         if (!isdupluicate)
01824            subpads.Add(subpad);
01825      }
01826      if (isdupluicate) {
01827         pad->GetListOfPrimitives()->RemoveAll(&subpads);
01828         subpads.Delete();
01829         subpads.Compress();
01830         padopt->SetPadModified();
01831      }
01832 
01833    } while (isdupluicate);
01834 
01835 
01836    // remove all subslots, which are correspond to non-existing subpads
01837    for(int n =slot->NumChilds()-1; n>=0; n--) {
01838       TGo4Slot* subslot = slot->GetChild(n);
01839       TPad* subpad = GetSlotPad(subslot);
01840       if (subpad!=0)
01841          if (pad->GetListOfPrimitives()->FindObject(subpad) == 0)
01842             delete subslot;
01843          else
01844            issubpads = true;
01845    }
01846 
01847    if (setdefaults) SetPadDefaults(pad);
01848 
01849    if (!issubpads) return;
01850 
01851    TIter iter(pad->GetListOfPrimitives());
01852    TObjArray removedItems;
01853    TObject* obj = 0;
01854    while ((obj = iter()) != 0) {
01855       TPad* subpad = dynamic_cast<TPad*> (obj);
01856       if (subpad!=0)
01857          ProcessPadStatusUpdate(subpad, slot, removeitems);
01858       else
01859          removedItems.Add(obj);
01860    }
01861 
01862    pad->GetListOfPrimitives()->RemoveAll(&removedItems);
01863 
01864    if (removeitems)
01865      ClearPadItems(slot, 0);
01866 }
01867 
01868 TGo4Slot* TGo4ViewPanel::AddDrawObject(TPad* pad, int kind, const char* itemname, TObject* obj, bool owner, const char* drawopt)
01869 {
01870    TGo4Slot* padslot = GetPadSlot(pad);
01871 
01872    if (padslot==0) {
01873       if (owner) delete obj;
01874       return 0;
01875    }
01876 
01877    // clear only if link is added
01878    if (kind<100)
01879      ClearPad(pad, false, true);
01880 
01881    TGo4Slot* tgtslot = 0;
01882 
01883    if (kind==kind_Link) {
01884       TClass* cl = Browser()->ItemClass(itemname);
01885       if ((cl!=0) && cl->InheritsFrom(TGo4Condition::Class()))
01886         UndrawItem(itemname);
01887 //        if (WhereItemDrawn(itemname)!=0) return 0;
01888 
01889 //      tgtslot = AddLink(itemname, padslot);
01890      TGo4Slot* brslot = Browser()->BrowserSlot(itemname);
01891 
01892      if (brslot!=0) {
01893         tgtslot = AddNewSlot(brslot->GetName(), padslot);
01894         SetLinkedName(tgtslot, itemname);
01895         if (fbCloneFlag)
01896           tgtslot->SetProxy(new TGo4DrawCloneProxy(brslot, this));
01897         else
01898           tgtslot->SetProxy(new TGo4LinkProxy(brslot));
01899      }
01900    } else {
01901       QString newslotname = itemname;
01902       if ((newslotname.length()==0) || (padslot->FindChild(newslotname.latin1())!=0)) {
01903          int cnt = 0;
01904          do {
01905            if ((itemname==0) || (*itemname==0))
01906               newslotname = "::SpecialObject_";
01907            else
01908               newslotname = itemname;
01909            newslotname += QString::number(cnt++);
01910          } while (padslot->FindChild(newslotname.latin1())!=0);
01911       }
01912       tgtslot = AddNewSlot(newslotname.latin1(), padslot);
01913       tgtslot->SetProxy(new TGo4ObjectProxy(obj, owner));
01914    }
01915    if (tgtslot==0) return 0;
01916 
01917    if (kind<100)
01918      CallPanelFunc(panel_Modified, pad);
01919 
01920    SetDrawKind(tgtslot, kind);
01921    SetSpecialDrawOption(tgtslot, drawopt);
01922 
01923    TGo4Picture* padopt = GetPadOptions(padslot);
01924    if (padopt!=0) {
01925       padopt->SetContentModified(true);
01926       padopt->SetPadModified();
01927       if ((kind<100) && (drawopt!=0))
01928          padopt->SetDrawOption(drawopt, TGo4Picture::PictureIndex);
01929    }
01930 
01931    return tgtslot;
01932 }
01933 
01934 TGo4Slot* TGo4ViewPanel::GetDrawObjectSlot(TPad* pad, const char* name)
01935 {
01936    TGo4Slot* slot = GetPadSlot(pad);
01937 
01938    return slot==0 ? 0 : slot->FindChild(name);
01939 }
01940 
01941 TObject* TGo4ViewPanel::GetDrawObject(TPad* pad, const char* name)
01942 {
01943    TGo4Slot* subslot = GetDrawObjectSlot(pad, name);
01944 
01945    return subslot==0 ? 0 : subslot->GetAssignedObject();
01946 }
01947 
01948 void TGo4ViewPanel::DeleteDrawObject(TPad* pad, const char* name)
01949 {
01950    TGo4Slot* padslot = GetPadSlot(pad);
01951 
01952    TGo4Slot* subslot = padslot==0 ? 0 : padslot->FindChild(name);
01953 
01954    if (subslot!=0) {
01955       delete subslot;
01956       TGo4Picture* padopt = GetPadOptions(padslot);
01957       if (padopt!=0) padopt->SetPadModified();
01958    }
01959 }
01960 
01961 void TGo4ViewPanel::DeleteDrawObject(TPad* pad, TObject* obj)
01962 {
01963    TGo4Slot* padslot = GetPadSlot(pad);
01964    if (padslot==0) return;
01965    for(int n=0;n<padslot->NumChilds();n++) {
01966       TGo4Slot* subslot = padslot->GetChild(n);
01967       if (GetDrawKind(subslot)<0) continue;
01968       if (subslot->GetAssignedObject()==obj) {
01969          delete subslot;
01970          break;
01971       }
01972    }
01973 }
01974 
01975 void TGo4ViewPanel::CollectSpecialObjects(TPad* pad, TObjArray* objs, int selectkind)
01976 {
01977    TGo4Slot* slot = GetPadSlot(pad);
01978    if ((slot==0) || (objs==0)) return;
01979 
01980    for(int n=0;n<slot->NumChilds();n++) {
01981       TGo4Slot* subslot = slot->GetChild(n);
01982       Int_t kind = GetDrawKind(subslot);
01983       if (kind<0) continue;
01984       if ((kind!=kind_Link) && ((selectkind<0) || (kind==selectkind))) {
01985          TObject* obj = subslot->GetAssignedObject();
01986          if (obj!=0) objs->Add(obj);
01987       }
01988    }
01989 }
01990 
01991 bool TGo4ViewPanel::DeleteDrawObjects(TPad* pad, int kindtodelete)
01992 {
01993    TGo4Slot* slot = GetPadSlot(pad);
01994    TGo4Picture* padopt = GetPadOptions(slot);
01995 
01996    if ((slot==0) || (padopt==0)) return false;
01997 
01998    bool res = false;
01999 
02000    for(int n=slot->NumChilds()-1;n>=0;n--) {
02001       TGo4Slot* subslot = slot->GetChild(n);
02002       Int_t kind = GetDrawKind(subslot);
02003       if (kind<0) continue;
02004       if ((kind!=kind_Link) && ((kindtodelete<0) || (kind==kindtodelete))) {
02005          res = true;
02006          delete subslot;
02007       }
02008    }
02009    if (res) padopt->SetPadModified();
02010    return true;
02011 }
02012 
02013 void TGo4ViewPanel::SetPadSuperImpose(TPad* pad, bool on)
02014 {
02015    TGo4Picture* padopt = GetPadOptions(pad);
02016    if (padopt!=0) {
02017       padopt->SetSuperimpose(on);
02018       padopt->SetPadModified();
02019    }
02020 }
02021 
02022 void TGo4ViewPanel::ProcessPadModifiedSignal()
02023 {
02024    fbModifiedSignalFlag = false;
02025    if (GetActivePad()==0) return;
02026 
02027    if (ScanDrawOptions(GetActivePad(), GetPadSlot(GetActivePad()), GetPadOptions(GetActivePad()), true))
02028       CallPanelFunc(panel_Updated, GetActivePad());
02029 }
02030 
02031 bool TGo4ViewPanel::ScanDrawOptions(TPad* pad, TGo4Slot* padslot, TGo4Picture* pic, bool onlyscan)
02032 {
02033    TGo4LockGuard lock;
02034 
02035    if ((pad==0) || (pic==0) || (padslot==0)) return false;
02036 
02037    bool optchanged = false;
02038    TObjLink* link = pad->GetListOfPrimitives()->FirstLink();
02039 
02040    while (link!=0) {
02041       const char* clname = link->GetObject()->ClassName();
02042       if ((strcmp(clname, "TFrame")==0) ||
02043           (strcmp(clname, "TPaveText")==0) ||
02044           (strcmp(clname, "TLegend")==0))
02045         link = link->Next();
02046       else
02047         break;
02048    }
02049 
02050    // take draw options from first drawn object
02051    if (link!=0) {
02052 
02053       TString newopt(link->GetOption());
02054       Int_t drawoptindx = GetSuperimposeSlot(padslot)==0 ? 0 : TGo4Picture::PictureIndex;
02055       TString oldopt(pic->GetDrawOption(drawoptindx));
02056 
02057       while (newopt.BeginsWith(NoStackDrawOption, TString::kIgnoreCase))
02058          newopt.Remove(0, strlen(NoStackDrawOption));
02059 
02060       if (oldopt!="asimage")
02061       if ((newopt.Length()!=oldopt.Length()) ||
02062           (newopt.CompareTo(oldopt, TString::kIgnoreCase)!=0)) {
02063            optchanged = true;
02064            pic->SetDrawOption(newopt.Data(), drawoptindx);
02065          }
02066 
02067       TH1* h1 = dynamic_cast<TH1*> (link->GetObject());
02068       if (h1!=0) {
02069          TPaveStats* stats = dynamic_cast<TPaveStats*>
02070            (h1->GetListOfFunctions()->FindObject("stats"));
02071          if (h1->TestBit(TH1::kNoStats))
02072             pic->SetHisStats(kFALSE);
02073          else {
02074             pic->SetHisStats(kTRUE);
02075             pic->SetStatsAttr(stats);
02076          }
02077       }
02078    }
02079 
02080    if (pad->GetLogx()!=pic->GetLogScale(0)) {
02081       pic->SetLogScale(0, pad->GetLogx());
02082       optchanged = true;
02083    }
02084 
02085    if (pad->GetLogy()!=pic->GetLogScale(1)) {
02086       pic->SetLogScale(1, pad->GetLogy());
02087       optchanged = true;
02088    }
02089 
02090    if (pad->GetLogz()!=pic->GetLogScale(2)) {
02091       pic->SetLogScale(2, pad->GetLogz());
02092       optchanged = true;
02093    }
02094 
02095    if (pad==GetCanvas())
02096      fbCanvasCrosshair = pad->HasCrosshair();
02097 
02098    TObjArray objs, objslots;
02099 
02100    CollectMainDrawObjects(padslot, &objs, &objslots, 0);
02101    ScanObjectsDrawOptions(onlyscan, padslot, &objs, &objslots);
02102 
02103    return optchanged;
02104 }
02105 
02106 void TGo4ViewPanel::ScanObjectsDrawOptions(bool onlyscan, TGo4Slot* padslot, TObjArray* objs, TObjArray* objslots)
02107 {
02108    TGo4Picture* pic = GetPadOptions(padslot);
02109 
02110    TPad* pad = GetSlotPad(padslot);
02111    if ((pad!=0) && (pic!=0))
02112       if (padslot->GetPar("::DrawOptAssigned")!=0) {
02113           pic->SetDrawAttributes(pad, TGo4Picture::PictureIndex);
02114       } else
02115       if (!onlyscan) {
02116          pic->GetDrawAttributes(pad, TGo4Picture::PictureIndex);
02117          padslot->SetPar("::DrawOptAssigned","1");
02118       }
02119 
02120    if ((padslot==0) || (pic==0) || (objs==0) || (objslots==0)) return;
02121 
02122    for(int n=0;n<=objs->GetLast();n++) {
02123       TObject* obj = objs->At(n);
02124       TGo4Slot* subslot = (TGo4Slot*) objslots->At(n);
02125 
02126       if ((obj==0) || (subslot==0)) continue;
02127 
02128       if (subslot->GetPar("::DrawOptAssigned")!=0) {
02129          pic->SetDrawAttributes(obj, n);
02130       } else
02131       if (!onlyscan) {
02132          pic->GetDrawAttributes(obj, n);
02133          subslot->SetPar("::DrawOptAssigned","1");
02134       }
02135    }
02136 }
02137 
02138 void TGo4ViewPanel::CollectMainDrawObjects(TGo4Slot* slot, TObjArray* objs, TObjArray* objslots, int modifier)
02139 {
02140    // modifier == 0 - no objects can be deleted
02141    //          == 1 - objects of same types should be in the list
02142    //          == 2 - only last object survive
02143 
02144    if ((slot==0) || (objs==0)) return;
02145 
02146    TObjArray mainslots;
02147 
02148    int lastobjtype = 0;
02149 
02150    for(int n=0;n<slot->NumChilds();n++) {
02151       TGo4Slot* subslot = slot->GetChild(n);
02152       Int_t kind = GetDrawKind(subslot);
02153 
02154       if ((kind<=0) || (kind>=kind_Additional)) continue;
02155 
02156       TObject* obj = subslot->GetAssignedObject();
02157       if (obj==0) continue;
02158 
02159       int objtype = 0;
02160 
02161       if (obj->InheritsFrom(TH1::Class())) objtype = 1; else
02162       if (obj->InheritsFrom(TGraph::Class())) objtype = 2;
02163 
02164       // can happen condition here, which is add as link and not identified as condition yet
02165       // should bot be recognised as "main" draw object
02166       if (objtype>0) {
02167          lastobjtype = objtype;
02168          mainslots.Add(subslot);
02169       }
02170    }
02171 
02172    Bool_t deletesomething = kFALSE;
02173 
02174    for(int n=0;n<=mainslots.GetLast();n++) {
02175       TGo4Slot* subslot = (TGo4Slot*) mainslots.At(n);
02176       TObject* obj = subslot->GetAssignedObject();
02177       Int_t objtype = 0;
02178       if (obj->InheritsFrom(TH1::Class())) objtype = 1; else
02179       if (obj->InheritsFrom(TGraph::Class())) objtype = 2;
02180 
02181       // check if all main object correspond to type of last object
02182       // if no, delete
02183 
02184       if ((n<mainslots.GetLast()) &&
02185           ((modifier==2) || ((modifier==1) && (lastobjtype!=objtype)))) {
02186          delete subslot;
02187          deletesomething = kTRUE;
02188       } else {
02189          objs->Add(obj);
02190          if (objslots!=0) objslots->Add(subslot);
02191          TGo4DrawCloneProxy* pr = dynamic_cast<TGo4DrawCloneProxy*> (subslot->GetProxy());
02192          if (pr!=0) {
02193             pr->UpdateTitle();
02194             pr->PerformRebin();
02195          }
02196       }
02197    }
02198 
02199    if (deletesomething) CleanupGedEditor();
02200 
02201    for(int n=0;n<slot->NumChilds();n++) {
02202       TGo4Slot* subslot = slot->GetChild(n);
02203 
02204       Int_t kind = GetDrawKind(subslot);
02205       if ((kind>=kind_Additional) && (kind<kind_Specials)) {
02206          TObject* obj = subslot->GetAssignedObject();
02207          if (obj!=0) {
02208             objs->Add(obj);
02209             if (objslots!=0) objslots->Add(subslot);
02210          }
02211       }
02212    }
02213 }
02214 
02215 TObject* TGo4ViewPanel::ProduceSuperimposeObject(TGo4Picture* padopt, TGo4Slot* sislot, TGo4Slot* legslot, TObjArray* objs, TObjArray * objslots, bool showitems)
02216 {
02217    if ((sislot==0) || (objs==0) || (padopt==0)) return 0;
02218 
02219    TObject* oldobj = sislot->GetAssignedObject();
02220 
02221    Bool_t ishstack = kFALSE;
02222    Bool_t isgstack = kFALSE;
02223    Bool_t iserror = kFALSE;
02224    Bool_t resetcolors = kFALSE;
02225 
02226    for(int n=0;n<=objs->GetLast();n++) {
02227       TObject* obj = objs->At(n);
02228       if (obj->InheritsFrom(TH1::Class())) ishstack = kTRUE; else
02229       if (obj->InheritsFrom(TGraph::Class())) isgstack = kTRUE; else
02230         iserror = kTRUE;
02231    }
02232 
02233    // if error, no superimpose is allowed
02234    if (iserror || (ishstack && isgstack)) {
02235        cerr << "Error detected: superimpose of multiple objects with different types" << endl;
02236        return 0;
02237    }
02238 
02239    if (ishstack) {
02240       THStack* hs = dynamic_cast<THStack*> (oldobj);
02241 
02242       if (hs==0) {
02243          hs = new THStack(objs->First()->GetName(), objs->First()->GetTitle());
02244          sislot->SetProxy(new TGo4DrawObjProxy(hs, kTRUE, kTRUE));
02245          resetcolors = kTRUE;
02246       } else {
02247          if (hs->GetHists())
02248             hs->GetHists()->Clear();
02249       }
02250 
02251       for(int n=0;n<=objs->GetLast();n++) {
02252          TH1* histo = (TH1*) objs->At(n);
02253 
02254          Int_t kind = GetDrawKind((TGo4Slot*) objslots->At(n));
02255          if ((resetcolors) || (kind==kind_FitModels))
02256             histo->SetLineColor(n+1);
02257          histo->GetXaxis()->UnZoom();
02258 
02259          const char* drawopt = padopt->GetDrawOption(n);
02260          if (drawopt==0)
02261             drawopt = GetSpecialDrawOption((TGo4Slot*) objslots->At(n));
02262 
02263          hs->Add(histo, drawopt);
02264       }
02265       oldobj = hs;
02266    } else
02267    if (isgstack) {
02268       TMultiGraph* mgr = dynamic_cast<TMultiGraph*> (oldobj);
02269       if (mgr==0) {
02270          mgr = new TMultiGraph(objs->First()->GetName(), objs->First()->GetTitle());
02271          sislot->SetProxy(new TGo4DrawObjProxy(mgr, kTRUE, kTRUE));
02272          resetcolors = kTRUE;
02273       } else
02274       if (mgr->GetListOfGraphs())
02275         mgr->GetListOfGraphs()->Clear();
02276       for(int n=0;n<=objs->GetLast();n++) {
02277          TGraph* gr = (TGraph*) objs->At(n);
02278          Int_t kind = GetDrawKind((TGo4Slot*) objslots->At(n));
02279 
02280          TString drawopt = padopt->GetDrawOption(n);
02281          if (drawopt.Length()==0)
02282             drawopt = GetSpecialDrawOption((TGo4Slot*) objslots->At(n));
02283          if (drawopt.Length()==0) drawopt = "AP";
02284 
02285          if (n>0) {
02286             // suppress multiple drawing of axis for subgraphs
02287             drawopt.ReplaceAll("a","");
02288             drawopt.ReplaceAll("A","");
02289          }
02290 
02291          if ((resetcolors) || (kind==kind_FitModels)) {
02292             gr->SetLineColor(n+1);
02293             gr->SetMarkerColor(n+1);
02294          }
02295          mgr->Add(gr, drawopt.Data());
02296       }
02297       oldobj = mgr;
02298    }
02299 
02300    if ((ishstack || isgstack) && (legslot!=0)) {
02301       TLegend* legend = dynamic_cast<TLegend*> (legslot->GetAssignedObject());
02302 
02303       if (legend == 0) {
02304          legend = new TLegend(0.6,0.91,0.95,0.995);
02305          legend->SetBorderSize(2);
02306          legslot->SetProxy(new TGo4ObjectProxy(legend, kTRUE));
02307       } else
02308         legend->Clear();
02309 
02310       for(int n=0;n<=objs->GetLast();n++) {
02311          TObject* stob = objs->At(n);
02312 
02313          const char* objname = stob->GetName();
02314 
02315          if (showitems && (objslots!=0)) {
02316             const char* itemname = GetLinkedName((TGo4Slot*) objslots->At(n));
02317             if (itemname!=0) objname = itemname;
02318          }
02319 
02320          legend->AddEntry(stob,objname,ishstack ? "l" : "p");
02321       }
02322    }
02323 
02324    return oldobj;
02325 }
02326 
02327 
02328 void TGo4ViewPanel::Divide( int numX, int numY )
02329 {
02330    // remove subpads wil not cleanup labels of this pad:
02331    // fxTGo4PreviewPanelSlots->ClearAllLabels(ActivePad);
02332 
02333    TPad* pad = GetActivePad();
02334 
02335    TGo4Slot* padslot = GetPadSlot(pad);
02336    if ((pad==0) || (padslot==0)) return;
02337 
02338    ClearPad(pad, true, true);
02339    RedrawPanel(pad, true);
02340 
02341    if ((numX>1) || (numY>1)) {
02342       pad->Divide(numX, numY);
02343 
02344       UpdatePadStatus(pad, true);
02345 
02346       RedrawPanel(pad, true);
02347    }
02348 
02349    // note: number of pads will be changed in list of previewpanelstatus by InitPad
02350 //   RefreshButtons();
02351 }
02352 
02353 void TGo4ViewPanel::SetSlotPad(TGo4Slot* padslot, TPad* pad)
02354 {
02355    TGo4Slot* tgtslot = padslot->FindChild("::ThisPad");
02356    if (tgtslot==0)
02357      tgtslot = new TGo4Slot(padslot, "::ThisPad", "Special object");
02358    tgtslot->SetProxy(new TGo4ObjectProxy(pad, kFALSE));
02359    SetDrawKind(tgtslot, kind_ThisPad);
02360    ConnectPad(pad);
02361 
02362    AllocatePadOptions(pad);
02363 }
02364 
02365 TGo4Slot* TGo4ViewPanel::GetPadSlot(TPad* pad)
02366 {
02367    if (pad==GetCanvas()) return GetPanelSlot();
02368 
02369    TGo4Iter iter(GetPanelSlot(), kTRUE);
02370    while (iter.next()) {
02371       TGo4Slot* subslot = iter.getslot();
02372       if (GetDrawKind(subslot)==kind_PadSlot)
02373         if (GetSlotPad(subslot)==pad) return subslot;
02374    }
02375    return 0;
02376 }
02377 
02378 TPad* TGo4ViewPanel::GetSlotPad(TGo4Slot* slot)
02379 {
02380    if (slot==0) return 0;
02381 
02382    TGo4Slot* tgtslot = slot->FindChild("::ThisPad");
02383 
02384    return tgtslot==0 ? 0 : (TPad*) tgtslot->GetAssignedObject();
02385 }
02386 
02387 bool TGo4ViewPanel::IsPadHasSubPads(TGo4Slot* padslot)
02388 {
02389    if (padslot==0) return false;
02390    for(int n=0;n<padslot->NumChilds();n++)
02391      if (GetSlotPad(padslot->GetChild(n))!=0) return true;
02392    return false;
02393 }
02394 
02395 bool TGo4ViewPanel::IsPadHasSubPads(TPad* pad)
02396 {
02397    return IsPadHasSubPads(GetPadSlot(pad));
02398 }
02399 
02400 void TGo4ViewPanel::MarkPadModified(TPad* pad)
02401 {
02402    TGo4Picture* padopt = GetPadOptions(pad);
02403    if (padopt!=0)
02404      padopt->SetPadModified();
02405 }
02406 
02407 bool TGo4ViewPanel::IsPanelPad(TPad* pad)
02408 {
02409    return GetPadSlot(pad)!=0;
02410 }
02411 
02412 int TGo4ViewPanel::GetNumberOfPads(TPad* toppad)
02413 {
02414    if (toppad==0) toppad = GetCanvas();
02415    int number = 1;
02416    TGo4Iter iter(GetPadSlot(toppad), kTRUE);
02417    while (iter.next()) {
02418      TPad* pad = GetSlotPad(iter.getslot());
02419      if (pad!=0) number++;
02420    }
02421    return number;
02422 }
02423 
02424 TPad* TGo4ViewPanel::GetSubPad(TPad* toppad, int num, bool onlytoplevel)
02425 {
02426    if (toppad==0) toppad = GetCanvas();
02427    TGo4Slot* slot = GetPadSlot(toppad);
02428    if (slot==0) return 0;
02429 
02430    int cnt=-1;
02431    if (!onlytoplevel || !IsPadHasSubPads(slot)) cnt++;
02432 
02433    if (num==cnt) return toppad;
02434 
02435    TGo4Iter iter(slot, kTRUE);
02436    while (iter.next()) {
02437       TGo4Slot* subslot = iter.getslot();
02438       TPad* pad = GetSlotPad(subslot);
02439       if (pad==0) continue;
02440       if (!onlytoplevel || !IsPadHasSubPads(subslot)) cnt++;
02441       if (num==cnt) return pad;
02442    }
02443    return 0;
02444 }
02445 
02446 void TGo4ViewPanel::ProducePadsList(TObjArray* arr, TPad* toppad)
02447 {
02448    if (arr==0) return;
02449    if (toppad==0) toppad = GetCanvas();
02450 
02451    arr->Add(toppad);
02452 
02453    TGo4Iter iter(GetPadSlot(toppad), kTRUE);
02454    while (iter.next()) {
02455      TPad* pad = GetSlotPad(iter.getslot());
02456      if (pad!=0) arr->Add(pad);
02457    }
02458 }
02459 
02460 const char* TGo4ViewPanel::GetDrawObjectLinkName( TPad * pad, TObject* obj )
02461 {
02462    TGo4Slot* slot = GetPadSlot(pad);
02463    if ((pad==0) || (slot==0) || (obj==0)) return 0;
02464 
02465    for(int n=0;n<slot->NumChilds();n++) {
02466       TGo4Slot* subslot = slot->GetChild(n);
02467       if (subslot->GetAssignedObject()==obj) return GetLinkedName(subslot);
02468    }
02469    return 0;
02470 }
02471 
02472 TGo4Slot* TGo4ViewPanel::GetSuperimposeSlot(TGo4Slot* padslot)
02473 {
02474    return padslot==0 ? 0 : padslot->FindChild("::Superimpose");
02475 }
02476 
02477 TGo4Slot* TGo4ViewPanel::GetPadMainObjectSlot(TPad* pad)
02478 {
02479    TGo4Slot* slot = GetPadSlot(pad);
02480    if ((pad==0) || (slot==0)) return 0;
02481 
02482    for(int n=0;n<slot->NumChilds();n++) {
02483       TGo4Slot* subslot = slot->GetChild(n);
02484       Int_t kind = GetDrawKind(subslot);
02485       if ((kind<=0) || (kind>=kind_Additional)) continue;
02486       TObject* obj = subslot->GetAssignedObject();
02487       if (obj!=0) return subslot;
02488    }
02489    return 0;
02490 }
02491 
02492 TObject* TGo4ViewPanel::GetPadMainObject(TPad* pad)
02493 {
02494    TGo4Slot* slot = GetPadMainObjectSlot(pad);
02495    return slot==0 ? 0 : slot->GetAssignedObject();
02496 }
02497 
02498 TCanvas* TGo4ViewPanel::GetCanvas()
02499 {
02500     return fxGo4QRootCanvas->getCanvas();
02501 }
02502 
02503 QGo4RootCanvas* TGo4ViewPanel::GetQCanvas()
02504 {
02505    return fxGo4QRootCanvas;
02506 }
02507 
02508 TPad * TGo4ViewPanel::GetActivePad()
02509 {
02510    return ActivePad;
02511 }
02512 
02513 void TGo4ViewPanel::AllocatePadOptions(TPad* pad)
02514 {
02515    TGo4Slot* padslot = GetPadSlot(pad);
02516    if (padslot==0) return;
02517 
02518    TGo4Slot* tgtslot = padslot->FindChild("::PadOptions");
02519    if (tgtslot==0) {
02520      tgtslot = new TGo4Slot(padslot, "::PadOptions", "Pad options slot");
02521      tgtslot->SetProxy(new TGo4ObjectProxy(new TGo4Picture, kTRUE));
02522      SetDrawKind(tgtslot, kind_PadOptions);
02523    }
02524 }
02525 
02526 TGo4Picture* TGo4ViewPanel::GetPadOptions(TPad* pad)
02527 {
02528    return GetPadOptions(GetPadSlot(pad));
02529 }
02530 
02531 TGo4Picture* TGo4ViewPanel::GetPadOptions(TGo4Slot* padslot)
02532 {
02533    if (padslot==0) return 0;
02534    TGo4Slot* tgtslot = padslot->FindChild("::PadOptions");
02535    return (tgtslot==0) ? 0 : (TGo4Picture*) tgtslot->GetAssignedObject();
02536 }
02537 
02538 TH1* TGo4ViewPanel::GetPadHistogram(TPad *pad)
02539 {
02540    TGo4Slot* padslot = GetPadSlot(pad);
02541 
02542    if ((pad==0) || (padslot==0)) return 0;
02543 
02544    TObject* obj = 0;
02545 
02546    TGo4Slot* sislot = GetSuperimposeSlot(padslot);
02547    if (sislot!=0) obj = sislot->GetAssignedObject();
02548 
02549    if (obj==0) obj = GetPadMainObject(pad);
02550    if (obj==0) return 0;
02551 
02552    if (obj->InheritsFrom(TH1::Class()))
02553       return (TH1*) obj;
02554 
02555    if (obj->InheritsFrom(TGraph::Class())) {
02556       TGraph* gr = dynamic_cast<TGraph*> (obj);
02557       if (gr!=0) return gr->GetHistogram();
02558    }
02559 
02560    if (obj->InheritsFrom(THStack::Class())) {
02561       THStack* hs = dynamic_cast<THStack*> (obj);
02562       if (hs!=0) return hs->GetHistogram();
02563    }
02564 
02565    if (obj->InheritsFrom(TMultiGraph::Class())) {
02566       TMultiGraph* mg = dynamic_cast<TMultiGraph*> (obj);
02567       if (mg) {
02568          if (mg->GetHistogram()) return mg->GetHistogram();
02569 
02570          TGraph* gr = 0;
02571          TIter iter(mg->GetListOfGraphs());
02572          while ((gr = (TGraph*)iter()) != 0)
02573            if (gr->GetHistogram()) return gr->GetHistogram();
02574       }
02575    }
02576 
02577    return 0;
02578 }
02579 
02580 void TGo4ViewPanel::BlockPanelRedraw(bool on)
02581 {
02582    if (on) fiSkipRedrawCounter++;
02583       else fiSkipRedrawCounter--;
02584 }
02585 
02586 bool TGo4ViewPanel::IsRedrawBlocked()
02587 {
02588    return fiSkipRedrawCounter>0;
02589 }
02590 
02591 void TGo4ViewPanel::UpdatePanelCaption()
02592 {
02593    TGo4Slot* slot = GetPadSlot(GetActivePad());
02594    if (slot==0) return;
02595 
02596    fSelectMenu->clear();
02597 
02598    TGo4Slot* sislot = GetSuperimposeSlot(slot);
02599 
02600    TObjArray objs, objslots;
02601    CollectMainDrawObjects(slot, &objs, &objslots, 0);
02602 
02603    Int_t nselectitem = 0;
02604 
02605    int selected = GetSelectedObjectIndex(slot);
02606 
02607    if ((selected>objs.GetLast()) ||
02608        ((selected==TGo4Picture::PictureIndex) && (sislot==0))) {
02609       SetSelectedObjectIndex(slot, 0);
02610       selected = 0;
02611    }
02612 
02613    if (sislot!=0) {
02614       fSelectMenu->insertItem("Master object", MasterSelectId);
02615       fSelectMenu->insertSeparator();
02616       nselectitem++;
02617    }
02618 
02619    QString capt = GetPanelName();
02620 
02621    QString fulllist = "";
02622    QString selslotname = "";
02623 
02624    for(int n=0;n<=objslots.GetLast();n++) {
02625       TGo4Slot* subslot = (TGo4Slot*) objslots.At(n);
02626       fSelectMenu->insertItem(objs.At(n)->GetName(), FirstSelectId+n);
02627       nselectitem++;
02628 
02629       QString subslotname = subslot->GetName();
02630       if (n==selected) {
02631          subslotname = QString("[") + subslotname + QString("]");
02632          selslotname = subslotname;
02633       }
02634       if (n>0) fulllist += ", ";
02635       fulllist += subslotname;
02636    }
02637 
02638    if ((selected!=TGo4Picture::PictureIndex) &&
02639        (objslots.GetLast()>0) && (selected<objslots.GetLast())) {
02640            fSelectMenu->insertSeparator();
02641            fSelectMenu->insertItem(QString("Show ") + selslotname + QString(" on top"), BringToFrontId);
02642        }
02643 
02644    if ((selected==TGo4Picture::PictureIndex) && (fulllist.length()>0))
02645       fulllist = QString("[") + fulllist + QString("]");
02646 
02647    if (nselectitem==0) {
02648       fMenuBar->setItemEnabled(SelectObjectId, false);
02649    } else {
02650       fMenuBar->setItemEnabled(SelectObjectId, true);
02651       if (selected==TGo4Picture::PictureIndex)
02652          fMenuBar->setItemChecked(MasterSelectId, true);
02653       else
02654          fMenuBar->setItemChecked(FirstSelectId+selected, true);
02655    }
02656 
02657    if (fulllist.length()>0) {
02658       capt += ": ";
02659       capt += fulllist;
02660    }
02661 
02662    if (capt.length()>60) {
02663       capt.truncate(58);
02664       capt+="...";
02665    }
02666 
02667    if (!fbFreezeTitle)
02668       setCaption(capt);
02669 }
02670 
02671 void TGo4ViewPanel::SetDrawKind(TGo4Slot* slot, int kind)
02672 {
02673    if (slot==0) return;
02674    if (kind<=0) slot->RemovePar("::DrawKind");
02675            else slot->SetIntPar("::DrawKind", kind);
02676 }
02677 
02678 void TGo4ViewPanel::SetSpecialDrawOption(TGo4Slot* slot, const char* drawopt)
02679 {
02680    if (slot==0) return;
02681    if (drawopt!=0)
02682       slot->SetPar("::DrawOpt", drawopt);
02683    else
02684       slot->RemovePar("::DrawOpt");
02685 }
02686 
02687 int TGo4ViewPanel::GetDrawKind(TGo4Slot* slot)
02688 {
02689    if (slot==0) return -1;
02690    Int_t kind;
02691    if (!slot->GetIntPar("::DrawKind",kind)) return -1;
02692    return kind;
02693 }
02694 
02695 const char* TGo4ViewPanel::GetSpecialDrawOption(TGo4Slot* slot)
02696 {
02697    return (slot==0) ? 0 : slot->GetPar("::DrawOpt");
02698 }
02699 
02700 void TGo4ViewPanel::SetSelectedObjectIndex(TGo4Slot* slot, int indx)
02701 {
02702    if (slot!=0) slot->SetIntPar("::SelectedObject", indx);
02703 }
02704 
02705 int TGo4ViewPanel::GetSelectedObjectIndex(TGo4Slot* slot)
02706 {
02707    if (slot==0) return 0;
02708    Int_t indx = 0;
02709    if (!slot->GetIntPar("::SelectedObject", indx)) indx = 0;
02710    return indx;
02711 }
02712 
02713 TObject* TGo4ViewPanel::GetSelectedObject(TPad * pad, const char** drawopt)
02714 {
02715    TGo4Slot* slot = GetPadSlot(pad);
02716    TGo4Picture* padopt = GetPadOptions(slot);
02717    if ((slot==0) || (padopt==0)) return 0;
02718 
02719    int indx = GetSelectedObjectIndex(slot);
02720 
02721    TGo4Slot* sislot = GetSuperimposeSlot(slot);
02722    if ((sislot!=0) && (indx==TGo4Picture::PictureIndex)) {
02723       if (drawopt!=0) *drawopt = padopt->GetDrawOption(TGo4Picture::PictureIndex);
02724       return sislot->GetAssignedObject();
02725    }
02726 
02727    TObjArray objs, objslots;
02728    CollectMainDrawObjects(slot, &objs, &objslots, 0);
02729 
02730    if (objs.GetLast()<0) return 0;
02731 
02732    if ((indx>objs.GetLast()) || (indx<0)) indx = 0;
02733 
02734    if (drawopt!=0) {
02735        const char* resopt = padopt->GetDrawOption(indx);
02736        if (resopt==0)
02737           resopt = GetSpecialDrawOption((TGo4Slot*) objslots.At(indx));
02738 
02739        *drawopt = resopt;
02740    }
02741 
02742    return objs.At(indx);
02743 }
02744 
02745 bool TGo4ViewPanel::ShiftSelectedObjectToEnd(TPad * pad)
02746 {
02747    TGo4Slot* slot = GetPadSlot(pad);
02748    TGo4Picture* padopt = GetPadOptions(slot);
02749    if ((slot==0) || (padopt==0)) return false;
02750 
02751    int indx = GetSelectedObjectIndex(slot);
02752 
02753    TObjArray objs, objslots;
02754    CollectMainDrawObjects(slot, &objs, &objslots, 0);
02755 
02756    // no sense to shift object which is already at the end
02757    if ((objs.GetLast()<=0) || (indx==objs.GetLast())) return false;
02758 
02759    TGo4Slot* selslot = (TGo4Slot*) objslots.At(indx);
02760    TGo4Slot* lastslot = (TGo4Slot*) objslots.Last();
02761 
02762    if (!slot->ShiftSlotAfter(selslot, lastslot)) return false;
02763 
02764    SetSelectedObjectIndex(slot, objs.GetLast());
02765 
02766    return true;
02767 }
02768 
02769 void TGo4ViewPanel::CheckObjectsAssigments( TPad * pad, TGo4Slot * padslot )
02770 {
02771    if ((pad==0) || (padslot==0)) return;
02772 
02773    TObjArray objs, objslots;
02774    CollectMainDrawObjects(padslot, &objs, &objslots, 0);
02775 
02776    int indx = GetSelectedObjectIndex(padslot);
02777    if (indx<0) indx = 0;
02778    
02779    TH1* selhisto = dynamic_cast<TH1*> ((indx<=objs.GetLast()) ? objs.At(indx) : 0);
02780    if (selhisto==0) selhisto = GetPadHistogram(pad);
02781 
02782    for(int n=0;n<padslot->NumChilds();n++) {
02783       TGo4Slot* subslot = padslot->GetChild(n);
02784       Int_t kind = GetDrawKind(subslot);
02785       TObject* obj = subslot->GetAssignedObject();
02786       if (obj==0) continue;
02787       
02788       TGo4Marker* mark = 0;
02789       TGo4Condition* cond = 0;
02790 
02791       // reset condition and marker histogram
02792       if ((kind>=kind_Specials) && (kind<kind_Other)) {
02793          if (obj->InheritsFrom(TGo4Condition::Class())) 
02794             cond = (TGo4Condition*) obj;     
02795          else
02796          if (obj->InheritsFrom(TGo4Marker::Class()))
02797             mark = (TGo4Marker*) obj;
02798       } else
02799       if (kind==kind_Condition) 
02800           cond = dynamic_cast<TGo4Condition*>(obj);
02801       
02802       TH1* oldhisto = 0;
02803       
02804       if (cond!=0) oldhisto = cond->GetWorkHistogram(); else
02805       if (mark!=0) oldhisto = mark->GetHistogram();
02806       
02807       if (oldhisto!=0) 
02808         if (objs.FindObject(oldhisto)==0) oldhisto = 0;
02809         
02810       if (oldhisto==0) 
02811         if (cond!=0) cond->SetWorkHistogram(selhisto); else
02812         if (mark!=0) mark->SetHistogram(selhisto);
02813    }
02814 }
02815 
02816 void TGo4ViewPanel::CheckForSpecialObjects(TPad *pad, TGo4Slot* padslot)
02817 {
02818    if ((pad==0) || (padslot==0)) return;
02819 
02820    TGo4Picture* pic = 0;
02821    TGo4Slot* picslot = 0;
02822    TCanvas* canv = 0;
02823    TGo4Slot* canvslot = 0;
02824 
02825    int numcond = 0;
02826 
02827    for(int n=0;n<padslot->NumChilds();n++) {
02828       TGo4Slot* subslot = padslot->GetChild(n);
02829       Int_t kind = GetDrawKind(subslot);
02830       if (kind==kind_Condition) numcond++;
02831 
02832       TObject* obj = subslot->GetAssignedObject();
02833       if (obj==0) continue;
02834 
02835       if ((kind<0) || (kind>=100)) continue;
02836 
02837       TGo4Condition* cond = dynamic_cast<TGo4Condition*>(obj);
02838       // change drawkind of condition which is drawn as normal object
02839       if (cond!=0) {
02840          numcond++;
02841          cond->SetLineColor(numcond+1);
02842          cond->SetFillColor(numcond+1);
02843          cond->SetFillStyle(3444);
02844          SetDrawKind(subslot, kind_Condition);
02845          continue;
02846       }
02847 
02848       if (pic==0) {
02849          pic = dynamic_cast<TGo4Picture*> (obj);
02850          if (pic!=0) picslot = subslot;
02851       }
02852 
02853       if (canv==0) {
02854          canv = dynamic_cast<TCanvas*> (obj);
02855          if (canv!=0) canvslot = subslot;
02856       }
02857    }
02858 
02859    if (pic!=0) {
02860 
02861       ClearPadItems(padslot, picslot);
02862 
02863       // remove all subpads if any but do not remove items while picture is there
02864       ClearPad(pad, false, true);
02865 
02866       ProcessPictureRedraw(GetLinkedName(picslot), pad, pic);
02867 
02868       if (pad==GetCanvas()) {
02869          QString mycaption = GetPanelName();
02870          mycaption += ": ";
02871          mycaption += pic->GetTitle();
02872          setCaption(mycaption);
02873          fbFreezeTitle = true;
02874       }
02875 
02876       // remove picture from the pad
02877       delete picslot;
02878 
02879       // cout << "!!!!!!!!!!!! Picture redraw done" << endl;
02880 
02881       return;
02882    }
02883 
02884    if (canv!=0) {
02885       // remove all other
02886       ClearPadItems(padslot, canvslot);
02887 
02888       // remove all subpads if any but do not remove items while picture is there
02889       ClearPad(pad, false, true);
02890 
02891       TVirtualPad* padsav = gPad;
02892 
02893       ProcessCanvasAdopt(pad, canv, GetLinkedName(canvslot));
02894 
02895       if (padsav!=0) padsav->cd();
02896 
02897       delete canvslot;
02898    }
02899 }
02900 
02901 void TGo4ViewPanel::ProcessPictureRedraw(const char* picitemname, TPad* pad, TGo4Picture* pic)
02902 {
02903    if ((pad==0) || (pic==0)) return;
02904 
02905    if (pic->IsDivided()) {
02906       pad->Divide(pic->GetDivX(), pic->GetDivY());
02907 
02908       // this create appropriate entries in the OM
02909       UpdatePadStatus(pad, false);
02910 
02911       for(Int_t posy=0; posy<pic->GetDivY(); posy++)
02912          for(Int_t posx=0; posx<pic->GetDivX(); posx++) {
02913            TGo4Picture* sub = pic->FindPic(posy,posx);
02914            if (sub!=0)
02915              ProcessPictureRedraw(picitemname, (TPad*) pad->GetPad(posy*pic->GetDivX() + posx + 1), sub);
02916        }
02917 
02918       return;
02919    }
02920 
02921    TGo4Picture* padopt = GetPadOptions(pad);
02922    if (padopt==0) {
02923       cerr << "!!!!!!!! Should not be" << endl;
02924       return;
02925    }
02926 
02927    padopt->CopyOptionsFrom(pic);
02928 
02929    padopt->GetDrawAttributes(pad, TGo4Picture::PictureIndex);
02930 
02931    TGo4BrowserProxy* brcont = Browser();
02932 
02933    Option_t* drawopt = pic->GetDrawOption(TGo4Picture::PictureIndex);
02934    if (drawopt!=0) pic->SetDrawOption(drawopt, TGo4Picture::PictureIndex);
02935 
02936    Int_t ndraw = 0;
02937 
02938    for (Int_t n=0; n<pic->GetNumObjNames(); n++) {
02939       Option_t* drawopt = pic->GetDrawOption(n);
02940       if (drawopt!=0) pic->SetDrawOption(drawopt, n);
02941 
02942       const char* objname = pic->GetObjName(n);
02943 
02944       TString drawname;
02945 
02946       if (brcont->DefineRelatedObject(picitemname, objname, drawname)) {
02947          TGo4Slot* slot = AddDrawObject(pad, kind_Link, drawname.Data(), 0, false, 0);
02948          brcont->GetBrowserObject(drawname.Data(), 2);
02949          ndraw++;
02950 
02951          if (pic->GetRebinX(n)>1) {
02952              slot->SetIntPar("::DoRebinX", pic->GetRebinX(n));
02953              slot->SetIntPar("::HasRebinX", pic->GetRebinX(n));
02954          }
02955 
02956          if (pic->GetRebinY(n)>1) {
02957              slot->SetIntPar("::DoRebinY", pic->GetRebinY(n));
02958              slot->SetIntPar("::HasRebinY", pic->GetRebinY(n));
02959          }
02960       }
02961    }
02962 
02963    if (ndraw>1)
02964      padopt->SetSuperimpose(true);
02965 
02966    TListIter iter(pic->GetSpecialObjects());
02967    TObject* obj = 0;
02968    while ((obj=iter())!=0) {
02969       Option_t* drawopt = iter.GetOption();
02970       if (dynamic_cast<TArrow*>(obj)!=0)
02971          AddMarkerObj(pad, kind_Arrow, obj->Clone());
02972       else
02973       if (dynamic_cast<TLatex*>(obj)!=0)
02974          AddMarkerObj(pad, kind_Latex, obj->Clone());
02975       else
02976       if (dynamic_cast<TGo4Marker*>(obj)!=0)
02977          AddMarkerObj(pad, kind_Marker, obj->Clone());
02978       else
02979       if (dynamic_cast<TGo4WinCond*>(obj)!=0)
02980          AddMarkerObj(pad, kind_Window, obj->Clone());
02981       else
02982       if (dynamic_cast<TGo4PolyCond*>(obj)!=0)
02983          AddMarkerObj(pad, kind_Poly, obj->Clone());
02984       else
02985       if (dynamic_cast<TPaveLabel*>(obj)!=0)
02986          AddDrawObject(pad, kind_Specials, obj->GetName(), obj->Clone(), kTRUE, drawopt ? drawopt : "br");
02987    }
02988 
02989    padopt->SetPadModified();
02990 }
02991 
02992 void TGo4ViewPanel::ProcessCanvasAdopt(TPad* tgtpad, TPad* srcpad, const char* srcpaditemname)
02993 {
02994    if ((tgtpad==0) || (srcpad==0)) return;
02995 
02996 //   cout << "ProcessCanvasAdopt " << srcpad->GetName() << endl;
02997 
02998    TGo4Slot* padslot = GetPadSlot(tgtpad);
02999 
03000    TGo4Picture* padopt = GetPadOptions(tgtpad);
03001 
03002    if ((padopt==0) || (padslot==0)) return;
03003 
03004    tgtpad->SetTickx(srcpad->GetTickx());
03005    tgtpad->SetTicky(srcpad->GetTicky());
03006    tgtpad->SetGridx(srcpad->GetGridx());
03007    tgtpad->SetGridy(srcpad->GetGridy());
03008    tgtpad->SetBorderSize(srcpad->GetBorderSize());
03009    tgtpad->SetBorderMode(srcpad->GetBorderMode());
03010    srcpad->TAttLine::Copy(*tgtpad);
03011    srcpad->TAttFill::Copy(*tgtpad);
03012    srcpad->TAttPad::Copy(*tgtpad);
03013 
03014    tgtpad->SetPhi(srcpad->GetPhi());
03015    tgtpad->SetTheta(srcpad->GetTheta());
03016 
03017    int nsubpads = 0, nmain = 0, mainkind = 0;
03018    TObjLink* link = srcpad->GetListOfPrimitives()->FirstLink();
03019    while (link!=0) {
03020       TObject* obj = link->GetObject();
03021       const char* drawopt = link->GetOption();
03022 
03023       TH1* h1 = 0;
03024 
03025       int kind = 0;
03026 
03027       TPad* srcsubpad = dynamic_cast<TPad*> (obj);
03028 
03029       TString itemname(srcpaditemname);
03030       itemname+="/";
03031       itemname+=obj->GetName();
03032 
03033       if (srcsubpad!=0) {
03034          nsubpads++;
03035          QString subpadname = tgtpad->GetName();
03036          subpadname += "_";
03037          subpadname += QString::number(nsubpads);
03038 
03039          Double_t xlow, ylow, xup, yup;
03040 
03041          srcsubpad->GetPadPar(xlow, ylow, xup, yup);
03042 
03043          tgtpad->cd();
03044          TPad* tgtsubpad = new TPad(subpadname.latin1(), srcsubpad->GetName(), xlow, ylow, xup, yup);
03045          tgtsubpad->SetNumber(nsubpads);
03046          tgtsubpad->Draw();
03047 
03048          TGo4Slot* subpadslot = AddNewSlot(tgtsubpad->GetName(), padslot);
03049          SetDrawKind(subpadslot, kind_PadSlot);
03050          SetSlotPad(subpadslot, tgtsubpad);
03051 
03052          ProcessCanvasAdopt(tgtsubpad, srcsubpad, itemname.Data());
03053       } else
03054       if (dynamic_cast<TGo4Condition*>(obj)!=0) {
03055          TGo4Condition* cond = (TGo4Condition*) obj->Clone();
03056          cond->SetWorkHistogram(0);
03057          AddDrawObject(tgtpad, kind_Condition, cond->GetName(), cond, kTRUE, 0);
03058       } else
03059       if (dynamic_cast<TGo4Marker*>(obj)!=0) {
03060           TGo4Marker* mark = (TGo4Marker*) obj->Clone();
03061           mark->SetHistogram(0);
03062           AddDrawObject(tgtpad, kind_Marker, mark->GetName(), mark, kTRUE, 0);
03063       } else
03064       if (dynamic_cast<TLatex*>(obj)!=0) {
03065          AddDrawObject(tgtpad, kind_Latex, obj->GetName(), obj->Clone(), kTRUE, 0);
03066       } else
03067       if (dynamic_cast<TPaveLabel*>(obj)!=0) {
03068          AddDrawObject(tgtpad, kind_Specials, obj->GetName(), obj->Clone(), kTRUE, drawopt ? drawopt : "br");
03069       } else
03070       if (dynamic_cast<TArrow*>(obj)!=0) {
03071          AddDrawObject(tgtpad, kind_Arrow, obj->GetName(), obj->Clone(), kTRUE, 0);
03072       } else
03073 
03074       if (dynamic_cast<TH1*>(obj)!=0) {
03075          kind = 1;
03076          h1 = (TH1*) obj;
03077       } else
03078 
03079       if (dynamic_cast<TGraph*>(obj)!=0) {
03080          kind = 2;
03081          h1 = ((TGraph*) obj)->GetHistogram();
03082       } else
03083 
03084       if (dynamic_cast<THStack*>(obj)!=0) {
03085          kind = 3;
03086          h1 = ((THStack*) obj)->GetHistogram();
03087       } else
03088 
03089       if (dynamic_cast<TMultiGraph*>(obj)!=0) {
03090          kind = 4;
03091          h1 = ((TMultiGraph*) obj)->GetHistogram();
03092       } else {
03093 //         cout << tgtpad->GetName() << ":  Add other object ???" << obj->GetName() << endl;
03094       }
03095 
03096       // only first object is added,
03097       // make superimpose only for histos and graphs
03098       if ((kind>0) && ((mainkind==0) || (kind==mainkind) && (kind<3))) {
03099 
03100 //         cout << tgtpad->GetName() << ":  Add main draw object " << obj->GetName()
03101 //              << "  class =  " << obj->ClassName()
03102 //              << "  srcitem = " << itemname << endl;
03103 
03104          if (drawopt!=0)
03105             padopt->SetDrawOption(drawopt, nmain);
03106 
03107          AddDrawObject(tgtpad, knd_Reference, obj->GetName(), obj, false, 0);
03108 
03109          mainkind = kind;
03110 
03111          if ((h1!=0) && (nmain==0)) {
03112             TakeFullRangeFromHisto(h1, padopt, nmain==0);
03113             Int_t ndim = h1->GetDimension();
03114             TakeSelectedAxisRange(0, padopt, h1->GetXaxis());
03115             if (ndim>1) TakeSelectedAxisRange(1, padopt, h1->GetYaxis());
03116             if (ndim>2) TakeSelectedAxisRange(2, padopt, h1->GetZaxis());
03117             if (ndim<3) {
03118                Double_t selmin = h1->GetMinimum();
03119                Double_t selmax = h1->GetMaximum();
03120 
03121                if (selmin<selmax) padopt->SetRange(ndim, selmin, selmax);
03122 
03123                padopt->SetAutoScale(!h1->TestBit(TH1::kIsZoomed) || (selmin>=selmax));
03124             }
03125          }
03126 
03127          nmain++;
03128       }
03129 
03130       link = link->Next();
03131    }
03132 
03133    if (nmain>1)
03134       padopt->SetSuperimpose(kTRUE);
03135 
03136    if (nsubpads==0)
03137       ScanDrawOptions(srcpad, padslot, padopt, false);
03138 }
03139 
03140 void TGo4ViewPanel::RedrawPanel(TPad* pad, bool force)
03141 {
03142    if (IsRedrawBlocked()) return;
03143 
03144    TGo4LockGuard lock;
03145 
03146    BlockPanelRedraw(true);
03147 
03148    bool isanychildmodified = false;
03149    bool ispadupdatecalled = false;
03150 
03151    QTime starttm = QTime::currentTime();
03152    bool intime = true;
03153 
03154    // this loop done to allow consiquent update of multi-pad canvas
03155    // each subpad separetely redrawn in ProcessPadRedraw() method and
03156    // than pad->Update() is called. If it takes too long,
03157    // loop is finishing and via paint timer will be activated later
03158 
03159    do {
03160       TPad* selpad = TGo4WorkSpace::Instance()->GetSelectedPad();
03161 
03162       isanychildmodified = ProcessPadRedraw(pad, force);
03163 
03164       TGo4WorkSpace::Instance()->SetSelectedPad(selpad);
03165 
03166       // here pad->Update should redraw only modifed subpad
03167       if (isanychildmodified) {
03168          pad->Update();
03169          ispadupdatecalled = true;
03170       }
03171 
03172       int delay = starttm.msecsTo(QTime::currentTime());
03173       intime = (delay>=0) && (delay<100);
03174 
03175    } while (!force && isanychildmodified && intime);
03176 
03177    if (ActivePad!=0)
03178      UpdatePanelCaption();
03179 
03180    RefreshButtons();
03181 
03182    // to correctly select active pad, one should call canvas->Update()
03183    if ((pad!=GetCanvas()) || !ispadupdatecalled)
03184       GetCanvas()->Update();
03185 
03186    QCheckBox* box1 = dynamic_cast<QCheckBox*> (child("ApplyToAllCheck"));
03187    if (box1!=0) box1->setChecked(fbApplyToAllFlag);
03188 
03189    BlockPanelRedraw(false);
03190 
03191    if (!force && isanychildmodified)
03192      ShootRepaintTimer(pad);
03193 }
03194 
03195 bool TGo4ViewPanel::ProcessPadRedraw(TPad* pad, bool force)
03196 {
03197    TGo4Slot* slot = GetPadSlot(pad);
03198    if (slot==0) return false;
03199 
03200    TGo4Picture* padopt = GetPadOptions(slot);
03201    if (padopt==0) return false;
03202 
03203    bool ischilds = false;
03204    bool ischildmodified = false;
03205 
03206    CheckObjectsAssigments(pad, slot);
03207 
03208    CheckForSpecialObjects(pad, slot);
03209 
03210    // this parameter ensure that all pads will be scaned one after another
03211    Int_t lastdrawnpad = 0;
03212    if (!force)
03213      if (!slot->GetIntPar("::LastDrawnPad",lastdrawnpad))
03214         lastdrawnpad = 0;
03215 
03216    Int_t subpadindx = 0;
03217 
03218    // first redraw all subpads
03219    for(int n=0;n<slot->NumChilds();n++) {
03220       subpadindx = (n + lastdrawnpad) % slot->NumChilds();
03221       TPad* subpad = GetSlotPad(slot->GetChild(subpadindx));
03222       if (subpad==0) continue;
03223       ischilds = true;
03224       if (ProcessPadRedraw(subpad, force)) {
03225          ischildmodified = true;
03226          if (!force) break; // break if any of child is modified
03227       }
03228    }
03229 
03230    if (!force && ischildmodified)
03231      slot->SetIntPar("::LastDrawnPad", subpadindx);
03232    else
03233      slot->RemovePar("::LastDrawnPad");
03234 
03235    if (!force && !padopt->IsPadModified()) return ischildmodified;
03236 
03237    bool updatecontent = padopt->IsContentModified();
03238 
03239    padopt->SetPadModified(false);
03240    padopt->SetContentModified(false);
03241 
03242    // do not draw anything else if subpads are there
03243    if (ischilds) return ischildmodified;
03244 
03245    pad->Clear();
03246 
03247    pad->SetCrosshair(fbCanvasCrosshair);
03248    pad->SetLogx(padopt->GetLogScale(0));
03249    pad->SetLogy(padopt->GetLogScale(1));
03250    pad->SetLogz(padopt->GetLogScale(2));
03251 
03252    TObjArray objs, objslots;
03253    CollectMainDrawObjects(slot, &objs, &objslots, padopt->IsSuperimpose() ? 1 : 2);
03254 
03255    ScanObjectsDrawOptions(false, slot, &objs, &objslots);
03256 
03257    TGo4Slot* sislot = GetSuperimposeSlot(slot);
03258    TGo4Slot* legslot = slot->FindChild("::Legend");
03259    TGo4Slot* asislot = slot->FindChild("::ASImage");
03260 
03261    // if nothing to draw, delete all additional slots and exit
03262    if (objs.GetLast()<0) {
03263       delete sislot;
03264       delete legslot;
03265       delete asislot;
03266 
03267       CallPanelFunc(panel_Updated, pad);
03268 
03269       // indicate that nothing is happen
03270       return true;
03271    }
03272 
03273    TH2* asihisto = 0;
03274 
03275    TObject* drawobj = 0;
03276 
03277    // Bool_t dosuperimpose = padopt->IsSuperimpose() && (objs.GetLast()>0);
03278    Bool_t dosuperimpose = objs.GetLast()>0;
03279 
03280    const char* drawopt = padopt->GetDrawOption(0);
03281 
03282    Bool_t doasiimage = (drawopt!=0) && !dosuperimpose && objs.Last()->InheritsFrom(TH2::Class());
03283    if (doasiimage)
03284       doasiimage = strstr(drawopt,"asimage")!=0;
03285 
03286    if (dosuperimpose) {
03287      if (sislot==0)
03288         sislot = new TGo4Slot(slot,"::Superimpose","place for superimpose object");
03289      if (padopt->IsLegendDraw()) {
03290         if (legslot==0)
03291           legslot = new TGo4Slot(slot,"::Legend","place for superimpose object");
03292      } else
03293        if (legslot!=0) {
03294           delete legslot;
03295           legslot = 0;
03296        }
03297 
03298      drawobj = ProduceSuperimposeObject(padopt, sislot, legslot, &objs, &objslots, padopt->IsTitleItem());
03299      if (drawobj==0) dosuperimpose = kFALSE;
03300    }
03301 
03302    if (!dosuperimpose) {
03303       if (sislot!=0) { delete sislot; sislot = 0; }
03304       if (legslot!=0) { delete legslot; legslot = 0; }
03305       drawobj = objs.Last();
03306    }
03307 
03308    if (doasiimage) {
03309       asihisto = dynamic_cast<TH2*> (drawobj);
03310       if (asihisto==0)
03311         doasiimage = false;
03312       else {
03313         if (asislot==0)
03314           asislot = new TGo4Slot(slot,"::ASImage","place for Go4 ASI image");
03315         TGo4ASImage* image = dynamic_cast<TGo4ASImage*> (asislot->GetAssignedObject());
03316         if (image==0) {
03317            image = new TGo4ASImage;
03318            asislot->SetProxy(new TGo4ObjectProxy(image, kTRUE));
03319            updatecontent = true;
03320         }
03321         if (updatecontent)
03322            image->SetHistogramContent(asihisto);
03323 
03324         drawobj = image;
03325       }
03326    }
03327 
03328    if (!doasiimage) {
03329       if (asislot!=0) { delete asislot; asislot = 0; }
03330    }
03331 
03332    gPad = pad;  // instead of pad->cd(), while it is redraw frame
03333 
03334    if (drawobj!=0)
03335       if (drawobj->InheritsFrom(TH1::Class())) {
03336           TH1* h1 = (TH1*) drawobj;
03337           h1->SetBit(kCanDelete, kFALSE);
03338           RedrawHistogram(pad, padopt, h1, updatecontent);
03339        } else
03340        if(drawobj->InheritsFrom(THStack::Class())) {
03341           THStack* hs = (THStack*) drawobj;
03342           RedrawStack(pad, padopt, hs, dosuperimpose, updatecontent);
03343        } else
03344        if(drawobj->InheritsFrom(TGraph::Class())) {
03345           TGraph* gr = (TGraph*) drawobj;
03346           RedrawGraph(pad, padopt, gr, updatecontent);
03347        } else
03348        if(drawobj->InheritsFrom(TMultiGraph::Class())) {
03349           TMultiGraph* mg = (TMultiGraph*) drawobj;
03350           RedrawMultiGraph(pad, padopt, mg, dosuperimpose, updatecontent);
03351        }
03352        else
03353        if(dynamic_cast<TGo4ASImage*>(drawobj)!=0) {
03354           TGo4ASImage* ai = (TGo4ASImage*) drawobj;
03355           RedrawImage(pad, padopt, ai, asihisto, updatecontent);
03356        }
03357 
03358    if (legslot!=0)
03359       RedrawLegend(pad, padopt, legslot);
03360 
03361    if (!doasiimage)
03362       RedrawSpecialObjects(pad, slot);
03363 
03364    CallPanelFunc(panel_Updated, pad);
03365 
03366    return true;
03367 }
03368 
03369 void TGo4ViewPanel::RedrawHistogram(TPad *pad, TGo4Picture* padopt, TH1 *his, bool scancontent)
03370 {
03371    if((pad==0) || (padopt==0) || (his==0)) return;
03372 
03373    if (scancontent)
03374       TakeFullRangeFromHisto(his, padopt, true);
03375 
03376    TString drawopt(padopt->GetDrawOption(0));
03377    if (drawopt.Length()==0) drawopt="hist";
03378    drawopt.ToUpper();
03379 
03380    his->SetStats(padopt->IsHisStats());
03381    his->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
03382    his->Draw(drawopt.Data());
03383 
03384    SetSelectedRangeToHisto(his, 0, padopt, true);
03385 }
03386 
03387 void TGo4ViewPanel::RedrawStack(TPad *pad, TGo4Picture* padopt, THStack * hs, bool dosuperimpose, bool scancontent)
03388 {
03389    if((pad==0) || (padopt==0) || (hs==0)) return;
03390 
03391    if (scancontent) {
03392       TIter iter(hs->GetHists());
03393       TH1 *h1 = 0;
03394       bool first = true;
03395       while ((h1 = (TH1*)iter())!=0) {
03396          TakeFullRangeFromHisto(h1, padopt, first);
03397          first = false;
03398       }
03399    }
03400 
03401    // never draw statistics with stack
03402 
03403    Int_t drawoptindx = dosuperimpose ? TGo4Picture::PictureIndex : 0;
03404    TString drawopt(padopt->GetDrawOption(drawoptindx));
03405    if (drawopt.Length()==0) drawopt="hist";
03406    if (!drawopt.Contains(NoStackDrawOption, TString::kIgnoreCase))
03407      drawopt.Prepend(NoStackDrawOption);
03408 
03409    hs->Draw(drawopt.Data());
03410    TH1* framehisto = hs->GetHistogram();
03411 
03412    if (framehisto==0) return;
03413 
03414    framehisto->SetStats(false);
03415    framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
03416    if (hs->GetHists()) {
03417       TH1* h1 = dynamic_cast<TH1*> (hs->GetHists()->First());
03418       if (h1!=0) {
03419          hs->SetTitle(h1->GetTitle());
03420          framehisto->SetTitle(h1->GetTitle());
03421          framehisto->GetXaxis()->SetTitle(h1->GetXaxis()->GetTitle());
03422          framehisto->GetYaxis()->SetTitle(h1->GetYaxis()->GetTitle());
03423          framehisto->GetZaxis()->SetTitle(h1->GetZaxis()->GetTitle());
03424       }
03425    }
03426 
03427    SetSelectedRangeToHisto(framehisto, hs, padopt, false);
03428 }
03429 
03430 
03431 void TGo4ViewPanel::RedrawGraph(TPad *pad, TGo4Picture* padopt, TGraph * gr, bool scancontent)
03432 {
03433    if((pad==0) || (padopt==0) || (gr==0)) return;
03434 
03435    if (scancontent) {
03436       TakeFullRangeFromGraph(gr, padopt, true);
03437       gr->SetEditable(kFALSE);
03438    }
03439 
03440    TString drawopt(padopt->GetDrawOption(0));
03441 
03442    if (drawopt.Length()==0) drawopt="AP";
03443 
03444    TH1* framehisto = gr->GetHistogram();
03445    if (framehisto==0) {
03446       gr->Draw(drawopt.Data());
03447       framehisto = gr->GetHistogram();
03448    }
03449    if (framehisto!=0) {
03450      framehisto->SetStats(padopt->IsHisStats());
03451      framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
03452    }
03453    gr->Draw(drawopt.Data());
03454 
03455    SetSelectedRangeToHisto(framehisto, 0, padopt, false);
03456 }
03457 
03458 void TGo4ViewPanel::RedrawMultiGraph(TPad *pad, TGo4Picture* padopt, TMultiGraph * mg, bool dosuperimpose, bool scancontent)
03459 {
03460    if((pad==0) || (padopt==0) || (mg==0)) return;
03461 
03462    TIter iter(mg->GetListOfGraphs());
03463    TGraph *gr(0), *firstgr(0);
03464    bool first = true;
03465    while ((gr = (TGraph*)iter())!=0) {
03466       if (scancontent) {
03467          gr->SetEditable(kFALSE);
03468          TakeFullRangeFromGraph(gr, padopt, first);
03469       }
03470       if (first) firstgr = gr;
03471       first = false;
03472    }
03473 
03474    Int_t drawoptindx = dosuperimpose ? TGo4Picture::PictureIndex : 0;
03475    TString drawopt(padopt->GetDrawOption(drawoptindx));
03476    if (drawopt.Length()==0) drawopt="AP";
03477    if (dosuperimpose) drawopt = "";
03478 
03479    // never draw statistics with multigraph
03480    TH1* framehisto = (dosuperimpose && (firstgr!=0)) ? firstgr->GetHistogram() : mg->GetHistogram();
03481 
03482    if (framehisto==0) {
03483       mg->Draw(drawopt.Data());
03484       framehisto = (dosuperimpose && (firstgr!=0)) ? firstgr->GetHistogram() : mg->GetHistogram();
03485    }
03486 
03487    if (framehisto!=0) {
03488 
03489       SetSelectedRangeToHisto(framehisto, 0, padopt, false);
03490 
03491       // this is workaround to prevent recreation of framehistogram in TMultiGraf::Paint
03492 
03493       Double_t miny, maxy, selmin, selmax;
03494       if (padopt->GetFullRange(1, miny, maxy) && !padopt->GetRangeY(selmin, selmax)) {
03495          framehisto->SetMaximum(maxy);
03496          framehisto->SetMinimum(miny);
03497       }
03498 
03499       framehisto->SetStats(kFALSE);
03500       framehisto->SetBit(TH1::kNoTitle, !padopt->IsHisTitle());
03501 
03502       // set title of first TGraph to TMultiGraph and frame histo
03503       if (firstgr!=0) {
03504          mg->SetTitle(firstgr->GetTitle());
03505          framehisto->SetTitle(firstgr->GetTitle());
03506          framehisto->GetXaxis()->SetTitle(firstgr->GetXaxis()->GetTitle());
03507          framehisto->GetYaxis()->SetTitle(firstgr->GetYaxis()->GetTitle());
03508       }
03509    }
03510    mg->Draw(drawopt.Data());
03511 }
03512 
03513 void TGo4ViewPanel::RedrawImage(TPad *pad, TGo4Picture* padopt, TGo4ASImage* im, TH2* asihisto, bool scancontent)
03514 {
03515    if((pad==0) || (padopt==0) || (im==0)) return;
03516 
03517    im->SetDrawData(asihisto, this, pad);
03518 
03519    if(scancontent)
03520       TakeFullRangeFromHisto(asihisto, padopt, true);
03521 
03522    double uminx, umaxx, uminy, umaxy;
03523    padopt->GetRange(0, uminx, umaxx);
03524    padopt->GetRange(1, uminy, umaxy);
03525    im->SetSelectedRange(uminx, umaxx, uminy, umaxy);
03526 
03527    im->Draw();
03528 }
03529 
03530 void TGo4ViewPanel::RedrawLegend(TPad *pad, TGo4Picture* padopt, TGo4Slot* legslot)
03531 {
03532    if (legslot==0) return;
03533    TLegend* legend = dynamic_cast<TLegend*> (legslot->GetAssignedObject());
03534    if (legend!=0)
03535       legend->Draw();
03536 }
03537 
03538 void TGo4ViewPanel::RedrawSpecialObjects(TPad *pad, TGo4Slot* padslot)
03539 {
03540    if ((pad==0) || (padslot==0)) return;
03541 
03542    CheckObjectsAssigments(pad, padslot);
03543 
03544    QString selname = GetSelectedMarkerName(pad);
03545    TObject* selectedobj = 0;
03546    const char* selectdrawopt = 0;
03547 
03548    for(int n=0;n<padslot->NumChilds();n++) {
03549       TGo4Slot* subslot = padslot->GetChild(n);
03550 
03551       Int_t kind = GetDrawKind(subslot);
03552 
03553       if ((kind<kind_Specials) || (kind>=kind_Other)) continue;
03554 
03555       const char* drawopt = GetSpecialDrawOption(subslot);
03556 
03557       TObject* obj = subslot->GetAssignedObject();
03558 
03559       if (obj==0) continue;
03560 
03561       if ((selname == obj->GetName()) && (selectedobj==0)) {
03562          selectedobj = obj;
03563          selectdrawopt = drawopt;
03564       } else
03565          obj->Draw(drawopt ? drawopt : "");
03566    }
03567 
03568    // if one has selected object on the pad, one should
03569    // draw it as last to bring it to the front of other
03570    if (selectedobj!=0)
03571       selectedobj->Draw(selectdrawopt ? selectdrawopt : "");
03572 }
03573 
03574 bool TGo4ViewPanel::IsApplyToAllFlag()
03575 {
03576    return fbApplyToAllFlag;
03577 }
03578 
03579 bool TGo4ViewPanel::IsFreezeTitle()
03580 {
03581    return fbFreezeTitle;
03582 }
03583 
03584 void TGo4ViewPanel::ChangeDrawOptionForPad(TGo4Slot* padslot, int kind, int value, const char* drawopt )
03585 {
03586    TGo4LockGuard lock;
03587 
03588    TGo4Picture* subopt = GetPadOptions(padslot);
03589    if (subopt==0) return;
03590    switch(kind) {
03591       case 0:
03592       case 1:
03593       case 2: {
03594          int selindx = GetSelectedObjectIndex(padslot);
03595          subopt->SetDrawOption(drawopt, selindx);
03596          subopt->SetPadModified();
03597          break;
03598       }
03599       case 100: {
03600          subopt->SetPadModified();
03601          break;
03602       }
03603       case 101: {
03604          TPad* subpad = GetSlotPad(padslot);
03605          if (subpad!=0) {
03606             subpad->SetFillColor(value);
03607             if (subpad->GetFrame())
03608               subpad->GetFrame()->SetFillColor(value);
03609          }
03610          subopt->SetPadModified();
03611          break;
03612       }
03613       default:
03614         subopt->ChangeDrawOption(kind, value);
03615    }
03616 }
03617 
03618 void TGo4ViewPanel::ChangeDrawOption(int kind, int value, const char* drawopt)
03619 {
03620    TGo4LockGuard lock;
03621 
03622    bool scanall = IsApplyToAllFlag();
03623 
03624    if (kind==100) {
03625       gStyle->SetPalette(value);
03626       scanall = true;
03627    }
03628 
03629    TPad* pad = scanall ? GetCanvas() : GetActivePad();
03630    if (pad==0) pad = GetCanvas();
03631    TGo4Slot* slot = GetPadSlot(pad);
03632    if (slot==0) return;
03633 
03634    ChangeDrawOptionForPad(slot, kind, value, drawopt);
03635 
03636    TGo4Iter iter(slot, true);
03637    while (iter.next())
03638       ChangeDrawOptionForPad(iter.getslot(), kind, value, drawopt);
03639 
03640    RedrawPanel(pad, false);
03641 }
03642 
03643 void TGo4ViewPanel::ResetPadFillColors(TPad* pad, int col)
03644 {
03645    TGo4LockGuard lock;
03646 
03647    if(pad==0) return;
03648    pad->SetFillColor((Color_t)col);
03649    TIter iter(pad->GetListOfPrimitives());
03650    TObject* obj = 0;
03651    while((obj=iter()) != 0) {
03652       TPad* subpad = dynamic_cast<TPad*>(obj);
03653       TFrame* fram = dynamic_cast<TFrame*>(obj);
03654       if(subpad!=0)
03655          ResetPadFillColors(subpad, col);
03656       else
03657       if(fram!=0)
03658          fram->SetFillColor((Color_t)col);
03659    }
03660 }
03661 
03662 void TGo4ViewPanel::ClearPad(TPad* pad, bool removeitems, bool removesubpads)
03663 {
03664    TGo4LockGuard lock;
03665 
03666    BlockPanelRedraw(true);
03667    CleanupGedEditor();
03668    ProcessPadClear(pad, removeitems, removesubpads);
03669    if (ActivePad==0)
03670      SetActivePad(GetCanvas());
03671    GetCanvas()->SetSelected(0);
03672    BlockPanelRedraw(false);
03673 }
03674 
03675 void TGo4ViewPanel::ClearPadItems(TGo4Slot* padslot, TGo4Slot* remain)
03676 {
03677    if (padslot==0) return;
03678 
03679    for (int n=padslot->NumChilds()-1; n>=0; n--) {
03680       TGo4Slot* subslot = padslot->GetChild(n);
03681       int kind = GetDrawKind(subslot);
03682       if ((kind<kind_Permanet) && (subslot!=remain)) {
03683          delete subslot;
03684       }
03685    }
03686 }
03687 
03688 void TGo4ViewPanel::ProcessPadClear(TPad * pad, bool removeitems, bool removesubpads)
03689 {
03690    TGo4Slot* slot = GetPadSlot(pad);
03691    TGo4Picture* padopt = GetPadOptions(slot);
03692    if ((slot==0) || (padopt==0)) return;
03693 
03694 //   padopt->Clear(""); // remove all settings completely
03695    padopt->SetPadModified();
03696 
03697    if (removeitems)
03698      ClearPadItems(slot, 0);
03699 
03700    CheckObjectsAssigments(pad, slot);
03701 
03702    for(int n=slot->NumChilds()-1; n>=0; n--) {
03703       TGo4Slot* subslot = slot->GetChild(n);
03704 
03705       TPad* subpad = GetSlotPad(subslot);
03706       if (subpad==0) continue;
03707       ProcessPadClear(subpad, removeitems || removesubpads, removesubpads);
03708       if (!removesubpads) continue;
03709       if (ActivePad==subpad) ActivePad=0;
03710 
03711       delete subslot;
03712 
03713       pad->GetListOfPrimitives()->Remove(subpad);
03714 
03715       CallPanelFunc(panel_PadDeleted, subpad);
03716 
03717       if (GetCanvas()->GetSelectedPad()==subpad)
03718         GetCanvas()->SetSelectedPad(0);
03719 
03720       delete subpad;
03721    }
03722 
03723    CallPanelFunc(panel_Modified, pad);
03724 }
03725 
03726 void TGo4ViewPanel::SetPadDefaults(TPad* pad)
03727 {
03728    TGo4LockGuard lock;
03729 
03730    if (pad==0) return;
03731    gStyle->SetOptStat(go4sett->getOptStat());
03732    fbCanvasCrosshair = go4sett->getPadCrosshair();
03733    fbCanvasEventstatus = go4sett->getPadEventStatus();
03734 
03735    int fiPadcolorR, fiPadcolorG, fiPadcolorB;
03736    go4sett->getCanvasColor(fiPadcolorR, fiPadcolorG, fiPadcolorB);
03737    int padfillcolor =  TColor::GetColor(fiPadcolorR, fiPadcolorG, fiPadcolorB);
03738 
03739    if (padfillcolor!=0) {
03740      // now define associated colors for WBOX shading
03741      // note: root restricts this mechanism to number<50
03742      // we extend it since TGX11ttf expects the shadow color
03743      // the following are copies from TColor code:
03744      Int_t nplanes = 16;
03745      if (gVirtualX) gVirtualX->GetPlanes(nplanes);
03746      if (nplanes == 0) nplanes = 16;
03747      TColor *normal = gROOT->GetColor(padfillcolor);
03748      if(normal!=0) {
03749        Float_t h,l,s;
03750        normal->GetHLS(h,l,s);
03751        const char* cname = normal->GetName();
03752        Text_t aname[64];
03753        // assign the color numbers and names for shading:
03754        Float_t dr, dg, db, lr, lg, lb;
03755        TColor *dark = gROOT->GetColor(100+padfillcolor);
03756        if(dark==0) {
03757           snprintf(aname,64,"%s%s",cname,"_dark");
03758           new TColor(100+padfillcolor, -1, -1, -1, aname);
03759           dark = gROOT->GetColor(100+padfillcolor);
03760        }
03761        TColor *light = gROOT->GetColor(150+padfillcolor);
03762        if(light==0) {
03763           snprintf(aname,64,"%s%s",cname,"_bright");
03764           new TColor(150+padfillcolor, -1, -1, -1, aname);
03765           light = gROOT->GetColor(150+padfillcolor);
03766        }
03767 
03768        // set dark color
03769        TColor::HLStoRGB(h, 0.7*l, s, dr, dg, db);
03770        if (dark!=0) {
03771           if (nplanes > 8) dark->SetRGB(dr, dg, db);
03772           else             dark->SetRGB(0.3,0.3,0.3);
03773        }
03774 
03775       // set light color
03776       TColor::HLStoRGB(h, 1.2*l, s, lr, lg, lb);
03777       if (light!=0) {
03778          if (nplanes > 8) light->SetRGB(lr, lg, lb);
03779          else             light->SetRGB(0.8,0.8,0.8);
03780       }
03781      } else { // if(normal)
03782        cerr <<"TGo4ViewPanel:: Could not assign root shadow colors for number " << padfillcolor << endl;
03783        cerr <<"Never come here!!!" <<endl;
03784      }
03785    }
03786 
03787    pad->SetCrosshair(fbCanvasCrosshair);
03788    pad->SetFillColor(padfillcolor);
03789 
03790    fMenuBar->setItemChecked(EventStatusId, !fbCanvasEventstatus);
03791    ShowEventStatus();
03792 
03793    TGo4Picture* padopt = GetPadOptions(pad);
03794    if (padopt!=0) {
03795       padopt->SetDrawOption(0, TGo4Picture::PictureIndex);
03796       padopt->SetDrawOption(0, 0);
03797       padopt->SetTitleTime(go4sett->getDrawTimeFlag());
03798       padopt->SetTitleDate(go4sett->getDrawDateFlag());
03799       padopt->SetTitleItem(go4sett->getDrawItemFlag());
03800       padopt->SetHisStats(go4sett->getStatBoxVisible());
03801    }
03802 }
03803 
03804 void TGo4ViewPanel::DisplayPadStatus(TPad * pad)
03805 {
03806    if (pad==0) return;
03807    QString output = pad->GetName();
03808    output.append(": ");
03809    TGo4Picture* padopt = GetPadOptions(pad);
03810    if (padopt!=0)
03811        if (padopt->IsSuperimpose()) output.append(" SuperImpose:");
03812 
03813    if (IsApplyToAllFlag()) output.append(" All Pads:");
03814    output.append(" Ready");
03815    if (CanvasStatus!=0)
03816      CanvasStatus->message(output);
03817 }
03818 
03819 void TGo4ViewPanel::MoveScale(int expandfactor, int xaction, int yaction, int zaction)
03820 {
03821    TPad* selpad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
03822    if (selpad==0) return;
03823 
03824 //   cout << "TGo4ViewPanel::MoveScale " << expandfactor << " " << xaction << endl;
03825 
03826    TGo4Picture* padopt = GetPadOptions(selpad);
03827    if (padopt!=0) {
03828 //     padopt->MoveScale(expandfactor, xaction, yaction);
03829       MoveSingleScale(expandfactor, xaction, 0, padopt);
03830       MoveSingleScale(expandfactor, yaction, 1, padopt);
03831       MoveSingleScale(expandfactor, zaction, 2, padopt);
03832       if ((xaction==0) && (yaction==0) && (zaction==0)) {
03833          padopt->ClearRange();
03834          padopt->SetAutoScale(true);
03835       }
03836       padopt->SetPadModified();
03837    }
03838 
03839    if (IsApplyToAllFlag()) {
03840       TGo4Iter iter(GetPadSlot(selpad), kTRUE);
03841       while (iter.next()) {
03842          TPad* subpad = GetSlotPad(iter.getslot());
03843          padopt = GetPadOptions(subpad);
03844          if (padopt==0) continue;
03845 
03846 //       padopt->MoveScale(expandfactor, xaction, yaction);
03847          MoveSingleScale(expandfactor, xaction, 0, padopt);
03848          MoveSingleScale(expandfactor, yaction, 1, padopt);
03849          MoveSingleScale(expandfactor, zaction, 2, padopt);
03850          if ((xaction==0) && (yaction==0) && (zaction==0)) {
03851             padopt->ClearRange();
03852             padopt->SetAutoScale(true);
03853          }
03854          padopt->SetPadModified();
03855       }
03856    }
03857 
03858    RedrawPanel(selpad, false);
03859 }
03860 
03861 void TGo4ViewPanel::MoveSingleScale( int expandfactor, int action, int naxis, TGo4Picture* padopt)
03862 {
03863    if (action<=0) return;
03864 
03865    double new_umin, new_umax, fmin, fmax, tmin,tmax;
03866    double fact = expandfactor / 100.;
03867 
03868    bool sel = padopt->GetRange(naxis, new_umin, new_umax);
03869 
03870    padopt->GetFullRange(naxis, fmin, fmax);
03871 
03872    // we use number of dimensions to determine if we have contents
03873    int ndim = padopt->GetFullRangeDim();
03874 
03875    if (!sel || (new_umin>=new_umax))
03876       padopt->GetFullRange(naxis, new_umin, new_umax);
03877 
03878    double shift = (new_umax - new_umin) * fact;
03879    // protect if changes is out of full axis ranges
03880    if (shift<=0) return;
03881 
03882    switch(action) {
03883       case 1: if ((new_umax+shift) > fmax) // SlotShiftL
03884                  shift = fmax - new_umax;
03885               new_umin += shift;
03886               new_umax += shift;
03887               break;
03888       case 2: if (new_umin-shift < fmin) // SlotShiftR
03889                  shift = new_umin - fmin;
03890               new_umin -= shift;
03891               new_umax -= shift;
03892               break;
03893       case 3: if(ndim == 1){
03894                  new_umax -= shift;  // Expand 1d upper
03895               if(naxis < 1)          // lower only for X
03896                 new_umin += shift;  // Expand 1d lower X
03897               }
03898               if(ndim == 2){
03899                  new_umax -= shift;  // Expand 2d upper
03900               if(naxis < 2)          // lower only for X,Y
03901                 new_umin += shift;  // Expand 1d lower X,Y
03902               }
03903               break;
03904       case 4: if(ndim == 1){       // Shrink 1d upper
03905               if(naxis < 1){        // X axis
03906                  tmax = (-fact*new_umin+(1.-fact)*new_umax)/(1.-2.*fact);
03907                 tmin = (-fact*new_umax+(1.-fact)*new_umin)/(1.-2.*fact);  // Shrink 1d X
03908                 }
03909                 else {              // content, lower has not been expanded
03910                  tmax = (-fact*new_umin+new_umax)/(1.-fact);
03911                 tmin = (-fact*new_umax+(1.-fact)*new_umin)/(1.-2.*fact);  // Shrink 1d X
03912                 }
03913               }
03914               if(ndim == 2){
03915               if(naxis < 2){        // X,Y axis
03916                  tmax = (-fact*new_umin+(1.-fact)*new_umax)/(1.-2.*fact);
03917                 tmin = (-fact*new_umax+(1.-fact)*new_umin)/(1.-2.*fact);  // Shrink 1d X
03918                 }
03919                 else {              // content, lower has not been expanded
03920                  tmax = (-fact*new_umin+new_umax)/(1.-fact);
03921                 tmin = (-fact*new_umax+(1.-fact)*new_umin)/(1.-2.*fact);  // Shrink 1d X
03922                 }
03923               }
03924              new_umin=tmin;
03925                new_umax=tmax;
03926               if (new_umin < fmin) new_umin = fmin;
03927               if (new_umax > fmax) new_umax = fmax;
03928               break;
03929       default: return;
03930    }
03931 
03932    TakeSelectedAxisRange(naxis, padopt, new_umin, new_umax, false);
03933 
03934    if (naxis==ndim)
03935      if (padopt->GetRange(naxis, new_umin, new_umax))
03936         padopt->SetAutoScale(kFALSE);
03937 }
03938 
03939 void TGo4ViewPanel::TakeFullRangeFromHisto(TH1* h1, TGo4Picture* padopt, bool isfirsthisto)
03940 {
03941    if ((h1==0) || (padopt==0)) return;
03942 
03943    TAxis* xax = h1->GetXaxis();
03944    TAxis* yax = h1->GetYaxis();
03945    TAxis* zax = h1->GetZaxis();
03946    int ndim = h1->GetDimension();
03947 
03948    if (isfirsthisto) {
03949       padopt->SetFullRangeDim(ndim);
03950       padopt->SetFullRange(0, xax->GetBinLowEdge(1),
03951                               xax->GetBinUpEdge(xax->GetNbins()));
03952       if (ndim>1)
03953          padopt->SetFullRange(1, yax->GetBinLowEdge(1),
03954                                  yax->GetBinUpEdge(yax->GetNbins()));
03955       else
03956          padopt->ClearFullRange(2);
03957 
03958       if (ndim>2)
03959          padopt->SetFullRange(2, zax->GetBinLowEdge(1),
03960                                  zax->GetBinUpEdge(zax->GetNbins()));
03961    } else
03962       ndim = padopt->GetFullRangeDim();
03963 
03964    if (ndim>=3) return;
03965 
03966    Int_t dimindx = (ndim==1) ? 1 : 2;
03967 
03968    Double_t minimum = 0, maximum = 0;
03969    Bool_t first = kTRUE;
03970    if (!isfirsthisto) {
03971       padopt->GetFullRange(dimindx, minimum, maximum);
03972       first = kFALSE;
03973    }
03974 
03975    for (Int_t biny=1;biny<=yax->GetNbins();biny++)
03976      for (Int_t binx=1;binx<=xax->GetNbins();binx++) {
03977         Int_t bin = h1->GetBin(binx,biny);
03978         Double_t value = h1->GetBinContent(bin);
03979         if (first) {
03980            minimum = value;
03981            maximum = value;
03982            first = kFALSE;
03983         }
03984         if (value < minimum) minimum = value; else
03985         if (value > maximum) maximum = value;
03986      }
03987 
03988    padopt->SetFullRange(dimindx, minimum, maximum);
03989 }
03990 
03991 void TGo4ViewPanel::TakeFullRangeFromGraph(TGraph * gr, TGo4Picture * padopt, bool isfirst)
03992 {
03993    if ((gr==0) || (padopt==0)) return;
03994 
03995    Double_t minx(0), maxx(0), miny(0), maxy(0), xx, yy;
03996 
03997    if (isfirst) {
03998       if (gr->GetN()>0) {
03999          gr->GetPoint(0, minx, miny);
04000          maxx = minx; maxy = miny;
04001       }
04002    } else {
04003       padopt->GetFullRange(0, minx, maxx);
04004       padopt->GetFullRange(1, miny, maxy);
04005    }
04006 
04007    for (Int_t n=0;n<gr->GetN();n++) {
04008       gr->GetPoint(n, xx, yy);
04009       if (xx<minx) minx = xx; else if (xx>maxx) maxx = xx;
04010       if (yy<miny) miny = yy; else if (yy>maxy) maxy = yy;
04011    }
04012 
04013    padopt->SetFullRangeDim(1);
04014    padopt->SetFullRange(0, minx, maxx);
04015    padopt->SetFullRange(1, miny, maxy);
04016    padopt->ClearFullRange(2);
04017 }
04018 
04019 void TGo4ViewPanel::SetSelectedRangeToHisto(TH1* h1, THStack* hs, TGo4Picture* padopt, bool isthishisto)
04020 {
04021    // set selected range and stats position for histogram
04022 
04023    if ((h1==0) || (padopt==0)) return;
04024 
04025    int ndim = padopt->GetFullRangeDim();
04026 
04027    bool autoscale = padopt->IsAutoScale();
04028 
04029    double hmin(0.), hmax(0.), umin, umax;
04030 
04031    if (padopt->GetRange(0, umin, umax))
04032       { 
04033         // note: go4 range is full visible range of histogram
04034         // [low edge first bin, up edge last bin]
04035         // need to correct for upper bin width when transforming to ROOT user range:
04036         TAxis* ax=h1->GetXaxis();
04037         Double_t bwidthx=ax->GetBinWidth(ax->FindFixBin(umax));
04038         ax->SetRangeUser(umin, umax-bwidthx);    
04039       }
04040    else
04041       h1->GetXaxis()->UnZoom();
04042 
04043    // this peace of code allows autoscale for THStack when autoscale is
04044    // on and some range is selected. In this case ROOT uses h1->GetMaximum(),
04045    // which is calculated inside selected range. Therefore, even if range
04046    // selection of any histogram does not affect range with of THStack, range
04047    // selection defines GetMaximum() and GetMinimum() behaviour, used in autoscale
04048    // Comment out, while with unzoom of X axis user do not see full histogram range,
04049    // only previous selection until next refresh
04050 
04051 /*
04052    if (hs!=0) {
04053       TIter next(hs->GetHists());
04054       TH1* hs_h1 = 0;
04055       while ( (hs_h1 = (TH1*) next()) !=0 )
04056          if (padopt->GetRange(0, umin, umax))
04057             {
04058              // note: go4 range is full visible range of histogram
04059              // [low edge first bin, up edge last bin]
04060             // need to correct for upper bin width when transforming to ROOT user range:
04061             TAxis* as=hs_h1->GetXaxis();
04062             Double_t bwidths=as->GetBinWidth(as->FindFixBin(umax));
04063             as->SetRangeUser(umin, umax-bwidths);    
04064             }
04065          else
04066             hs_h1->GetXaxis()->UnZoom();
04067    }
04068 */
04069    if (padopt->GetRange(1, umin, umax)) {
04070       if (!autoscale && (ndim==1)) {
04071          hmin = umin;
04072          hmax = umax;
04073       }
04074         // note: go4 range is full visible range of histogram
04075         // [low edge first bin, up edge last bin]
04076         // need to correct for upper bin width when transforming to ROOT user range:
04077         TAxis* ay=h1->GetYaxis();
04078         Double_t bwidthy=ay->GetBinWidth(ay->FindFixBin(umax));
04079         ay->SetRangeUser(umin, umax-bwidthy);    
04080    } else {
04081       h1->GetYaxis()->UnZoom();
04082    }
04083 
04084    if (padopt->GetRange(2, umin, umax) && (ndim>1)) {
04085      if (!autoscale && (ndim==2)) {
04086         hmin = umin;
04087         hmax = umax;
04088      }
04089          // note: go4 range is full visible range of histogram
04090         // [low edge first bin, up edge last bin]
04091         // need to correct for upper bin width when transforming to ROOT user range:
04092         TAxis* az=h1->GetZaxis();
04093         Double_t bwidthz=az->GetBinWidth(az->FindFixBin(umax));
04094         az->SetRangeUser(umin, umax-bwidthz);    
04095    } else
04096      h1->GetZaxis()->UnZoom();
04097 
04098    if (hmin!=hmax) {
04099       // if scale axis is log, prevent negative values, othervise
04100       // histogram will not be displayed
04101       if (padopt->GetLogScale(ndim)) {
04102          if (hmax<=0) hmax = 1.;
04103          if ((hmin<=0) || (hmin>=hmax)) {
04104             hmin = hmax*1e-4;
04105             if (hmin>1.) hmin = 1;
04106          }
04107       }
04108 
04109       h1->SetMinimum(hmin);
04110       h1->SetMaximum(hmax);
04111       h1->SetBit(TH1::kIsZoomed);
04112       if (hs!=0) {
04113          hs->SetMinimum(hmin);
04114          hs->SetMaximum(hmax);
04115       }
04116    } else {
04117       // this is autoscale mode,
04118       h1->SetMinimum();
04119       h1->SetMaximum();
04120       if (hs!=0) {
04121          hs->SetMinimum();
04122          hs->SetMaximum();
04123       }
04124       h1->ResetBit(TH1::kIsZoomed);
04125       // here one can estimate actual range  which will be displayed on canvas
04126 
04127       if (ndim<3) {
04128          Double_t selmin = h1->GetMinimum();
04129          Double_t selmax = h1->GetMaximum();
04130 
04131          if (selmin>=selmax) padopt->ClearRange(ndim);
04132          else {
04133             bool islogscale = (ndim==1) && (padopt->GetLogScale(1)>0);
04134 
04135             if (islogscale) {
04136                if ((selmin>0) && (selmax>0)) {
04137                   selmin = TMath::Log10(selmin) + TMath::Log10(0.5);
04138                   selmin = TMath::Power(10, selmin);
04139                   selmax = TMath::Log10(selmax) + TMath::Log10(2*(0.9/0.95));
04140                   selmax = TMath::Power(10, selmax);
04141                }
04142 
04143             } else {
04144                Double_t yMARGIN = 0.05;
04145                #if ROOT_VERSION_CODE > ROOT_VERSION(5,0,9)
04146                yMARGIN = gStyle->GetHistTopMargin();
04147                #endif
04148                Double_t dymin = yMARGIN*(selmax-selmin);
04149                if ((selmin>=0) && (selmin-dymin < 0)) selmin = 0;
04150                                            else selmin-=dymin;
04151                selmax += yMARGIN*(selmax-selmin);
04152             }
04153 
04154             padopt->SetRange(ndim, selmin, selmax);
04155          }
04156       }
04157 
04158    }
04159 
04160    if (padopt->IsHisStats() && isthishisto) {
04161       TPaveStats* stats = dynamic_cast<TPaveStats*>
04162               (h1->GetListOfFunctions()->FindObject("stats"));
04163       if (stats==0) {
04164          stats  = new TPaveStats(
04165                        gStyle->GetStatX()-gStyle->GetStatW(),
04166                        gStyle->GetStatY()-gStyle->GetStatH(),
04167                        gStyle->GetStatX(),
04168                        gStyle->GetStatY(),"brNDC");
04169           stats->SetParent(h1);
04170           stats->UseCurrentStyle();
04171           stats->SetName("stats");
04172           h1->GetListOfFunctions()->Add(stats);
04173           stats->ConvertNDCtoPad();
04174         }
04175       padopt->GetStatsAttr(stats);
04176    }
04177 }
04178 
04179 bool TGo4ViewPanel::GetVisibleRange(TPad* pad, int naxis, double& min, double& max)
04180 {
04181    TGo4Picture* padopt = GetPadOptions(pad);
04182    if (padopt==0) return false;
04183 
04184    int NumDim = padopt->GetFullRangeDim();
04185 
04186    if ((naxis<0) || (naxis>NumDim)) return false;
04187 
04188    bool res = padopt->GetRange(naxis, min, max);
04189    if (!res || (min>=max))
04190       res = padopt->GetFullRange(naxis, min, max);
04191    return res;
04192 }
04193 
04194 
04195 bool TGo4ViewPanel::TakeSelectedAxisRange(int naxis, TGo4Picture* padopt, double selmin, double selmax, bool force)
04196 {
04197    if ((selmin==-1) && (selmax==-1)) return false;
04198 
04199 //   cout << "TakeSelectedAxisRange " << naxis << "  min = " << selmin << "  max = " << selmax << endl;
04200 
04201    double min, max, umin, umax;
04202 
04203    bool full = padopt->GetFullRange(naxis, min, max);
04204    bool sel = padopt->GetRange(naxis, umin, umax);
04205 
04206    if (!full || (min>=max) || (selmin>=selmax)) {
04207       padopt->ClearRange(naxis);
04208       return true;
04209    }
04210 
04211    double delta = (max-min) / 100000.;
04212    bool changed = false;
04213 
04214    if (umin<umax) {
04215       if (fabs(umin-selmin)>delta) { umin = selmin; changed = true; }
04216       if (fabs(umax-selmax)>delta) { umax = selmax; changed = true; }
04217    } else {
04218       umin = selmin;
04219       umax = selmax;
04220       changed = true;
04221    }
04222 
04223    if ((selmin<min+delta) && (selmax>max-delta) && !force)
04224       padopt->ClearRange(naxis);
04225    else
04226       padopt->SetRange(naxis, umin, umax);
04227 
04228    return changed;
04229 }
04230 
04231 bool TGo4ViewPanel::TakeSelectedAxisRange(int naxis,  TGo4Picture * padopt, TAxis* ax)
04232 {
04233    Double_t selmin, selmax;
04234 
04235    // check if something selected on axis
04236    if (((ax->GetFirst()<=0) && (ax->GetLast()>=ax->GetNbins()-1)) ||
04237        (ax->GetFirst()>=ax->GetLast())) {
04238           selmin = -1111;
04239           selmax = -1111;
04240        } else {
04241           selmin = ax->GetBinLowEdge(ax->GetFirst());
04242           selmax = ax->GetBinUpEdge(ax->GetLast());
04243        }
04244 
04245    return TakeSelectedAxisRange(naxis, padopt, selmin, selmax, false);
04246 }
04247 
04248 void TGo4ViewPanel::PadRangeAxisChanged(TPad* pad)
04249 {
04250    TGo4LockGuard lock;
04251 
04252    TGo4Picture* padopt = GetPadOptions(pad);
04253 
04254    if (IsRedrawBlocked() || (pad==0) || (padopt==0)) return;
04255 
04256    // check if we have histogram and can take range from it
04257    TH1* h1 = GetPadHistogram(pad);
04258 
04259    if (h1!=0) {
04260       Int_t ndim = padopt->GetFullRangeDim();
04261 
04262       TakeSelectedAxisRange(0, padopt, h1->GetXaxis());
04263       if (ndim>1) TakeSelectedAxisRange(1, padopt, h1->GetYaxis());
04264       if (ndim>2) TakeSelectedAxisRange(2, padopt, h1->GetZaxis());
04265       if (ndim<3) {
04266 
04267          bool iszoomed = h1->TestBit(TH1::kIsZoomed);
04268 
04269          padopt->SetAutoScale(!iszoomed);
04270 
04271          Double_t selmin = h1->GetMinimum();
04272          Double_t selmax = h1->GetMaximum();
04273 
04274          if (iszoomed)
04275             padopt->SetRange(ndim, selmin, selmax);
04276          else
04277             if (selmin>=selmax) padopt->ClearRange(ndim);
04278             else {
04279                bool islogscale = (ndim==1) && (pad->GetLogy()>0);
04280 
04281                if (islogscale) {
04282                   if ((selmin>0) && (selmax>0)) {
04283                      selmin = TMath::Log10(selmin) + TMath::Log10(0.5);
04284                      selmin = TMath::Power(10, selmin);
04285                      selmax = TMath::Log10(selmax) + TMath::Log10(2*(0.9/0.95));
04286                      selmax = TMath::Power(10, selmax);
04287                   }
04288 
04289                } else {
04290                   Double_t yMARGIN = 0.05;
04291                   #if ROOT_VERSION_CODE > ROOT_VERSION(5,0,9)
04292                   yMARGIN = gStyle->GetHistTopMargin();
04293                   #endif
04294                   Double_t dymin = yMARGIN*(selmax-selmin);
04295                   if ((selmin>=0) && (selmin-dymin < 0)) selmin = 0;
04296                                               else selmin-=dymin;
04297                   selmax += yMARGIN*(selmax-selmin);
04298                }
04299 
04300                padopt->SetRange(ndim, selmin, selmax);
04301             }
04302       }
04303 
04304       // inform that options were changed in panel
04305       CallPanelFunc(panel_Updated, pad);
04306       return;
04307    }
04308 
04309    Double_t rxmin, rxmax, rymin, rymax;
04310    pad->GetRangeAxis(rxmin, rymin, rxmax, rymax);
04311 
04312    if (pad->GetLogx()>0) {
04313       rxmin = TMath::Power(10., rxmin);
04314       rxmax = TMath::Power(10., rxmax);
04315    }
04316 
04317    if (pad->GetLogy()>0) {
04318       rymin = TMath::Power(10., rymin);
04319       rymax = TMath::Power(10., rymax);
04320    }
04321 
04322    PadRangeAxisChanged(pad, rxmin, rxmax, rymin, rymax);
04323 }
04324 
04325 void TGo4ViewPanel::PadRangeAxisChanged(TPad* pad, double rxmin, double rxmax, double rymin, double rymax)
04326 {
04327    TGo4LockGuard lock;
04328 
04329    if (IsRedrawBlocked() || (pad==0)) return;
04330 
04331    TGo4Picture* padopt = GetPadOptions(pad);
04332    if (padopt==0) return;
04333 
04334    TakeSelectedAxisRange(0, padopt, rxmin, rxmax, false);
04335    TakeSelectedAxisRange(1, padopt, rymin, rymax, false);
04336 
04337    CallPanelFunc(panel_Updated, pad);
04338 }
04339 
04340 void TGo4ViewPanel::GetSelectedRange(int& ndim, bool& autoscale, double& xmin, double& xmax, double& ymin, double& ymax, double& zmin, double& zmax)
04341 {
04342    ndim = 0;
04343    TGo4Picture* padopt = GetPadOptions(GetActivePad());
04344    if (padopt==0) return;
04345 
04346    ndim = padopt->GetFullRangeDim();
04347    autoscale = padopt->IsAutoScale();
04348 
04349    GetVisibleRange(GetActivePad(), 0, xmin, xmax);
04350    GetVisibleRange(GetActivePad(), 1, ymin, ymax);
04351    GetVisibleRange(GetActivePad(), 2, zmin, zmax);
04352 }
04353 
04354 void TGo4ViewPanel::SetAutoScale(bool on, TPad* selpad)
04355 {
04356    TGo4LockGuard lock;
04357 
04358    bool modified = false;
04359    bool applytoall = false;
04360 
04361    if (selpad==0) {
04362       applytoall = IsApplyToAllFlag();
04363       selpad = applytoall ? GetCanvas() : GetActivePad();
04364    }
04365    if (selpad==0) return;
04366 
04367    TGo4Picture* padopt = GetPadOptions(selpad);
04368    if (padopt!=0) {
04369       if (on!=padopt->IsAutoScale()) padopt->SetPadModified();
04370       padopt->SetAutoScale(on);
04371       modified = modified || padopt->IsPadModified();
04372    }
04373 
04374    if (applytoall) {
04375       TGo4Iter iter(GetPadSlot(selpad), kTRUE);
04376       while (iter.next()) {
04377          TPad* subpad = GetSlotPad(iter.getslot());
04378          padopt = GetPadOptions(subpad);
04379          if (padopt==0) continue;
04380          if (on!=padopt->IsAutoScale()) padopt->SetPadModified();
04381          padopt->SetAutoScale(on);
04382          modified = modified || padopt->IsPadModified();
04383       }
04384    }
04385 
04386    if (modified) RedrawPanel(selpad, false);
04387 }
04388 
04389 void TGo4ViewPanel::SetSelectedRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
04390 {
04391    TGo4LockGuard lock;
04392 
04393    TPad* selpad = IsApplyToAllFlag() ? GetCanvas() : GetActivePad();
04394    if (selpad==0) return;
04395 
04396    TGo4Picture* padopt = GetPadOptions(selpad);
04397    if (padopt!=0) {
04398       Int_t ndim = padopt->GetFullRangeDim();
04399 
04400       TakeSelectedAxisRange(0, padopt, xmin, xmax, true);
04401       if (ndim>1) TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
04402       if (ndim>2) TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
04403       if (!padopt->IsAutoScale()) {
04404          if (ndim==1) TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
04405          if (ndim==2) TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
04406       }
04407       padopt->SetPadModified();
04408    }
04409 
04410    if (IsApplyToAllFlag()) {
04411       TGo4Iter iter(GetPadSlot(selpad), kTRUE);
04412       while (iter.next()) {
04413          TPad* subpad = GetSlotPad(iter.getslot());
04414          padopt = GetPadOptions(subpad);
04415          if (padopt==0) continue;
04416          Int_t ndim = padopt->GetFullRangeDim();
04417          TakeSelectedAxisRange(0, padopt, xmin, xmax, true);
04418          if (ndim>1) TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
04419          if (ndim>2) TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
04420          if (!padopt->IsAutoScale()) {
04421             if (ndim==1) TakeSelectedAxisRange(1, padopt, ymin, ymax, true);
04422             if (ndim==2) TakeSelectedAxisRange(2, padopt, zmin, zmax, true);
04423          }
04424 
04425          padopt->SetPadModified();
04426       }
04427    }
04428 
04429    RedrawPanel(selpad, false);
04430 }
04431 
04432 void TGo4ViewPanel::enterEvent( QEvent * e )
04433 {
04434     QWidget::enterEvent(e);
04435 //    if (ScanDrawOptions(GetActivePad(), GetPadOptions(GetActivePad()), true)) {
04436 //      cout << "Options are changed" << endl;
04437 //      CallPanelFunc(panel_Updated, GetActivePad());
04438 //    }
04439 }
04440 
04441 void TGo4ViewPanel::leaveEvent( QEvent * e )
04442 {
04443     #if ROOT_VERSION_CODE < ROOT_VERSION(4,3,1)
04444 
04445 //    #if __GO4ROOTVERSION__ < 40301
04446     if(fxPeditor) fxPeditor->DeleteEditors();
04447     #endif
04448     QWidget::leaveEvent(e);
04449 //    if (ScanDrawOptions(GetActivePad(), GetPadOptions(GetActivePad()), true)) {
04450 //      cout << "Options are changed" << endl;
04451 //       CallPanelFunc(panel_Updated, GetActivePad());
04452 //    }
04453 }
04454 
04455 void TGo4ViewPanel::closeEvent( QCloseEvent* ce )
04456 {
04457     ce->accept();
04458     delete this;
04459 }
04460 
04461 void TGo4ViewPanel::paintEvent(QPaintEvent* e)
04462 {
04463    QWidget::paintEvent(e);
04464 }
04465 
04466 void TGo4ViewPanel::resizeEvent(QResizeEvent * e)
04467 {
04468    QWidget::resizeEvent(e);
04469 }
04470 
04471 void TGo4ViewPanel::mouseReleaseEvent(QMouseEvent * e)
04472 {
04473    CheckResizeFlags();
04474 }
04475 
04476 void TGo4ViewPanel::ResizeGedEditorSlot()
04477 {
04478    TGo4LockGuard lock;
04479 
04480    ResizeGedEditor();
04481    fxGo4QRootCanvas->checkResizeFlag();
04482 }
04483 
04484 void TGo4ViewPanel::ResizeGedEditor()
04485 {
04486    #ifdef __GO4GED__
04487    TGo4LockGuard lock;
04488    TGedEditor* ed = dynamic_cast<TGedEditor*> (fxPeditor);
04489    if ((ed!=0) && fbEditorFrameVisible)
04490       ed->Resize(fxRooteditor->width(),fxRooteditor->height());
04491    #endif
04492 }
04493 
04494 void TGo4ViewPanel::ActivateInGedEditor(TObject* obj)
04495 {
04496    if (!fbEditorFrameVisible) return;
04497    #ifdef __GO4GED__
04498    TGedEditor* ed = dynamic_cast<TGedEditor*> (fxPeditor);
04499    if ((ed!=0) && (obj!=0))
04500       if (!obj->InheritsFrom(THStack::Class()) && !obj->InheritsFrom(TMultiGraph::Class())) {
04501          gTQSender = GetCanvas();
04502          ed->SetModel(GetActivePad(), obj, kButton1Down);
04503       }
04504    #endif
04505 }
04506 
04507 void TGo4ViewPanel::CleanupGedEditor()
04508 {
04509    #ifdef __GO4GED__
04510 //   cout << "TGo4ViewPanel::CleanupGedEditor()" << endl;
04511    TGedEditor* ed = dynamic_cast<TGedEditor*> (fxPeditor);
04512    if (ed==0) return;
04513    if (fDummyHisto==0) {
04514        fDummyHisto=new TH1I("dummyhisto","dummyhisto",100, -10., 10.);
04515        fDummyHisto->FillRandom("gaus",1000);
04516        fDummyHisto->SetDirectory(0);
04517        fDummyHisto->SetBit(kCanDelete, kFALSE);
04518    }
04519    gTQSender = GetCanvas();
04520    ed->SetModel(0, fDummyHisto, kButton1Down);
04521    ed->SetModel(0, GetCanvas(), kButton1Down);
04522    #endif
04523 }
04524 
04525 void TGo4ViewPanel::CheckResizeFlags()
04526 {
04527    TGo4LockGuard lock;
04528    fxGo4QRootCanvas->checkResizeFlag();
04529    go4sett->storePanelSize(this);
04530 }
04531 
04532 void TGo4ViewPanel::ShootRepaintTimer()
04533 {
04534    ShootRepaintTimer(GetCanvas());
04535 }
04536 
04537 void TGo4ViewPanel::ShootRepaintTimer(TPad* pad)
04538 {
04539    if (IsRepaintTimerActive()) return;
04540 
04541    if (pad==0) pad = GetCanvas();
04542 
04543    fxRepaintTimerPad = pad;
04544    CallServiceFunc(service_PanelTimer);
04545 }
04546 
04547 bool TGo4ViewPanel::IsRepaintTimerActive()
04548 {
04549    return fxRepaintTimerPad!=0;
04550 }
04551 
04552 void TGo4ViewPanel::checkRepaintSlot()
04553 {
04554    TPad* pad = fxRepaintTimerPad;
04555    fxRepaintTimerPad = 0;
04556    CheckResizeFlags();
04557    if (pad!=0)
04558       RedrawPanel(pad, false);
04559 }
04560 
04561 void TGo4ViewPanel::PadDeleted(TPad* pad)
04562 {
04563 //   if (pad==GetActivePad())
04564 //     SetActivePad(GetCanvas());
04565 
04566    TGo4Slot* slot = GetPadSlot(pad);
04567    if (slot!=0) delete slot;
04568 
04569    GetCanvas()->SetSelectedPad(GetCanvas());
04570    GetCanvas()->SetSelected(GetCanvas());
04571    TGo4WorkSpace::Instance()->SetSelectedPad(GetCanvas());
04572 }
04573 
04574 // marker functions
04575 
04576 int TGo4ViewPanel::GetNumMarkers(TPad* pad, int kind)
04577 {
04578    TGo4Slot* slot = GetPadSlot(pad);
04579    if (slot==0) return 0;
04580 
04581    int res = 0;
04582 
04583    for (int n=0; n<slot->NumChilds();n++) {
04584      TGo4Slot* subslot = slot->GetChild(n);
04585      if (GetDrawKind(subslot)==kind) res++;
04586    }
04587    return res;
04588 }
04589 
04590 void TGo4ViewPanel::AddMarkerObj(TPad* pad, int kind, TObject* obj)
04591 {
04592    TGo4Slot* padslot = GetPadSlot(pad);
04593    if (padslot==0) { delete obj; return; }
04594 
04595    QString basename;
04596    switch(kind) {
04597      case kind_Marker: basename = "Marker"; break;
04598      case kind_Window: basename = "Window"; break;
04599      case kind_Poly: basename = "Polygon"; break;
04600      case kind_Latex: basename = "Latex"; break;
04601      case kind_Arrow: basename = "Arrow"; break;
04602      default: basename = "Something"; break;
04603    }
04604 
04605    QString slotname;
04606    int cnt = 0;
04607    do {
04608      slotname = basename + QString::number(cnt++);
04609    } while (padslot->FindChild(slotname.latin1())!=0);
04610 
04611    TGo4Slot* objslot = AddDrawObject(pad, kind, slotname.latin1(), obj, true, 0);
04612 
04613    SetActiveObj(pad, kind, objslot);
04614 }
04615 
04616 void TGo4ViewPanel::SetActiveObj(TPad* pad, int kind, TGo4Slot* activeslot)
04617 {
04618    TGo4Slot* slot = GetPadSlot(pad);
04619    if (slot==0) return;
04620 
04621    for (int n=0; n<slot->NumChilds();n++) {
04622       TGo4Slot* subslot = slot->GetChild(n);
04623       int drawkind = GetDrawKind(subslot);
04624       if (drawkind!=kind) continue;
04625 
04626       if (subslot!=activeslot)
04627         subslot->RemovePar("::ActiveMarker");
04628       else
04629         subslot->SetPar("::ActiveMarker", "1");
04630    }
04631 }
04632 
04633 TObject* TGo4ViewPanel::GetActiveObj(TPad* pad, int kind)
04634 {
04635    int selkind;
04636    TObject* selobj;
04637    TGo4Slot* selslot = GetSelectedSlot(pad, &selkind, &selobj);
04638    if ((kind==selkind) && (selobj!=0)) return selobj;
04639 
04640    TGo4Slot* slot = GetPadSlot(pad);
04641    if (slot==0) return 0;
04642 
04643    TObject* lastobj = 0;
04644 
04645    for (int n=0; n<slot->NumChilds();n++) {
04646       TGo4Slot* subslot = slot->GetChild(n);
04647       int drawkind = GetDrawKind(subslot);
04648       if (drawkind!=kind) continue;
04649 
04650       lastobj = subslot->GetAssignedObject();
04651       if (subslot->GetPar("::ActiveMarker")!=0)
04652         return lastobj;
04653    }
04654 
04655    return lastobj;
04656 }
04657 
04658 QString TGo4ViewPanel::GetActiveObjName(TPad* pad, int kind)
04659 {
04660    TObject* obj = GetActiveObj(pad, kind);
04661    return (obj==0) ? QString("null") : QString(obj->GetName());
04662 }
04663 
04664 void TGo4ViewPanel::OptionsMenuItemActivated(int id)
04665 {
04666    TGo4LockGuard lock;
04667 
04668    switch (id) {
04669       case CrosshairId: {
04670          fbCanvasCrosshair = !fMenuBar->isItemChecked(CrosshairId);
04671          GetCanvas()->SetCrosshair(fbCanvasCrosshair);
04672 
04673          #if ROOT_VERSION_CODE < ROOT_VERSION(4,0,8)
04674 
04675 //         #if __GO4ROOTVERSION__ < 40008
04676            TGo4Iter(GetPadSlot(GetCanvas()), true);
04677            while (iter.next()) {
04678              TPad* subpad = GetSlotPad(iter.getslot());
04679              if (subpad!=0) {
04680                 subpad->SetCrosshair(fbCanvasCrosshair);
04681                 subpad->Modified();
04682              }
04683           }
04684          #endif
04685 
04686          GetCanvas()->Modified();
04687          GetCanvas()->Update();
04688          CallPanelFunc(panel_Updated, GetCanvas());
04689          break;
04690       }
04691 
04692       case FreezeTitleId: {
04693          fbFreezeTitle = !fMenuBar->isItemChecked(FreezeTitleId);
04694          break;
04695       }
04696 
04697       case SetTitleTextId:  {
04698          bool ok = false;
04699          QString mycaption = caption();
04700          QString oldtitle = mycaption.remove(fPanelName + ": ");
04701          QString text = QInputDialog::getText(
04702                           GetPanelName(), "Enter Viewpanel Title:", QLineEdit::Normal,
04703                          oldtitle, &ok, this );
04704          if ( ok && !text.isEmpty() ) {
04705             QString mycaption = GetPanelName();
04706             mycaption += ": ";
04707             mycaption += text;
04708             setCaption(mycaption);
04709             fbFreezeTitle = true;
04710          }
04711          break;
04712       }
04713 
04714       default:
04715         if (id>1000) {
04716            bool s = !fMenuBar->isItemChecked(id);
04717            ChangeDrawOption(id-1000, s, 0);
04718         }
04719    }
04720 }
04721 
04722 
04723 void TGo4ViewPanel::ApplyToAllToggled(bool on)
04724 {
04725 //   if (IsRedrawBlocked()) return;
04726 
04727    fbApplyToAllFlag = on;
04728 }
04729 
04730 void TGo4ViewPanel::AutoScaleToggled(bool on)
04731 {
04732    if (IsRedrawBlocked()) return;
04733 
04734    SetAutoScale(on, 0);
04735 }
04736 
04737 void TGo4ViewPanel::panelSlot(TGo4ViewPanel * panel, TPad * pad, int signalid)
04738 {
04739    if (panel!=this) return;
04740 
04741    BlockPanelRedraw(true);
04742 
04743    TGo4Picture* padopt = GetPadOptions(GetActivePad());
04744    if (padopt!=0)
04745      fAutoScaleCheck->setChecked(padopt->IsAutoScale());
04746 
04747    BlockPanelRedraw(false);
04748 }
04749 
04750 void TGo4ViewPanel::SuperImposeToggled(bool on)
04751 {
04752    if (IsRedrawBlocked()) return;
04753 
04754    ChangeDrawOption(11, on, "");
04755 }
04756 
04757 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Fri Nov 28 12:59:26 2008 for Go4-v3.04-1 by  doxygen 1.4.2