]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MONITOR/AliMonitorClient.cxx
bug fixed while filling the object AliPMDcluster
[u/mrichter/AliRoot.git] / MONITOR / AliMonitorClient.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  This class receives monitor histograms from a monitor process and        //
21 //  provides a graphical user interface for browsing and analysing the       //
22 //  monitor histograms.                                                      //
23 //                                                                           //
24 ///////////////////////////////////////////////////////////////////////////////
25
26
27 #include "AliMonitorClient.h"
28 #include "AliMonitorDialog.h"
29 #include "AliMonitorProcess.h"
30 #include <TGMsgBox.h>
31 #include <TGFileDialog.h>
32 #include <TSystem.h>
33 #include <TMessage.h>
34 #include <TCanvas.h>
35 #include <TApplication.h>
36 #include <TStyle.h>
37
38
39 ClassImp(AliMonitorClient) 
40
41
42 const char* AliMonitorClient::fgSettingsFileName = ".AliMonitorClient";
43
44 //_____________________________________________________________________________
45 class AliMonitorStringDlg : public AliMonitorDialog {
46
47 public:
48   AliMonitorStringDlg(TString& string, TGFrame* main, const char* title,
49                       const char* label);
50   virtual ~AliMonitorStringDlg();
51
52   virtual void       OnOkClicked();
53
54 private:
55   TGLayoutHints*     fStringLayout;
56   TGLabel*           fStringLabel;
57   TGTextEntry*       fStringEntry;
58
59   TString&           fString;
60 };
61
62
63 //_____________________________________________________________________________
64 AliMonitorStringDlg::AliMonitorStringDlg(TString& string, TGFrame* main, 
65                                          const char* title, 
66                                          const char* label) :
67   AliMonitorDialog(main, 300, 80), fString(string)
68 {
69 // create a dialog for connecting to a monitor process
70
71   fStringLayout = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2);
72   fStringLabel = new TGLabel(fFrame, label);
73   fFrame->AddFrame(fStringLabel, fStringLayout);
74   fStringEntry = new TGTextEntry(fFrame, string.Data());
75   fStringEntry->Resize(100, fStringEntry->GetDefaultHeight());
76   fFrame->AddFrame(fStringEntry, fStringLayout);
77
78   fString = "";
79
80   fMain->SetWindowName(title);
81   fMain->MapSubwindows();
82   fMain->Layout();
83   gClient->WaitFor(fMain);
84 }
85
86 //_____________________________________________________________________________
87 AliMonitorStringDlg::~AliMonitorStringDlg()
88 {
89 // clean up
90
91   delete fStringLabel;
92   delete fStringLayout;
93   delete fStringEntry;
94 }
95
96 //_____________________________________________________________________________
97 void AliMonitorStringDlg::OnOkClicked()
98 {
99   fString = fStringEntry->GetText();
100 }
101
102
103
104 //_____________________________________________________________________________
105 class AliMonitorNumberDlg : public AliMonitorDialog {
106
107 public:
108   AliMonitorNumberDlg(Float_t& value, TGFrame* main, const char* title,
109                       const char* label, Float_t min);
110   virtual ~AliMonitorNumberDlg();
111
112   virtual void       OnOkClicked();
113
114 private:
115   TGLayoutHints*     fNumberLayout;
116   TGLabel*           fNumberLabel;
117   TGNumberEntry*     fNumberEntry;
118
119   Float_t&           fNumber;
120 };
121
122
123 //_____________________________________________________________________________
124 AliMonitorNumberDlg::AliMonitorNumberDlg(Float_t& value, TGFrame* main, 
125                                          const char* title, const char* label, 
126                                          Float_t min) :
127   AliMonitorDialog(main, 250, 80), fNumber(value)
128 {
129 // create a dialog for getting a number
130
131   fNumberLayout = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2);
132   fNumberLabel = new TGLabel(fFrame, label);
133   fFrame->AddFrame(fNumberLabel, fNumberLayout);
134   fNumberEntry = new TGNumberEntry(fFrame, value, 4, -1,
135                                    TGNumberFormat::kNESRealOne);
136   fNumberEntry->SetLimits(TGNumberFormat::kNELLimitMin, min, 0);
137   fFrame->AddFrame(fNumberEntry, fNumberLayout);
138
139   fNumber = -1;
140
141   fMain->SetWindowName(title);
142   fMain->MapSubwindows();
143   fMain->Layout();
144   gClient->WaitFor(fMain);
145 }
146
147 //_____________________________________________________________________________
148 AliMonitorNumberDlg::~AliMonitorNumberDlg()
149 {
150 // clean up
151
152   delete fNumberLabel;
153   delete fNumberLayout;
154   delete fNumberEntry;
155 }
156
157 //_____________________________________________________________________________
158 void AliMonitorNumberDlg::OnOkClicked()
159 {
160   fNumber = fNumberEntry->GetNumber();
161 }
162
163
164
165 // constants for menu entries
166 enum {kMenuFileConnect, kMenuFileDisconnect, kMenuFileOpen, kMenuFileExit,
167       kMenuViewToolBar, kMenuViewTree, kMenuViewDescription, 
168       kMenuViewReference, kMenuViewStatistics,
169       kMenuFavAdd, kMenuFavDelete, 
170       kMenuFavLoad, kMenuFavSave,  kMenuFavSaveAs, kMenuFavSaveOnExit,
171       kMenuRefLoad, kMenuRefThreshold, 
172       kMenuRefTakeCurrent, kMenuRefSave, kMenuRefSaveAs,
173       kMenuOptLoop, kMenuOptPrint, 
174       kMenuOptSave, kMenuOptSaveOnExit,
175       kMenuHelpDoc, kMenuHelpAbout
176 };
177
178 //_____________________________________________________________________________
179 AliMonitorClient::AliMonitorClient():
180   TGMainFrame(gClient->GetRoot(), 500, 300)
181 {
182 // initialize the monitoring client window
183
184   // *** menu bar ***
185   fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,
186                                       0, 0, 1, 1);
187   fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
188   fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
189
190   // File menu
191   fMenuFile = new TGPopupMenu(gClient->GetRoot());
192   fMenuFile->AddEntry("&Connect...", kMenuFileConnect);
193   fMenuFile->AddEntry("&Disconnect...", kMenuFileDisconnect);
194   fMenuFile->HideEntry(kMenuFileDisconnect);
195   fMenuFile->AddEntry("&Open...", kMenuFileOpen);
196   fMenuFile->AddSeparator();
197   fMenuFile->AddEntry("E&xit", kMenuFileExit);
198   fMenuFile->Connect("Activated(Int_t)", "AliMonitorClient", this,
199                      "OnMenuActivated(Int_t)");
200
201   // View menu
202   fMenuView = new TGPopupMenu(gClient->GetRoot());
203   fMenuView->AddEntry("Tool&bar", kMenuViewToolBar);
204   fMenuView->CheckEntry(kMenuViewToolBar);
205   fMenuView->AddEntry("&Tree", kMenuViewTree);
206   fMenuView->CheckEntry(kMenuViewTree);
207   fMenuView->AddEntry("&Description", kMenuViewDescription);
208   fMenuView->CheckEntry(kMenuViewDescription);
209   fMenuView->AddSeparator();
210   fMenuView->AddEntry("&Reference", kMenuViewReference);
211   fMenuView->CheckEntry(kMenuViewReference);
212   AliMonitorHisto::SetDrawRef(kTRUE);
213   fMenuView->AddEntry("&Statistics", kMenuViewStatistics);
214   fMenuView->CheckEntry(kMenuViewStatistics);
215   gStyle->SetOptStat(1110);
216   fMenuView->Connect("Activated(Int_t)", "AliMonitorClient", this,
217                      "OnMenuActivated(Int_t)");
218
219   // Favorites menu
220   fMenuFavorites = new TGPopupMenu(gClient->GetRoot());
221   fMenuFavorites->AddEntry("&Add", kMenuFavAdd);
222   fMenuFavorites->DisableEntry(kMenuFavAdd);
223   fMenuFavorites->AddEntry("&Delete", kMenuFavDelete);
224   fMenuFavorites->DisableEntry(kMenuFavDelete);
225   fMenuFavorites->AddSeparator();
226   fMenuFavorites->AddEntry("&Load...", kMenuFavLoad);
227   fMenuFavorites->AddEntry("&Save", kMenuFavSave);
228   fMenuFavorites->DisableEntry(kMenuFavSave);
229   fMenuFavorites->AddEntry("&Save As...", kMenuFavSaveAs);
230   fMenuFavorites->DisableEntry(kMenuFavSaveAs);
231   fMenuFavorites->AddEntry("Save On &Exit", kMenuFavSaveOnExit);
232   fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
233   fMenuFavorites->Connect("Activated(Int_t)", "AliMonitorClient", this,
234                           "OnMenuActivated(Int_t)");
235
236   // Reference menu
237   fMenuReference = new TGPopupMenu(gClient->GetRoot());
238   fMenuReference->AddEntry("&Load...", kMenuRefLoad);
239   fMenuReference->AddEntry("&Threshold...", kMenuRefThreshold);
240   fMenuReference->AddSeparator();
241   fMenuReference->AddEntry("Take &Current", kMenuRefTakeCurrent);
242   fMenuReference->DisableEntry(kMenuRefTakeCurrent);
243   fMenuReference->AddEntry("&Save", kMenuRefSave);
244   fMenuReference->DisableEntry(kMenuRefSave);
245   fMenuReference->AddEntry("Save &As...", kMenuRefSaveAs);
246   fMenuReference->DisableEntry(kMenuRefSaveAs);
247   fMenuReference->Connect("Activated(Int_t)", "AliMonitorClient", this,
248                           "OnMenuActivated(Int_t)");
249
250   // Options menu
251   fMenuOptions = new TGPopupMenu(gClient->GetRoot());
252   fMenuOptions->AddEntry("&Loop Interval...", kMenuOptLoop);
253   fMenuOptions->AddEntry("&Print Command...", kMenuOptPrint);
254   fMenuOptions->AddSeparator();
255   fMenuOptions->AddEntry("&Save Settings", kMenuOptSave);
256   fMenuOptions->AddEntry("Save Settings on &Exit", kMenuOptSaveOnExit);
257   fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
258   fMenuOptions->Connect("Activated(Int_t)", "AliMonitorClient", this,
259                         "OnMenuActivated(Int_t)");
260
261   // Help menu
262   fMenuHelp = new TGPopupMenu(gClient->GetRoot());
263   fMenuHelp->AddEntry("&Documentation...", kMenuHelpDoc);
264   fMenuHelp->AddEntry("A&bout...", kMenuHelpAbout);
265   fMenuHelp->Connect("Activated(Int_t)", "AliMonitorClient", this,
266                      "OnMenuActivated(Int_t)");
267
268   // menu bar
269   fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
270   fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
271   fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout);
272   fMenuBar->AddPopup("F&avorites", fMenuFavorites, fMenuBarItemLayout);
273   fMenuBar->AddPopup("&Reference", fMenuReference, fMenuBarItemLayout);
274   fMenuBar->AddPopup("&Options", fMenuOptions, fMenuBarItemLayout);
275   fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout);
276
277   AddFrame(fMenuBar, fMenuBarLayout);
278
279
280   // *** tool bar ***
281   fToolBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2);
282   fToolBarSep = new TGHorizontal3DLine(this);
283   AddFrame(fToolBarSep, fToolBarLayout);
284   fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame);
285   AddFrame(fToolBar, fToolBarLayout);
286
287   // event number field
288   fEventNumberLayout = new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 
289                                          10, 2, 10, 5);
290   fEventNumber = new TGNumberEntry(fToolBar, 1, 4, 10, 
291                                    TGNumberFormat::kNESInteger);
292   fEventNumber->SetLimits(TGNumberFormat::kNELLimitMin, 1, 0);
293   fToolBar->AddFrame(fEventNumber, fEventNumberLayout);
294   fEventNumber->GetNumberEntry()->Connect("ReturnPressed()", 
295                                           "AliMonitorClient", this,
296                                           "OnEventNumberChanged()");
297   fEventNumber->GetButtonUp()->Connect("Clicked()", 
298                                        "AliMonitorClient", this,
299                                        "OnEventNumberChanged()");
300   fEventNumber->GetButtonDown()->Connect("Clicked()", 
301                                          "AliMonitorClient", this,
302                                          "OnEventNumberChanged()");
303
304   // draw event button
305   ToolBarData_t eventButton = {"h1_s.xpm", "draw event histogram", 
306                                kTRUE, 11, NULL};
307   fToolBar->AddButton(this, &eventButton, 5);
308   fEventButton = eventButton.fButton;
309   fEventButton->Connect("Pressed()", "AliMonitorClient", this,
310                         "OnEventButtonPressed()");
311
312   // draw sum button
313   ToolBarData_t sumButton = {"h2_s.xpm", "draw sum histogram", 
314                              kTRUE, 12, NULL};
315   fToolBar->AddButton(this, &sumButton, 5);
316   fSumButton = sumButton.fButton;
317   fSumButton->Connect("Pressed()", "AliMonitorClient", this,
318                       "OnSumButtonPressed()");
319
320   // draw run button
321   ToolBarData_t runButton = {"h3_s.xpm", "draw run histogram", 
322                              kTRUE, 13, NULL};
323   fToolBar->AddButton(this, &runButton, 5);
324   fRunButton = runButton.fButton;
325   fRunButton->SetDown(kTRUE);
326   fRunButton->Connect("Pressed()", "AliMonitorClient", this,
327                       "OnRunButtonPressed()");
328
329   // loop button
330   char fileName[256];
331   sprintf(fileName, "%s/MONITOR/loop_on.xpm", gSystem->Getenv("ALICE_ROOT"));
332   ToolBarData_t loopButton = {fileName, "loop over histograms", 
333                               kFALSE, 21, NULL};
334   fToolBar->AddButton(this, &loopButton, 25);
335   fLoopButton = loopButton.fButton;
336   fLoopButton->Connect("Clicked()", "AliMonitorClient", this,
337                        "OnLoopButtonClicked()");
338   fLoopOnPicture = gClient->GetPicture(fileName);
339   sprintf(fileName, "%s/MONITOR/loop_off2.xpm", gSystem->Getenv("ALICE_ROOT"));
340   fLoopOffPicture = gClient->GetPicture(fileName);
341
342   // previous button
343   sprintf(fileName, "%s/MONITOR/previous_s.xpm", 
344           gSystem->Getenv("ALICE_ROOT"));
345   ToolBarData_t previousButton = {fileName, "go to previous histogram", 
346                                   kFALSE, 22, NULL};
347   fToolBar->AddButton(this, &previousButton, 5);
348   fPreviousButton = previousButton.fButton;
349   fPreviousButton->Connect("Clicked()", "AliMonitorClient", this,
350                            "OnPreviousButtonClicked()");
351
352   // next button
353   sprintf(fileName, "%s/MONITOR/next_s.xpm", gSystem->Getenv("ALICE_ROOT"));
354   ToolBarData_t nextButton = {fileName, "go to next histogram", 
355                               kFALSE, 23, NULL};
356   fToolBar->AddButton(this, &nextButton, 5);
357   fNextButton = nextButton.fButton;
358   fNextButton->Connect("Clicked()", "AliMonitorClient", this,
359                        "OnNextButtonClicked()");
360
361   // copy button
362   sprintf(fileName, "%s/MONITOR/copy_s.xpm", gSystem->Getenv("ALICE_ROOT"));
363   ToolBarData_t copyButton = {fileName, 
364                               "copy the current histogram to a new canvas", 
365                               kFALSE, 31, NULL};
366   fToolBar->AddButton(this, &copyButton, 25);
367   fCopyButton = copyButton.fButton;
368   fCopyButton->Connect("Clicked()", "AliMonitorClient", this,
369                        "OnCopyButtonClicked()");
370
371   // save button
372   sprintf(fileName, "%s/MONITOR/save_s.xpm", gSystem->Getenv("ALICE_ROOT"));
373   ToolBarData_t saveButton = {fileName, "save the current histogram", 
374                               kFALSE, 32, NULL};
375   fToolBar->AddButton(this, &saveButton, 5);
376   fSaveButton = saveButton.fButton;
377   fSaveButton->Connect("Clicked()", "AliMonitorClient", this,
378                        "OnSaveButtonClicked()");
379
380   // print button
381   ToolBarData_t printButton = {"printer_s.xpm", "print the current histogram", 
382                              kFALSE, 33, NULL};
383   fToolBar->AddButton(this, &printButton, 5);
384   fPrintButton = printButton.fButton;
385   fPrintButton->Connect("Clicked()", "AliMonitorClient", this,
386                         "OnPrintButtonClicked()");
387
388   // *** frames ***
389   fBottomLayout = new TGLayoutHints(kLHintsExpandX | kLHintsBottom);
390   fLeftLayout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
391   fExpandLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
392
393   fVerticalFrame = new TGVerticalFrame(this, 10, 10);
394   AddFrame(fVerticalFrame, fExpandLayout);
395
396   fHorizontalFrame = new TGHorizontalFrame(fVerticalFrame, 10, 10);
397   fVerticalFrame->AddFrame(fHorizontalFrame, fExpandLayout);
398
399   // tree frame
400   fTreeFrame = new TGCompositeFrame(fHorizontalFrame, 10, 10, 
401                                     kSunkenFrame | kFixedWidth);
402   fHorizontalFrame->AddFrame(fTreeFrame, fLeftLayout);
403   fTreeCanvas = new TGCanvas(fTreeFrame, 10, 10);
404   fTreeFrame->AddFrame(fTreeCanvas, fExpandLayout);
405   fTree = new TGListTree(fTreeCanvas, kHorizontalFrame);
406   fTreeCanvas->AddFrame(fTree, fExpandLayout);
407   fTree->Connect("Clicked(TGListTreeItem*,Int_t)", "AliMonitorClient",
408                  this, "OnTreeClicked(TGListTreeItem*,Int_t)");
409   fTree->Connect("ReturnPressed(TGListTreeItem*)", "AliMonitorClient",
410                  this, "OnTreeReturnPressed(TGListTreeItem*)");
411
412   // tree items
413   fAllItem = fTree->AddItem(NULL, "All");
414   fFavoritesItem = fTree->AddItem(NULL, "Favorites");
415   fComparisonItem = fTree->AddItem(NULL, "Comparison");
416   fHistoPicture = fClient->GetPicture("h1_t.xpm"); 
417   fTreeFrame->Resize(100, fTreeFrame->GetDefaultHeight());
418
419   // tree / histogram splitter
420   fTreeSplitter = new TGVSplitter(fHorizontalFrame, 4);
421   fTreeSplitter->SetFrame(fTreeFrame, kTRUE);
422   fHorizontalFrame->AddFrame(fTreeSplitter, fLeftLayout);
423
424   // histogram frame
425   fDrawFrame = new TGCompositeFrame(fHorizontalFrame, 10, 10, kSunkenFrame);
426   fHorizontalFrame->AddFrame(fDrawFrame, fExpandLayout);
427   fDrawCanvas = new TRootEmbeddedCanvas("current monitor histogram", 
428                                         fDrawFrame, 10, 10);
429   fDrawFrame->AddFrame(fDrawCanvas, fExpandLayout);
430
431   // description frame
432   fDescriptionFrame = new TGCompositeFrame(fVerticalFrame, 10, 60, 
433                                            kSunkenFrame | kFixedHeight);
434   fVerticalFrame->AddFrame(fDescriptionFrame, fBottomLayout);
435   fDescription = new TGTextView(fDescriptionFrame, 10, 60, "");
436   fDescriptionFrame->AddFrame(fDescription, fExpandLayout);
437
438   // histogram / description splitter
439   fDescriptionSplitter = new TGHSplitter(fVerticalFrame, 4, 4);
440   fVerticalFrame->AddFrame(fDescriptionSplitter, fBottomLayout);
441   fDescriptionSplitter->SetFrame(fDescriptionFrame, kFALSE);
442
443   // main window
444   Connect("CloseWindow()", "AliMonitorClient", this, "CloseWindow()");
445   SetWindowName("Monitor Client");
446   SetWMSize(GetWidth(), GetHeight());
447   Move(100, 100);
448   SetWMPosition(100, 100);
449   MapSubwindows();
450   Layout();
451   MapWindow();
452
453
454   // default data members
455   fServerName = "localhost";
456   fSocket = NULL;
457   fSocketHandler = NULL;
458
459   fFolder = CreateTopFolder();
460
461   fCurrentItem = NULL;
462   fBaseItem = NULL;
463   fLoopTimer = NULL;
464   fLoopInterval = 1000;
465
466   fFavoritesFileName = "";
467
468   fReferenceFileName = "";
469   fReference = CreateTopFolder();
470   AliMonitorHisto::SetThreshold(5.0);
471
472   fPrintCommand = "gv";
473
474   // load saved settings
475   LoadSettings();
476 }
477
478 //_____________________________________________________________________________
479 AliMonitorClient::~AliMonitorClient()
480 {
481 // clean up
482
483   delete fMenuBarLayout;
484   delete fMenuBarItemLayout;
485   delete fMenuBarHelpLayout;
486   delete fMenuFile;
487   delete fMenuView;
488   delete fMenuFavorites;
489   delete fMenuReference;
490   delete fMenuOptions;
491   delete fMenuHelp;
492   delete fMenuBar;
493
494   delete fEventNumberLayout;
495   delete fEventNumber;
496   delete fToolBarLayout;
497   delete fToolBarSep;
498   delete fToolBar;
499
500   delete fBottomLayout;
501   delete fLeftLayout;
502   delete fExpandLayout;
503
504   delete fTree;
505   delete fTreeCanvas;
506   delete fTreeFrame;
507   delete fTreeSplitter;
508
509   delete fDrawCanvas;
510   delete fDrawFrame;
511
512   delete fDescriptionSplitter;
513   delete fDescription;
514   delete fDescriptionFrame;
515
516   delete fVerticalFrame;
517   delete fHorizontalFrame;
518
519   if (fSocket) {
520     fSocket->Close();
521     delete fSocket;
522     delete fSocketHandler;
523   }
524
525   if (fFolder) delete fFolder;
526
527   if (fLoopTimer) {
528     fLoopTimer->TurnOff();
529     delete fLoopTimer;
530   }
531
532   if (fReference) delete fReference;
533 }
534
535
536 //_____________________________________________________________________________
537 void AliMonitorClient::CloseWindow()
538 {
539 // terminate the application when the window is closed
540
541   if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
542     SaveFavorites();
543   }
544   if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
545     SaveSettings();
546   }
547   gApplication->Terminate(0);
548 }
549
550
551 //_____________________________________________________________________________
552 void AliMonitorClient::OnNewData()
553 {
554 // called when data has arrived from the monitor server
555
556   if (CheckForNewData()) UpdateAll();
557 }
558
559
560 //_____________________________________________________________________________
561 void AliMonitorClient::OnMenuActivated(Int_t id)
562 {
563 // called when a menu item was selected
564
565   switch (id) {
566
567   case kMenuFileConnect: {
568     if (ConnectToServer()) UpdateAll();
569     break;
570   }
571
572   case kMenuFileDisconnect: {
573     DisconnectFromServer();
574     break;
575   }
576
577   case kMenuFileOpen: {
578     if (OpenFile()) UpdateAll();
579     break;
580   }
581
582   case kMenuFileExit: {
583     CloseWindow();
584     break;
585   }
586
587   case kMenuViewToolBar: {
588     ViewToolBar(!fMenuView->IsEntryChecked(kMenuViewToolBar));
589     break;
590   }
591
592   case kMenuViewTree: {
593     ViewTree(!fMenuView->IsEntryChecked(kMenuViewTree));
594     break;
595   }
596
597   case kMenuViewDescription: {
598     ViewDescription(!fMenuView->IsEntryChecked(kMenuViewDescription));
599     break;
600   }
601
602   case kMenuViewReference: {
603     ViewReference(!fMenuView->IsEntryChecked(kMenuViewReference));
604     UpdateHisto();
605     break;
606   }
607
608   case kMenuViewStatistics: {
609     ViewStatistics(!fMenuView->IsEntryChecked(kMenuViewStatistics));
610     UpdateHisto();
611     break;
612   }
613
614   case kMenuFavAdd: {
615     if (AddFavorite()) {
616       fMenuFavorites->EnableEntry(kMenuFavSave);
617       fMenuFavorites->EnableEntry(kMenuFavSaveAs);
618     }
619     break;
620   }
621
622   case kMenuFavDelete: {
623     if (DeleteFavorite()) {
624       UpdateHisto();
625       UpdateDescription();
626       fMenuFavorites->DisableEntry(kMenuFavDelete);
627       fMenuFavorites->EnableEntry(kMenuFavSave);
628       fMenuFavorites->EnableEntry(kMenuFavSaveAs);
629     }
630     break;
631   }
632
633   case kMenuFavLoad: {
634     if (LoadFavorites()) {
635       UpdateHisto();
636       UpdateDescription();
637       fMenuFavorites->DisableEntry(kMenuFavSave);
638       fMenuFavorites->EnableEntry(kMenuFavSaveAs);
639     }
640     break;
641   }
642
643   case kMenuFavSave: {
644     if (SaveFavorites()) {
645       fMenuFavorites->DisableEntry(kMenuFavSave);
646     }
647     break;
648   }
649
650   case kMenuFavSaveAs: {
651     if (SaveFavoritesAs()) {
652       fMenuFavorites->DisableEntry(kMenuFavSave);
653     }
654     break;
655   }
656
657   case kMenuFavSaveOnExit: {
658     if (fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit)) {
659       fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
660     } else {
661       fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
662     }
663     break;
664   }
665
666   case kMenuRefLoad: {
667     if (LoadReference()) {
668       SetReference();
669       UpdateHisto();
670       UpdateComparisonTree();
671       fMenuReference->EnableEntry(kMenuRefSaveAs);
672     }
673     break;
674   }
675
676   case kMenuRefThreshold: {
677     Float_t threshold = AliMonitorHisto::GetThreshold();
678     new AliMonitorNumberDlg(threshold, this, 
679                             "Comparison with Reference Histograms",
680                             "threshold for comparison:", 0.);
681     if (threshold < 0) break;
682
683     AliMonitorHisto::SetThreshold(threshold);
684     UpdateHisto();
685     UpdateComparisonTree();
686     break;
687   }
688
689   case kMenuRefTakeCurrent: {
690     if (TakeCurrentReference()) {
691       UpdateHisto();
692       UpdateComparisonTree();
693       fMenuReference->EnableEntry(kMenuRefSave);
694       fMenuReference->EnableEntry(kMenuRefSaveAs);
695     }
696     break;
697   }
698
699   case kMenuRefSave: {
700     if (SaveReference()) {
701       fMenuReference->DisableEntry(kMenuRefSave);
702     }
703     break;
704   }
705
706   case kMenuRefSaveAs: {
707     if (SaveReferenceAs()) {
708       fMenuReference->DisableEntry(kMenuRefSave);
709     }
710     break;
711   }
712
713   case kMenuOptLoop: {
714     Float_t interval = fLoopInterval * 0.001;
715     new AliMonitorNumberDlg(interval, this, "Loop Interval",
716                             "loop time in seconds:", 0.1);
717     if (interval < 0) break;
718
719     fLoopInterval = Int_t(1000 * interval);
720     if (fLoopTimer) {
721       fLoopTimer->Stop();
722       fLoopTimer->Start(fLoopInterval);
723     }
724     break;
725   }
726
727   case kMenuOptPrint: {
728     TString printCommand(fPrintCommand);
729     new AliMonitorStringDlg(printCommand, this, "Print Command",
730                             "shell command for printing:");
731     if (printCommand.IsNull()) break;
732
733     fPrintCommand = printCommand;
734     break;
735   }
736
737   case kMenuOptSaveOnExit: {
738     if (fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit)) {
739       fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
740     } else {
741       fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
742     }
743     break;
744   }
745
746   case kMenuOptSave: {
747     SaveSettings();
748     break;
749   }
750
751   case kMenuHelpAbout: {
752     Int_t result;
753     new TGMsgBox(gClient->GetRoot(), this, 
754                  "About", "AliMonitorClient $Revision$", 
755                  kMBIconAsterisk, kMBOk, &result);
756     break;
757   }
758
759   default: {
760     Int_t result;
761     new TGMsgBox(gClient->GetRoot(), this, 
762                  "AliMonitorClient", "not yet implemented", 
763                  kMBIconExclamation, kMBOk, &result);
764   }
765   }
766 }
767
768
769 //_____________________________________________________________________________
770 void AliMonitorClient::OnEventNumberChanged()
771 {
772 // called when the event number in the tool button was changed
773
774   if (!fRunButton->IsDown()) {
775     UpdateHisto();
776     UpdateComparisonTree();
777   }
778 }
779
780 //_____________________________________________________________________________
781 void AliMonitorClient::OnEventButtonPressed()
782 {
783 // called when the event tool button was clicked
784
785   fSumButton->SetDown(kFALSE);
786   fRunButton->SetDown(kFALSE);
787   UpdateHisto();
788   UpdateComparisonTree();
789 }
790
791 //_____________________________________________________________________________
792 void AliMonitorClient::OnSumButtonPressed()
793 {
794 // called when the sum tool button was clicked
795
796   fEventButton->SetDown(kFALSE);
797   fRunButton->SetDown(kFALSE);
798   UpdateHisto();
799   UpdateComparisonTree();
800 }
801
802 //_____________________________________________________________________________
803 void AliMonitorClient::OnRunButtonPressed()
804 {
805 // called when the run tool button was clicked
806
807   fEventButton->SetDown(kFALSE);
808   fSumButton->SetDown(kFALSE);
809   UpdateHisto();
810   UpdateComparisonTree();
811 }
812
813 //_____________________________________________________________________________
814 void AliMonitorClient::OnLoopButtonClicked()
815 {
816 // called when the loop tool button was clicked
817
818   // if loop is not running, start the loop timer and 
819   // set the stop loop button picture
820   if (!fLoopTimer) {  
821     if (!fBaseItem) {
822       if (!GetBaseItem()) return;
823     }
824     fLoopTimer = new TTimer(fLoopInterval);
825     fLoopTimer->Connect("Timeout()", "AliMonitorClient", this, 
826                         "OnLoopTimer()");
827     ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOffPicture);
828     fLoopTimer->TurnOn();
829
830   // if the loop is running, stop it
831   } else {
832     StopLoop();
833   }
834 }
835
836 //_____________________________________________________________________________
837 void AliMonitorClient::OnPreviousButtonClicked()
838 {
839 // called when the previous tool button was clicked
840
841   if (!fBaseItem) {
842     if (!GetBaseItem()) return;
843   }
844   StopLoop();
845   GoToPreviousItem();
846 }
847
848 //_____________________________________________________________________________
849 void AliMonitorClient::OnNextButtonClicked()
850 {
851 // called when the next tool button was clicked
852
853   if (!fBaseItem) {
854     if (!GetBaseItem()) return;
855   }
856   StopLoop();
857   GoToNextItem();
858 }
859
860 //_____________________________________________________________________________
861 void AliMonitorClient::OnCopyButtonClicked()
862 {
863 // called when the copy tool button was clicked
864
865   fDrawCanvas->GetCanvas()->DrawClone();
866 }
867
868 //_____________________________________________________________________________
869 void AliMonitorClient::OnSaveButtonClicked()
870 {
871 // called when the save tool button was clicked
872
873   // display a file save dialog
874   static TGFileInfo fileInfo;
875   static const char* fileTypes[] = {"PostScript",   "*.ps",
876                                     "Encapsulated PostScript", "*.eps",
877                                     "SVG",          "*.svg",
878                                     "Gif files",    "*.gif",
879                                     "Macro files",  "*.C",
880                                     "ROOT files", "*.root", 
881                                     "All files",  "*", 
882                                     NULL,         NULL};
883   fileInfo.fFileTypes = fileTypes;
884   new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
885   if (!fileInfo.fFilename) return;
886
887   fDrawCanvas->GetCanvas()->SaveAs(fileInfo.fFilename);
888 }
889
890 //_____________________________________________________________________________
891 void AliMonitorClient::OnPrintButtonClicked()
892 {
893 // called when the print tool button was clicked
894
895   // save the canvas to a temporary postscript file
896   char fileName[L_tmpnam+4];
897   sprintf(fileName, "%s.ps", tmpnam(NULL));
898   fDrawCanvas->GetCanvas()->SaveAs(fileName);
899
900   // call the print command and delete the temporary file
901   char command[256];
902   sprintf(command, "%s %s", fPrintCommand.Data(), fileName);
903   gSystem->Exec(command);
904   gSystem->Unlink(fileName);
905 }
906
907
908 //_____________________________________________________________________________
909 void AliMonitorClient::OnTreeClicked(TGListTreeItem* item, Int_t)
910 {
911 // called when an item in the histogram tree is clicked
912
913   OnTreeReturnPressed(item);
914 }
915
916 //_____________________________________________________________________________
917 void AliMonitorClient::OnTreeReturnPressed(TGListTreeItem* item)
918 {
919 // called when return is pressed at an item in the histogram tree
920
921   fCurrentItem = item;
922   fBaseItem = NULL;
923   StopLoop();
924   UpdateItem(kFALSE);
925 }
926
927
928 //_____________________________________________________________________________
929 void AliMonitorClient::OnLoopTimer()
930 {
931 // called by the loop timer when a new histogram should be displayed
932
933   if (!fBaseItem) {
934     if (!GetBaseItem()) return;
935   }
936   GoToNextItem();
937 }
938
939
940 //_____________________________________________________________________________
941 TFolder* AliMonitorClient::CreateTopFolder()
942 {
943 // create a top folder for monitor histograms
944
945   return (new TFolder("Monitor", "monitor histograms"));
946 }
947
948 //_____________________________________________________________________________
949 AliMonitorHisto* AliMonitorClient::GetHisto(const char* folderName, 
950                                             const char* histoName)
951 {
952 // find the monitor histogram with the given name in the given folder
953
954   TGListTreeItem* folderItem = fTree->FindChildByName(fAllItem, folderName);
955   if (folderItem) {
956     TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
957     if (histoItem) return (AliMonitorHisto*) histoItem->GetUserData();
958   }
959   return NULL;
960 }
961
962 //_____________________________________________________________________________
963 TGListTreeItem* AliMonitorClient::GetItem(TGListTreeItem* base, 
964                                           const char* folderName, 
965                                           const char* histoName, 
966                                           Bool_t create)
967 {
968 // find the tree item with given name in the given folder
969 // if create is kTRUE it is created if it is not there
970
971   // get or create the folder
972   TGListTreeItem* folderItem = fTree->FindChildByName(base, folderName);
973   if (!folderItem) {
974     if (!create) return NULL;
975     folderItem = fTree->AddItem(base, folderName);
976   }
977
978   // get or create the histo
979   TGListTreeItem* histoItem = fTree->FindChildByName(folderItem, histoName);
980   if (!histoItem) {
981     if (!create) return NULL;
982     histoItem = fTree->AddItem(folderItem, histoName,
983                                fClient->GetPicture("h1_t.xpm"),
984                                fClient->GetPicture("h1_t.xpm"));
985   }
986   return histoItem;
987 }
988
989
990 //_____________________________________________________________________________
991 Bool_t AliMonitorClient::ConnectToServer()
992 {
993 // display the dialog for the server name or ip and try to connect to it
994
995   TString serverName(fServerName);
996
997   do {
998     // ask for the server name or ip
999     new AliMonitorStringDlg(serverName, this, "Connection to monitor process",
1000                             "monitor server name or ip:");
1001     if (serverName.IsNull()) return kFALSE;
1002
1003     // connect to the server
1004     fSocket = new TSocket(serverName, AliMonitorProcess::kgPort);
1005     if (!fSocket || !fSocket->IsValid() || (fSocket->Send("client") <= 0)) {
1006       if (fSocket) delete fSocket;
1007       fSocket = NULL;
1008       Int_t result;
1009       new TGMsgBox(gClient->GetRoot(), this, "Connect",
1010                    "connection to monitor server failed", 
1011                    kMBIconExclamation, kMBOk, &result);
1012
1013     } else {  // set up a handler for notifying when new data is there
1014       fServerName = serverName;
1015       fSocketHandler = new TFileHandler(fSocket->GetDescriptor(), 
1016                                         TFileHandler::kRead);
1017       fSocketHandler->Connect("Notified()", "AliMonitorClient", this,
1018                               "OnNewData()");
1019       fSocketHandler->Add();
1020       TInetAddress adr = fSocket->GetInetAddress();
1021       Info("ConnectToServer", "connected to server:\n %s (%s), port %d\n",
1022            adr.GetHostName(), adr.GetHostAddress(), adr.GetPort());
1023       fMenuFile->HideEntry(kMenuFileConnect);
1024       fMenuFile->HideEntry(kMenuFileOpen);
1025       fMenuFile->EnableEntry(kMenuFileDisconnect);
1026     };
1027
1028   } while (!fSocket);
1029
1030   // delete the old monitor histos
1031   if (fFolder) delete fFolder;
1032   fFolder = CreateTopFolder();
1033   return kTRUE;
1034 }
1035
1036 //_____________________________________________________________________________
1037 void AliMonitorClient::DisconnectFromServer()
1038 {
1039 // disconnect from the monitor server
1040
1041   // are-you-really-sure-dialog
1042   Int_t result;
1043   new TGMsgBox(gClient->GetRoot(), this, "Disconnect",
1044                "Do you really want to disconnect from the monitor server?", 
1045                kMBIconQuestion, kMBYes | kMBNo, &result);
1046   if (result == kMBNo) return;
1047
1048   // disconnect from the server
1049   fSocketHandler->Remove();
1050   fSocket->Send("Finished"); 
1051   fSocket->Close();
1052   delete fSocket;
1053   fSocket = NULL;
1054   fMenuFile->HideEntry(kMenuFileDisconnect);
1055   fMenuFile->EnableEntry(kMenuFileConnect);
1056   fMenuFile->EnableEntry(kMenuFileOpen);
1057 }
1058
1059 //_____________________________________________________________________________
1060 Bool_t AliMonitorClient::OpenFile()
1061 {
1062 // open a file with monitor histograms
1063
1064   // display a file open dialog
1065   static TGFileInfo fileInfo;
1066   static const char* fileTypes[] = {"ROOT files", "*.root", 
1067                                     "All files",  "*", 
1068                                     NULL,         NULL};
1069   fileInfo.fFileTypes = fileTypes;
1070   new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1071   if (!fileInfo.fFilename) return kFALSE;
1072
1073   // open the root file
1074   TFile* file = TFile::Open(fileInfo.fFilename);
1075   if (!file || !file->IsOpen()) {
1076     Int_t result;
1077     new TGMsgBox(gClient->GetRoot(), this, "Open",
1078                  "The file could not be opened.", 
1079                  kMBIconExclamation, kMBOk, &result);
1080     return kFALSE;
1081   }
1082
1083   // get the folder with the monitor histograms
1084   TFolder* folder = (TFolder*) file->Get("Monitor");
1085   if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1086     Int_t result;
1087     new TGMsgBox(gClient->GetRoot(), this, "Open",
1088                  "The file does not contain monitor histograms.", 
1089                  kMBIconExclamation, kMBOk, &result);
1090     file->Close();
1091     delete file;
1092     return kFALSE;
1093   }
1094
1095   // replace the old folder with the new one
1096   file->Clear();
1097   file->Close();
1098   delete file;
1099   if (fFolder) delete fFolder;
1100   fFolder = folder;
1101   return kTRUE;
1102 }
1103
1104
1105 //_____________________________________________________________________________
1106 void AliMonitorClient::ViewToolBar(Bool_t visible)
1107 {
1108 // en- or disable the view of the tool bar
1109
1110   if (visible) {
1111     ShowFrame(fToolBarSep);
1112     ShowFrame(fToolBar);
1113     fMenuView->CheckEntry(kMenuViewToolBar);
1114   } else {
1115     HideFrame(fToolBarSep);
1116     HideFrame(fToolBar);
1117     fMenuView->UnCheckEntry(kMenuViewToolBar);
1118   }
1119 }
1120
1121 //_____________________________________________________________________________
1122 void AliMonitorClient::ViewTree(Bool_t visible)
1123 {
1124 // en- or disable the view of the tree
1125
1126   if (visible) {
1127     fHorizontalFrame->ShowFrame(fTreeFrame);
1128     fHorizontalFrame->ShowFrame(fTreeSplitter);
1129     fMenuView->CheckEntry(kMenuViewTree);
1130   } else {
1131     fHorizontalFrame->HideFrame(fTreeFrame);
1132     fHorizontalFrame->HideFrame(fTreeSplitter);
1133     fMenuView->UnCheckEntry(kMenuViewTree);
1134   }
1135 }
1136
1137 //_____________________________________________________________________________
1138 void AliMonitorClient::ViewDescription(Bool_t visible)
1139 {
1140 // en- or disable the view of the histogram description
1141
1142   if (visible) {
1143     fVerticalFrame->ShowFrame(fDescriptionFrame);
1144     fVerticalFrame->ShowFrame(fDescriptionSplitter);
1145     fMenuView->CheckEntry(kMenuViewDescription);
1146   } else {
1147     fVerticalFrame->HideFrame(fDescriptionFrame);
1148     fVerticalFrame->HideFrame(fDescriptionSplitter);
1149     fMenuView->UnCheckEntry(kMenuViewDescription);
1150   }
1151 }
1152
1153 //_____________________________________________________________________________
1154 void AliMonitorClient::ViewReference(Bool_t visible)
1155 {
1156 // en- or disable the view of the reference histos
1157
1158   if (visible) {
1159     AliMonitorHisto::SetDrawRef(kTRUE);
1160     fMenuView->CheckEntry(kMenuViewReference);
1161   } else {
1162     AliMonitorHisto::SetDrawRef(kFALSE);
1163     fMenuView->UnCheckEntry(kMenuViewReference);
1164   }
1165 }
1166
1167 //_____________________________________________________________________________
1168 void AliMonitorClient::ViewStatistics(Bool_t visible)
1169 {
1170 // en- or disable the view of the statistics box
1171
1172   if (visible) {
1173     gStyle->SetOptStat(1110);
1174     fMenuView->CheckEntry(kMenuViewStatistics);
1175   } else {
1176     gStyle->SetOptStat(0);
1177     fMenuView->UnCheckEntry(kMenuViewStatistics);
1178   }
1179 }
1180
1181
1182 //_____________________________________________________________________________
1183 Bool_t AliMonitorClient::AddFavorite()
1184 {
1185 // add the current histogram or folder to the list of favorites
1186
1187   if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1188
1189   // get the folder item
1190   TGListTreeItem* folderItem = fCurrentItem->GetParent();
1191   if (fCurrentItem->GetFirstChild()) folderItem = fCurrentItem;
1192
1193   Bool_t result = kFALSE;
1194
1195   // add a folder
1196   if (fCurrentItem->GetFirstChild()) {
1197     TGListTreeItem* histoItem = fCurrentItem->GetFirstChild();
1198     while (histoItem) {
1199       if (!GetItem(fFavoritesItem, folderItem->GetText(), 
1200                    histoItem->GetText(), kFALSE)) result = kTRUE;
1201       TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(), 
1202                                      histoItem->GetText(), kTRUE);
1203       item->SetUserData(histoItem->GetUserData());
1204       histoItem = histoItem->GetNextSibling();
1205     }
1206
1207   // add a histo
1208   } else {
1209     if (!GetItem(fFavoritesItem, folderItem->GetText(), 
1210                  fCurrentItem->GetText(), kFALSE)) result = kTRUE;
1211     TGListTreeItem* item = GetItem(fFavoritesItem, folderItem->GetText(), 
1212                                    fCurrentItem->GetText(), kTRUE);
1213     item->SetUserData(fCurrentItem->GetUserData());
1214   }
1215
1216   if (result) gClient->NeedRedraw(fTree);
1217   return result;
1218 }
1219
1220 //_____________________________________________________________________________
1221 Bool_t AliMonitorClient::DeleteFavorite()
1222 {
1223 // delete the current histogram or folder from the list of favorites
1224
1225   // check that the current item is a favorites histo or folder
1226   if (!fCurrentItem || !fCurrentItem->GetParent()) return kFALSE;
1227   TGListTreeItem* base = fCurrentItem;
1228   while (base->GetParent()) base = base->GetParent();
1229   if (base != fFavoritesItem) return kFALSE;
1230
1231   // delete it
1232   TGListTreeItem* parent = fCurrentItem->GetParent();
1233   fTree->DeleteItem(fCurrentItem);
1234   fCurrentItem = NULL;
1235
1236   // delete the parent folder if it is empty now
1237   if (parent->GetParent() != NULL) {
1238     if (!parent->GetFirstChild()) fTree->DeleteItem(parent);
1239   }
1240
1241   gClient->NeedRedraw(fTree);
1242   return kTRUE;
1243 }
1244
1245 //_____________________________________________________________________________
1246 Bool_t AliMonitorClient::LoadFavorites(Bool_t dialog)
1247 {
1248 // load the list of favorites from a file
1249
1250   // display a file open dialog
1251   TGFileInfo fileInfo;
1252   static const char* fileTypes[] = {"Favorites files", "*.fav", 
1253                                     "All files",  "*", 
1254                                     NULL,         NULL};
1255   fileInfo.fFileTypes = fileTypes;
1256   fileInfo.fIniDir = StrDup(".");
1257   fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1258   if (dialog) {
1259     new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1260     if (!fileInfo.fFilename) return kFALSE;
1261   }
1262
1263   // open the text file
1264   FILE* file = fopen(fileInfo.fFilename, "rt");
1265   if (!file) {
1266     Int_t result;
1267     new TGMsgBox(gClient->GetRoot(), this, "Load Favorites",
1268                  "The file could not be opened.", 
1269                  kMBIconExclamation, kMBOk, &result);
1270     return kFALSE;
1271   }
1272
1273   // delete the old favorites
1274   TGListTreeItem* favFolderItem = fFavoritesItem->GetFirstChild();
1275   while (favFolderItem) {
1276     TGListTreeItem* deleteItem = favFolderItem;
1277     favFolderItem = favFolderItem->GetNextSibling();
1278     fTree->DeleteItem(deleteItem);
1279   }
1280
1281   // scan the text file and add the favorites histos
1282   char buffer[256];
1283   while (!feof(file)) {
1284     if (fgets(buffer, 255, file) == NULL) break;
1285     char* folder = strtok(buffer, "/");
1286     char* item = strtok(NULL, "\n");
1287     if (item[strlen(item)-1] == '\n') item[strlen(item)-1] = 0;
1288     if (!folder || !item) continue;
1289
1290     AliMonitorHisto* histo = GetHisto(folder, item);
1291     TGListTreeItem* histoItem = GetItem(fFavoritesItem, folder, item, kTRUE);
1292     histoItem->SetUserData(histo);
1293   }
1294   fclose(file);
1295
1296   return kTRUE;
1297 }
1298
1299 //_____________________________________________________________________________
1300 Bool_t AliMonitorClient::SaveFavorites()
1301 {
1302 // save the list of favorites in a file with the name fFavoritesFileName
1303
1304   // if no file name is given use a default one
1305   if (fFavoritesFileName.IsNull()) {
1306     char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(), 
1307                                              "AliMonitorClient.fav");
1308     fFavoritesFileName = fileName;
1309     free(fileName);
1310   }
1311
1312   // open the text file
1313   FILE* file = fopen(fFavoritesFileName.Data(), "wt");
1314   if (!file) {
1315     Int_t result;
1316     new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1317                  "The file could not be opened.", 
1318                  kMBIconExclamation, kMBOk, &result);
1319     return kFALSE;
1320   }
1321
1322   // loop over folders
1323   TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1324   while (folderItem) {
1325
1326     // loop over histos
1327     TGListTreeItem* histoItem = folderItem->GetFirstChild();
1328     while (histoItem) {
1329
1330       // write the favorites
1331       if (fprintf(file, "%s/%s\n", folderItem->GetText(), 
1332                   histoItem->GetText()) <= 0) {
1333         Int_t result;
1334         new TGMsgBox(gClient->GetRoot(), this, "Save Favorites",
1335                      "An error occured while sving the favorites.", 
1336                      kMBIconExclamation, kMBOk, &result);
1337         fclose(file);
1338         return kFALSE;
1339       }
1340       histoItem = histoItem->GetNextSibling();
1341     }
1342
1343     folderItem = folderItem->GetNextSibling();
1344   }
1345
1346   fclose(file);
1347   Info("SaveFavorites", "favorites saved to file %s", 
1348        fFavoritesFileName.Data());
1349   return kTRUE;
1350 }
1351
1352 //_____________________________________________________________________________
1353 Bool_t AliMonitorClient::SaveFavoritesAs()
1354 {
1355 // ask for a file name and save the favorites to this file
1356
1357   // display a save file dialog
1358   TGFileInfo fileInfo;
1359   static const char* fileTypes[] = {"Favorites files", "*.fav", 
1360                                     "All files",  "*", 
1361                                     NULL,         NULL};
1362   fileInfo.fFileTypes = fileTypes;
1363   fileInfo.fIniDir = StrDup(".");
1364   fileInfo.fFilename = StrDup(fFavoritesFileName.Data());
1365   new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1366   if (!fileInfo.fFilename) return kFALSE;
1367
1368   // save the favorites
1369   fFavoritesFileName = fileInfo.fFilename;
1370   return SaveFavorites();
1371 }
1372
1373
1374 //_____________________________________________________________________________
1375 Bool_t AliMonitorClient::LoadReference(Bool_t dialog)
1376 {
1377 // load reference histograms from a file
1378
1379   // display a file open dialog
1380   TGFileInfo fileInfo;
1381   static const char* fileTypes[] = {"ROOT files", "*.root", 
1382                                     "All files",  "*", 
1383                                     NULL,         NULL};
1384   fileInfo.fFileTypes = fileTypes;
1385   fileInfo.fIniDir = StrDup(".");
1386   fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1387   if (dialog) {
1388     new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fileInfo);
1389     if (!fileInfo.fFilename) return kFALSE;
1390   }
1391
1392   // open the root file
1393   TFile* file = TFile::Open(fileInfo.fFilename);
1394   if (!file || !file->IsOpen()) {
1395     Int_t result;
1396     new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1397                  "The file could not be opened.", 
1398                  kMBIconExclamation, kMBOk, &result);
1399     return kFALSE;
1400   }
1401
1402   // get the folder with the monitor histograms
1403   TFolder* folder = (TFolder*) file->Get("Monitor");
1404   if (!folder || !folder->InheritsFrom(TFolder::Class())) {
1405     Int_t result;
1406     new TGMsgBox(gClient->GetRoot(), this, "Load Reference",
1407                  "The file does not contain monitor histograms.", 
1408                  kMBIconExclamation, kMBOk, &result);
1409     file->Close();
1410     delete file;
1411     return kFALSE;
1412   }
1413
1414   // replace the old reference folder with the new one
1415   fReferenceFileName = fileInfo.fFilename;
1416   file->Clear();
1417   file->Close();
1418   delete file;
1419   if (fReference) delete fReference;
1420   fReference = folder;
1421   return kTRUE;
1422 }
1423
1424 //_____________________________________________________________________________
1425 void AliMonitorClient::SetReference()
1426 {
1427 // set the reference histograms for all monitor histograms
1428
1429   // loop over folder
1430   TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1431   while (TFolder* folder = (TFolder*) iFolder->Next()) {
1432     TFolder* refFolder = (TFolder*) fReference->FindObject(folder->GetName());
1433     if (!refFolder) continue;
1434
1435     // loop over histos
1436     TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1437     while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1438       AliMonitorHisto* refHisto = 
1439         (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1440       if (!refHisto) continue;
1441       histo->SetReference(refHisto);
1442     }
1443     delete iHisto;
1444
1445   }
1446   delete iFolder;
1447 }
1448
1449 //_____________________________________________________________________________
1450 Bool_t AliMonitorClient::TakeCurrentReference()
1451 {
1452 // take the current monitor histogram or folder as reference
1453
1454   // check that a histo or folder is selected
1455   if (!fCurrentItem) return kFALSE;
1456   AliMonitorHisto* histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
1457   if (!histo && !fCurrentItem->GetFirstChild()) return kFALSE;
1458
1459   // confirm-dialog
1460   char message[256];
1461   if (histo) {
1462     sprintf(message, "Do you want to take the current histogram %s/%s "
1463             "as reference histogram?", fCurrentItem->GetParent()->GetText(),
1464             histo->GetName());
1465   } else {
1466     sprintf(message, "Do you want to take all current histogram of the "
1467             "folder %s as reference histogram?", fCurrentItem->GetText());
1468   }
1469   Int_t result;
1470   new TGMsgBox(gClient->GetRoot(), this, "Take Current as Reference",
1471                message, kMBIconQuestion, kMBYes | kMBNo, &result);
1472   if (result != kMBYes) return kFALSE;
1473
1474   // take ...
1475   if (histo) {   // ... a histo
1476     TakeReferenceHisto(fCurrentItem->GetParent()->GetText(), histo);
1477   } else if (fCurrentItem->GetParent()) {  // ... a folder
1478     TakeReferenceFolder(fCurrentItem);
1479   } else {  // ... a top folder
1480     TGListTreeItem* folderItem = fCurrentItem->GetFirstChild();
1481     while (folderItem) {
1482       TakeReferenceFolder(folderItem);
1483       folderItem = folderItem->GetNextSibling();
1484     }
1485   }
1486   return kTRUE;
1487 }
1488
1489 //_____________________________________________________________________________
1490 void AliMonitorClient::TakeReferenceHisto(const char* folderName,
1491                                           AliMonitorHisto* histo)
1492 {
1493 // take the given monitor histogram as reference histogram
1494
1495   // get or create the reference folder
1496   TFolder* refFolder = (TFolder*) fReference->FindObject(folderName);
1497   if (!refFolder) refFolder = fReference->AddFolder(folderName, folderName);
1498
1499   // delete the old reference histo
1500   AliMonitorHisto* refHisto = 
1501     (AliMonitorHisto*) refFolder->FindObject(histo->GetName());
1502   if (refHisto) {
1503     refFolder->Remove(refHisto);
1504     delete refHisto;
1505   }
1506
1507   // add the new one and use it as reference
1508   refFolder->Add(new AliMonitorHisto(*histo));
1509   histo->SetReference(histo);
1510 }
1511
1512 //_____________________________________________________________________________
1513 void AliMonitorClient::TakeReferenceFolder(TGListTreeItem* item)
1514 {
1515 // take all monitor histogram in the given folder as reference histograms
1516
1517   // loop over histos
1518   TGListTreeItem* histoItem = item->GetFirstChild();
1519   while (histoItem) {
1520     AliMonitorHisto* histo = (AliMonitorHisto*) histoItem->GetUserData();
1521     if (histo) TakeReferenceHisto(item->GetText(), histo);
1522     histoItem = histoItem->GetNextSibling();
1523   }
1524 }
1525
1526 //_____________________________________________________________________________
1527 Bool_t AliMonitorClient::SaveReference()
1528 {
1529 // save the reference histograms to the file with name fReferenceFileName
1530
1531   // if no file name is given use a default one
1532   if (fFavoritesFileName.IsNull()) {
1533     char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(), 
1534                                              "AliMonitorClientRef.root");
1535     fFavoritesFileName = fileName;
1536     free(fileName);
1537   }
1538
1539   // open the root file
1540   TFile* file = TFile::Open(fReferenceFileName, "RECREATE");
1541   if (!file || !file->IsOpen()) {
1542     Int_t result;
1543     new TGMsgBox(gClient->GetRoot(), this, "Save Reference",
1544                  "The file could not be opened.", 
1545                  kMBIconExclamation, kMBOk, &result);
1546     if (file) delete file;
1547     return kFALSE;
1548   }
1549
1550   // write the reference folder
1551   fReference->Write();
1552   file->Close();
1553   delete file;
1554   Info("SaveReference", "reference histograms saved to file %s", 
1555        fReferenceFileName.Data());
1556   return kTRUE;
1557 }
1558
1559 //_____________________________________________________________________________
1560 Bool_t AliMonitorClient::SaveReferenceAs()
1561 {
1562 // ask for a file name and save the reference histograms to this file
1563
1564   // display a save file dialog
1565   TGFileInfo fileInfo;
1566   static const char* fileTypes[] = {"ROOT files", "*.root", 
1567                                     "All files",  "*", 
1568                                     NULL,         NULL};
1569   fileInfo.fFileTypes = fileTypes;
1570   fileInfo.fIniDir = StrDup(".");
1571   fileInfo.fFilename = StrDup(fReferenceFileName.Data());
1572   new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fileInfo);
1573   if (!fileInfo.fFilename) return kFALSE;
1574
1575   // save the references
1576   fReferenceFileName = fileInfo.fFilename;
1577   return SaveReference();
1578 }
1579
1580
1581 //_____________________________________________________________________________
1582 void AliMonitorClient::StopLoop()
1583 {
1584 // stop looping over histograms
1585
1586   // stop the timer and reset the loop button picture
1587   if (fLoopTimer) {
1588     fLoopTimer->TurnOff();
1589     delete fLoopTimer;
1590     fLoopTimer = NULL;
1591     ((TGPictureButton*) fLoopButton)->SetPicture(fLoopOnPicture);
1592   }
1593 }
1594
1595 //_____________________________________________________________________________
1596 void AliMonitorClient::LoadSettings()
1597 {
1598 // load setting from the file with the name fgSettingFileName and apply them
1599
1600   // open the text file
1601   char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(), 
1602                                            fgSettingsFileName);
1603   FILE* file = fopen(fileName, "rt");
1604   if (!file) {
1605     free(fileName);
1606     return;
1607   }
1608
1609   // scan the text file and apply the settings
1610   char buffer[256];
1611   while (!feof(file)) {
1612     if (fgets(buffer, 255, file) == NULL) break;
1613     char* token = strtok(buffer, "=");
1614     char* value = strtok(NULL, "\n");
1615     if (!token || !value) continue;
1616     if (value[strlen(value)-1] == '\n') value[strlen(value)-1] = 0;
1617
1618     if (strcmp(token, "ServerName") == 0) {
1619       fServerName = value;
1620
1621     } else if (strcmp(token, "ViewToolBar") == 0) {
1622       ViewToolBar(strcmp(value, "0") != 0);
1623     } else if (strcmp(token, "ViewTree") == 0) {
1624       ViewTree(strcmp(value, "0") != 0);
1625     } else if (strcmp(token, "ViewDescription") == 0) {
1626       ViewDescription(strcmp(value, "0") != 0);
1627     } else if (strcmp(token, "ViewReference") == 0) {
1628       ViewReference(strcmp(value, "0") != 0);
1629     } else if (strcmp(token, "ViewStatistics") == 0) {
1630       ViewStatistics(strcmp(value, "0") != 0);
1631
1632     } else if (strcmp(token, "FavoritesFileName") == 0) {
1633       fFavoritesFileName = value;
1634       LoadFavorites(kFALSE);
1635     } else if (strcmp(token, "FavoritesSaveOnExit") == 0) {
1636       if (strcmp(value, "0") != 0) {
1637         fMenuFavorites->CheckEntry(kMenuFavSaveOnExit);
1638       } else {
1639         fMenuFavorites->UnCheckEntry(kMenuFavSaveOnExit);
1640       }
1641
1642     } else if (strcmp(token, "ReferenceFileName") == 0) {
1643       fReferenceFileName = value;
1644       LoadReference(kFALSE);
1645     } else if (strcmp(token, "ReferenceThreshold") == 0) {
1646       AliMonitorHisto::SetThreshold(atof(value));
1647
1648     } else if (strcmp(token, "LoopInterval") == 0) {
1649       fLoopInterval = atoi(value);
1650     } else if (strcmp(token, "PrintCommand") == 0) {
1651       fPrintCommand = value;
1652     } else if (strcmp(token, "SettingsSaveOnExit") == 0) {
1653       if (strcmp(value, "0") != 0) {
1654         fMenuOptions->CheckEntry(kMenuOptSaveOnExit);
1655       } else {
1656         fMenuOptions->UnCheckEntry(kMenuOptSaveOnExit);
1657       }
1658     }
1659   }
1660
1661   fclose(file);
1662   Info("LoadSettings", "settings from file %s applied", fileName);
1663   free(fileName);
1664 }
1665
1666 //_____________________________________________________________________________
1667 void AliMonitorClient::SaveSettings()
1668 {
1669 // save setting to the file with the name fgSettingFileName
1670
1671   // open the text file
1672   char* fileName = gSystem->ConcatFileName(gSystem->HomeDirectory(), 
1673                                            fgSettingsFileName);
1674   FILE* file = fopen(fileName, "wt");
1675   if (!file) {
1676     Int_t result;
1677     new TGMsgBox(gClient->GetRoot(), this, "Save Settings",
1678                  "The file could not be opened.", 
1679                  kMBIconExclamation, kMBOk, &result);
1680     free(fileName);
1681     return;
1682   }
1683
1684   // write the settings
1685   fprintf(file, "ServerName=%s\n", fServerName.Data());
1686
1687   fprintf(file, "ViewToolBar=%d\n", 
1688           fMenuView->IsEntryChecked(kMenuViewToolBar));
1689   fprintf(file, "ViewTree=%d\n", 
1690           fMenuView->IsEntryChecked(kMenuViewTree));
1691   fprintf(file, "ViewDescription=%d\n", 
1692           fMenuView->IsEntryChecked(kMenuViewDescription));
1693   fprintf(file, "ViewReference=%d\n", 
1694           fMenuView->IsEntryChecked(kMenuViewReference));
1695   fprintf(file, "ViewStatistics=%d\n", 
1696           fMenuView->IsEntryChecked(kMenuViewStatistics));
1697
1698   if (!fFavoritesFileName.IsNull()) {
1699     fprintf(file, "FavoritesFileName=%s\n", fFavoritesFileName.Data());
1700   }
1701   fprintf(file, "FavoritesSaveOnExit=%d\n", 
1702           fMenuFavorites->IsEntryChecked(kMenuFavSaveOnExit));
1703
1704   if (!fReferenceFileName.IsNull()) {
1705     fprintf(file, "ReferenceFileName=%s\n", fReferenceFileName.Data());
1706   }
1707   fprintf(file, "ReferenceThreshold=%.1f\n", AliMonitorHisto::GetThreshold());
1708
1709   fprintf(file, "LoopInterval=%d\n", fLoopInterval);
1710   fprintf(file, "PrintCommand=%s\n", fPrintCommand.Data());
1711   fprintf(file, "SettingsSaveOnExit=%d\n", 
1712           fMenuOptions->IsEntryChecked(kMenuOptSaveOnExit));
1713
1714   fclose(file);
1715   Info("SaveSettings", "settings saved to file %s", fileName);
1716   free(fileName);
1717 }
1718
1719
1720 //_____________________________________________________________________________
1721 Bool_t AliMonitorClient::GetBaseItem()
1722 {
1723 // get the base item for looping over histograms
1724
1725   if (fCurrentItem) {
1726     // the base item is a folder
1727     fBaseItem = fCurrentItem;
1728     // if the current item is a histo, its parent is the base folder
1729     if (fBaseItem->GetParent() && fBaseItem->GetParent()->GetParent()) {
1730       fBaseItem = fBaseItem->GetParent();
1731     }
1732
1733   } else {  // if no item is selected the All item is the base item
1734     fBaseItem = fAllItem;
1735     fCurrentItem = fBaseItem->GetFirstChild();
1736     if (!fCurrentItem) return kFALSE;
1737   }
1738
1739   return kTRUE;
1740 }
1741
1742 //_____________________________________________________________________________
1743 Bool_t AliMonitorClient::GoToNextItem()
1744 {
1745 // go to the next histogram in the loop
1746
1747   if (!fCurrentItem) return kFALSE;
1748   if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1749
1750   // remember the start item to avoid an endless loop
1751   TGListTreeItem* startItem = fCurrentItem;
1752
1753   do {
1754     // folder -> first child
1755     if (fCurrentItem->GetFirstChild()) {
1756       fCurrentItem = fCurrentItem->GetFirstChild();
1757
1758     // histo -> next histo
1759     } else if ((fCurrentItem != fBaseItem) &&
1760                (fCurrentItem->GetNextSibling())) {
1761       fCurrentItem = fCurrentItem->GetNextSibling();
1762
1763     // last histo in folder -> next folder
1764     } else if ((fCurrentItem != fBaseItem) &&
1765                (fCurrentItem->GetParent() != fBaseItem) &&
1766                fCurrentItem->GetParent()->GetNextSibling()) {
1767       fCurrentItem = fCurrentItem->GetParent()->GetNextSibling();
1768
1769     // last histo in last folder -> first folder
1770     } else {
1771       fCurrentItem = fBaseItem->GetFirstChild();
1772     }
1773
1774     // abort if no next item found
1775     if (fCurrentItem == startItem) return kFALSE;
1776
1777   // end loop if an item with a monitor histo was found
1778   } while (!fCurrentItem->GetUserData());
1779
1780   UpdateItem(kTRUE);
1781   return kTRUE;
1782 }
1783
1784 //_____________________________________________________________________________
1785 Bool_t AliMonitorClient::GoToPreviousItem()
1786 {
1787 // go to the previous histogram in the loop
1788
1789   if (!fCurrentItem) return kFALSE;
1790   if (!fBaseItem || !fBaseItem->GetFirstChild()) return kFALSE;
1791
1792   // remember the start item to avoid an endless loop
1793   TGListTreeItem* startItem = fCurrentItem;
1794
1795   do {
1796     // folder -> last child
1797     if (fCurrentItem->GetFirstChild()) {
1798       fCurrentItem = fCurrentItem->GetFirstChild();
1799       while (fCurrentItem->GetNextSibling()) {
1800         fCurrentItem = fCurrentItem->GetNextSibling();
1801       }
1802
1803     // histo -> previous histo
1804     } else if ((fCurrentItem != fBaseItem) && 
1805                (fCurrentItem->GetPrevSibling())) {
1806       fCurrentItem = fCurrentItem->GetPrevSibling();
1807
1808     // first histo in folder -> previous folder
1809     } else if ((fCurrentItem != fBaseItem) && 
1810                (fCurrentItem->GetParent() != fBaseItem) &&
1811                fCurrentItem->GetParent()->GetPrevSibling()) {
1812       fCurrentItem = fCurrentItem->GetParent()->GetPrevSibling();
1813
1814     // first histo in first folder -> last folder
1815     } else {
1816       fCurrentItem = fBaseItem->GetFirstChild();
1817       while (fCurrentItem->GetNextSibling()) {
1818         fCurrentItem = fCurrentItem->GetNextSibling();
1819       }
1820     }
1821
1822     // abort if no next item found
1823     if (fCurrentItem == startItem) return kFALSE;
1824
1825   // end loop if an item with a monitor histo was found
1826   } while (!fCurrentItem->GetUserData());
1827
1828   UpdateItem(kTRUE);
1829   return kTRUE;
1830 }
1831
1832 //_____________________________________________________________________________
1833 void AliMonitorClient::UpdateItem(Bool_t highlight)
1834 {
1835 // update the displayed tree for currently selected item
1836
1837   if (highlight) {  // highlight the selected item and open its parent folders
1838     TGListTreeItem* parent = fCurrentItem->GetParent();
1839     while (parent) {
1840       if (!parent->IsOpen()) fTree->OpenItem(parent);
1841       parent = parent->GetParent();
1842     }
1843     fTree->HighlightItem(fCurrentItem);
1844     gClient->NeedRedraw(fTree);
1845   }
1846
1847   // update displayed histo
1848   UpdateDescription();
1849   UpdateHisto();
1850
1851   // en- or disable the "Reference/Take Current" menu item
1852   TGListTreeItem* base = fCurrentItem;
1853   while (base->GetParent()) base = base->GetParent();
1854   if (base != fComparisonItem) {
1855     fMenuReference->EnableEntry(kMenuRefTakeCurrent);
1856   } else {
1857     fMenuReference->DisableEntry(kMenuRefTakeCurrent);
1858   }
1859
1860   // en- or disable the "Favorites/Add" and "Favorites/Delete" menu items
1861   if (fCurrentItem->GetParent()) {
1862     if (base == fFavoritesItem) {
1863       fMenuFavorites->DisableEntry(kMenuFavAdd);
1864       fMenuFavorites->EnableEntry(kMenuFavDelete);
1865     } else {
1866       fMenuFavorites->EnableEntry(kMenuFavAdd);
1867       fMenuFavorites->DisableEntry(kMenuFavDelete);
1868     }
1869   } else {
1870     fMenuFavorites->DisableEntry(kMenuFavAdd);
1871     fMenuFavorites->DisableEntry(kMenuFavDelete);
1872   }
1873 }
1874
1875
1876 //_____________________________________________________________________________
1877 Bool_t AliMonitorClient::CheckForNewData()
1878 {
1879 // check whether the monitor process server sent new data
1880
1881   // receive a message from the server
1882   if (!fSocket || !fSocket->IsValid()) return kFALSE;
1883   TMessage* message = NULL;
1884   Int_t result = fSocket->Recv(message);
1885
1886   // replace the old folder of monitor histos with the new one
1887   if (result > 0) {
1888     if (fFolder) delete fFolder;
1889     fFolder = (TFolder*) message->ReadObject(message->GetClass());
1890     return kTRUE;
1891   }
1892
1893   return kFALSE;
1894 }
1895
1896 //_____________________________________________________________________________
1897 void AliMonitorClient::ClearItems(TGListTreeItem* base)
1898 {
1899 // remove the references to the histograms from all subitems of the 
1900 // given tree item
1901
1902   // loop over folders
1903   TGListTreeItem* folderItem = base->GetFirstChild();
1904   while (folderItem) {
1905
1906     // loop over histos
1907     TGListTreeItem* histoItem = folderItem->GetFirstChild();
1908     while (histoItem) {
1909       histoItem->SetUserData(NULL);
1910       histoItem = histoItem->GetNextSibling();
1911     }
1912
1913     folderItem = folderItem->GetNextSibling();
1914   }
1915 }
1916
1917 //_____________________________________________________________________________
1918 void AliMonitorClient::CleanUpTree(TGListTreeItem* base)
1919 {
1920 // remove items without monitor histograms and 
1921 // folders without monitor histograms
1922
1923   // loop over folders
1924   TGListTreeItem* folderItem = base->GetFirstChild();
1925   while (folderItem) {
1926
1927     // loop over histos
1928     TGListTreeItem* histoItem = folderItem->GetFirstChild();
1929     while (histoItem) {
1930       TGListTreeItem* deleteItem = NULL;
1931       if (!histoItem->GetUserData()) deleteItem = histoItem;
1932       histoItem = histoItem->GetNextSibling();
1933       if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1934       if (deleteItem) fTree->DeleteItem(deleteItem);
1935     }
1936
1937     folderItem = folderItem->GetNextSibling();
1938   }
1939
1940   // loop over folders and remove empty folders
1941   folderItem = base->GetFirstChild();
1942   while (folderItem) {
1943     TGListTreeItem* deleteItem = NULL;
1944     if (!folderItem->GetFirstChild()) deleteItem = folderItem;
1945     folderItem = folderItem->GetNextSibling();
1946     if (fCurrentItem == deleteItem) fCurrentItem = NULL;
1947     if (deleteItem) fTree->DeleteItem(deleteItem);
1948   }
1949 }
1950
1951 //_____________________________________________________________________________
1952 void AliMonitorClient::UpdateTree()
1953 {
1954 // update the tree of monitor histograms
1955
1956   // delete references to old monitor histograms
1957   ClearItems(fAllItem);
1958
1959   // loop over folder
1960   TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
1961   while (TFolder* folder = (TFolder*) iFolder->Next()) {
1962
1963     // loop over histos
1964     TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
1965     while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
1966
1967       // add new monitor histograms
1968       TGListTreeItem* histoItem = GetItem(fAllItem, folder->GetName(),
1969                                           histo->GetName(), kTRUE);
1970       histoItem->SetUserData(histo);
1971     }
1972     delete iHisto;
1973
1974   }
1975   delete iFolder;
1976
1977   // remove items and folders without monitor histograms
1978   CleanUpTree(fAllItem);
1979
1980   gClient->NeedRedraw(fTree);
1981 }
1982
1983 //_____________________________________________________________________________
1984 void AliMonitorClient::UpdateFavoritesTree()
1985 {
1986 // update the tree of favorite monitor histograms
1987
1988   // loop over folders
1989   TGListTreeItem* folderItem = fFavoritesItem->GetFirstChild();
1990   while (folderItem) {
1991
1992     // loop over histos
1993     TGListTreeItem* histoItem = folderItem->GetFirstChild();
1994     while (histoItem) {
1995
1996       // set monitor histo
1997       histoItem->SetUserData(GetHisto(folderItem->GetText(), 
1998                                       histoItem->GetText()));
1999       histoItem = histoItem->GetNextSibling();
2000     }
2001
2002     folderItem = folderItem->GetNextSibling();
2003   }
2004 }
2005
2006 //_____________________________________________________________________________
2007 void AliMonitorClient::UpdateComparisonTree()
2008 {
2009 // update the tree of monitor histograms with significant deviation
2010 // from the reference histograms
2011
2012   if (!fFolder) return;
2013
2014   // delete references to old monitor histograms
2015   ClearItems(fComparisonItem);
2016
2017   // add monitor histograms where the comparison returns a deviation
2018   // loop over folders
2019   TIterator* iFolder = fFolder->GetListOfFolders()->MakeIterator();
2020   while (TFolder* folder = (TFolder*) iFolder->Next()) {
2021
2022     // loop over histos
2023     TIterator* iHisto = folder->GetListOfFolders()->MakeIterator();
2024     while (AliMonitorHisto* histo = (AliMonitorHisto*) iHisto->Next()) {
2025
2026       // compare the histo to its reference
2027       Bool_t comparison = kTRUE;
2028       if (fEventButton->IsDown()) {
2029         comparison = histo->CompareEvent(fEventNumber->GetIntNumber());
2030       } else if (fSumButton->IsDown()) {
2031         comparison = histo->CompareSum(fEventNumber->GetIntNumber());
2032       } else {
2033         comparison = histo->CompareRun();
2034       }
2035
2036       // add it to the comparison tree in case of a bad comparison result
2037       if (!comparison) {
2038         TGListTreeItem* histoItem = GetItem(fComparisonItem, folder->GetName(),
2039                                             histo->GetName(), kTRUE);
2040         histoItem->SetUserData(histo);
2041       }
2042     }
2043     delete iHisto;
2044
2045   }
2046   delete iFolder;
2047
2048   // remove items and folders without monitor histograms
2049   CleanUpTree(fComparisonItem);
2050
2051   gClient->NeedRedraw(fTree);
2052 }
2053
2054 //_____________________________________________________________________________
2055 void AliMonitorClient::UpdateDescription()
2056 {
2057 // update the description of the current monitor histogram
2058
2059   fDescription->Clear();
2060   AliMonitorHisto* histo = NULL;
2061   if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2062   if (histo) fDescription->LoadBuffer(histo->GetDescription().Data());
2063
2064   gClient->NeedRedraw(fDescription);
2065 }
2066
2067 //_____________________________________________________________________________
2068 void AliMonitorClient::UpdateHisto()
2069 {
2070 // update the current monitor histogram
2071
2072   // clear the canvas if no histo is selected
2073   AliMonitorHisto* histo = NULL;
2074   if (fCurrentItem) histo = (AliMonitorHisto*) fCurrentItem->GetUserData();
2075   if (!histo) {
2076     fDrawCanvas->GetCanvas()->Clear();
2077     fDrawCanvas->GetCanvas()->Update();
2078     return;
2079   }
2080
2081   // draw the histo for a single event or summed over several events or a run
2082   fDrawCanvas->GetCanvas()->cd();
2083   if (fEventButton->IsDown()) {
2084     histo->DrawEvent(fEventNumber->GetIntNumber());
2085   } else if (fSumButton->IsDown()) {
2086     histo->DrawSum(fEventNumber->GetIntNumber());
2087   } else {
2088     histo->DrawRun();
2089   }
2090 }
2091
2092 //_____________________________________________________________________________
2093 void AliMonitorClient::UpdateAll()
2094 {
2095 // update the trees, the histogram and the description
2096
2097   UpdateTree();
2098   UpdateFavoritesTree();
2099   UpdateComparisonTree();
2100   UpdateDescription();
2101   UpdateHisto();
2102 }
2103