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

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