source: trunk/Mars/mbase/MEnv.cc@ 19344

Last change on this file since 19344 was 19086, checked in by tbretz, 6 years ago
pos is a pointer, must be !=0 not >0
File size: 34.1 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 2/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MEnv
28//
29// It is a slightly changed version of TEnv. It logs all resources which are
30// touched, so that you can print all untouched resources by
31// PrintUntouched()
32//
33// A new special resource is available. With the resource "Include"
34// you can include resources from other files, for example
35//
36// Include: file1.rc file2.rc
37//
38// Including can be done recursively. Resources from the included files
39// have lower priority. This allows to write a resource file with your
40// default resources which then can be included in other files overwriting
41// some of the resources.
42//
43// If given paths are not absolute there base is always th elocation of
44// the including file.
45//
46// Class Version 1:
47// ----------------
48// + TString fName
49//
50//////////////////////////////////////////////////////////////////////////////
51#include "MEnv.h"
52
53#include <fstream>
54#include <exception>
55
56#include <Gtypes.h>
57#include <TObjString.h>
58#include <TObjArray.h>
59
60#include <TPave.h>
61#include <TAttText.h>
62#include <TAttMarker.h>
63#include <THashList.h> // needed since root v5.10/00 (TEnv::GetTable)
64
65#include "MLog.h"
66#include "MLogManip.h"
67
68#include "MArgs.h"
69#include "MString.h"
70
71ClassImp(MEnv);
72
73using namespace std;
74
75//---------------------------------------------------------------------------
76//
77// (Default) constructor. If the given file cannot be accessed SetRcName("")
78// is called which can then be checked by IsValid()
79//
80// The second argument is the default name. Usually as name of the MEnv
81// the base name of the file is returned. By giving a default name
82// you can overwrite this behavious. This is useful for I/O
83// because it allows to use Read and Write without argument.
84//
85MEnv::MEnv(const char *name, const char *defname) : TEnv(name), fName(defname)
86{
87 fChecked.SetOwner();
88
89 // If TEnv::TEnv has not set fRcName
90 if (!IsValid())
91 return;
92
93 // ExpandPathName (not done by TEnv::TEnv) and read again
94 TString fname(name);
95 gSystem->ExpandPathName(fname);
96
97 // Is file accessible
98 if (gSystem->AccessPathName(fname, kFileExists))
99 fname = "";
100
101 SetRcName(fname);
102
103 if (!IsTEnvCompliant(name)){
104 throw "This file can't be correctly parsed by TEnv";
105 return;
106 }
107
108 // No file found
109 if (fname.IsNull())
110 return;
111
112 // File has been already processed, but ReadInclude is part of a
113 // derived function, i.e. not yet executed.
114 if (GetEntries()>0 || fname==name)
115 {
116 if (ReadInclude()<0)
117 SetRcName("");
118 return;
119 }
120
121 // File not yet processed. Reread file.
122 if (ReadFile(fname, kEnvLocal)<0)
123 SetRcName("");
124}
125
126//---------------------------------------------------------------------------
127//
128// Process an Include directive and read the corresponding contents
129//
130Int_t MEnv::ReadInclude()
131{
132 // Check for "Include" resource
133 const TString incl = GetValue("Include", "");
134 if (incl.IsNull())
135 return 0;
136
137 const char *dir = gSystem->DirName(GetRcName());
138
139 // Tokenize the array into single files divided by a whitespace
140 TObjArray *arr = incl.Tokenize(" ");
141
142 // We have to rebuild the Include array from scratch to get the
143 // correct sorting for a possible rereading.
144 SetValue("Include", "");
145
146 // FIXME: Make sure that recursions don't crash the system!
147
148 for (int i=0; i<arr->GetEntries(); i++)
149 {
150 // Get file name to include
151 TString fenv = (*arr)[i]->GetName();
152
153 // If the is not anabsolute path we prepend the dir-name
154 // of the including file. This allows that includes
155 // do not necessarily need absolute paths and paths are always
156 // relative to the location of th eincluding file.
157 if (!gSystem->IsAbsoluteFileName(fenv))
158 {
159 fenv.Prepend("/");
160 fenv.Prepend(dir);
161 }
162
163 // Read included file and check if its valid
164 const MEnv env(fenv);
165 if (!env.IsValid())
166 {
167 delete arr;
168 return -1;
169 }
170
171 // Add file name before its childs
172 SetValue("+Include", fenv);
173
174 // If it is valid add entries from include without overwriting,
175 // i.e. the included resources have lower priority
176 AddEnv(env, kFALSE);
177
178 // Get a possible child include from env
179 const TString incl2 = const_cast<MEnv&>(env).GetValue("Include", "");
180 if (!incl2.IsNull())
181 SetValue("+Include", incl2);
182 }
183
184 delete arr;
185
186 // Get final compiled resource
187 TString inc = GetValue("Include", "");
188
189 // Remove obsolete whitespaces for convinience
190 inc.ReplaceAll(" ", " ");
191 inc = inc.Strip(TString::kBoth);
192
193 // Set final resource, now as kEnvLocal (previously set as kEnvChanged)
194 SetValue("Include", inc, kEnvLocal);
195
196 // FIXME: Remove douplets in the correct order
197
198 return 0;
199}
200
201//---------------------------------------------------------------------------
202//
203// Check if the input file is compatible to the way TEnv parses a resource file.
204//
205// Returns true in case everything is file and
206// false in case there is a problem with the file.
207//
208// Background:
209// This check has been introduced as a workaround for a ROOT feature.
210// TEnv will not see the last line in a text file, when this last line
211// does not end with a \n.
212//
213// In addition we check for the occurence of \r, since some editors would
214// place \r instead of \n (unlike windows that uses \n\r), which would
215// also result in problems.
216// FIXME: So currently we also complain about "\n\r" and "\r\n" as well as
217// "\r \t \n" or "\n \t\t\t\r", which would in fact not be a problem at
218// all.
219Bool_t MEnv::IsTEnvCompliant(const char *fname)
220{
221 ifstream ifs(fname);
222 bool printable_char_since_last_lf = false;
223 char c;
224 while (ifs.good()){
225 ifs.get(c);
226
227 if (c==13){
228 gLog << err << "Menv::IsTEnvCompliant - file:" << fname
229 << " contains \\r this might lead to parsing errors. "
230 <<"Please exchange \\r by \\n everywhere in that file."
231 << endl;
232 return false;
233 }
234 if (c=='\n'){
235 printable_char_since_last_lf = false;
236 }
237 if (isgraph(c)){
238 printable_char_since_last_lf = true;
239 }
240 }
241 if (printable_char_since_last_lf){
242 gLog << err << "Menv::IsTEnvCompliant - file:" << fname
243 << " must have \\n at the end of the file. "
244 <<"Please make sure this is the case."
245 << endl;
246 return false;
247 }
248 return true;
249}
250
251//---------------------------------------------------------------------------
252//
253// Read and parse the resource file for a certain level.
254// Returns -1 on case of error, 0 in case of success.
255//
256// Check for an include directive
257//
258Int_t MEnv::ReadFile(const char *fname, EEnvLevel level)
259{
260 // First read the file via TEnv
261 if (TEnv::ReadFile(fname, level)<0)
262 return -1;
263
264 return ReadInclude();
265}
266
267// --------------------------------------------------------------------------
268//
269// Read an object from the current directory. If no name is given
270// the name of this object is used.
271//
272Int_t MEnv::Read(const char *name)
273{
274 const Int_t rc = TEnv::Read(name?name:(const char*)fName);
275 //if (name)
276 // SetName(name);
277 return rc;
278}
279
280//---------------------------------------------------------------------------
281//
282// Make sure that the name used for writing doesn't contain a full path
283//
284const char *MEnv::GetName() const
285{
286 if (!fName.IsNull())
287 return fName;
288
289 const char *pos = strrchr(GetRcName(), '/');
290 return pos ? pos+1 : GetRcName();
291}
292
293//---------------------------------------------------------------------------
294//
295// Return the total number of entries in the table
296//
297Int_t MEnv::GetEntries() const
298{
299 if (!GetTable())
300 return -1;
301
302 return GetTable()->GetEntries();
303}
304
305//---------------------------------------------------------------------------
306//
307// Compile str+post and make sure that in between there is a unique dot.
308//
309TString MEnv::Compile(TString str, const char *post) const
310{
311 if (!str.IsNull() && !str.EndsWith("."))
312 str += ".";
313
314 str += post;
315
316 return str;
317}
318
319//---------------------------------------------------------------------------
320//
321// Get the value from the table and remember the value as checked
322//
323Int_t MEnv::GetValue(const char *name, Int_t dflt)
324{
325 if (!fChecked.FindObject(name))
326 fChecked.Add(new TObjString(name));
327 return TEnv::GetValue(name, dflt);
328}
329
330//---------------------------------------------------------------------------
331//
332// Get the value from the table and remember the value as checked
333//
334Double_t MEnv::GetValue(const char *name, Double_t dflt)
335{
336 if (!fChecked.FindObject(name))
337 fChecked.Add(new TObjString(name));
338 return TEnv::GetValue(name, dflt);
339}
340
341//---------------------------------------------------------------------------
342//
343// Get the value from the table and remember the value as checked
344//
345const char *MEnv::GetValue(const char *name, const char *dflt)
346{
347 if (!fChecked.FindObject(name))
348 fChecked.Add(new TObjString(name));
349 return TEnv::GetValue(name, dflt);
350}
351
352//---------------------------------------------------------------------------
353//
354// TEnv doen't have a streamer --> cannot be cloned
355// --> we have to clone it ourself
356//
357TObject *MEnv::Clone(const char *) const
358{
359 MEnv *env = new MEnv("/dev/null");
360 env->SetRcName(GetRcName());
361 env->AddEnv(*this);
362 return env;
363}
364
365//---------------------------------------------------------------------------
366//
367// Interprete fill style: Hollow, Solid, Hatch, 0%-100%
368// If no text style is detected the value is converted to an integer.
369//
370Int_t MEnv::GetFillStyle(const char *name, Int_t dftl)
371{
372 TString str = GetValue(name, "");
373 str = str.Strip(TString::kBoth);
374 if (str.IsNull())
375 return dftl;
376
377 str.ToLower();
378
379 switch (str.Hash())
380 {
381 case 2374867578U: return 0; // hollow
382 case 764279305U: return 1001; // solid
383 case 1854683492U: return 2001; // hatch
384 }
385
386 return str.EndsWith("%") ? 4000+str.Atoi() : str.Atoi();
387}
388
389//---------------------------------------------------------------------------
390//
391// Interprete line style: Solid, Dashed, Dotted, DashDotted
392// If no line style is detected the value is converted to an integer.
393//
394Int_t MEnv::GetLineStyle(const char *name, Int_t dftl)
395{
396 TString str = GetValue(name, "");
397 str = str.Strip(TString::kBoth);
398 if (str.IsNull())
399 return dftl;
400
401 str.ToLower();
402
403 switch (str.Hash())
404 {
405 case 764279305U: return kSolid;
406 case 241979881U: return kDashed;
407 case 2391642602U: return kDotted;
408 case 1124931659U: return kDashDotted;
409 }
410
411 return str.Atoi();
412}
413
414//---------------------------------------------------------------------------
415//
416// Interprete alignment: Top, Right, Left, Bottom, Center, tr, cc, bl, ...
417// If no text align is detected the value is converted to an integer.
418//
419// eg.
420// Top Right
421// Bottom Center
422// Center
423// tr
424// br
425// cr
426//
427Int_t MEnv::GetAlign(const char *name, Int_t dftl)
428{
429 TString str = GetValue(name, "");
430 str = str.Strip(TString::kBoth);
431 if (str.IsNull())
432 return dftl;
433
434 str.ToLower();
435
436 switch (str.Hash())
437 {
438 case 29746: return 33; // tr
439 case 25379: return 22; // cc
440 case 25132: return 11; // bl
441
442 case 25388: return 12; // cl
443 case 25394: return 32; // cr
444
445 case 29731: return 23; // tc
446 case 25123: return 32; // bc
447
448 case 29740: return 13; // tl
449 case 25138: return 13; // br
450 }
451
452 Int_t align = 0;
453 if (str.Contains("right", TString::kIgnoreCase))
454 align += 3;
455 if (str.Contains("left", TString::kIgnoreCase))
456 align += 1;
457 if (str.Contains("bottom", TString::kIgnoreCase))
458 align += 10;
459 if (str.Contains("top", TString::kIgnoreCase))
460 align += 30;
461
462 if (str.Contains("center", TString::kIgnoreCase))
463 {
464 if (align==0)
465 return 22;
466 if (align/10==0)
467 return align+20;
468 if (align%10==0)
469 return align+2;
470 }
471
472 return align>0 ? align : str.Atoi();
473}
474
475//---------------------------------------------------------------------------
476//
477// Interprete color: Black, White, Red, Green, Blue, Yellow, Magenta,
478// Cyan, Gray1-5, Grey1-5.
479// If no text color is detected the value is converted to an integer.
480//
481// eg.
482// Red
483// Light Red
484// Dark Red
485//
486Int_t MEnv::GetColor(const char *name, Int_t dftl)
487{
488 TString str = GetValue(name, "");
489
490 str = str.Strip(TString::kBoth);
491 if (str.IsNull())
492 return dftl;
493
494 str.ToLower();
495
496 Int_t offset=0;
497 if (str.Contains("dark"))
498 {
499 str.ReplaceAll("dark", "");
500 str = str.Strip(TString::kBoth);
501 offset = 100;
502 }
503 if (str.Contains("light"))
504 {
505 str.ReplaceAll("light", "");
506 str = str.Strip(TString::kBoth);
507 offset = 150;
508 }
509
510 switch (str.Hash())
511 {
512 case 2368543371U: return kWhite+offset;
513 case 1814927399U: return kBlack+offset;
514 case 7496964U: return kRed+offset;
515 case 2897107074U: return kGreen+offset;
516 case 1702194402U: return kBlue+offset;
517 case 2374817882U: return kYellow+offset;
518 case 2894218701U: return kMagenta+offset;
519 case 1851881955U: return kCyan+offset;
520 case 749623518U: return 19; // grey1
521 case 749623517U: return 18; // grey2
522 case 749623516U: return 17; // grey3
523 case 749623515U: return 16; // grey4
524 case 749623514U: return 15; // grey5
525 case 749623513U: return 14; // grey6
526 case 749623512U: return 13; // grey7
527 case 749623511U: return 12; // grey8
528 case 741234910U: return 19; // gray1
529 case 741234909U: return 18; // gray2
530 case 741234908U: return 17; // gray3
531 case 741234907U: return 16; // gray4
532 case 741234906U: return 15; // gray5
533 case 741234905U: return 14; // gray6
534 case 741234904U: return 13; // gray7
535 case 741234903U: return 12; // gray8
536 }
537 return str.Atoi();
538}
539
540//---------------------------------------------------------------------------
541//
542// As possible convert the color col into a text string which can be
543// interpreted by GetColor before setting the resource value
544//
545void MEnv::SetColor(const char *name, Int_t col)
546{
547 TString val;
548
549 if (col>99 && col<101+kCyan)
550 {
551 val = "Dark ";
552 col -= 100;
553 }
554 if (col>150 && col<151+kCyan)
555 {
556 val = "Light ";
557 col -= 150;
558 }
559
560 switch (col)
561 {
562 case kWhite: val += "White"; break;
563 case kBlack: val += "Black"; break;
564 case kRed: val += "Red"; break;
565 case kGreen: val += "Green"; break;
566 case kBlue: val += "Blue"; break;
567 case kYellow: val += "Yellow"; break;
568 case kMagenta: val += "Magenta"; break;
569 case kCyan: val += "Cyan"; break;
570 case 19: val += "Grey1"; break;
571 case 18: val += "Grey2"; break;
572 case 17: val += "Grey3"; break;
573 case 16: val += "Grey4"; break;
574 case 15: val += "Grey5"; break;
575 case 14: val += "Grey6"; break;
576 case 13: val += "Grey7"; break;
577 case 12: val += "Grey8"; break;
578 }
579
580 if (val.IsNull())
581 val += col;
582
583 SetValue(name, val);
584}
585
586//---------------------------------------------------------------------------
587//
588// As possible convert the alignment align into a text string which can be
589// interpreted by GetAlign before setting the resource value
590//
591void MEnv::SetAlign(const char *name, Int_t align)
592{
593 TString val;
594 if (align==22)
595 {
596 SetValue(name, "Center");
597 return;
598 }
599
600 switch (align%10)
601 {
602 case 1: val += "Left"; break;
603 case 2: val += "Center"; break;
604 case 3: val += "Right"; break;
605 }
606
607 switch (align/10)
608 {
609 case 1: val += "Bottom"; break;
610 case 2: val += "Center"; break;
611 case 3: val += "Top"; break;
612 }
613
614 SetValue(name, val);
615}
616
617//---------------------------------------------------------------------------
618//
619// As possible convert the fill style style into a text string which can be
620// interpreted by GetFillStyle before setting the resource value
621//
622void MEnv::SetFillStyle(const char *name, Int_t style)
623{
624 TString val;
625
626 if (style>3999 && style<4101)
627 val = MString::Format("%d%%", style-4000);
628
629 switch (style)
630 {
631 case 0: val = "Hollow"; break;
632 case 1001: val = "Solid"; break;
633 case 2001: val = "Hatch"; break;
634 }
635
636 if (val.IsNull())
637 val += style;
638
639 SetValue(name, val);
640}
641
642//---------------------------------------------------------------------------
643//
644// As possible convert the line style style into a text string which can be
645// interpreted by GetLineStyle before setting the resource value
646//
647void MEnv::SetLineStyle(const char *name, Int_t style)
648{
649 TString val;
650 switch (style)
651 {
652 case kSolid: val = "Solid"; break;
653 case kDashed: val = "Dashed"; break;
654 case kDotted: val = "Dotted"; break;
655 case kDashDotted: val = "DashDotted"; break;
656 }
657
658 if (val.IsNull())
659 val += style;
660
661 SetValue(name, val);
662}
663
664//---------------------------------------------------------------------------
665//
666// As possible convert the marker style style into a text string which can be
667// interpreted by GetLineStyle before setting the resource value
668//
669void MEnv::SetMarkerStyle(const char *name, Int_t style)
670{
671 TString val;
672 switch (style)
673 {
674 case kDot: val = "dot";
675 case kPlus: val = "plus";
676 case kCircle: val = "circle";
677 case kMultiply: val = "multiply";
678 case kFullDotSmall: val = "fulldotsmall";
679 case kFullDotMedium: val = "fulldotmedium";
680 case kFullDotLarge: val = "fulldotlarge";
681// case kOpenTriangleDown: val = "opentriangledown";
682// case kFullCross: val = "fullcross";
683 case kFullCircle: val = "fullcircle";
684 case kFullSquare: val = "fullsquare";
685 case kFullTriangleDown: val = "fulltriangledown";
686 case kOpenCircle: val = "opencircle";
687 case kOpenSquare: val = "opensquare";
688 case kOpenTriangleUp: val = "opentriangleup";
689 case kOpenDiamond: val = "opendiamond";
690 case kOpenCross: val = "opencross";
691 case kFullStar: val = "fullstar";
692 case kOpenStar: val = "openstar";
693 }
694
695 if (val.IsNull())
696 val += style;
697
698 SetValue(name, val);
699}
700
701//---------------------------------------------------------------------------
702//
703// Get the attributed from a TAttLine (if dftl is given use it as default)
704// name.LineColor <see also GetColor>
705// name.LineStyle
706// name.LineWidth
707// For more details on the meaning see TAttLine
708//
709void MEnv::GetAttLine(const char *name, TAttLine &line, TAttLine *dftl)
710{
711 const TString color = Compile(name, "LineColor");
712 const TString style = Compile(name, "LineStyle");
713 const TString width = Compile(name, "LineWidth");
714
715 if (!dftl)
716 dftl = &line;
717
718 const Color_t col = GetColor(color, dftl->GetLineColor());
719 const Style_t sty = GetLineStyle(style, dftl->GetLineStyle());
720 const Style_t wid = GetValue(width, dftl->GetLineWidth());
721
722 line.SetLineColor(col);
723 line.SetLineStyle(sty);
724 line.SetLineWidth(wid);
725}
726
727//---------------------------------------------------------------------------
728//
729// Get the attributed from a TAttText (if dftl is given use it as default)
730// name.TextColor <see also GetColor>
731// name.TextAlign <see also GetAlign>
732// name.TextAngle
733// name.TextFont
734// name.TextSize
735// For more details on the meaning see TAttText
736//
737void MEnv::GetAttText(const char *name, TAttText &text, TAttText *dftl)
738{
739 const TString color = Compile(name, "TextColor");
740 const TString align = Compile(name, "TextAlign");
741 const TString angle = Compile(name, "TextAngle");
742 const TString font = Compile(name, "TextFont");
743 const TString size = Compile(name, "TextSize");
744
745 if (!dftl)
746 dftl = &text;
747
748 const Color_t col = GetColor(color, dftl->GetTextColor());
749 const Short_t ali = GetAlign(align, dftl->GetTextAlign());
750 const Float_t ang = GetValue(angle, dftl->GetTextAngle());
751 const Font_t fon = GetValue(font, dftl->GetTextFont());
752 const Float_t siz = GetValue(size, dftl->GetTextSize());
753
754 text.SetTextColor(col);
755 text.SetTextAlign(ali);
756 text.SetTextAngle(ang);
757 text.SetTextFont(fon);
758 text.SetTextSize(siz);
759}
760
761//---------------------------------------------------------------------------
762//
763// Get the attributed from a TAttFill (if dftl is given use it as default)
764// name.FillColor <see also GetColor>
765// name.FillStyle <see also GetFillStyle>
766// For more details on the meaning see TAttFill
767//
768void MEnv::GetAttFill(const char *name, TAttFill &fill, TAttFill *dftl)
769{
770 const TString color = Compile(name, "FillColor");
771 const TString style = Compile(name, "FillStyle");
772
773 if (!dftl)
774 dftl = &fill;
775
776 const Color_t col = GetColor(color, dftl->GetFillColor());
777 const Style_t sty = GetFillStyle(style, dftl->GetFillStyle());
778
779 fill.SetFillColor(col);
780 fill.SetFillStyle(sty);
781}
782
783//---------------------------------------------------------------------------
784//
785// Get the attributed from a TAttMarker (if dftl is given use it as default)
786// name.MarkerColor <see also GetColor>
787// name.MarkerStyle
788// name.MarkerSize
789// For more details on the meaning see TAttMarker
790//
791void MEnv::GetAttMarker(const char *name, TAttMarker &marker, TAttMarker *dftl)
792{
793 const TString color = Compile(name, "MarkerColor");
794 const TString style = Compile(name, "MarkerStyle");
795 const TString size = Compile(name, "MarkerSize");
796
797 if (!dftl)
798 dftl = &marker;
799
800 const Color_t col = GetColor(color, dftl->GetMarkerColor());
801 const Style_t sty = GetValue(style, dftl->GetMarkerStyle());
802 const Size_t siz = GetValue(size, dftl->GetMarkerSize());
803
804 marker.SetMarkerColor(col);
805 marker.SetMarkerStyle(sty);
806 marker.SetMarkerSize(siz);
807}
808
809//---------------------------------------------------------------------------
810//
811// Get the attributed from a TPave (if dftl is given use it as default)
812// name.CornerRadius
813// name.BorderSize
814// name.Option
815// Also all resources from TAttLine and TAttFill are supported.
816//
817// For your conveinience: If the CornerRadius is greater than 0 "arc" is
818// added to the options. If it is equal or less than 0 "arc" is removed
819// from the options.
820//
821// For more details on the meaning see TPave
822//
823void MEnv::GetAttPave(const char *str, TPave &pave, TPave *dftl)
824{
825 const TString post(str);
826
827 TString name(pave.GetName());
828 if (!name.IsNull() && name!=pave.ClassName())
829 name = Compile(name, post);
830
831 GetAttLine(name, pave, dftl);
832 GetAttFill(name, pave, dftl);
833
834 const TString corner = Compile(name, "CornerRadius");
835 const TString border = Compile(name, "BorderSize");
836 const TString option = Compile(name, "Option");
837
838 if (!dftl)
839 dftl = &pave;
840
841 const Double_t cor = GetValue(corner, dftl->GetCornerRadius());
842 const Int_t bor = GetValue(border, dftl->GetBorderSize());
843
844 pave.SetCornerRadius(cor);
845 pave.SetBorderSize(bor);
846
847 TString opt = GetValue(option, dftl->GetOption());
848 opt.ToLower();
849
850 const Bool_t has = pave.GetCornerRadius()>0;
851
852 if (has && !opt.Contains("arc"))
853 opt += "arc";
854
855 if (!has && opt.Contains("arc"))
856 opt.ReplaceAll("arc", "");
857
858 pave.SetOption(opt);
859
860}
861
862//---------------------------------------------------------------------------
863//
864// Get the attributed for the TObject obj. Use dftl for default attributes
865// if given.
866//
867// There is support for:
868// TPave <see GetAttPave>
869// TAttLine <see GetAttLine>
870// TAttText <see GetAttText>
871// TAttFill <see GetAttFill>
872// TAttMarker <see GetAttMarker>
873//
874void MEnv::GetAttributes(const char *name, TObject *obj, TObject *dftl)
875{
876 //TAttAxis *line = dynamic_cast<TAttAxis*>(obj);
877 //TAtt3D *line = dynamic_cast<TAtt3D*>(obj);
878 //TAttCanvas *line = dynamic_cast<TAttCanvas*>(obj);
879 //TAttFillCanvas *line = dynamic_cast<TAttFillEitor*>(obj);
880 //TAttLineCanvas *line = dynamic_cast<TAttLineCanvas*>(obj);
881 //TAttLineEditor *line = dynamic_cast<TAttLineEditor*>(obj);
882 //TAttMarkerCanvas *line = dynamic_cast<TAttMarkerCanvas*>(obj);
883 //TAttMarkerEditor *line = dynamic_cast<TAttMarkerEditor*>(obj);
884 //TAttPad *line = dynamic_cast<TAttPad*>(obj);
885 //TAttParticle *line = dynamic_cast<TAttParticle*>(obj);
886 //TAttTextCanvas *line = dynamic_cast<TAttTextCanvas*>(obj);
887 //TAttTextEditor *line = dynamic_cast<TAttTextEditor*>(obj);
888
889 TPave *pave = dynamic_cast<TPave*>(obj);
890 TAttLine *line = dynamic_cast<TAttLine*>(obj);
891 TAttText *text = dynamic_cast<TAttText*>(obj);
892 TAttFill *fill = dynamic_cast<TAttFill*>(obj);
893 TAttMarker *mark = dynamic_cast<TAttMarker*>(obj);
894
895 if (pave)
896 {
897 GetAttPave(name, *pave, dynamic_cast<TPave*>(dftl));
898 return;
899 }
900
901 if (line)
902 GetAttLine(name, *line, dynamic_cast<TAttLine*>(dftl));
903 if (text)
904 GetAttText(name, *text, dynamic_cast<TAttText*>(dftl));
905 if (fill)
906 GetAttFill(name, *fill, dynamic_cast<TAttFill*>(dftl));
907 if (mark)
908 GetAttMarker(name, *mark, dynamic_cast<TAttMarker*>(dftl));
909}
910
911//---------------------------------------------------------------------------
912//
913// Set the resources from a TAttLine:
914// name.LineColor <see also SetColor>
915// name.LineStyle
916// name.LineWidth
917//
918void MEnv::SetAttLine(const char *name, const TAttLine &line)
919{
920 const TString color = Compile(name, "LineColor");
921 const TString style = Compile(name, "LineStyle");
922 const TString width = Compile(name, "LineWidth");
923
924 SetColor(color, line.GetLineColor());
925 SetLineStyle(style, line.GetLineStyle());
926 SetValue(width, line.GetLineWidth());
927}
928
929//---------------------------------------------------------------------------
930//
931// Set the resources from a TAttText:
932// name.TextColor <see also SetColor>
933// name.TextAlign <see also SetAlign>
934// name.TextAngle
935// name.TextFont
936// name.TextSize
937//
938void MEnv::SetAttText(const char *name, const TAttText &text)
939{
940 const TString color = Compile(name, "TextColor");
941 const TString align = Compile(name, "TextAlign");
942 const TString angle = Compile(name, "TextAngle");
943 const TString font = Compile(name, "TextFont");
944 const TString size = Compile(name, "TextSize");
945
946 SetColor(color, text.GetTextColor());
947 SetAlign(align, text.GetTextAlign());
948 SetValue(angle, text.GetTextAngle());
949 SetValue(font, text.GetTextFont());
950 SetValue(size, text.GetTextSize());
951}
952
953//---------------------------------------------------------------------------
954//
955// Set the resources from a TAttFill:
956// name.FillColor <see also SetColor>
957// name.FillStyle <see also SetFillStyle>
958//
959void MEnv::SetAttFill(const char *name, const TAttFill &fill)
960{
961 const TString color = Compile(name, "FillColor");
962 const TString style = Compile(name, "FillStyle");
963
964 SetColor(color, fill.GetFillColor());
965 SetFillStyle(style, fill.GetFillStyle());
966}
967
968//---------------------------------------------------------------------------
969//
970// Set the resources from a TAttMarker:
971// name.MarkerColor <see also SetColor>
972// name.MarkerStyle
973// name.MarkerSize
974//
975void MEnv::SetAttMarker(const char *name, const TAttMarker &marker)
976{
977 const TString color = Compile(name, "MarkerColor");
978 const TString style = Compile(name, "MarkerStyle");
979 const TString size = Compile(name, "MarkerSize");
980
981 SetColor(color, marker.GetMarkerColor());
982 SetMarkerStyle(style, marker.GetMarkerStyle());
983 SetValue(size, marker.GetMarkerSize());
984}
985
986//---------------------------------------------------------------------------
987//
988// Set the resources from a TPave:
989// name.CornerRadius
990// name.BorderSize
991// name.Option
992// Also all resources from TAttLine and TAttFill are supported.
993//
994void MEnv::SetAttPave(const char *str, const TPave &pave)
995{
996 const TString name(str);
997
998 SetAttLine(name, pave);
999 SetAttFill(name, pave);
1000
1001 const TString corner = Compile(name, "CornerRadius");
1002 const TString border = Compile(name, "BorderSize");
1003 const TString option = Compile(name, "Option");
1004
1005 SetValue(corner, const_cast<TPave&>(pave).GetCornerRadius());
1006 SetValue(border, const_cast<TPave&>(pave).GetBorderSize());
1007 SetValue(option, pave.GetOption());
1008}
1009
1010//---------------------------------------------------------------------------
1011//
1012// Set the attributed for the TObject obj.
1013//
1014// There is support for:
1015// TPave <see SetAttPave>
1016// TAttLine <see SetAttLine>
1017// TAttText <see SetAttText>
1018// TAttFill <see SetAttFill>
1019// TAttMarker <see SetAttMarker>
1020//
1021void MEnv::SetAttributes(const char *name, const TObject *obj)
1022{
1023 const TPave *pave = dynamic_cast<const TPave*>(obj);
1024 const TAttLine *line = dynamic_cast<const TAttLine*>(obj);
1025 const TAttText *text = dynamic_cast<const TAttText*>(obj);
1026 const TAttFill *fill = dynamic_cast<const TAttFill*>(obj);
1027 const TAttMarker *mark = dynamic_cast<const TAttMarker*>(obj);
1028
1029 if (pave)
1030 {
1031 SetAttPave(name, *pave);
1032 return;
1033 }
1034
1035 if (line)
1036 SetAttLine(name, *line);
1037 if (text)
1038 SetAttText(name, *text);
1039 if (fill)
1040 SetAttFill(name, *fill);
1041 if (mark)
1042 SetAttMarker(name, *mark);
1043}
1044
1045//---------------------------------------------------------------------------
1046//
1047// Add all values from TEnv env the this MEnv. To not overwrite existing
1048// values set overwrite to kFALSE
1049//
1050void MEnv::AddEnv(const TEnv &env, Bool_t overwrite)
1051{
1052 if (!GetTable() || !env.GetTable())
1053 return;
1054
1055 TIter Next(env.GetTable());
1056
1057 TEnvRec *er;
1058 while ((er = (TEnvRec*)Next()))
1059 {
1060 if (overwrite || !Defined(er->GetName()))
1061 SetValue(er->GetName(), er->GetValue(), er->GetLevel(), er->GetType());
1062 }
1063}
1064
1065//---------------------------------------------------------------------------
1066//
1067// Check MArgs for all options "--rc=" and remove them. Options should be
1068// given like
1069//
1070// program --rc=Option1:Test1 --rc=Option2.SubOption:Test2
1071//
1072// If all resources could be interpeted corrctly kTRUE is returned. If
1073// there were problems kFALSE is returned.
1074//
1075Bool_t MEnv::TakeEnv(MArgs &arg, Bool_t print, Bool_t overwrite)
1076{
1077 if (!GetTable())
1078 {
1079 gLog << err << "ERROR - MEnv not yet initialized." << endl;
1080 return kFALSE;
1081 }
1082
1083 Bool_t ret = kTRUE;
1084 while (1)
1085 {
1086 const TString rc = arg.GetStringAndRemove("--rc=");
1087 if (rc.IsNull())
1088 break;
1089
1090 const Ssiz_t pos = rc.First(':');
1091 if (pos<0)
1092 {
1093 gLog << warn << "WARNING - Resource '" << rc << "' doesn't contain a colon... ignored." << endl;
1094 ret=kFALSE;
1095 continue;
1096 }
1097 if (pos==0)
1098 {
1099 gLog << warn << "WARNING - Resource '" << rc << "' doesn't contain a name... ignored." << endl;
1100 ret=kFALSE;
1101 continue;
1102 }
1103 if (pos==rc.Length()-1)
1104 {
1105 gLog << warn << "WARNING - Resource '" << rc << "' empty... ignored." << endl;
1106 ret=kFALSE;
1107 continue;
1108 }
1109
1110 const TString name = rc(0, pos);
1111 const TString val = rc(pos+1, rc.Length());
1112
1113 if (print)
1114 gLog << all << "Command line resource '" << name << "' with value '" << val << "'...";
1115
1116 const Bool_t exists = Defined(name);
1117 if (!exists)
1118 {
1119 SetValue(name, val, kEnvLocal);
1120 if (print)
1121 gLog << "set." << endl;
1122 continue;
1123 }
1124
1125 if (overwrite)
1126 {
1127 SetValue(name, "");
1128 SetValue(name, val, kEnvLocal);
1129 if (print)
1130 gLog << "changed." << endl;
1131 continue;
1132 }
1133
1134 if (print)
1135 gLog << "skipped/existing." << endl;
1136 }
1137 return ret;
1138}
1139
1140//---------------------------------------------------------------------------
1141//
1142// Add name and full path to output
1143//
1144void MEnv::PrintEnv(EEnvLevel level) const
1145{
1146 if (!TString(GetRcName()).IsNull())
1147 {
1148 cout << "# Path: " << GetRcName() << endl;
1149 cout << "# File: " << gSystem->BaseName(GetRcName()) << endl;
1150 }
1151 if (!fName.IsNull())
1152 cout << "# Name: " << fName << endl;
1153
1154 TEnv::PrintEnv(level);
1155}
1156
1157//---------------------------------------------------------------------------
1158//
1159// Print resources which have never been touched (for debugging)
1160//
1161void MEnv::PrintUntouched() const
1162{
1163 int i=0;
1164 gLog << inf << flush;
1165
1166 TString sep = "Untouched Resources in ";
1167 sep += GetRcName();
1168 gLog.Separator(sep);
1169 TIter Next(GetTable());
1170 TObject *o=0;
1171
1172 while ((o=Next()))
1173 if (!fChecked.FindObject(o->GetName()))
1174 {
1175 gLog << warn << " - Resource " << o->GetName() << " untouched" << endl;
1176 i++;
1177 }
1178 if (i==0)
1179 gLog << inf << "None." << endl;
1180 else
1181 gLog << inf << i << " resources have not been touched." << endl;
1182}
1183
1184//---------------------------------------------------------------------------
1185//
1186// Return number of resources which have not been touched.
1187//
1188Int_t MEnv::GetNumUntouched() const
1189{
1190 int i=0;
1191 TIter Next(GetTable());
1192 TObject *o=0;
1193 while ((o=Next()))
1194 if (!fChecked.FindObject(o->GetName()))
1195 i++;
1196 return i;
1197}
Note: See TracBrowser for help on using the repository browser.