source: trunk/MagicSoft/Mars/mmain/MStatusDisplay.cc@ 2089

Last change on this file since 2089 was 2087, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 46.6 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, 4/2003 <mailto:tbretz@astro-uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MStatusDisplay
28//
29// This status display can be used (and is used) to display results in
30// a tabbed window. The window can be written to and read from a root file
31// (see Read and Write) or printed as a postscript file (see SaveAsPS).
32//
33// To write gif files of C-Macros use SaveAsGif() or SaveAsC().
34// Direct printing to the default printer (via lpr) can be done by
35// PrintToLpr().
36//
37// It has also to half status lines which can be used to display the status
38// or something going on. Together with the status lines it has a progress
39// bar which can display the progress of a job or loop.
40// Access the progress bar by GetProgressBar()
41//
42// To add a new tab and get a pointer to the newly created TCanvas
43// use AddTab.
44//
45// If you have a MStatusDisplay and you are not sure whether it was
46// destroyed by the user meanwhile use:
47// gROOT->GetListOfSpecials()->FindObject(pointer);
48// Each MStatusDisplay is added to list list by its constructor and
49// removed from the list by the destructor.
50//
51// You can redirect an output to a MLog-logstream by calling SetLogStream().
52// To disable redirction call SetLogStream(NULL)
53//
54// Because updates to the tabs are only done/displayed if a tab is active
55// using the gui doesn't make things slower (<1%) if the first (legend
56// tab) is displayed. This gives you the possibility to look into
57// the current progress of a loop without loosing more time than the
58// single update of the tab.
59//
60/////////////////////////////////////////////////////////////////////////////
61#include "MStatusDisplay.h"
62
63#include <iostream.h>
64
65#include <TLine.h> // TLine
66#include <TText.h> // TText
67#include <TFile.h> // gFile
68#include <TFrame.h> // TFrame
69#include <TStyle.h> // gStyle
70#include <TCanvas.h> // TCanvas
71#include <TSystem.h> // gSystem
72#include <TDatime.h> // TDatime
73#include <TRandom.h> // TRandom
74#include <TObjArray.h> // TObjArray
75#include <TPostScript.h> // TPostScript
76
77#include <TGTab.h> // TGTab
78#include <TGLabel.h> // TGLabel
79#include <TG3DLine.h> // TGHorizontal3DLine
80#include <TGButton.h> // TGPictureButton
81#include <TGTextView.h> // TGTextView
82#include <TGStatusBar.h> // TGStatusBar
83#include <TGProgressBar.h> // TGHProgressBar
84
85#include <TRootEmbeddedCanvas.h> // TRootEmbeddedCanvas
86
87#include "MLog.h" // MLog
88#include "MLogManip.h" // inf, warn, err
89
90#include "MGList.h" // MGList
91#include "MGMenu.h" // MGMenu, TGMenu
92#include "MSearch.h" // MSearch
93#include "MParContainer.h" // MParContainer::GetDescriptor
94
95#undef DEBUG
96//#define DEBUG
97
98ClassImp(MStatusDisplay);
99
100// ------------ Workaround for a non working TGTextView::Search -------------
101class MGTextView : public TGTextView
102{
103public:
104 MGTextView(const TGWindow *parent, UInt_t w, UInt_t h, Int_t id = -1,
105 UInt_t sboptions = 0, ULong_t back = GetWhitePixel()) :
106 TGTextView(parent, w, h, id, sboptions, back) {}
107 MGTextView(const TGWindow *parent, UInt_t w, UInt_t h, TGText *text,
108 Int_t id = -1, UInt_t sboptions = 0, ULong_t back = GetWhitePixel()) :
109 TGTextView(parent, w, h, text, id, sboptions, back) {}
110 MGTextView(const TGWindow *parent, UInt_t w, UInt_t h, const char *string,
111 Int_t id = -1, UInt_t sboptions = 0, ULong_t back = GetWhitePixel()) :
112 TGTextView(parent, w, h, string, id, sboptions, back) {}
113
114 void Mark(Long_t xPos, Long_t yPos) { TGTextView::Mark(xPos, yPos); }
115 void UnMark() { TGTextView::UnMark(); }
116
117 Bool_t Search(const char *string, Bool_t direction, Bool_t caseSensitive)
118 {
119 // Taken from TGTextView::Search and modified.
120
121 TGLongPosition pos, pos2;
122 pos2.fX = pos2.fY = 0;
123 if (fIsMarked) {
124 if (!direction)
125 {
126 pos2.fX = fMarkedStart.fX;
127 pos2.fY = fMarkedStart.fY;
128 }
129 else
130 {
131 pos2.fX = fMarkedEnd.fX + 1;
132 pos2.fY = fMarkedEnd.fY;
133 }
134 }
135 if (!fText->Search(&pos, pos2, string, direction, caseSensitive))
136 return kFALSE;
137 UnMark();
138 fIsMarked = kTRUE;
139 fMarkedStart.fY = fMarkedEnd.fY = pos.fY;
140 fMarkedStart.fX = pos.fX;
141 fMarkedEnd.fX = fMarkedStart.fX + strlen(string);
142 pos.fY = ToObjYCoord(fVisible.fY);
143 if ((fMarkedStart.fY < pos.fY) ||
144 (ToScrYCoord(fMarkedStart.fY) >= (Int_t)fCanvas->GetHeight()))
145 pos.fY = fMarkedStart.fY;
146 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
147 if ((fMarkedStart.fX < pos.fX) ||
148 (ToScrXCoord(fMarkedStart.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()))
149 pos.fX = fMarkedStart.fX;
150
151 SetVsbPosition((ToScrYCoord(pos.fY) + fVisible.fY)/fScrollVal.fY);
152 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY) + fVisible.fX)/fScrollVal.fX);
153 DrawRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
154 UInt_t(ToScrYCoord(fMarkedEnd.fY+1) - ToScrYCoord(fMarkedEnd.fY)));
155
156 return kTRUE;
157 }
158};
159// --------------------------------------------------------------------------
160
161// --------------------------------------------------------------------------
162//
163// Add menu bar to the GUI
164//
165void MStatusDisplay::AddMenuBar()
166{
167 //
168 // File Menu
169 //
170 MGPopupMenu *filemenu = new MGPopupMenu(gClient->GetRoot());
171 // filemenu->AddEntry("S&ave [F2]", kFileSave);
172 // filemenu->AddEntry("Save &As... [Shift-F2]", kFileSaveAs);
173 filemenu->AddEntry("Save As status.&ps", kFileSaveAsPS);
174 filemenu->AddEntry("Save As status.&gif", kFileSaveAsGIF);
175 filemenu->AddEntry("Save As status.&C", kFileSaveAsC);
176 filemenu->AddEntry("Save As status.&root", kFileSaveAsRoot);
177 filemenu->AddSeparator();
178 filemenu->AddEntry("Print with &lpr", kFilePrint);
179 filemenu->AddEntry("Set printer &name", kFilePrinterName);
180 filemenu->AddSeparator();
181 filemenu->AddEntry("E&xit", kFileExit);
182 filemenu->Associate(this);
183
184 //
185 // Tab Menu
186 //
187 MGPopupMenu *tabmenu = new MGPopupMenu(gClient->GetRoot());
188 // tabmenu->AddEntry("S&ave [F2]", kFileSave);
189 // tabmenu->AddEntry("Save &As... [Shift-F2]", kFileSaveAs);
190 tabmenu->AddEntry("Save As tab-i.&ps", kTabSaveAsPS);
191 tabmenu->AddEntry("Save As tab-i.&gif", kTabSaveAsGIF);
192 tabmenu->AddEntry("Save As tab-i.&C", kTabSaveAsC);
193 tabmenu->AddEntry("Save As tab-i.&root", kTabSaveAsRoot);
194 tabmenu->AddSeparator();
195 tabmenu->AddEntry("Print with &lpr", kFilePrint);
196 tabmenu->AddSeparator();
197 tabmenu->AddEntry("Next [&+]", kTabNext);
198 tabmenu->AddEntry("Previous [&-]", kTabPrevious);
199 tabmenu->Associate(this);
200
201 //
202 // Loop Menu
203 //
204 MGPopupMenu *loopmenu = new MGPopupMenu(gClient->GetRoot());
205 loopmenu->AddEntry("&Stop", kLoopStop);
206 loopmenu->Associate(this);
207
208 //
209 // Loop Menu
210 //
211 MGPopupMenu *sizemenu = new MGPopupMenu(gClient->GetRoot());
212 sizemenu->AddEntry("Fit to 640x&480", kSize640);
213 sizemenu->AddEntry("Fit to 800x&600", kSize800);
214 sizemenu->AddEntry("Fit to 960x7&20", kSize960);
215 sizemenu->AddEntry("Fit to 1024x&768", kSize1024);
216 sizemenu->AddEntry("Fit to 1280x&1024", kSize1280);
217 sizemenu->Associate(this);
218
219 //
220 // Log Menu
221 //
222 MGPopupMenu *logmenu = new MGPopupMenu(gClient->GetRoot());
223 logmenu->AddEntry("&Copy Selected", kLogCopy);
224 logmenu->AddEntry("Cl&ear all", kLogClear);
225 logmenu->AddSeparator();
226 logmenu->AddEntry("Select &All", kLogSelect);
227 logmenu->AddSeparator();
228 logmenu->AddEntry("&Find...", kLogFind);
229 logmenu->AddSeparator();
230 logmenu->AddEntry("&Save", kLogSave);
231 logmenu->AddEntry("Save &append", kLogAppend);
232 logmenu->Associate(this);
233
234 //
235 // Menu Bar
236 //
237 TGLayoutHints *layitem = new TGLayoutHints(kLHintsNormal, 0, 4, 0, 0);
238 fList->Add(layitem);
239
240 MGMenuBar *menubar = new MGMenuBar(this, 1, 1, kHorizontalFrame);
241 menubar->AddPopup("&File", filemenu, layitem);
242 menubar->AddPopup("Lo&g", logmenu, layitem);
243 menubar->AddPopup("&Size", sizemenu, layitem);
244 menubar->AddPopup("&Tab", tabmenu, layitem);
245 menubar->AddPopup("&Loop", loopmenu, layitem);
246 menubar->BindKeys(this);
247 AddFrame(menubar);
248
249 //
250 // Line below menu bar
251 //
252 TGLayoutHints *laylinesep = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
253 fList->Add(laylinesep);
254
255 TGHorizontal3DLine *linesep = new TGHorizontal3DLine(this);
256 AddFrame(linesep, laylinesep);
257
258 //
259 // Add everything to autodel list
260 //
261 fList->Add(filemenu);
262 fList->Add(loopmenu);
263 fList->Add(sizemenu);
264 fList->Add(menubar);
265 fList->Add(tabmenu);
266 fList->Add(logmenu);
267 fList->Add(linesep);
268}
269
270// --------------------------------------------------------------------------
271//
272// Add the title tab
273//
274void MStatusDisplay::AddMarsTab()
275{
276 // Create Tab1
277 TGCompositeFrame *f = fTab->AddTab("-=MARS=-");
278
279 // Add MARS version
280 TGLabel *l = new TGLabel(f, Form("Official Release: V%s", MARSVER));
281 fList->Add(l);
282
283 TGLayoutHints *layb = new TGLayoutHints(kLHintsCenterX|kLHintsTop, 10, 10, 10, 10);
284 fList->Add(layb);
285 f->AddFrame(l, layb);
286
287 // Add root version
288 l = new TGLabel(f, Form("Using ROOT v%s", ROOTVER));
289 fList->Add(l);
290
291 TGLayoutHints *lay = new TGLayoutHints(kLHintsCenterX|kLHintsTop);
292 fList->Add(lay);
293 f->AddFrame(l, lay);
294
295 // Add Mars logo picture
296 const TGPicture *pic2 = fList->GetPicture("marslogo.xpm");
297 if (pic2)
298 {
299 TGPictureButton *mars = new TGPictureButton(f, pic2, kPicMars);
300 fList->Add(mars);
301 mars->Associate(this);
302
303 TGLayoutHints *lay2 = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 10, 10, 10, 10);
304 fList->Add(lay2);
305 f->AddFrame(mars, lay2);
306 }
307
308 // Add date and time
309 TDatime d;
310 l = new TGLabel(f, d.AsString());
311 fList->Add(l);
312 f->AddFrame(l, lay);
313
314 // Add copyright notice
315 l = new TGLabel(f, "(c) MAGIC Software Development, 2000-2003");
316 fList->Add(l);
317 f->AddFrame(l, layb);
318}
319
320// --------------------------------------------------------------------------
321//
322// Adds the logbook tab to the GUI if it was not added previously.
323//
324// The logbook is updated four times a second only if the tab is visible.
325//
326// You can redirect an output to a MLog-logstream by calling SetLogStream().
327// To disable redirction call SetLogStream(NULL)
328//
329// if enable==kFALSE the stdout is disabled/enabled. Otherwise stdout
330// is ignored.
331//
332void MStatusDisplay::SetLogStream(MLog *log, Bool_t enable)
333{
334 if (log && fLogBox==NULL)
335 {
336 fLogIdx = fTab->GetNumberOfTabs();
337
338 // Create Tab1
339 TGCompositeFrame *f = fTab->AddTab("-Logbook-");
340
341 // Create Text View
342 fLogBox = new MGTextView(f, 1, 1); // , -1, 0, TGFrame::GetDefaultFrameBackground());
343 if (fFont)
344 fLogBox->SetFont(fFont);
345 //fLogBox->Associate(this);
346
347 // Add List box to the tab
348 TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY,2,2,2,2);
349 f->AddFrame(fLogBox, lay);
350
351 // layout and map tab
352 Layout();
353 MapSubwindows();
354
355 // make it visible
356 gClient->ProcessEventsFor(fTab);
357 }
358
359 if (log)
360 {
361 fLog = log;
362
363 log->SetOutputGui(fLogBox, kTRUE);
364 log->EnableOutputDevice(MLog::eGui);
365 if (!enable)
366 log->DisableOutputDevice(MLog::eStdout);
367
368 fLogTimer.Start();
369 }
370 else
371 {
372 fLogTimer.Stop();
373
374 fLog->DisableOutputDevice(MLog::eGui);
375 fLog->SetOutputGui(NULL);
376 if (!enable)
377 fLog->EnableOutputDevice(MLog::eStdout);
378
379 fLog = &gLog;
380 }
381}
382
383// --------------------------------------------------------------------------
384//
385// Add the Tabs and the predifined Tabs to the GUI
386//
387void MStatusDisplay::AddTabs()
388{
389 fTab = new TGTab(this, 300, 300);
390
391 AddMarsTab();
392
393 // Add fTab to Frame
394 TGLayoutHints *laytabs = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY, 5, 5, 5);
395 AddFrame(fTab, laytabs);
396
397 fList->Add(fTab);
398 fList->Add(laytabs);
399}
400
401// --------------------------------------------------------------------------
402//
403// Add the progress bar to the GUI
404//
405void MStatusDisplay::AddProgressBar()
406{
407 TGLayoutHints *laybar=new TGLayoutHints(kLHintsExpandX, 5, 5, 5, 5);
408 fList->Add(laybar);
409
410 fBar=new TGHProgressBar(this);
411 fBar->ShowPosition();
412 AddFrame(fBar, laybar);
413 fList->Add(fBar);
414}
415
416// --------------------------------------------------------------------------
417//
418// Adds the status bar to the GUI
419//
420void MStatusDisplay::AddStatusBar()
421{
422 fStatusBar = new TGStatusBar(this, 1, 1);
423
424 //
425 // 1-a a
426 // 1: ------|----
427 //
428 // a/(1-a) = (1-a)/1
429 // a^2+a-1 = 0
430 // a = (-1+-sqrt(1+4))/2 = sqrt(5)/2-1/2 = 0.618
431 //
432 Int_t p[2] = {38, 62};
433
434 fStatusBar->SetParts(p, 2);
435
436 TGLayoutHints *layb = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 5, 4, 0, 3);
437 AddFrame(fStatusBar, layb);
438
439 fList->Add(fStatusBar);
440 fList->Add(layb);
441}
442
443// --------------------------------------------------------------------------
444//
445// Change the text in the status line 1
446//
447void MStatusDisplay::SetStatusLine1(const char *txt)
448{
449 fStatusBar->SetText(txt, 0);
450 gClient->ProcessEventsFor(fStatusBar);
451}
452
453// --------------------------------------------------------------------------
454//
455// Change the text in the status line 2
456//
457void MStatusDisplay::SetStatusLine2(const char *txt)
458{
459 fStatusBar->SetText(txt, 1);
460 gClient->ProcessEventsFor(fStatusBar);
461}
462
463// --------------------------------------------------------------------------
464//
465// Display information about the name of a container
466//
467void MStatusDisplay::SetStatusLine2(const MParContainer &cont)
468{
469 SetStatusLine2(Form("%s: %s", cont.GetDescriptor(), cont.GetTitle()));
470}
471
472// --------------------------------------------------------------------------
473//
474// Default constructor. Opens a window with a progress bar. Get a pointer
475// to the bar by calling GetBar. This pointer can be used for the
476// eventloop.
477//
478// Be carefull: killing or closing the window while the progress meter
479// is still in use may cause segmentation faults. Please kill the window
480// always by deleting the corresponding object.
481//
482// Update time default: 10s
483//
484MStatusDisplay::MStatusDisplay(Long_t t)
485: TGMainFrame(gClient->GetRoot(), 1, 1), fTimer(this, t, kTRUE), fStatus(kLoopNone), fLog(&gLog), fLogIdx(-1), fLogTimer(this, 250, kTRUE), fLogBox(NULL)
486{
487 gROOT->GetListOfSpecials()->Add(this);
488 gROOT->GetListOfCleanups()->Add(this);
489
490 fFont = gVirtualX->LoadQueryFont("7x13bold");
491
492 //
493 // Create a list handling GUI widgets
494 //
495 fList = new MGList;
496 fList->SetOwner();
497
498 //
499 // set the smallest and biggest size of the Main frame
500 // and move it to its appearance position
501 SetWMSizeHints(570, 480, 1280, 980, 1, 1);
502 Move(rand()%100+50, rand()%100+50);
503 //Resize(740, 600);
504 Resize(570, 480);
505
506 //
507 // Create the layout hint for the root embedded canavses
508 //
509 fLayCanvas = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY);
510 fList->Add(fLayCanvas);
511
512 //
513 // Add Widgets (from top to bottom)
514 //
515 AddMenuBar();
516 AddTabs();
517 AddProgressBar();
518 AddStatusBar();
519
520 //
521 // Now do an automatic layout of the widgets and display the window
522 //
523 Layout();
524 MapSubwindows();
525
526 SetWindowName("Status Display");
527 SetIconName("Status Display");
528
529 MapWindow();
530
531 gSystem->ProcessEvents();
532}
533
534// --------------------------------------------------------------------------
535//
536// Destruct the window with all its tiles. Also the Progress Bar object
537// is deleted.
538//
539MStatusDisplay::~MStatusDisplay()
540{
541 SetLogStream(NULL);
542
543 delete fList;
544
545 if (fFont)
546 gVirtualX->DeleteFont(fFont);
547
548 gROOT->GetListOfSpecials()->Remove(this);
549 gROOT->GetListOfCleanups()->Remove(this);
550}
551
552// --------------------------------------------------------------------------
553//
554// Takes a TGCompositeFrame as argument. Searches for the first
555// TRootEmbeddedCanvas which is contained by it and returns a pointer
556// to the corresponding TCanvas. If it isn't found NULL is returned.
557//
558TCanvas *MStatusDisplay::GetCanvas(TGCompositeFrame *cf) const
559{
560 TIter Next(cf->GetList());
561
562 TGFrameElement *f;
563 while ((f=(TGFrameElement*)Next()))
564 if (f->fFrame->InheritsFrom(TRootEmbeddedCanvas::Class()))
565 return ((TRootEmbeddedCanvas*)f->fFrame)->GetCanvas();
566
567 return NULL;
568}
569
570// --------------------------------------------------------------------------
571//
572// Returns GetCanvas of the i-th Tab.
573//
574TCanvas *MStatusDisplay::GetCanvas(int i) const
575{
576 if (i<0 || i>=fTab->GetNumberOfTabs())
577 {
578 *fLog << warn << "MStatusDisplay::GetCanvas: Out of range." << endl;
579 return NULL;
580 }
581
582 return GetCanvas(fTab->GetTabContainer(i));
583}
584
585// --------------------------------------------------------------------------
586//
587// Searches for a TRootEmbeddedCanvas in the TGCompositeFramme of the
588// Tab with the name 'name'. Returns the corresponding TCanvas or
589// NULL if something isn't found.
590//
591TCanvas *MStatusDisplay::GetCanvas(const TString &name) const
592{
593 TGFrameElement *f;
594 TIter Next(fTab->GetList());
595 while ((f=(TGFrameElement*)Next()))
596 {
597 TObject *frame = f->fFrame;
598 if (!frame->InheritsFrom(TGTabElement::Class()))
599 continue;
600
601 TGTabElement *tab = (TGTabElement*)frame;
602 if (tab->GetString()==name)
603 break;
604 }
605
606 // Search for the next TGCompositeFrame in the list
607 while ((f=(TGFrameElement*)Next()))
608 {
609 TObject *frame = f->fFrame;
610 if (frame->InheritsFrom(TGCompositeFrame::Class()))
611 return GetCanvas((TGCompositeFrame*)frame);
612 }
613
614 return NULL;
615}
616
617// --------------------------------------------------------------------------
618//
619// Calls TCanvas::cd(), for the canvas returned by GetCanvas.
620//
621Bool_t MStatusDisplay::CdCanvas(const TString &name)
622{
623 TCanvas *c = GetCanvas(name);
624 if (!c)
625 return kFALSE;
626
627 c->cd();
628 return kTRUE;
629}
630
631// --------------------------------------------------------------------------
632//
633// Adds a new tab with the name 'name'. Adds a TRootEmbeddedCanvas to the
634// tab and returns a reference to the corresponding TCanvas.
635//
636TCanvas &MStatusDisplay::AddTab(const char *name)
637{
638 // Add new tab
639 TGCompositeFrame *f = fTab->AddTab(name);
640
641 // create root embedded canvas and add it to the tab
642 TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas(name, f, f->GetWidth(), f->GetHeight(), 0);
643 f->AddFrame(ec, fLayCanvas);
644 fList->Add(ec);
645
646 // set background and border mode of the canvas
647 TCanvas &c = *ec->GetCanvas();
648
649 c.SetFillColor(16/*165*//*17*//*203*/);
650 c.SetBorderMode(0);
651
652 // If kNoContaxtMenu set set kNoCOntextMenu of the canvas
653 if (TestBit(kNoContextMenu))
654 c.SetBit(kNoContextMenu);
655
656 // layout and map new tab
657#if ROOT_VERSION_CODE < ROOT_VERSION(3,03,00)
658 MapSubwindows();
659 Layout();
660#else
661 Layout();
662 MapSubwindows();
663#endif
664
665 // display new tab in the main frame
666 gClient->ProcessEventsFor(fTab);
667
668 *fLog << inf << "Adding Tab '" << name << "' (" << f->GetWidth() << "x";
669 *fLog << f->GetHeight() << ", TCanvas=" << &c << ")" << endl;
670
671 // return pointer to new canvas
672 return c;
673}
674
675// --------------------------------------------------------------------------
676//
677// Update a canvas in a tab, takes the corresponding TGCompositeFrame
678// as an argument
679//
680void MStatusDisplay::UpdateTab(TGCompositeFrame *f)
681{
682 if (!f)
683 return;
684
685 TCanvas *c=GetCanvas(f);
686 if (!c)
687 return;
688
689 c->Modified();
690 c->Update();
691 c->Paint();
692}
693
694// --------------------------------------------------------------------------
695//
696// Saves the given canvas (pad) or all pads (num<0) as a temporary
697// postscript file and prints it using 'lpr'. If a printer name is set
698// via SetPrinter 'lpr -Pname' is used.
699//
700Int_t MStatusDisplay::PrintToLpr(Int_t num)
701{
702 TString name = "mars";
703
704 for (int i=0; i<6; i++)
705 name += (char)(gRandom->Uniform(25)+65);
706
707 name += ".ps";
708
709 const Int_t pages = SaveAsPS(num, name);
710
711 SetStatusLine1("Printing...");
712 SetStatusLine2("");
713
714 if (!pages)
715 {
716 *fLog << warn << "MStatusDisplay::PrintToLpr: Sorry, couldn't save file as temporary postscript!" << endl;
717 SetStatusLine2("Failed!");
718 return 0;
719 }
720
721 TString cmd="lpr ";
722 if (!fPrinter.IsNull())
723 {
724 cmd += "-P";
725 cmd += fPrinter;
726 cmd += " ";
727 }
728 cmd += name;
729
730 gSystem->Exec(cmd);
731 gSystem->Unlink(name);
732
733 SetStatusLine2(Form("Done (%dpages)", pages));
734
735 return pages;
736}
737
738/*
739 if (...)
740 fMenu->AddPopup("&CaOs", fCaOs, NULL);
741 else
742 fMenu->RemovePopup("CaOs");
743 fMenu->Resize(fMenu->GetDefaultSize());
744 MapSubwindows();
745 MapWindow();
746 */
747
748// --------------------------------------------------------------------------
749//
750// Process the kC_COMMAND, kCM_MENU messages
751//
752Bool_t MStatusDisplay::ProcessMessageCommandMenu(Long_t id)
753{
754 switch (id)
755 {
756 case kLoopStop:
757 case kFileExit:
758 if (id==kFileExit && !TestBit(kIsLocked))
759 delete this;
760 fStatus = (Status_t)id;
761 return kTRUE;
762/*
763 case kFileSave:
764 cout << "Save..." << endl;
765 return kTRUE;
766
767 case kFileSaveAs:
768 cout << "SaveAs..." << endl;
769 return kTRUE;
770*/
771 case kFileSaveAsPS:
772 SaveAsPS();
773 return kTRUE;
774
775 case kFileSaveAsGIF:
776 SaveAsGIF();
777 return kTRUE;
778
779 case kFileSaveAsC:
780 SaveAsC();
781 return kTRUE;
782
783 case kFileSaveAsRoot:
784 SaveAsRoot();
785 return kTRUE;
786
787 case kFilePrint:
788 PrintToLpr();
789 return kTRUE;
790
791 case kTabSaveAsPS:
792 SaveAsPS(fTab->GetCurrent());
793 return kTRUE;
794
795 case kTabSaveAsGIF:
796 SaveAsGIF(fTab->GetCurrent());
797 return kTRUE;
798
799 case kTabSaveAsC:
800 SaveAsC(fTab->GetCurrent());
801 return kTRUE;
802
803 case kTabSaveAsRoot:
804 SaveAsRoot(fTab->GetCurrent());
805 return kTRUE;
806
807 case kTabPrint:
808 PrintToLpr(fTab->GetCurrent());
809 return kTRUE;
810
811 case kTabNext:
812 fTab->SetTab(fTab->GetCurrent()+1);
813 return kTRUE;
814
815 case kTabPrevious:
816 fTab->SetTab(fTab->GetCurrent()-1);
817 return kTRUE;
818
819 case kSize640:
820 Resize(570, 480);
821 return kTRUE;
822 case kSize800:
823 Resize(740, 600);
824 return kTRUE;
825 case kSize960:
826 Resize(880, 700);
827 return kTRUE;
828 case kSize1024:
829 Resize(980, 768);
830 return kTRUE;
831 case kSize1280:
832 Resize(1280, 980);
833 return kTRUE;
834
835 case kLogClear:
836 fLogBox->Clear();
837 return kTRUE;
838 case kLogCopy:
839 fLogBox->Copy();
840 return kTRUE;
841 case kLogSelect:
842 fLogBox->SelectAll();
843 return kTRUE;
844 case kLogFind:
845 new MSearch(this);
846 return kTRUE;
847 case kLogSave:
848 SetStatusLine1("Saving log...");
849 SetStatusLine2("");
850 *fLog << inf << "Saving log... " << flush;
851 if (fLogBox->GetText()->Save("statusdisplay.log"))
852 {
853 *fLog << "done." << endl;
854 SetStatusLine2("done.");
855 }
856 else
857 {
858 *fLog << "failed!" << endl;
859 SetStatusLine2("Failed!");
860 }
861 return kTRUE;
862
863 case kLogAppend:
864 SetStatusLine1("Appending logg...");
865 SetStatusLine2("");
866 *fLog << inf << "Appending log... " << flush;
867 if (fLogBox->GetText()->Append("statusdisplay.log"))
868 {
869 *fLog << "done." << endl;
870 SetStatusLine2("done.");
871 }
872 else
873 {
874 *fLog << "failed!" << endl;
875 SetStatusLine2("Failed!");
876 }
877 return kTRUE;
878#ifdef DEBUG
879 default:
880 cout << "Command-Menu #" << id << endl;
881#endif
882 }
883 return kTRUE;
884
885}
886
887// --------------------------------------------------------------------------
888//
889// Process the kC_COMMAND messages
890//
891Bool_t MStatusDisplay::ProcessMessageCommand(Long_t submsg, Long_t mp1, Long_t mp2)
892{
893 switch (submsg)
894 {
895 case kCM_MENU:
896 return ProcessMessageCommandMenu(mp1); // mp2=userdata
897 case kCM_TAB:
898 for (int i=1; i<fTab->GetNumberOfTabs(); i++)
899 fTab->GetTabContainer(i)->UnmapWindow();
900 UpdateTab(fTab->GetTabContainer(mp1));
901 fTab->GetTabContainer(mp1)->MapWindow();
902 /*
903 if (mp1>0)
904 fMenu->AddPopup("&CaOs", fCaOs, NULL);
905 else
906 fMenu->RemovePopup("CaOs");
907 fMenu->Resize(fMenu->GetDefaultSize());
908 MapSubwindows();
909 MapWindow();
910 */
911 return kTRUE;
912#ifdef DEBUG
913 case kCM_MENUSELECT:
914 cout << "Command-Menuselect #" << mp1 << " (UserData=" << (void*)mp2 << ")" << endl;
915 return kTRUE;
916
917 case kCM_BUTTON:
918 cout << "Command-Button." << endl;
919 return kTRUE;
920
921 case kCM_CHECKBUTTON:
922 cout << "Command-CheckButton." << endl;
923 return kTRUE;
924
925 case kCM_RADIOBUTTON:
926 cout << "Command-RadioButton." << endl;
927 return kTRUE;
928
929 case kCM_LISTBOX:
930 cout << "Command-Listbox #" << mp1 << " (LineId #" << mp2 << ")" << endl;
931 return kTRUE;
932
933 case kCM_COMBOBOX:
934 cout << "Command-ComboBox." << endl;
935 return kTRUE;
936 default:
937 cout << "Command: " << "Submsg:" << submsg << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
938#endif
939 }
940 return kTRUE;
941}
942
943// --------------------------------------------------------------------------
944//
945// Process the kC_TEXTVIEW messages
946//
947Bool_t MStatusDisplay::ProcessMessageTextview(Long_t submsg, Long_t mp1, Long_t mp2)
948{
949 // kC_TEXTVIEW, kTXT_ISMARKED, widget id, [true|false] //
950 // kC_TEXTVIEW, kTXT_DATACHANGE, widget id, 0 //
951 // kC_TEXTVIEW, kTXT_CLICK2, widget id, position (y << 16) | x) //
952 // kC_TEXTVIEW, kTXT_CLICK3, widget id, position (y << 16) | x) //
953 // kC_TEXTVIEW, kTXT_F3, widget id, true //
954 // kC_TEXTVIEW, kTXT_OPEN, widget id, 0 //
955 // kC_TEXTVIEW, kTXT_CLOSE, widget id, 0 //
956 // kC_TEXTVIEW, kTXT_SAVE, widget id, 0 //
957#ifdef DEBUG
958 switch (submsg)
959 {
960 case kTXT_ISMARKED:
961 cout << "Textview-IsMarked #" << mp1 << " " << (mp2?"yes":"no") << endl;
962 return kTRUE;
963
964 case kTXT_DATACHANGE:
965 cout << "Textview-DataChange #" << mp1 << endl;
966 return kTRUE;
967
968 case kTXT_CLICK2:
969 cout << "Textview-Click2 #" << mp1 << " x=" << (mp2&0xffff) << " y= " << (mp2>>16) << endl;
970 return kTRUE;
971
972 case kTXT_CLICK3:
973 cout << "Textview-Click3 #" << mp1 << " x=" << (mp2&0xffff) << " y= " << (mp2>>16) << endl;
974 return kTRUE;
975
976 case kTXT_F3:
977 cout << "Textview-F3 #" << mp1 << endl;
978 return kTRUE;
979
980 case kTXT_OPEN:
981 cout << "Textview-Open #" << mp1 << endl;
982 return kTRUE;
983
984 case kTXT_CLOSE:
985 cout << "Textview-Close #" << mp1 << endl;
986 return kTRUE;
987
988 case kTXT_SAVE:
989 cout << "Textview-Save #" << mp1 << endl;
990 return kTRUE;
991
992 default:
993 cout << "Textview: " << "Submsg:" << submsg << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
994 }
995#endif
996 return kTRUE;
997}
998
999// --------------------------------------------------------------------------
1000//
1001// Process the kC_USER messages
1002//
1003Bool_t MStatusDisplay::ProcessMessageUser(Long_t submsg, Long_t mp1, Long_t mp2)
1004{
1005 // kS_START, case sensitive | backward<<1, char *txt
1006 switch (submsg)
1007 {
1008 case kS_START:
1009 fLogBox->Search((char*)mp2, !(mp1&2>>1), mp1&1);
1010 return kTRUE;
1011#ifdef DEBUG
1012 default:
1013 cout << "User: " << "Submsg:" << submsg << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
1014#endif
1015 }
1016 return kTRUE;
1017}
1018
1019// --------------------------------------------------------------------------
1020//
1021// Process the messages from the GUI
1022//
1023Bool_t MStatusDisplay::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
1024{
1025 // Can be found in WidgetMessageTypes.h
1026 cout << "Msg: " << GET_MSG(msg) << " Submsg:" << GET_SUBMSG(msg);
1027 cout << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
1028 switch (GET_MSG(msg))
1029 {
1030 case kC_COMMAND:
1031 return ProcessMessageCommand(GET_SUBMSG(msg), mp1, mp2);
1032
1033 case kC_TEXTVIEW:
1034 return ProcessMessageTextview(GET_SUBMSG(msg), mp1, mp2);
1035
1036 case kC_USER:
1037 return ProcessMessageUser(GET_SUBMSG(msg), mp1, mp2);
1038 }
1039#ifdef DEBUG
1040 cout << "Msg: " << GET_MSG(msg) << " Submsg:" << GET_SUBMSG(msg);
1041 cout << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
1042#endif
1043 return kTRUE;
1044}
1045
1046void MStatusDisplay::CloseWindow()
1047{
1048 // Got close message for this MainFrame. Calls parent CloseWindow()
1049 // (which destroys the window) and terminate the application.
1050 // The close message is generated by the window manager when its close
1051 // window menu item is selected.
1052
1053 // CloseWindow must be overwritten because otherwise CloseWindow
1054 // and the destructor are calling DestroyWindow which seems to be
1055 // in conflict with the TRootEmbeddedCanvas.
1056 delete this;
1057}
1058
1059// --------------------------------------------------------------------------
1060//
1061// Calls SetBit(kNoContextMenu) for all TCanvas objects found in the
1062// Tabs.
1063//
1064void MStatusDisplay::SetNoContextMenu(Bool_t flag)
1065{
1066 flag ? SetBit(kNoContextMenu) : ResetBit(kNoContextMenu);
1067 for (int i=1; i<fTab->GetNumberOfTabs(); i++)
1068 {
1069 TCanvas *c = GetCanvas(i);
1070 if (c)
1071 flag ? c->SetBit(kNoContextMenu) : c->ResetBit(kNoContextMenu);
1072 }
1073}
1074
1075// --------------------------------------------------------------------------
1076//
1077// Updates the canvas (if existing) in the currenly displayed Tab.
1078// The update intervall is controlled by StartUpdate and StopUpdate
1079//
1080Bool_t MStatusDisplay::HandleTimer(TTimer *timer)
1081{
1082 const Int_t c = fTab->GetCurrent();
1083
1084 // Skip Legend Tab
1085 if (c==0)
1086 return kTRUE;
1087
1088 // Update a canvas tab (if visible)
1089 if (timer==&fTimer && c!=fLogIdx)
1090 {
1091 UpdateTab(fTab->GetCurrentContainer());
1092 return kTRUE;
1093 }
1094
1095 // update the logbook tab (if visible)
1096 if (timer==&fLogTimer && c==fLogIdx)
1097 {
1098 fLog->UpdateGui();
1099
1100 /*
1101 if (!fLogBox->TestBit(kHasChanged))
1102 return kTRUE;
1103
1104 fLogBox->ResetBit(kHasChanged);
1105 */
1106 return kTRUE;
1107 }
1108
1109 return kTRUE;
1110}
1111
1112// --------------------------------------------------------------------------
1113//
1114// Draws a clone of a canvas into a new canvas. Taken from TCanvas.
1115//
1116void MStatusDisplay::DrawClonePad(TCanvas &newc, const TCanvas &oldc) const
1117{
1118 //copy pad attributes
1119 newc.Range(oldc.GetX1(),oldc.GetY1(),oldc.GetX2(),oldc.GetY2());
1120 newc.SetTickx(oldc.GetTickx());
1121 newc.SetTicky(oldc.GetTicky());
1122 newc.SetGridx(oldc.GetGridx());
1123 newc.SetGridy(oldc.GetGridy());
1124 newc.SetLogx(oldc.GetLogx());
1125 newc.SetLogy(oldc.GetLogy());
1126 newc.SetLogz(oldc.GetLogz());
1127 newc.SetBorderSize(oldc.GetBorderSize());
1128 newc.SetBorderMode(oldc.GetBorderMode());
1129 ((TAttLine&)oldc).Copy((TAttLine&)newc);
1130 ((TAttFill&)oldc).Copy((TAttFill&)newc);
1131 ((TAttPad&)oldc).Copy((TAttPad&)newc);
1132
1133 //copy primitives
1134 TObject *obj;
1135 TIter next(oldc.GetListOfPrimitives());
1136 while ((obj=next())) {
1137 gROOT->SetSelectedPad(&newc);
1138 newc.GetListOfPrimitives()->Add(obj->Clone(),obj->GetDrawOption());
1139 }
1140 newc.Modified();
1141 newc.Update();
1142}
1143
1144// --------------------------------------------------------------------------
1145//
1146// Reads the contents of a saved MStatusDisplay from a file.
1147//
1148Int_t MStatusDisplay::Read(const char *name)
1149{
1150 if (!gFile)
1151 {
1152 *fLog << warn << "MStatusDisplay::Read: No file found. Please create a TFile first." << endl;
1153 return 0;
1154 }
1155
1156 if (!gFile->IsOpen())
1157 {
1158 *fLog << warn << "MStatusDisplay::Read: File not open. Please open the TFile first." << endl;
1159 return 0;
1160 }
1161
1162 TObjArray list;
1163
1164 const Int_t n = list.Read(name);
1165 if (n==0)
1166 {
1167 *fLog << warn << "MStatusDisplay::Read: No objects read." << endl;
1168 return 0;
1169 }
1170
1171 TIter Next(&list);
1172 TCanvas *c;
1173 while ((c=(TCanvas*)Next()))
1174 DrawClonePad(AddTab(c->GetName()), *c);
1175
1176 *fLog << inf << "MStatusDisplay: Key " << name << " with " << n << " keys read from file." << endl;
1177
1178 return n;
1179}
1180
1181// --------------------------------------------------------------------------
1182//
1183// Writes the contents of a MStatusDisplay to a file.
1184//
1185Int_t MStatusDisplay::Write(Int_t num, const char *name, Int_t option, Int_t bufsize)
1186{
1187 if (!gFile)
1188 {
1189 *fLog << warn << "MStatusDisplay::Write: No file found. Please create a TFile first." << endl;
1190 return 0;
1191 }
1192
1193 if (!gFile->IsOpen())
1194 {
1195 *fLog << warn << "MStatusDisplay::Write: File not open. Please open the TFile first." << endl;
1196 return 0;
1197 }
1198
1199 if (!gFile->IsWritable())
1200 {
1201 *fLog << warn << "MStatusDisplay::Write: File not writable." << endl;
1202 return 0;
1203 }
1204
1205 if (num==0)
1206 {
1207 *fLog << warn << "MStatusDisplay::Write: Tab doesn't contain an embedded Canvas... skipped." << endl;
1208 return 0;
1209 }
1210
1211 if (num>=fTab->GetNumberOfTabs())
1212 {
1213 *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
1214 return 0;
1215 }
1216
1217 TObjArray list;
1218
1219 const Int_t from = num<0 ? 1 : num;
1220 const Int_t to = num<0 ? fTab->GetNumberOfTabs() : num+1;
1221
1222 TCanvas *c;
1223 for (int i=from; i<to; i++)
1224 if ((c = GetCanvas(i)))
1225 list.Add(c);
1226
1227 const Int_t n = list.Write(name, kSingleKey);
1228
1229 *fLog << inf << "MStatusDisplay: " << n << " keys written to file as key " << name << "." << endl;
1230
1231 return n;
1232}
1233
1234// --------------------------------------------------------------------------
1235//
1236// Use this to start the synchronous (GUI eventloop driven) tab update.
1237// Can also be used to change the update intervall. If millisec<0
1238// the intervall given in SetUpdateTime is used. If the intervall in
1239// SetUpdateTime is <0 nothing is done. (Call SetUpdateTime(-1) to
1240// disable the automatic update in a MEventloop.
1241//
1242void MStatusDisplay::StartUpdate(Int_t millisec)
1243{
1244 if (fTimer.GetTime()<TTime(0))
1245 return;
1246 fTimer.Start(millisec);
1247}
1248
1249// --------------------------------------------------------------------------
1250//
1251// Stops the automatic GUI update
1252//
1253void MStatusDisplay::StopUpdate()
1254{
1255 fTimer.Stop();
1256}
1257
1258// --------------------------------------------------------------------------
1259//
1260// Set the update interval for the GUI update, see StartUpdate.
1261//
1262void MStatusDisplay::SetUpdateTime(Long_t t)
1263{
1264 fTimer.SetTime(t);
1265}
1266
1267// --------------------------------------------------------------------------
1268//
1269// Set the background color in a canvas
1270//
1271void MStatusDisplay::CanvasSetFillColor(TPad &p, Int_t col) const
1272{
1273 TObject *obj;
1274
1275 // See also TPad::UseCurrentStyle
1276 TIter Next(p.GetListOfPrimitives());
1277 while ((obj=Next()))
1278 {
1279 if (obj->InheritsFrom(TPad::Class()))
1280 CanvasSetFillColor(*(TPad*)obj, col);
1281 if (obj->InheritsFrom(TFrame::Class()))
1282 ((TFrame*)obj)->SetFillColor(col);
1283 }
1284
1285 p.SetFillColor(col);
1286}
1287
1288void MStatusDisplay::AddExtension(TString &name, const TString &ext, Int_t num) const
1289{
1290 if (name.IsNull())
1291 {
1292 name = "status";
1293 if (num>0)
1294 {
1295 name += "-";
1296 name += num;
1297 }
1298 }
1299
1300 if (name.EndsWith("."+ext))
1301 return;
1302
1303 name += ".";
1304 name += ext;
1305}
1306
1307Bool_t MStatusDisplay::CheckTabForCanvas(int num) const
1308{
1309 if (num>=fTab->GetNumberOfTabs())
1310 {
1311 *fLog << warn << "Tab #" << num << " doesn't exist..." << endl;
1312 return kFALSE;
1313 }
1314 if (num==0)
1315 {
1316 *fLog << warn << "Tab #" << num << " doesn't contain an embedded canvas..." << endl;
1317 return kFALSE;
1318 }
1319 if (fTab->GetNumberOfTabs()<2 || !gPad)
1320 {
1321 *fLog << warn << "Sorry, you must have at least one existing canvas (gPad!=NULL)" << endl;
1322 return kFALSE;
1323 }
1324 return kTRUE;
1325}
1326
1327// --------------------------------------------------------------------------
1328//
1329// In case of num<0 all tabs are written into the PS file. If num>0
1330// the canvas in the corresponding tab is written to the file.
1331// Name is the name of the file (with or without extension).
1332//
1333// Returns the number of pages written.
1334//
1335// To write all tabs you can also use SaveAsPS(name)
1336//
1337Int_t MStatusDisplay::SaveAsPS(Int_t num, TString name)
1338{
1339 SetStatusLine1("Writing Postscript file...");
1340 SetStatusLine2("");
1341
1342 if (!CheckTabForCanvas(num))
1343 {
1344 SetStatusLine2("Failed!");
1345 return 0;
1346 }
1347
1348 AddExtension(name, "ps", num);
1349
1350 if (num<0)
1351 *fLog << inf << "Open ps-File: " << name << endl;
1352
1353 TPad *padsav = (TPad*)gPad;
1354 TVirtualPS *psave = gVirtualPS;
1355
1356 TPostScript ps(name, 112);
1357 ps.SetBit(TPad::kPrintingPS);
1358 ps.PrintFast(13, "/nan {1} def ");
1359
1360 gVirtualPS = &ps;
1361
1362 //
1363 // Create a list to delete the canvas clones
1364 //
1365 TList l;
1366 l.SetOwner();
1367
1368 //
1369 // Create some GUI elements for a page legend
1370 //
1371 TLine line;
1372
1373 int page = 1;
1374
1375 //
1376 // Maintain tab numbers
1377 //
1378 const Int_t from = num<0 ? 1 : num;
1379 const Int_t to = num<0 ? fTab->GetNumberOfTabs() : num+1;
1380
1381 for (int i=from; i<to; i++)
1382 {
1383 TCanvas *c;
1384 if (!(c = GetCanvas(i)))
1385 {
1386 if (num<0)
1387 *fLog << inf << " - ";
1388 *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
1389 continue;
1390 }
1391
1392 SetStatusLine2(Form("Tab #%d", i));
1393
1394 //
1395 // Init page and page size, make sure, that the canvas in the file
1396 // has the same Aspect Ratio than on the screen.
1397 //
1398 ps.NewPage();
1399
1400 Float_t psw = 26; // A4 - width
1401 Float_t psh = 20; // A4 - height
1402
1403 const Float_t cw = c->GetWw();
1404 const Float_t ch = c->GetWh();
1405
1406 if (psw/psh>cw/ch)
1407 psw = cw/ch*psh;
1408 else
1409 psh = ch/cw*psw;
1410
1411 ps.Range(psw, psh); // A4
1412
1413 //
1414 // Clone canvas and change background color and schedule for
1415 // deletion
1416 //
1417 TCanvas *n = (TCanvas*)c->Clone();
1418 CanvasSetFillColor(*n, kWhite);
1419 l.Add(n);
1420
1421 //
1422 // Paint canvas into root file
1423 //
1424 if (num<0)
1425 *fLog << inf << " - ";
1426 *fLog << inf << "Writing Tab #" << i << ": " << c->GetName() << " (" << n << ") ";
1427 if (num>0)
1428 *fLog << "to " << name;
1429 *fLog << "..." << flush;
1430
1431 n->SetBatch(kTRUE);
1432 n->Paint();
1433
1434 //
1435 // Use the canvas as coordinate system for the overlaying text
1436 //
1437 gPad = n;
1438
1439 //
1440 // Print overlaying text (NDC = %)
1441 //
1442 ps.SetTextColor(kBlack);
1443 ps.SetTextSize(0.015);
1444 ps.SetTextFont(22);
1445 ps.SetTextAlign(11); // left top
1446 ps.TextNDC(0, 1.02, TString(" ")+n->GetName());
1447 ps.SetTextAlign(21); // cent top
1448 ps.TextNDC(0.5, 1.02, "MARS - Magic Analysis and Reconstruction Software");
1449 ps.SetTextAlign(31); // right top
1450 ps.TextNDC(1, 1.02, Form("Page No.%i (%i) ", page++, i));
1451 line.PaintLineNDC(0, 1.015, 1, 1.015);
1452
1453 //
1454 // Finish drawing page
1455 //
1456 n->SetBatch(kFALSE);
1457 if (num<0)
1458 *fLog << "done." << endl;
1459 }
1460
1461 gPad = NULL; // Important!
1462
1463 l.Delete();
1464
1465 ps.Close();
1466
1467 gVirtualPS = psave;
1468 padsav->cd();
1469
1470 *fLog << inf << "done." << endl;
1471
1472 SetStatusLine2(Form("Done (%dpages)", page-1));
1473
1474 return page-1;
1475}
1476
1477Bool_t MStatusDisplay::SaveAsGIF(Int_t num, TString name)
1478{
1479 SetStatusLine1("Writing GIF file...");
1480 SetStatusLine2("");
1481
1482 if (!CheckTabForCanvas(num))
1483 {
1484 SetStatusLine2("Failed!");
1485 return 0;
1486 }
1487
1488 AddExtension(name, "gif", num);
1489
1490 if (num<0)
1491 *fLog << inf << "Writing gif-Files..." << endl;
1492
1493 TPad *padsav = (TPad*)gPad;
1494
1495 int page = 1;
1496
1497 //
1498 // Maintain tab numbers
1499 //
1500 const Int_t from = num<0 ? 1 : num;
1501 const Int_t to = num<0 ? fTab->GetNumberOfTabs() : num+1;
1502
1503 for (int i=from; i<to; i++)
1504 {
1505 TCanvas *c;
1506 if (!(c = GetCanvas(i)))
1507 {
1508 if (num<0)
1509 *fLog << inf << " - ";
1510 *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
1511 continue;
1512 }
1513
1514 SetStatusLine2(Form("Tab #%d", i));
1515
1516 //
1517 // Clone canvas and change background color and schedule for
1518 // deletion
1519 //
1520 //TCanvas *n = (TCanvas*)c->Clone();
1521 //CanvasSetFillColor(*n, kWhite);
1522
1523 //
1524 // Paint canvas into root file
1525 //
1526 TString writename = name;
1527 if (num<0)
1528 {
1529 TString numname = "-";
1530 numname += i;
1531 writename.Insert(name.Last('.'), numname);
1532 }
1533 if (num<0)
1534 *fLog << inf << " - ";
1535 *fLog << inf << "Writing Tab #" << i << " to " << writename << ": " << c->GetName() << " (" << c << ") ";
1536 if (num>0)
1537 *fLog << "to " << name;
1538 *fLog << "..." << flush;
1539
1540 c->Draw();
1541 c->SaveAs(writename);
1542 /*
1543 n->Draw();
1544 n->SaveAs(writename);
1545 delete n;
1546 */
1547
1548 if (num<0)
1549 *fLog << "done." << endl;
1550 }
1551
1552 padsav->cd();
1553
1554 *fLog << inf << "done." << endl;
1555
1556 SetStatusLine2("Done.");
1557
1558 return page-1;
1559}
1560
1561Bool_t MStatusDisplay::SaveAsC(Int_t num, TString name)
1562{
1563 SetStatusLine1("Writing C++ file...");
1564 SetStatusLine2("");
1565
1566 if (!CheckTabForCanvas(num))
1567 {
1568 SetStatusLine2("Failed!");
1569 return 0;
1570 }
1571
1572 AddExtension(name, "C", num);
1573
1574 if (num<0)
1575 *fLog << inf << "Writing C-Files..." << endl;
1576
1577 TPad *padsav = (TPad*)gPad;
1578
1579 int page = 1;
1580
1581 //
1582 // Maintain tab numbers
1583 //
1584 const Int_t from = num<0 ? 1 : num;
1585 const Int_t to = num<0 ? fTab->GetNumberOfTabs() : num+1;
1586
1587 for (int i=from; i<to; i++)
1588 {
1589 TCanvas *c;
1590 if (!(c = GetCanvas(i)))
1591 {
1592 if (num<0)
1593 *fLog << inf << " - ";
1594 *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
1595 continue;
1596 }
1597
1598 SetStatusLine2(Form("Tab #%d", i));
1599
1600 //
1601 // Clone canvas and change background color and schedule for
1602 // deletion
1603 //
1604 TCanvas *n = (TCanvas*)c->Clone();
1605 CanvasSetFillColor(*n, kWhite);
1606
1607 //
1608 // Paint canvas into root file
1609 //
1610 TString writename = name;
1611 if (num<0)
1612 {
1613 TString numname = "-";
1614 numname += i;
1615 writename.Insert(name.Last('.'), numname);
1616 }
1617 if (num<0)
1618 *fLog << inf << " - ";
1619 *fLog << inf << "Writing Tab #" << i << " to " << writename << ": " << c->GetName() << " (" << n << ") ";
1620 if (num>0)
1621 *fLog << "to " << name;
1622 *fLog << "..." << flush;
1623
1624 n->SaveSource(writename, "");
1625 delete n;
1626
1627 if (num<0)
1628 *fLog << "done." << endl;
1629 }
1630
1631 padsav->cd();
1632
1633 *fLog << inf << "done." << endl;
1634
1635 SetStatusLine2("Done.");
1636
1637 return page-1;
1638}
1639
1640// --------------------------------------------------------------------------
1641//
1642// In case of num<0 all tabs are written into the PS file. If num>0
1643// the canvas in the corresponding tab is written to the file.
1644// Name is the name of the file (with or without extension).
1645//
1646// Returns the number of keys written.
1647//
1648// To write all tabs you can also use SaveAsPS(name)
1649//
1650Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name)
1651{
1652 SetStatusLine1("Writing root file...");
1653 SetStatusLine2("");
1654
1655 if (!CheckTabForCanvas(num))
1656 {
1657 SetStatusLine2("Failed!");
1658 return 0;
1659 }
1660
1661 AddExtension(name, "root", num);
1662
1663 TFile *fsave = gFile;
1664 TFile file(name, "RECREATE", "MARS - Status Window Contents", 9);
1665 const Int_t keys = Write(num);
1666 gFile = fsave;
1667
1668 SetStatusLine2("Done.");
1669
1670 return keys;
1671}
1672
1673Bool_t MStatusDisplay::HandleConfigureNotify(Event_t *evt)
1674{
1675 //cout << "----- Start -----" << endl;
1676
1677 UInt_t w = evt->fWidth;
1678 UInt_t h = evt->fHeight;
1679
1680 //cout << "Old: " << GetWidth() << " " << GetHeight() << " " << GetBorderWidth() << endl;
1681 //cout << "New: " << w << " " << h << endl;
1682
1683 Bool_t wchanged = w!=GetWidth();
1684 Bool_t hchanged = h!=GetHeight();
1685
1686 if (!wchanged && !hchanged)
1687 {
1688 Layout();
1689 return kTRUE;
1690 }
1691
1692 if (GetWidth()==1 && GetHeight()==1)
1693 return kTRUE;
1694
1695 // calculate the constant part of the window
1696 const UInt_t cw = GetWidth() -fTab->GetWidth();
1697 const UInt_t ch = GetHeight()-fTab->GetHeight();
1698
1699 // canculate new size of frame (canvas @ 1:sqrt(2))
1700 if (hchanged)
1701 w = (UInt_t)((h-ch)*sqrt(2)+.5)+cw;
1702 else
1703 h = (UInt_t)((w-cw)/sqrt(2)+.5)+ch;
1704
1705 //cout << "Res: " << w << " " << h << " " << evt->fX << " " << evt->fY << endl;
1706
1707 // resize frame
1708 Resize(w, h);
1709
1710 return kTRUE;
1711}
1712
1713Bool_t MStatusDisplay::HandleEvent(Event_t *event)
1714{
1715 /*
1716 if (event->fType!=9)
1717 {
1718 cout << "Event: " << event->fType << " ";
1719 cout << event->fX << " " << event->fY << endl;
1720 }
1721 */
1722 /*
1723 switch (event->fType) {
1724 case kConfigureNotify:
1725 //while (gVirtualX->CheckEvent(fId, kConfigureNotify, *event))
1726 // ;
1727 HandleConfigureNotify(event);
1728 return kTRUE;
1729 }
1730 */
1731 // if (event->fType==kConfigureNotify && event->fX!=0 && event->fY!=0)
1732 // return kTRUE;
1733
1734 return TGMainFrame::HandleEvent(event);
1735}
Note: See TracBrowser for help on using the repository browser.