Ignore:
Timestamp:
04/19/03 18:39:05 (22 years ago)
Author:
tbretz
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mmain/MStatusDisplay.cc

    r1957 r1965  
    2727// MStatusDisplay
    2828//
    29 //  upon an idea of Robert Wagner
     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// It has also to half status lines which can be used to display the status
     34// or something going on. Together with the status lines it has a progress
     35// bar which can display the progress of a job or loop.
     36// Access the progress bar by GetProgressBar()
     37//
     38// To add a new tab and get a pointer to the newly created TCanvas
     39// use AddTab.
     40//
     41// If you have a MStatusDisplay and you are not sure whether it was
     42// destroyed by the user meanwhile use:
     43//   gROOT->GetListOfSpecials()->FindObject(pointer);
     44// Each MStatusDisplay is added to list list by its constructor and
     45// removed from the list by the destructor.
     46//
     47// You can redirect an output to a MLog-logstream by calling SetLogStream().
     48// To disable redirction call SetLogStream(NULL)
     49//
     50// Because updates to the tabs are only done/displayed if a tab is active
     51// using the gui doesn't make things slower (<1%) if the first (legend
     52// tab) is displayed. This gives you the possibility to look into
     53// the current progress of a loop without loosing more time than the
     54// single update of the tab.
    3055//
    3156/////////////////////////////////////////////////////////////////////////////
     
    3459#include <iostream.h>
    3560
    36 #include <TCanvas.h>        // TCanvas
    37 #include <TSystem.h>        // gSystem
    38 
    39 #include <TGTab.h>          // TGTab
    40 #include <TGLabel.h>        // TGLabel
    41 #include <TGButton.h>       // TGPictureButton
    42 #include <TGProgressBar.h>  // TGHProgressBar
     61#include <TLine.h>                // TLine
     62#include <TText.h>                // TText
     63#include <TFile.h>                // gFile
     64#include <TFrame.h>               // TFrame
     65#include <TStyle.h>               // gStyle
     66#include <TCanvas.h>              // TCanvas
     67#include <TSystem.h>              // gSystem
     68#include <TDatime.h>              // TDatime
     69#include <TRandom.h>              // TRandom
     70#include <TObjArray.h>            // TObjArray
     71#include <TPostScript.h>          // TPostScript
     72
     73#include <TGTab.h>                // TGTab
     74#include <TGLabel.h>              // TGLabel
     75#include <TG3DLine.h>             // TGHorizontal3DLine
     76#include <TGButton.h>             // TGPictureButton
     77#include <TGListBox.h>            // TGListBox
     78#include <TGProgressBar.h>        // TGHProgressBar
    4379
    4480#include <TRootEmbeddedCanvas.h>  // TRootEmbeddedCanvas
    4581
    46 #include "MGList.h"
     82#include "MLog.h"                 // MLog
     83#include "MLogManip.h"            // inf, warn, err
     84
     85#include "MGList.h"               // MGList
     86#include "MGMenu.h"               // MGMenu, TGMenu
     87#include "MParContainer.h"        // MParContainer::GetDescriptor
    4788
    4889ClassImp(MStatusDisplay);
    4990
     91// --------------------------------------------------------------------------
     92//
     93// Add menu bar to the GUI
     94//
     95void MStatusDisplay::AddMenuBar()
     96{
     97    //
     98    // File Menu
     99    //
     100    MGPopupMenu *filemenu = new MGPopupMenu(gClient->GetRoot());
     101    // filemenu->AddEntry("S&ave [F2]", kFileSave);
     102    // filemenu->AddEntry("Save &As... [Shift-F2]", kFileSaveAs);
     103    filemenu->AddEntry("Save As status.&ps", kFileSaveAsPS);
     104    // filemenu->AddEntry("Save As status.&gif", kFileSaveAsGIF);
     105    // filemenu->AddEntry("Save As status.&C", kFileSaveAsC);
     106    filemenu->AddEntry("Save As status.&root", kFileSaveAsRoot);
     107    filemenu->AddSeparator();
     108    filemenu->AddEntry("Print with &lpr", kFilePrint);
     109    filemenu->AddEntry("Set printer &name", kFilePrinterName);
     110    filemenu->AddSeparator();
     111    filemenu->AddEntry("E&xit", kFileExit);
     112    filemenu->Associate(this);
     113
     114    //
     115    // Tab Menu
     116    //
     117    MGPopupMenu *tabmenu = new MGPopupMenu(gClient->GetRoot());
     118    // tabmenu->AddEntry("S&ave [F2]", kFileSave);
     119    // tabmenu->AddEntry("Save &As... [Shift-F2]", kFileSaveAs);
     120    tabmenu->AddEntry("Save As tab-i.&ps", kTabSaveAsPS);
     121    // tabmenu->AddEntry("Save As tab-i.&gif", kTabSaveAsGIF);
     122    // tabmenu->AddEntry("Save As tab-i.&C", kTabSaveAsC);
     123    tabmenu->AddEntry("Save As tab-i.&root", kTabSaveAsRoot);
     124    tabmenu->AddSeparator();
     125    tabmenu->AddEntry("Print with &lpr", kFilePrint);
     126    tabmenu->AddSeparator();
     127    tabmenu->AddEntry("Next [&+]",     kTabNext);
     128    tabmenu->AddEntry("Previous [&-]", kTabPrevious);
     129    tabmenu->Associate(this);
     130
     131    //
     132    // Loop Menu
     133    //
     134    MGPopupMenu *loopmenu = new MGPopupMenu(gClient->GetRoot());
     135    loopmenu->AddEntry("&Stop", kLoopStop);
     136    loopmenu->Associate(this);
     137
     138    //
     139    // Menu Bar
     140    //
     141    MGMenuBar *menubar = new MGMenuBar(this, 1, 1, kHorizontalFrame);
     142    menubar->AddPopup("&File", filemenu, NULL);
     143    menubar->AddPopup("&Tab",  tabmenu,  NULL);
     144    menubar->AddPopup("&Loop", loopmenu, NULL);
     145    menubar->BindKeys(this);
     146    AddFrame(menubar);
     147
     148    //
     149    // Line below menu bar
     150    //
     151    TGLayoutHints *laylinesep  = new TGLayoutHints(kLHintsTop|kLHintsExpandX);
     152    fList->Add(laylinesep);
     153
     154    TGHorizontal3DLine *linesep = new TGHorizontal3DLine(this);
     155    AddFrame(linesep, laylinesep);
     156
     157    //
     158    // Add everything to autodel list
     159    //
     160    fList->Add(filemenu);
     161    fList->Add(loopmenu);
     162    fList->Add(menubar);
     163    fList->Add(tabmenu);
     164    fList->Add(linesep);
     165}
     166
     167// --------------------------------------------------------------------------
     168//
     169// Add the title tab
     170//
     171void MStatusDisplay::AddMarsTab()
     172{
     173    // Create Tab1
     174    TGCompositeFrame *f = fTab->AddTab("-=MARS=-");
     175
     176    // Add MARS version
     177    TString txt = "Official Release: V";
     178    TGLabel *l = new TGLabel(f, txt+MARSVER);
     179    fList->Add(l);
     180
     181    TGLayoutHints *layb = new TGLayoutHints(kLHintsCenterX|kLHintsTop, 10, 10, 10, 10);
     182    fList->Add(layb);
     183    f->AddFrame(l, layb);
     184
     185    // Add root version
     186    txt = "Using ROOT v";
     187    l = new TGLabel(f, txt+ROOTVER);
     188    fList->Add(l);
     189
     190    TGLayoutHints *lay = new TGLayoutHints(kLHintsCenterX|kLHintsTop);
     191    fList->Add(lay);
     192    f->AddFrame(l, lay);
     193
     194    // Add Mars logo picture
     195    const TGPicture *pic2 = fList->GetPicture("marslogo.xpm");
     196    if (pic2)
     197    {
     198        TGPictureButton *mars  = new TGPictureButton(f, pic2, kPicMars);
     199        fList->Add(mars);
     200        mars->Associate(this);
     201
     202        TGLayoutHints *lay2 = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 10, 10, 10, 10);
     203        fList->Add(lay2);
     204        f->AddFrame(mars, lay2);
     205    }
     206
     207    // Add date and time
     208    TDatime d;
     209    l = new TGLabel(f, d.AsString());
     210    fList->Add(l);
     211    f->AddFrame(l, lay);
     212
     213    // Add copyright notice
     214    l = new TGLabel(f, "(c) MAGIC Software Development, 2000-2003");
     215    fList->Add(l);
     216    f->AddFrame(l, layb);
     217}
     218
     219// --------------------------------------------------------------------------
     220//
     221// Adds the logbook tab to the GUI if it was not added previously.
     222//
     223// The logbook is updated four times a second only if the tab is visible.
     224//
     225// You can redirect an output to a MLog-logstream by calling SetLogStream().
     226// To disable redirction call SetLogStream(NULL)
     227//
     228void MStatusDisplay::SetLogStream(MLog *log)
     229{
     230    if (log && fLogBox==NULL)
     231    {
     232        fLogIdx = fTab->GetNumberOfTabs();
     233
     234        // Create Tab1
     235        TGCompositeFrame *f = fTab->AddTab("-Logbook-");
     236
     237        // Create TGListBox for logging contents
     238        fLogBox = new TGListBox(f, 1, 1);
     239        fLogBox->ChangeBackground(TGFrame::GetBlackPixel());
     240
     241        // Add List box to the tab
     242        TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY);//, 5, 6, 5);
     243        f->AddFrame(fLogBox, lay);
     244
     245        // layout and map tab
     246        Layout();
     247        MapSubwindows();
     248
     249        // make it visible
     250        gClient->ProcessEventsFor(fTab);
     251    }
     252
     253    if (log)
     254    {
     255        fLog = log;
     256
     257        log->SetOutputGui(fLogBox, kTRUE);
     258        log->DisableOutputDevice(MLog::eStdout);
     259        log->EnableOutputDevice(MLog::eGui);
     260
     261        fLogTimer.Start();
     262    }
     263    else
     264    {
     265        fLogTimer.Stop();
     266
     267        fLog->DisableOutputDevice(MLog::eGui);
     268        fLog->EnableOutputDevice(MLog::eStdout);
     269        fLog->SetOutputGui(NULL);
     270
     271        fLog = &gLog;
     272    }
     273}
     274
     275// --------------------------------------------------------------------------
     276//
     277// Add the Tabs and the predifined Tabs to the GUI
     278//
     279void MStatusDisplay::AddTabs()
     280{
     281    fTab = new TGTab(this, 300, 300);
     282
     283    AddMarsTab();
     284
     285    // Add fTab to Frame
     286    TGLayoutHints *laytabs = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY, 5, 6, 5);
     287    AddFrame(fTab, laytabs);
     288
     289    fList->Add(fTab);
     290    fList->Add(laytabs);
     291}
     292
     293// --------------------------------------------------------------------------
     294//
     295// Add the progress bar to the GUI
     296//
    50297void MStatusDisplay::AddProgressBar()
    51298{
    52     TGLayoutHints *laybar=new TGLayoutHints(kLHintsExpandX, 10,10,10,10);
     299    TGLayoutHints *laybar=new TGLayoutHints(kLHintsExpandX, 5, 6, 5, 5);
    53300    fList->Add(laybar);
    54301
     
    59306}
    60307
    61 enum {
    62     kPicMagic,
    63     kPicMars
    64 };
    65 
    66 void MStatusDisplay::AddTabs()
    67 {
    68     fTab = new TGTab(this, 300, 300);
    69 
    70     //
    71     // Create Tab1
    72     //
    73     TGCompositeFrame *f = fTab->AddTab("-=MARS=-");
    74 
    75     /*
    76     TGHorizontalFrame *hf = new TGHorizontalFrame(f, 1, 1);
    77 
    78     TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY, 10., 10., 10., 10.);
    79     fList->Add(lay);
    80     f->AddFrame(hf, lay);
    81 
    82     const TGPicture *pic1 = fList->GetPicture("magiclogo.xpm");
    83     if (pic1)
    84     {
    85         TGPictureButton *magic = new TGPictureButton(hf, pic1, kPicMagic);
    86         fList->Add(magic);
    87         magic->Associate(this);
    88 
    89         TGLayoutHints *lay1 = new TGLayoutHints(kLHintsLeft|kLHintsTop,  10., 10., 20., 10.);
    90         fList->Add(lay1);
    91         hf->AddFrame(magic, lay1);
    92     }
    93     */
    94     const TGPicture *pic2 = fList->GetPicture("marslogo.xpm");
    95     if (pic2)
    96     {
    97         TGPictureButton *mars  = new TGPictureButton(f, pic2, kPicMars);
    98         fList->Add(mars);
    99         mars->Associate(this);
    100 
    101         TGLayoutHints *lay2 = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 10., 10., 10., 10.);
    102         fList->Add(lay2);
    103         f->AddFrame(mars, lay2);
    104     }
    105 
    106     //
    107     // Crete second gui elemet for tab1 (TGVertical Frame)
    108     //
    109     TGLayoutHints *laytabs = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY, 10, 10, 10, 10);
    110     AddFrame(fTab, laytabs);
    111 
    112     fList->Add(fTab);
    113     fList->Add(laytabs);
    114 }
    115 
    116 void MStatusDisplay::AddStatusLine1()
    117 {
    118     TGCompositeFrame *f = new TGCompositeFrame(this, 1, 1, kSunkenFrame);
     308
     309// --------------------------------------------------------------------------
     310//
     311// Adds the status lines to the GUI
     312//
     313void MStatusDisplay::AddStatusLines()
     314{
     315    TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 1);
     316
     317    TGCompositeFrame *f = new TGCompositeFrame(hf, 1, 1, kSunkenFrame);
    119318
    120319    fLine1 = new TGLabel(f, "");
    121320
    122     TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 5, 5, 2, 2);
     321    TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 0, 5);
    123322    f->AddFrame(fLine1, lay);
    124     AddFrame(f, lay);
     323    hf->AddFrame(f, lay);
    125324
    126325    fList->Add(f);
    127326    fList->Add(fLine1);
    128327    fList->Add(lay);
    129 }
    130 
    131 void MStatusDisplay::AddStatusLine2()
    132 {
    133     TGCompositeFrame *f = new TGCompositeFrame(this, 1, 1, kSunkenFrame);
     328
     329    f = new TGCompositeFrame(hf, 1, 1, kSunkenFrame);
    134330
    135331    fLine2 = new TGLabel(f, "");
    136 
    137     TGLayoutHints *lay = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 5, 5, 2, 2);
    138332    f->AddFrame(fLine2, lay);
    139     AddFrame(f, lay);
    140 
     333    hf->AddFrame(f, lay);
     334
     335    TGLayoutHints *layf = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 5, 0, 0, 3);
     336    AddFrame(hf, layf);
     337
     338    fList->Add(layf);
    141339    fList->Add(f);
    142340    fList->Add(fLine2);
    143     fList->Add(lay);
    144 }
    145 
     341    fList->Add(hf);
     342}
     343
     344// --------------------------------------------------------------------------
     345//
     346// Change the text in the status line 1
     347//
    146348void MStatusDisplay::SetStatusLine1(const char *txt)
    147349{
    148350    fLine1->SetText(txt);
    149 }
    150 
     351    gClient->ProcessEventsFor(fLine1);
     352}
     353
     354// --------------------------------------------------------------------------
     355//
     356// Change the text in the status line 2
     357//
    151358void MStatusDisplay::SetStatusLine2(const char *txt)
    152359{
    153360    fLine2->SetText(txt);
     361    gClient->ProcessEventsFor(fLine2);
     362}
     363
     364// --------------------------------------------------------------------------
     365//
     366// Display information about the name of a container
     367//
     368void MStatusDisplay::SetStatusLine2(const MParContainer &cont)
     369{
     370    TString txt = cont.GetDescriptor();
     371    txt += ": ";
     372    txt += cont.GetTitle();
     373
     374    cout << txt << endl;
     375
     376    SetStatusLine2(txt);
    154377}
    155378
     
    164387//   always by deleting the corresponding object.
    165388//
    166 MStatusDisplay::MStatusDisplay() : TGTransientFrame(gClient->GetRoot(), gClient->GetRoot(), 1, 1)
    167 {
     389// Update time default: 10s
     390//
     391MStatusDisplay::MStatusDisplay(Long_t t)
     392: TGMainFrame(gClient->GetRoot(), 1, 1), fTimer(this, t, kTRUE), fLog(&gLog), fLogIdx(-1), fLogTimer(this, 250, kTRUE), fLogBox(NULL)
     393{
     394    gROOT->GetListOfSpecials()->Add(this);
     395
     396    //
     397    // Create a list handling GUI widgets
     398    //
    168399    fList = new MGList;
    169400    fList->SetOwner();
    170401
    171     SetWMSizeHints(640, 480, 1280, 1024, 10, 10); // set the smallest and biggest size of the Main frame
     402    //
     403    // set the smallest and biggest size of the Main frame
     404    // and move it to its appearance position
     405    SetWMSizeHints(640, 548, 1280, 1024, 10, 10);
    172406    Move(rand()%100+50, rand()%100+50);
    173407
    174     fLayCanvas = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY, 3, 3, 3, 3);
     408    //
     409    // Create the layout hint for the root embedded canavses
     410    //
     411    fLayCanvas = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY);
    175412    fList->Add(fLayCanvas);
    176413
     414    //
     415    // Add Widgets (from top to bottom)
     416    //
     417    AddMenuBar();
    177418    AddTabs();
    178419    AddProgressBar();
    179     AddStatusLine1();
    180     AddStatusLine2();
    181 
     420    AddStatusLines();
     421
     422    //
     423    // Now do an automatic layout of the widgets and display the window
     424    //
     425    Layout();
    182426    MapSubwindows();
    183 
    184     Layout();
    185427
    186428    SetWindowName("Status Display");
     
    188430
    189431    MapWindow();
     432
     433    //lient->ProcessEventsFor(this);
     434    gSystem->ProcessEvents();
    190435}
    191436
     
    198443{
    199444    delete fList;
     445
     446    gROOT->GetListOfSpecials()->Remove(this);
    200447}
    201448
    202 TCanvas *MStatusDisplay::GetCanvas(TGCompositeFrame *cf)
     449// --------------------------------------------------------------------------
     450//
     451// Takes a TGCompositeFrame as argument. Searches for the first
     452// TRootEmbeddedCanvas which is contained by it and returns a pointer
     453// to the corresponding TCanvas. If it isn't found NULL is returned.
     454//
     455TCanvas *MStatusDisplay::GetCanvas(TGCompositeFrame *cf) const
    203456{
    204457    TIter Next(cf->GetList());
     
    212465}
    213466
    214 TCanvas *MStatusDisplay::GetCanvas(int i)
     467// --------------------------------------------------------------------------
     468//
     469// Returns GetCanvas of the i-th Tab.
     470//
     471TCanvas *MStatusDisplay::GetCanvas(int i) const
    215472{
    216473    if (i<0 || i>=fTab->GetNumberOfTabs())
    217474    {
    218         cout << "MStatusDisplay::GetCanvas: Out of range." << endl;
     475        *fLog << warn << "MStatusDisplay::GetCanvas: Out of range." << endl;
    219476        return NULL;
    220477    }
     
    223480}
    224481
    225 TCanvas *MStatusDisplay::GetCanvas(const TString &name)
     482// --------------------------------------------------------------------------
     483//
     484// Searches for a TRootEmbeddedCanvas in the TGCompositeFramme of the
     485// Tab with the name 'name'. Returns the corresponding TCanvas or
     486// NULL if something isn't found.
     487//
     488TCanvas *MStatusDisplay::GetCanvas(const TString &name) const
    226489{
    227490    TGFrameElement *f;
     
    249512}
    250513
     514// --------------------------------------------------------------------------
     515//
     516// Calls TCanvas::cd(), for the canvas returned by GetCanvas.
     517//
     518Bool_t MStatusDisplay::CdCanvas(const TString &name)
     519{
     520    TCanvas *c = GetCanvas(name);
     521    if (!c)
     522        return kFALSE;
     523
     524    c->cd();
     525    return kTRUE;
     526}
     527
     528// --------------------------------------------------------------------------
     529//
     530// Adds a new tab with the name 'name'. Adds a TRootEmbeddedCanvas to the
     531// tab and returns a reference to the corresponding TCanvas.
     532//
    251533TCanvas &MStatusDisplay::AddTab(const char *name)
    252534{
     535    // Add new tab
    253536    TGCompositeFrame *f = fTab->AddTab(name);
    254537
    255     TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas(name, f, 100, 100, 0);
     538    // create root embedded canvas and add it to the tab
     539    TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas(name, f, f->GetWidth(), f->GetHeight(), 0);
    256540    f->AddFrame(ec, fLayCanvas);
    257541    fList->Add(ec);
    258542
     543    // set background and border mode of the canvas
    259544    TCanvas &c = *ec->GetCanvas();
    260545
    261     c.SetFillColor(/*165*/17);
     546    c.SetFillColor(16/*165*//*17*//*203*/);
    262547    c.SetBorderMode(0);
    263548
     549    // If kNoContaxtMenu set set kNoCOntextMenu of the canvas
     550    if (TestBit(kNoContextMenu))
     551        c.SetBit(kNoContextMenu);
     552
     553    // layout and map new tab
     554    Layout();
    264555    MapSubwindows();
    265     Layout();
    266     // MapWindow();
    267 
    268     cout << "Adding Tab '" << name << "' (TCanvas=" << &c << ")" <<  ec << endl;
    269 
     556
     557    // display new tab in the main frame
     558    gClient->ProcessEventsFor(fTab);
     559
     560    *fLog << inf << "Adding Tab '" << name << "' (" << f->GetWidth() << "x";
     561    *fLog << f->GetHeight() << ", TCanvas=" << &c << ")" << endl;
     562
     563    // return pointer to new canvas
    270564    return c;
    271565}
    272566
     567// --------------------------------------------------------------------------
     568//
     569// Update a canvas in a tab, takes the corresponding TGCompositeFrame
     570// as an argument
     571//
     572void MStatusDisplay::UpdateTab(TGCompositeFrame *f)
     573{
     574    if (!f)
     575        return;
     576
     577    TCanvas *c=GetCanvas(f);
     578    if (!c)
     579        return;
     580
     581    c->Modified();
     582    c->Update();
     583    c->Paint();
     584}
     585
     586// --------------------------------------------------------------------------
     587//
     588// Saves the given canvas (pad) or all pads (num<0) as a temporary
     589// postscript file and prints it using 'lpr'. If a printer name is set
     590// via SetPrinter 'lpr -Pname' is used.
     591//
     592Int_t MStatusDisplay::PrintToLpr(Int_t num) const
     593{
     594    TString name = "mars";
     595
     596    for (int i=0; i<6; i++)
     597        name += (char)(gRandom->Uniform(25)+65);
     598
     599    name += ".ps";
     600
     601    const Int_t pages = SaveAsPS(num, name);
     602    if (!pages)
     603    {
     604        *fLog << warn << "MStatusDisplay::PrintToLpr: Sorry, couldn't save file as temporary postscript!" << endl;
     605        return 0;
     606    }
     607
     608    TString cmd="lpr ";
     609    if (!fPrinter.IsNull())
     610    {
     611        cmd += "-P";
     612        cmd += fPrinter;
     613        cmd += " ";
     614    }
     615    cmd += name;
     616
     617    gSystem->Exec(cmd);
     618    gSystem->Unlink(name);
     619
     620    return pages;
     621}
     622
     623// --------------------------------------------------------------------------
     624//
     625// Process the kC_COMMAND, kCM_MENU  messages
     626//
     627Bool_t MStatusDisplay::ProcessMessageCommandMenu(Long_t id)
     628{
     629    //cout << "Menu #" << id << endl;
     630    switch (id)
     631    {
     632    case kLoopStop:
     633    case kFileExit:
     634        if (id==kFileExit && !TestBit(kIsLocked))
     635            delete this;
     636        fStatus = (Status_t)id;
     637        return kTRUE;
     638/*
     639    case kFileSave:
     640        cout << "Save..." << endl;
     641        return kTRUE;
     642
     643    case kFileSaveAs:
     644        cout << "SaveAs..." << endl;
     645        return kTRUE;
     646*/
     647    case kFileSaveAsPS:
     648        //cout << "FileSaveAsPS..." << endl;
     649        SaveAsPS();
     650        return kTRUE;
     651/*
     652    case kFileSaveAsGIF:
     653        cout << "FileSaveAsGIF..." << endl;
     654        SaveAsGIF();
     655        return kTRUE;
     656
     657    case kFileSaveAsC:
     658        cout << "FileSaveAsC..." << endl;
     659        SaveAsC();
     660        return kTRUE;
     661*/
     662    case kFileSaveAsRoot:
     663        SaveAsRoot();
     664        return kTRUE;
     665
     666    case kFilePrint:
     667        PrintToLpr();
     668        return kTRUE;
     669
     670    case kTabSaveAsPS:
     671        SaveAsPS(fTab->GetCurrent());
     672        return kTRUE;
     673/*
     674    case kTabSaveAsGIF:
     675        cout << "TabSaveAsGIF... " << fTab->GetCurrent() <<  endl;
     676        SaveAsGIF(fTab->GetCurrent());
     677        return kTRUE;
     678
     679    case kTabSaveAsC:
     680        cout << "TabSaveAsC... " << fTab->GetCurrent() <<  endl;
     681        SaveAsC(fTab->GetCurrent());
     682        return kTRUE;
     683*/
     684    case kTabSaveAsRoot:
     685        SaveAsRoot(fTab->GetCurrent());
     686        return kTRUE;
     687
     688    case kTabPrint:
     689        PrintToLpr(fTab->GetCurrent());
     690        return kTRUE;
     691
     692    case kTabNext:
     693        fTab->SetTab(fTab->GetCurrent()+1);
     694        return kTRUE;
     695
     696    case kTabPrevious:
     697        fTab->SetTab(fTab->GetCurrent()-1);
     698        return kTRUE;
     699    }
     700    return kTRUE;
     701
     702    cout << "Command-Menu: Id=" << id << endl;
     703}
     704
     705// --------------------------------------------------------------------------
     706//
     707// Process the kC_COMMAND messages
     708//
     709Bool_t MStatusDisplay::ProcessMessageCommand(Long_t submsg, Long_t mp1, Long_t mp2)
     710{
     711    switch (submsg)
     712    {
     713    case kCM_MENU:
     714        return ProcessMessageCommandMenu(mp1);
     715
     716    case kCM_MENUSELECT:
     717        cout << "Menuselect #" << mp1 << endl;
     718        return kTRUE;
     719
     720    case kCM_TAB:
     721        for (int i=1; i<fTab->GetNumberOfTabs(); i++)
     722            fTab->GetTabContainer(i)->UnmapWindow();
     723        UpdateTab(fTab->GetTabContainer(mp1));
     724        fTab->GetTabContainer(mp1)->MapWindow();
     725        /*
     726        if (mp1>0)
     727            fMenu->AddPopup("&CaOs", fCaOs, NULL);
     728        else
     729            fMenu->RemovePopup("CaOs");
     730        fMenu->Resize(fMenu->GetDefaultSize());
     731        MapSubwindows();
     732        MapWindow();
     733        */
     734        return kTRUE;
     735
     736    case kCM_BUTTON:
     737        if (mp1==kPicMars)
     738            return kTRUE;
     739        return kTRUE;
     740    }
     741
     742    cout << "Command: " << "Submsg:" << submsg << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
     743    return kTRUE;
     744}
     745
     746// --------------------------------------------------------------------------
     747//
     748// Process the messages from the GUI
     749//
    273750Bool_t MStatusDisplay::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
    274751{
    275     cout << "Msg: " << GET_MSG(msg) << " Submsg:" << GET_SUBMSG(msg) << " Mp1=";
    276     cout << mp1 << " Mp2=" << mp2 << endl;
     752    switch (GET_MSG(msg))
     753    {
     754    case kC_COMMAND:
     755        return ProcessMessageCommand(GET_SUBMSG(msg), mp1, mp2);
     756    }
     757
     758    cout << "Msg: " << GET_MSG(msg) << " Submsg:" << GET_SUBMSG(msg);
     759    cout << " Mp1=" << mp1 << " Mp2=" << mp2 << endl;
    277760
    278761    return kTRUE;
     
    292775}
    293776
     777// --------------------------------------------------------------------------
     778//
     779// Calls SetBit(kNoContextMenu) for all TCanvas objects found in the
     780// Tabs.
     781//
     782void MStatusDisplay::SetNoContextMenu(Bool_t flag=kTRUE)
     783{
     784    flag ? SetBit(kNoContextMenu) : ResetBit(kNoContextMenu);
     785    for (int i=1; i<fTab->GetNumberOfTabs(); i++)
     786    {
     787        TCanvas *c = GetCanvas(i);
     788        if (c)
     789            flag ? c->SetBit(kNoContextMenu) : c->ResetBit(kNoContextMenu);
     790    }
     791}
     792
     793// --------------------------------------------------------------------------
     794//
     795// Updates the canvas (if existing) in the currenly displayed Tab.
     796// The update intervall is controlled by StartUpdate and StopUpdate
     797//
     798Bool_t MStatusDisplay::HandleTimer(TTimer *timer)
     799{
     800    const Int_t c = fTab->GetCurrent();
     801
     802    // Skip Legend Tab
     803    if (c==0)
     804        return kTRUE;
     805
     806    if (timer==&fTimer)
     807    {
     808        TGCompositeFrame *f=fTab->GetCurrentContainer();
     809        if (f!=fLogBox)
     810            return kTRUE;
     811
     812        UpdateTab(f);
     813        return kTRUE;
     814    }
     815    if (timer==&fLogTimer && c==fLogIdx)
     816    {
     817        fLog->UpdateGui();
     818
     819        if (!fLogBox->TestBit(kHasChanged))
     820            return kTRUE;
     821
     822        fLogBox->MapSubwindows();
     823        fLogBox->Layout();
     824        fLogBox->ResetBit(kHasChanged);
     825        return kTRUE;
     826    }
     827
     828    return kTRUE;
     829}
     830
     831// --------------------------------------------------------------------------
     832//
     833// Draws a clone of a canvas into a new canvas. Taken from TCanvas.
     834//
     835void MStatusDisplay::DrawClonePad(TCanvas &newc, const TCanvas &oldc) const
     836{
     837    //copy pad attributes
     838    newc.Range(oldc.GetX1(),oldc.GetY1(),oldc.GetX2(),oldc.GetY2());
     839    newc.SetTickx(oldc.GetTickx());
     840    newc.SetTicky(oldc.GetTicky());
     841    newc.SetGridx(oldc.GetGridx());
     842    newc.SetGridy(oldc.GetGridy());
     843    newc.SetLogx(oldc.GetLogx());
     844    newc.SetLogy(oldc.GetLogy());
     845    newc.SetLogz(oldc.GetLogz());
     846    newc.SetBorderSize(oldc.GetBorderSize());
     847    newc.SetBorderMode(oldc.GetBorderMode());
     848    ((TAttLine&)oldc).Copy((TAttLine&)newc);
     849    ((TAttFill&)oldc).Copy((TAttFill&)newc);
     850    ((TAttPad&)oldc).Copy((TAttPad&)newc);
     851
     852    //copy primitives
     853    TObject *obj;
     854    TIter next(oldc.GetListOfPrimitives());
     855    while ((obj=next())) {
     856        gROOT->SetSelectedPad(&newc);
     857        newc.GetListOfPrimitives()->Add(obj->Clone(),obj->GetDrawOption());
     858    }
     859    newc.Modified();
     860    newc.Update();
     861}
     862
     863// --------------------------------------------------------------------------
     864//
     865// Reads the contents of a saved MStatusDisplay from a file.
     866//
     867Int_t MStatusDisplay::Read(const char *name)
     868{
     869    if (!gFile)
     870    {
     871        *fLog << warn << "MStatusDisplay::Read: No file found. Please create a TFile first." << endl;
     872        return 0;
     873    }
     874
     875    if (!gFile->IsOpen())
     876    {
     877        *fLog << warn << "MStatusDisplay::Read: File not open. Please open the TFile first." << endl;
     878        return 0;
     879    }
     880
     881    TObjArray list;
     882
     883    const Int_t n = list.Read(name);
     884    if (n==0)
     885    {
     886        *fLog << warn << "MStatusDisplay::Read: No objects read." << endl;
     887        return 0;
     888    }
     889
     890    TIter Next(&list);
     891    TCanvas *c;
     892    while ((c=(TCanvas*)Next()))
     893        DrawClonePad(AddTab(c->GetName()), *c);
     894
     895    *fLog << inf << "MStatusDisplay: Key " << name << " with " << n << " keys read from file." << endl;
     896
     897    return n;
     898}
     899
     900// --------------------------------------------------------------------------
     901//
     902// Writes the contents of a MStatusDisplay to a file.
     903//
     904Int_t MStatusDisplay::Write(Int_t num, const char *name, Int_t option, Int_t bufsize)
     905{
     906    if (!gFile)
     907    {
     908        *fLog << warn << "MStatusDisplay::Write: No file found. Please create a TFile first." << endl;
     909        return 0;
     910    }
     911
     912    if (!gFile->IsOpen())
     913    {
     914        *fLog << warn << "MStatusDisplay::Write: File not open. Please open the TFile first." << endl;
     915        return 0;
     916    }
     917
     918    if (!gFile->IsWritable())
     919    {
     920        *fLog << warn << "MStatusDisplay::Write: File not writable." << endl;
     921        return 0;
     922    }
     923
     924    if (num==0)
     925    {
     926        *fLog << warn << "MStatusDisplay::Write: Tab doesn't contain an embedded Canvas... skipped." << endl;
     927        return 0;
     928    }
     929
     930    if (num>=fTab->GetNumberOfTabs())
     931    {
     932        *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
     933        return 0;
     934    }
     935
     936    TObjArray list;
     937
     938    const Int_t from = num<0 ? 1 : num;
     939    const Int_t to   = num<0 ? fTab->GetNumberOfTabs() : num+1;
     940
     941    TCanvas *c;
     942    for (int i=from; i<to; i++)
     943        if ((c = GetCanvas(i)))
     944            list.Add(c);
     945
     946    const Int_t n = list.Write(name, kSingleKey);
     947
     948    *fLog << inf << "MStatusDisplay: " << n << " keys written to file as key " << name << "." << endl;
     949
     950    return n;
     951}
     952
     953// --------------------------------------------------------------------------
     954//
     955// Use this to start the synchronous (GUI eventloop driven) tab update.
     956// Can also be used to change the update intervall. If millisec<0
     957// the intervall given in SetUpdateTime is used. If the intervall in
     958// SetUpdateTime is <0 nothing is done. (Call SetUpdateTime(-1) to
     959// disable the automatic update in a MEventloop.
     960//
     961void MStatusDisplay::StartUpdate(Int_t millisec=-1)
     962{
     963    if (fTimer.GetTime()<TTime(0))
     964        return;
     965    fTimer.Start(millisec);
     966}
     967
     968// --------------------------------------------------------------------------
     969//
     970// Stops the automatic GUI update
     971//
     972void MStatusDisplay::StopUpdate()
     973{
     974    fTimer.Stop();
     975}
     976
     977// --------------------------------------------------------------------------
     978//
     979// Set the update interval for the GUI update, see StartUpdate.
     980//
     981void MStatusDisplay::SetUpdateTime(Long_t t)
     982{
     983    fTimer.SetTime(t);
     984}
     985
     986// --------------------------------------------------------------------------
     987//
     988// Set the background color in a canvas
     989//
     990void MStatusDisplay::CanvasSetFillColor(TPad &p, Int_t col) const
     991{
     992    TObject *obj;
     993
     994    TIter Next(p.GetListOfPrimitives());
     995    while ((obj=Next()))
     996    {
     997        if (obj->InheritsFrom(TPad::Class()))
     998            CanvasSetFillColor(*(TPad*)obj, col);
     999        if (obj->InheritsFrom(TFrame::Class()))
     1000            ((TFrame*)obj)->SetFillColor(col);
     1001    }
     1002
     1003    p.SetFillColor(col);
     1004}
     1005
     1006void MStatusDisplay::AddExtension(TString &name, const TString &ext, Int_t num) const
     1007{
     1008    if (name.IsNull())
     1009    {
     1010        name = "status";
     1011        if (num>0)
     1012        {
     1013            name += "-";
     1014            name += num;
     1015        }
     1016    }
     1017
     1018    if (name.EndsWith("."+ext))
     1019        return;
     1020
     1021    name += ".";
     1022    name += ext;
     1023}
     1024
     1025// --------------------------------------------------------------------------
     1026//
     1027// In case of num<0 all tabs are written into the PS file. If num>0
     1028// the canvas in the corresponding tab is written to the file.
     1029// Name is the name of the file (with or without extension).
     1030//
     1031// Returns the number of pages written.
     1032//
     1033// To write all tabs you can also use SaveAsPS(name)
     1034//
     1035Int_t MStatusDisplay::SaveAsPS(Int_t num, TString name) const
     1036{
     1037    if (num>=fTab->GetNumberOfTabs())
     1038    {
     1039        *fLog << warn << "Tab #" << num << " doesn't exist..." << endl;
     1040        return 0;
     1041    }
     1042    if (num==0)
     1043    {
     1044        *fLog << warn << "Tab #" << num << " doesn't contain an embedded canvas..." << endl;
     1045        return 0;
     1046    }
     1047    if (fTab->GetNumberOfTabs()<2 || !gPad)
     1048    {
     1049        *fLog << warn << "Sorry, you must have at least one existing canvas (gPad!=NULL)" << endl;
     1050        return 0;
     1051    }
     1052
     1053    AddExtension(name, "ps", num);
     1054
     1055    if (num<0)
     1056        *fLog << inf << "Open ps-File: " << name << endl;
     1057
     1058    TPad       *padsav = (TPad*)gPad;
     1059    TVirtualPS *psave  = gVirtualPS;
     1060
     1061    TPostScript ps(name, 112);
     1062    ps.SetBit(TPad::kPrintingPS);
     1063    ps.PrintFast(13, "/nan {1} def ");
     1064
     1065    gVirtualPS = &ps;
     1066
     1067    //
     1068    // Create a list to delete the canvas clones
     1069    //
     1070    TList l;
     1071    l.SetOwner();
     1072
     1073    //
     1074    // Create some GUI elements for a page legend
     1075    //
     1076    TLine line;
     1077
     1078    int page = 1;
     1079
     1080    //
     1081    // Maintain tab numbers
     1082    //
     1083    const Int_t from = num<0 ? 1 : num;
     1084    const Int_t to   = num<0 ? fTab->GetNumberOfTabs() : num+1;
     1085
     1086    for (int i=from; i<to; i++)
     1087    {
     1088        TCanvas *c;
     1089        if (!(c = GetCanvas(i)))
     1090        {
     1091            if (num<0)
     1092                *fLog << inf << " - ";
     1093            *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
     1094            continue;
     1095        }
     1096
     1097        //
     1098        // Init page and page size, make sure, that the canvas in the file
     1099        // has the same Aspect Ratio than on the screen.
     1100        //
     1101        ps.NewPage();
     1102
     1103        Float_t psw = 26; // A4 - width
     1104        Float_t psh = 20; // A4 - height
     1105
     1106        const Float_t cw = c->GetWw();
     1107        const Float_t ch = c->GetWh();
     1108
     1109        if (psw/psh>cw/ch)
     1110            psw = cw/ch*psh;
     1111        else
     1112            psh = ch/cw*psw;
     1113
     1114        ps.Range(psw, psh); // A4
     1115
     1116        //
     1117        // Clone canvas and change background color and schedule for
     1118        // deletion
     1119        //
     1120        TCanvas *n = (TCanvas*)c->Clone();
     1121        CanvasSetFillColor(*n, kWhite);
     1122        l.Add(n);
     1123
     1124        //
     1125        // Paint canvas into root file
     1126        //
     1127        if (num<0)
     1128            *fLog << inf << " - ";
     1129        *fLog << "Writing Tab #" << i << ": " << c->GetName() << " (" << n << ") ";
     1130        if (num>0)
     1131            *fLog << "to " << name;
     1132        *fLog << "..." << flush;
     1133
     1134        n->SetBatch(kTRUE);
     1135        n->Paint();
     1136
     1137        //
     1138        // Use the canvas as coordinate system for the overlaying text
     1139        //
     1140        gPad = n;
     1141
     1142        //
     1143        // Print overlaying text (NDC = %)
     1144        //
     1145        ps.SetTextColor(kBlack);
     1146        ps.SetTextSize(0.015);
     1147        ps.SetTextFont(22);
     1148        ps.SetTextAlign(11); // left top
     1149        ps.TextNDC(0, 1.02, TString("  ")+n->GetName());
     1150        ps.SetTextAlign(21); // cent top
     1151        ps.TextNDC(0.5, 1.02, "MARS - Magic Analysis and Reconstruction Software");
     1152        ps.SetTextAlign(31); // right top
     1153        ps.TextNDC(1, 1.02, Form("Page No.%i (%i)  ", page++, i));
     1154        line.PaintLineNDC(0, 1.015, 1, 1.015);
     1155
     1156        //
     1157        // Finish drawing page
     1158        //
     1159        n->SetBatch(kFALSE);
     1160        if (num<0)
     1161            *fLog << "done." << endl;
     1162    }
     1163
     1164    gPad = NULL; // Important!
     1165
     1166    l.Delete();
     1167
     1168    ps.Close();
     1169
     1170    gVirtualPS = psave;
     1171    padsav->cd();
     1172
     1173    *fLog << inf << "done." << endl;
     1174
     1175    return page-1;
     1176}
     1177
     1178/*
     1179void MStatusDisplay::SaveAsGIF(Int_t num, TString name) const
     1180{
     1181    AddExtension(name, "gif", num);
     1182
     1183    cout << "Open gif-File: " << name << endl;
     1184    cout << " SORRY, not implemented." << endl;
     1185}
     1186
     1187void MStatusDisplay::SaveAsC(Int_t num, TString name) const
     1188{
     1189    AddExtension(name, "C", num);
     1190
     1191    cout << "Open C-File: " << name << endl;
     1192    cout << " SORRY, not implemented." << endl;
     1193}
     1194*/
     1195
     1196// --------------------------------------------------------------------------
     1197//
     1198// In case of num<0 all tabs are written into the PS file. If num>0
     1199// the canvas in the corresponding tab is written to the file.
     1200// Name is the name of the file (with or without extension).
     1201//
     1202// Returns the number of keys written.
     1203//
     1204// To write all tabs you can also use SaveAsPS(name)
     1205//
     1206Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name)
     1207{
     1208    if (num>=fTab->GetNumberOfTabs())
     1209    {
     1210        *fLog << warn << "Tab #" << num << " doesn't exist..." << endl;
     1211        return 0;
     1212    }
     1213    if (num==0)
     1214    {
     1215        *fLog << warn << "Tab #" << num << " doesn't contain an embedded canvas..." << endl;
     1216        return 0;
     1217    }
     1218    if (fTab->GetNumberOfTabs()<2 || !gPad)
     1219    {
     1220        *fLog << warn << "Sorry, you must have at least one existing canvas." << endl;
     1221        return 0;
     1222    }
     1223
     1224    AddExtension(name, "root", num);
     1225
     1226    TFile *fsave = gFile;
     1227    TFile file(name, "RECREATE", "MARS - Status Window Contents", 9);
     1228    const Int_t keys = Write(num);
     1229    gFile = fsave;
     1230
     1231    return keys;
     1232}
Note: See TracChangeset for help on using the changeset viewer.