Go from pointer to ifstream to ifstream.
[u/mrichter/AliRoot.git] / MUON / AliMUONPainterMasterFrame.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 #include "AliMUONPainterMasterFrame.h"
19
20 #include "AliMUONChamberPainter.h"
21 #include "AliMUONPainterGroup.h"
22 #include "AliMUONPainterMatrix.h"
23 #include "AliMUONPainterMatrixFrame.h"
24 #include "AliMUONPainterInterfaceHelper.h"
25 #include "AliMUONPainterRegistry.h"
26 #include "AliMUONAttPainterSelectorFrame.h"
27 #include "AliMUONVPainter.h"
28 #include "AliCodeTimer.h"
29 #include "AliLog.h"
30 #include <Riostream.h>
31 #include <TApplication.h>
32 #include <TCanvas.h>
33 #include <TEnv.h>
34 #include <TGComboBox.h>
35 #include <TGFileDialog.h>
36 #include <TGLabel.h>
37 #include <TObjArray.h>
38 #include <TObjString.h>
39 #include <TGButtonGroup.h>
40 #include <TGMsgBox.h>
41 #include <TSystem.h>
42
43 /// \class AliMUONPainterMasterFrame
44 ///
45 /// Main window of the 2D display
46 ///
47 /// \author Laurent Aphecetche, Subatech
48
49 ///\cond CLASSIMP
50 ClassImp(AliMUONPainterMasterFrame)
51 ///\endcond
52
53 const Int_t AliMUONPainterMasterFrame::fgkBorderSize = 10;
54
55 //_____________________________________________________________________________
56 AliMUONPainterMasterFrame::AliMUONPainterMasterFrame(const TGWindow* p, 
57                                                      UInt_t w, UInt_t h, AliMUONPainterMatrix* matrix)
58 : TGCompositeFrame(p,w,h,kVerticalFrame),
59 fNavigationFrame(0x0),
60 fPainterMatrixFrame(0x0),
61 fBackButton(0x0),
62 fForwardButton(0x0),
63 fGroupTitle(0x0),
64 fPrintMeButton(0x0),
65 fPrintAsButton(0x0),
66 fNavigation(),
67 fCurrentNavigationPosition(-1),
68 fAttPainterSelectorFrame(0x0)
69 {  
70   /// ctor
71     
72   UInt_t wi = w - fgkBorderSize*2;
73   UInt_t hi = h - fgkBorderSize*3;
74   
75   fNavigationFrame = new TGHorizontalFrame(this,wi);
76   
77   AddFrame(fNavigationFrame,new TGLayoutHints(kLHintsExpandX|kLHintsTop,
78                                               fgkBorderSize,fgkBorderSize,
79                                               fgkBorderSize,fgkBorderSize));
80   
81   fBackButton = new TGPictureButton(fNavigationFrame,
82                                     gClient->GetPicture("tb_back.xpm"));
83   
84   fForwardButton = new TGPictureButton(fNavigationFrame,
85                                        gClient->GetPicture("tb_forw.xpm"));    
86
87   fPrintMeButton = new TGTextButton(fNavigationFrame,"Print");
88   fPrintAsButton = new TGTextButton(fNavigationFrame,"Print As...");
89
90   fAttPainterSelectorFrame = new AliMUONAttPainterSelectorFrame(fNavigationFrame,w/2,20);
91   
92   fGroupTitle = new TGLabel(fNavigationFrame,"");
93   
94   fNavigationFrame->AddFrame(fBackButton,new TGLayoutHints(kLHintsCenterY));
95   fNavigationFrame->AddFrame(fForwardButton,new TGLayoutHints(kLHintsCenterY));
96   
97   fNavigationFrame->AddFrame(fAttPainterSelectorFrame,new TGLayoutHints(kLHintsCenterY,10));
98
99   fNavigationFrame->AddFrame(fPrintMeButton,new TGLayoutHints(kLHintsCenterY,10));
100   fNavigationFrame->AddFrame(fPrintAsButton,new TGLayoutHints(kLHintsCenterY,10));
101
102   fAttPainterSelectorFrame->Connect("Clicked(AliMUONAttPainter*)",
103                                     "AliMUONPainterMasterFrame",
104                                     this,
105                                     "AttributesChanged(AliMUONAttPainter*)");
106   
107   fNavigationFrame->AddFrame(fGroupTitle,new TGLayoutHints(kLHintsExpandX|kLHintsCenterX|kLHintsCenterY,10));
108   
109   fForwardButton->Connect("Clicked()","AliMUONPainterMasterFrame",
110                           this,
111                           "Forward()");
112
113   fBackButton->Connect("Clicked()","AliMUONPainterMasterFrame",
114                           this,
115                           "Backward()");
116     
117   fPrintMeButton->Connect("Clicked()","AliMUONPainterMasterFrame",
118                         this,
119                         "PrintMe()");
120
121   fPrintAsButton->Connect("Clicked()","AliMUONPainterMasterFrame",
122                         this,
123                         "PrintAs()");
124   
125   UInt_t w1 = wi;
126   //  UInt_t h1 = hi - fNavigationFrame->GetHeight() - 3*fgkBorderSize;
127   UInt_t h1 = hi - 7*12;
128   
129   MakeTopPainterMatrix(w1,h1,matrix);
130
131   AddFrame(fPainterMatrixFrame,new TGLayoutHints(kLHintsExpandX,
132                                                 fgkBorderSize,fgkBorderSize,
133                                                 0,fgkBorderSize));
134   
135   AliMUONPainterInterfaceHelper::SetBackgroundColor("MasterFrame.Navigation",*fNavigationFrame);
136   AliMUONPainterInterfaceHelper::SetBackgroundColor("MasterFrame.Main",*this);
137   
138   AliDebug(1,Form("fNavigation=%p",&fNavigation));
139   
140   AliMUONPainterRegistry::Instance()->Connect("PainterMatrixWantToShow(AliMUONPainterMatrix*)",
141                                               "AliMUONPainterMasterFrame",
142                                               this,
143                                               "PainterMatrixWantToShow(AliMUONPainterMatrix*)");
144   
145   fPainterMatrixFrame->DataSourceWasChanged(matrix->DataPattern().Data(),matrix->Data(),matrix->DataIndex());
146 }
147
148 //_____________________________________________________________________________
149 AliMUONPainterMasterFrame::~AliMUONPainterMasterFrame()
150 {
151   /// dtor
152   Cleanup();
153 }
154
155 //_____________________________________________________________________________
156 void
157 AliMUONPainterMasterFrame::AddPainterMatrix(AliMUONPainterMatrix* painterMatrix)
158 {
159   /// array is adopted (by the registry)
160
161   AliDebug(1,Form("matrix=%p %s",painterMatrix,painterMatrix->GetName()));
162   
163   Int_t i = AliMUONPainterRegistry::Instance()->Register(painterMatrix);
164
165   SetNavigation(i);
166 }
167
168 //_____________________________________________________________________________
169 void
170 AliMUONPainterMasterFrame::PainterMatrixWantToShow(AliMUONPainterMatrix* group)
171 {
172   /// FIXME: should check whether we are the active window before
173   /// responding to this message ?
174
175   AliDebug(1,Form("group=%p %s",group,group->GetName()));
176   
177   Int_t i = AliMUONPainterRegistry::Instance()->FindIndexOf(group);
178
179   Int_t alreadyThere(-1);
180   
181   for ( Int_t j = 0; j < fNavigation.GetSize(); ++j )
182   {
183     if ( fNavigation[j] == i ) alreadyThere = j;
184   }
185   
186   if (alreadyThere<0) 
187   {
188     SetNavigation(i);
189   }
190   else
191   {
192     fCurrentNavigationPosition = alreadyThere;
193   }
194   
195   ShowPainterMatrix(group);  
196 }
197      
198 //_____________________________________________________________________________
199 void
200 AliMUONPainterMasterFrame::PrintAs() const
201 {
202   /// Handle the PrintAs button
203   
204   TGFileInfo fileInfo;
205   
206   new TGFileDialog(gClient->GetRoot(),gClient->GetRoot(),
207                    kFDSave,&fileInfo);
208   
209   if ( fileInfo.fFilename ) 
210   {
211     SaveAs(gSystem->ExpandPathName(Form("%s",fileInfo.fFilename)),"RECREATE");
212   }
213 }
214
215 //_____________________________________________________________________________
216 void
217 AliMUONPainterMasterFrame::PrintMe() const
218 {
219   /// Handle the PrintMe button
220   
221   SaveAs(gSystem->ExpandPathName(Form("%s.png",fPainterMatrixFrame->Matrix()->GetName())),"RECREATE");
222 }
223
224 //_____________________________________________________________________________
225 void
226 AliMUONPainterMasterFrame::SetNavigation(Int_t i)
227 {
228   /// Change navigation position
229   
230   ++fCurrentNavigationPosition;
231   fNavigation.Set(fCurrentNavigationPosition+1);
232   fNavigation[fCurrentNavigationPosition] = i;
233 }
234
235 //_____________________________________________________________________________
236 void
237 AliMUONPainterMasterFrame::ShowPainterMatrix(AliMUONPainterMatrix* painterMatrix)
238 {
239   /// Change the painter matrix we show
240   
241   fPainterMatrixFrame->Use(painterMatrix);
242   
243   painterMatrix->Connect("Clicked(AliMUONVPainter*,Double_t*)",
244                          "AliMUONPainterMasterFrame",this,
245                          "Clicked(AliMUONVPainter*,Double_t*)");
246
247   painterMatrix->Connect("ShiftClicked(AliMUONVPainter*,Double_t*)",
248                          "AliMUONPainterMasterFrame",this,
249                          "ShiftClicked(AliMUONVPainter*,Double_t*)");
250   
251   fPainterMatrixFrame->Connect("TitleHasChanged(const char*)",
252                               "AliMUONPainterMasterFrame",this,
253                               "ChangeTitle(const char*)");
254   UpdateNavigation();
255   
256   UpdateAttributes(*(fPainterMatrixFrame->Matrix()));
257   
258   AliMUONPainterRegistry::Instance()->AddToHistory(painterMatrix);
259   
260   Layout();
261 }
262
263 //_____________________________________________________________________________
264 void
265 AliMUONPainterMasterFrame::ChangeTitle(const char* newTitle)
266 {
267   /// Change the top title
268   
269   fGroupTitle->SetText(newTitle);
270   fGroupTitle->Resize();
271   Layout();
272 }
273
274 //_____________________________________________________________________________
275 void
276 AliMUONPainterMasterFrame::Backward()
277 {
278   /// Move back one step in the history
279   --fCurrentNavigationPosition;
280   
281   AliMUONPainterMatrix* group = 
282     AliMUONPainterRegistry::Instance()->PainterMatrix(fNavigation[fCurrentNavigationPosition]);
283   
284   ShowPainterMatrix(group);
285   
286   UpdateNavigation();
287 }
288
289 //_____________________________________________________________________________
290 void
291 AliMUONPainterMasterFrame::Forward()
292 {
293   /// Move forward one step in history
294   
295   ++fCurrentNavigationPosition;
296   
297   AliMUONPainterMatrix* group = 
298     AliMUONPainterRegistry::Instance()->PainterMatrix(fNavigation[fCurrentNavigationPosition]);
299   
300   ShowPainterMatrix(group);
301   
302   UpdateNavigation();
303 }
304
305 //_____________________________________________________________________________
306 void 
307 AliMUONPainterMasterFrame::Clicked(AliMUONVPainter* painter, Double_t* values)
308 {
309   /// A given painter was (singly) clicked
310
311   if ( painter->CanBeDetached() )
312   {
313     fPainterMatrixFrame->MouseLeave(painter);
314   
315     AliMUONPainterMatrix* matrix = new AliMUONPainterMatrix(painter->Name().Data());
316
317     AliMUONVPainter* p = painter->Detach();
318
319     p->SetResponder(1);
320
321     matrix->Adopt(p);
322   
323     AddPainterMatrix(matrix);
324     ShowPainterMatrix(matrix);
325   }
326   else
327   {
328     painter->DrawHistogram(values);
329   }
330 }
331
332 //_____________________________________________________________________________
333 void 
334 AliMUONPainterMasterFrame::ShiftClicked(AliMUONVPainter* painter, Double_t*)
335 {
336   /// A given painter was shift-clicked
337   
338   if ( !painter->CanBeDetached() ) return;
339   
340   AliMUONPainterMatrix* currentMatrix = fPainterMatrixFrame->Matrix();
341   
342   AliMUONAttPainter a = painter->Attributes();
343   
344   TString basename(Form("%s-DUAL",painter->GetName()));
345   
346   TString newName = AliMUONPainterMatrix::NameIt(currentMatrix->Whatname(),basename.Data(),a);
347   
348   AliMUONPainterMatrix* matrix = AliMUONPainterRegistry::Instance()->PainterMatrix(newName.Data());
349   
350   if (!matrix)
351   {
352     // No. So we must make a new matrix painter from the existing one,
353     // and add to this new matrix the painters of the other one, but
354     // using the new attributes...
355     
356     // create "opposite" attributes
357     AliMUONAttPainter a1(a);
358     AliMUONAttPainter a2(a);
359   
360     a2.Invert();
361     
362     a1.SetCathodeAndPlaneDisabled(kTRUE);
363     a2.SetCathodeAndPlaneDisabled(kTRUE);
364     
365     AliMUONVPainter* p1 = AliMUONVPainter::CreatePainter(painter->ClassName(),
366                                                          a1,
367                                                          painter->ID0(),
368                                                          painter->ID1());
369     
370     AliMUONVPainter* p2 = AliMUONVPainter::CreatePainter(painter->ClassName(),
371                                                          a2,
372                                                          painter->ID0(),
373                                                          painter->ID1());
374     
375     if (!p1 || !p2)
376     {
377       Int_t ret;
378       new TGMsgBox(gClient->GetRoot(), this,
379                    "Invalid combination", "Cannot create 2 views from this painter",
380                    kMBIconExclamation, kMBOk, &ret);
381       PainterMatrixWantToShow(currentMatrix);
382       delete p1;
383       delete p2;
384       return;
385     }
386     
387     p1->UpdateGroupsFrom(*(painter->Master()));
388     p2->UpdateGroupsFrom(*(painter->Master()));
389     
390     p1->SetResponder(1);
391     p2->SetResponder(1);
392     
393     Int_t nx(2);
394     Int_t ny(1);
395     
396     AliMpArea area(painter->Area());
397     
398     if ( area.GetDimensionX() > 1.2*area.GetDimensionY() ) 
399     {
400       nx = 1;
401       ny = 2;
402     }
403     
404     matrix = new AliMUONPainterMatrix(basename.Data(),nx,ny);
405     
406     matrix->Adopt(p1);
407     matrix->Adopt(p2);
408     
409     AddPainterMatrix(matrix);
410   }
411   
412   matrix->SetData(currentMatrix->DataPattern(),
413                   currentMatrix->Data(),
414                   currentMatrix->DataIndex());
415   
416   fPainterMatrixFrame->MouseLeave(painter);
417   
418   PainterMatrixWantToShow(matrix);
419 }
420
421 //_____________________________________________________________________________
422 void 
423 AliMUONPainterMasterFrame::SaveAs(const char* filename, Option_t* option) const
424 {
425   /// Save painter matrix (in the sense of "print") in filename
426   fPainterMatrixFrame->SaveAs(filename,option);
427 }
428
429 //_____________________________________________________________________________
430 void
431 AliMUONPainterMasterFrame::Update()
432 {
433   /// Update ourselves
434   
435   fPainterMatrixFrame->Update();
436   fPainterMatrixFrame->UpdateInterface(kFALSE);
437 }
438
439 //_____________________________________________________________________________
440 void
441 AliMUONPainterMasterFrame::UpdateAttributes(const AliMUONPainterMatrix& painterMatrix)
442 {
443   /// Update the view buttons from the matrix we actually plot
444   
445   fAttPainterSelectorFrame->Update(painterMatrix.Attributes());
446 }
447
448 //_____________________________________________________________________________
449 void
450 AliMUONPainterMasterFrame::MakeTopPainterMatrix(UInt_t w, UInt_t h, AliMUONPainterMatrix* matrix)
451 {
452   /// Create the first painter matrix that appears when we are create
453   /// FIXME: how to make this more flexible ?
454   
455   fPainterMatrixFrame = new AliMUONPainterMatrixFrame(this,w,h);
456
457   if (matrix)
458   {
459     PainterMatrixWantToShow(matrix);
460   }
461   else
462   {
463     AliError("Cannot work without a painterMatrix");
464   }
465 }
466
467 //_____________________________________________________________________________
468 void
469 AliMUONPainterMasterFrame::UpdateNavigation()
470 {
471   /// Update navigation frame
472
473   fBackButton->SetEnabled(kTRUE);
474   fForwardButton->SetEnabled(kTRUE);
475
476   if ( fCurrentNavigationPosition == 0 ) 
477   {
478     fBackButton->SetEnabled(kFALSE);
479   }
480   if ( fCurrentNavigationPosition == fNavigation.GetSize()-1 ) 
481   {
482     fForwardButton->SetEnabled(kFALSE);
483   }
484 }
485
486 //_____________________________________________________________________________
487 void
488 AliMUONPainterMasterFrame::AttributesChanged(const AliMUONAttPainter* newValues)
489 {
490   /// Attributes changed (e.g. from cath0 to cath1 or bending to nonbending, etc...)
491   
492   AliMUONPainterMatrix* currentMatrix = fPainterMatrixFrame->Matrix();
493   
494   AliMUONAttPainter a = currentMatrix->Validate(*newValues);
495   
496   if (!a.IsValid())
497   {
498     Int_t ret;
499     new TGMsgBox(gClient->GetRoot(), this,
500                  "Invalid combination", "Change of attributes not possible for this object",
501                  kMBIconExclamation, kMBOk, &ret);
502     PainterMatrixWantToShow(currentMatrix);
503     return;
504   }
505   
506   // First check if we already have this matrix available
507   
508   TString newName = AliMUONPainterMatrix::NameIt(currentMatrix->Whatname(),currentMatrix->Basename(),a);
509   
510   AliMUONPainterMatrix* matrix = AliMUONPainterRegistry::Instance()->PainterMatrix(newName.Data());
511
512   if (!matrix)
513   {
514     // No. So we must make a new matrix painter from the existing one,
515     // and add to this new matrix the painters of the other one, but
516     // using the new attributes...
517     
518     matrix = currentMatrix->Clone(a);
519   
520     AddPainterMatrix(matrix);
521   }
522   
523   matrix->SetData(currentMatrix->DataPattern(),
524                   currentMatrix->Data(),
525                   currentMatrix->DataIndex());
526   
527   PainterMatrixWantToShow(matrix);
528 }