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

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