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

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