Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 8961)
+++ trunk/MagicSoft/Mars/Changelog	(revision 8962)
@@ -49,4 +49,29 @@
    * mraw/Makefile, mraw/RawLinkDef.h:
      - removed MRawFileWrite
+
+   * mbase/MStatusDisplay.[h,cc]:
+     - added the tif file format
+     - added the csv file format
+     - fixed the bmp and xml menu entries
+     - added again to list of specials to allow for access from the
+       interpreter
+     - added title to AddTab. The title is stored as canvas title
+     - added some warpper to access FindobjectInCanvas and Print
+       from the MStatusDisplay to gain access from the interpreter
+     - Removed obsolete DrawClonePad wrapper in Display and
+       added title
+     - added FillArray to add all canvases to a temporary MStatusArray
+     - removed obsolete CanvasSetFillColor
+     - use mktemp in UpdatePSHeader
+     - some code cleanup. Moved some common code from the SaveAs function
+       to the new InitWrite* functions
+     - implemented %%tab%% and %%name%%
+     - added a workround (MyCanvas) to get the title and footer in the 
+       ps-files also in root 5.18
+     - removed cloning of the canvases whereever possible.Gave problems
+       in root 5.18 (not yet understood)
+     - changed color mode of postscrip files from rgb to cmyk
+     - UpdatePSHeader not long needed in root >=5.12
+     - reorganized header file
 
 
Index: trunk/MagicSoft/Mars/NEWS
===================================================================
--- trunk/MagicSoft/Mars/NEWS	(revision 8961)
+++ trunk/MagicSoft/Mars/NEWS	(revision 8962)
@@ -75,4 +75,8 @@
 
    * Tabs now can have a title which is displayed in the postscript file
+
+   * When multiple file are written at once (e.g. pngs from a display)
+     it is now possible to use the tab name and or tab number in the
+     file name. For details see showplos's help.
 
  ;merpp
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 8961)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 8962)
@@ -60,4 +60,6 @@
 /////////////////////////////////////////////////////////////////////////////
 #include "MStatusDisplay.h"
+
+#include <errno.h>
 
 #include <fstream>                // fstream
@@ -264,8 +266,8 @@
     savemenu->AddEntry(MString::Format("%s&jpg", fname.Data()),  kFileSaveAsJPG);
     savemenu->AddEntry(MString::Format("%s&xpm", fname.Data()),  kFileSaveAsXPM);
-    //savemenu->AddEntry("Save status.x&cf",  kFileSaveAsXCF);
-    //savemenu->AddEntry("Save status.&tiff", kFileSaveAsTIFF);
-    savemenu->AddEntry("Save status.&bmp",  kFileSaveAsBMP);
-    savemenu->AddEntry("Save status.&xml",  kFileSaveAsXML);
+    savemenu->AddEntry(MString::Format("%s&tiff",fname.Data()),  kFileSaveAsTIFF);
+    savemenu->AddEntry(MString::Format("%s&bmp", fname.Data()),  kFileSaveAsBMP);
+    savemenu->AddEntry(MString::Format("%sx&ml", fname.Data()),  kFileSaveAsXML);
+    savemenu->AddEntry(MString::Format("%scs&v", fname.Data()),  kFileSaveAsCSV);
     savemenu->AddSeparator();
     savemenu->AddEntry(MString::Format("%s&C",    fname.Data()), kFileSaveAsC);
@@ -303,8 +305,8 @@
     savemenu2->AddEntry(MString::Format("%s&jpg", fname2.Data()),  kTabSaveAsJPG);
     savemenu2->AddEntry(MString::Format("%s&xpm", fname2.Data()),  kTabSaveAsXPM);
-    //savemenu->AddEntry("Save status.x&cf",  kFileSaveAsXCF);
-    //savemenu->AddEntry("Save status.&tiff", kFileSaveAsTIFF);
-    savemenu->AddEntry("Save status.&bmp",  kFileSaveAsBMP);
-    savemenu->AddEntry("Save status.&xml",  kFileSaveAsXML);
+    savemenu2->AddEntry(MString::Format("%s&tiff",fname2.Data()),  kTabSaveAsTIFF);
+    savemenu2->AddEntry(MString::Format("%s&bmp", fname2.Data()),  kTabSaveAsBMP);
+    savemenu2->AddEntry(MString::Format("%sx&ml", fname2.Data()),  kTabSaveAsXML);
+    savemenu2->AddEntry(MString::Format("%scs&v", fname2.Data()),  kTabSaveAsCSV);
     savemenu2->AddSeparator();
     savemenu2->AddEntry(MString::Format("%s&C",    fname2.Data()), kTabSaveAsC);
@@ -700,5 +702,5 @@
     // from the list in the destructor.
     //
-//    gROOT->GetListOfSpecials()->Add(this);
+    gROOT->GetListOfSpecials()->Add(this);
 
     fFont = gVirtualX->LoadQueryFont("7x13bold");
@@ -1017,5 +1019,5 @@
 // tab and returns a reference to the corresponding TCanvas.
 //
-TCanvas &MStatusDisplay::AddTab(const char *name)
+TCanvas &MStatusDisplay::AddTab(const char *name, const char *title)
 {
     /*
@@ -1033,5 +1035,5 @@
         const UInt_t ch = 2*cw/3 + 25; // 25: Menu, etc
 
-        // The constructor of TCanvas adds the canvas to th eglobal list
+        // The constructor of TCanvas adds the canvas to the global list
         // of canvases gROOT->GetListOfCanvases(). If a canvas with an
         // identical name exists already in this list, the canvas is
@@ -1044,5 +1046,5 @@
         // part of the list of cleanups, thus fBatch need not to be added
         // to the list of cleanups.
-        TCanvas *c = new TCanvas("", name, -cw, ch);
+        TCanvas *c = new TCanvas("", title?title:"", -cw, ch);
         c->SetName(name);
         fBatch->Add(c);
@@ -1066,4 +1068,7 @@
     // set background and border mode of the canvas
     TCanvas &c = *ec->GetCanvas();
+
+    if (title)
+        c.SetTitle(title);
 
     c.SetFillColor(16/*165*//*17*//*203*/);
@@ -1212,5 +1217,4 @@
             return "";
     }
-
 
     if (c.Contains("%f") && ext)
@@ -1588,11 +1592,7 @@
         return kTRUE;
 
-    //case kFileSaveAsXCF:
-    //    SaveAsXCF();
-    //    return kTRUE;
-
-    //case kFileSaveAsTIFF:
-    //    SaveAsTIFF();
-    //    return kTRUE;
+    case kFileSaveAsTIFF:
+        SaveAsTIFF();
+        return kTRUE;
 
     case kFileSaveAsBMP:
@@ -1604,4 +1604,8 @@
         return kTRUE;
 
+    case kFileSaveAsCSV:
+        SaveAsCSV();
+        return kTRUE;
+
     case kFileSaveAsC:
         SaveAsC();
@@ -1648,11 +1652,7 @@
         return kTRUE;
 
-    //case kTabSaveAsXCF:
-    //    SaveAsXCF(fTab->GetCurrent());
-    //    return kTRUE;
-
-    //case kTabSaveAsTIFF:
-    //    SaveAsTIFF(fTab->GetCurrent());
-    //    return kTRUE;
+    case kTabSaveAsTIFF:
+        SaveAsTIFF(fTab->GetCurrent());
+        return kTRUE;
 
     case kTabSaveAsBMP:
@@ -1662,4 +1662,8 @@
     case kTabSaveAsXML:
         SaveAsXML(fTab->GetCurrent());
+        return kTRUE;
+
+    case kTabSaveAsCSV:
+        SaveAsCSV(fTab->GetCurrent());
         return kTRUE;
 
@@ -2070,4 +2074,22 @@
 // --------------------------------------------------------------------------
 //
+// Find an object in a canvas (uses MStatusArray as helper)
+//
+void MStatusDisplay::PrintContent(Option_t *o) const
+{
+    MStatusArray(*this).Print(o);
+}
+
+// --------------------------------------------------------------------------
+//
+// Find an object in a canvas (uses MStatusArray as helper)
+//
+TObject *MStatusDisplay::FindObjectInCanvas(const char *obj, const char *base, const char *canv) const
+{
+    return MStatusArray(*this).FindObjectInCanvas(obj, base, canv);
+}
+
+// --------------------------------------------------------------------------
+//
 // Draws a clone of a canvas into a new canvas. Taken from TCanvas.
 //
@@ -2132,4 +2154,8 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Display the contexts of a TObjArray in the display (all canvases)
+//
 Bool_t MStatusDisplay::Display(const TObjArray &list, const char *tab)
 {
@@ -2148,6 +2174,7 @@
     while ((c=(TCanvas*)Next()))
         //if (!GetCanvas(c->GetName()))
-        if (!tab || c->GetName()==(TString)tab)
-            DrawClonePad(c->GetName(), *c);
+        if (c->InheritsFrom(TCanvas::Class()))
+            if (!tab || c->GetName()==(TString)tab)
+                DrawClonePad(AddTab(c->GetName(), c->GetTitle()), *c);
 
     return kTRUE;
@@ -2175,4 +2202,9 @@
 
     const Int_t n = list.Read(name);
+
+    //
+    // If no status display was found with this name try to find canvases
+    // in the file and s´display them instead.
+    //
     if (n==0)
     {
@@ -2225,49 +2257,8 @@
 // --------------------------------------------------------------------------
 //
-// Writes the contents of a MStatusDisplay to a file.
-//
-Int_t MStatusDisplay::Write(Int_t num, const char *name, Int_t /*option*/, Int_t /*bufsize*/) const
-{
-    if (!gFile)
-    {
-        *fLog << warn << "MStatusDisplay::Write: No file found. Please create a TFile first." << endl;
-        return 0;
-    }
-
-    if (!gFile->IsOpen())
-    {
-        *fLog << warn << "MStatusDisplay::Write: File not open. Please open the TFile first." << endl;
-        return 0;
-    }
-
-    if (!gFile->IsWritable())
-    {
-        *fLog << warn << "MStatusDisplay::Write: File not writable." << endl;
-        return 0;
-    }
-
-    if (num==0)
-    {
-        *fLog << warn << "MStatusDisplay::Write: Tab doesn't contain an embedded Canvas... skipped." << endl;
-        return 0;
-    }
-
-    if (!gROOT->IsBatch() && num>=fTab->GetNumberOfTabs())
-    {
-        *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
-        return 0;
-    }
-    if (gROOT->IsBatch() && num>fBatch->GetSize())
-    {
-        *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
-        return 0;
-    }
-
-    MStatusArray list;
-
-    TNamed named;
-    named.SetTitle(fTitle);
-    list.Add(&named);
-
+// Add all canvases to the MStatusArray
+//
+void MStatusDisplay::FillArray(MStatusArray &list, Int_t num) const
+{
     Int_t from, to;
     GetCanvasRange(from, to, num);
@@ -2277,4 +2268,55 @@
         if ((c = GetCanvas(i)))
             list.Add(c);
+}
+
+// --------------------------------------------------------------------------
+//
+// Writes the contents of a MStatusDisplay to a file.
+//
+Int_t MStatusDisplay::Write(Int_t num, const char *name, Int_t /*option*/, Int_t /*bufsize*/) const
+{
+    if (!gFile)
+    {
+        *fLog << warn << "MStatusDisplay::Write: No file found. Please create a TFile first." << endl;
+        return 0;
+    }
+
+    if (!gFile->IsOpen())
+    {
+        *fLog << warn << "MStatusDisplay::Write: File not open. Please open the TFile first." << endl;
+        return 0;
+    }
+
+    if (!gFile->IsWritable())
+    {
+        *fLog << warn << "MStatusDisplay::Write: File not writable." << endl;
+        return 0;
+    }
+
+    if (num==0)
+    {
+        *fLog << warn << "MStatusDisplay::Write: Tab doesn't contain an embedded Canvas... skipped." << endl;
+        return 0;
+    }
+
+    if (!gROOT->IsBatch() && num>=fTab->GetNumberOfTabs())
+    {
+        *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
+        return 0;
+    }
+    if (gROOT->IsBatch() && num>fBatch->GetSize())
+    {
+        *fLog << warn << "MStatusDisplay::Write: Tab doesn't exist... skipped." << endl;
+        return 0;
+    }
+
+    MStatusArray list;
+
+    // Be careful: So far Display() assumes that it is the first entry in the list
+    TNamed named;
+    named.SetTitle(fTitle);
+    list.Add(&named);
+
+    FillArray(list, num);
 
     const Int_t n = list.Write(name, kSingleKey);
@@ -2322,25 +2364,4 @@
 {
     fTimer.SetTime(t);
-}
-
-// --------------------------------------------------------------------------
-//
-// Set the background color in a canvas
-//
-void MStatusDisplay::CanvasSetFillColor(TPad &p, Int_t col) const
-{
-    TObject *obj;
-
-    // See also TPad::UseCurrentStyle
-    TIter Next(p.GetListOfPrimitives());
-    while ((obj=Next()))
-    {
-        if (obj->InheritsFrom(TPad::Class()))
-            CanvasSetFillColor(*(TPad*)obj, col);
-        if (obj->InheritsFrom(TFrame::Class()))
-            ((TFrame*)obj)->SetFillColor(col);
-    }
-
-    p.SetFillColor(col);
 }
 
@@ -2407,6 +2428,20 @@
     const TString newstr("%%DocumentPaperSizes: a4\n%%Orientation: Landscape\n");
 
+    TString tmp(name+"XXXXXX");
+
+    // FIXME: Use mkstemp instead
+    if (!mktemp(const_cast<char*>(tmp.Data())))
+    {
+        *fLog << err << "ERROR - MStatusDisplay::UpdatePSHeader: mktemp failed." << endl;
+        return;
+    }
+
     ifstream fin(name);
-    ofstream fout(name+".$$$");
+    ofstream fout(tmp);
+    if (!fout)
+    {
+        *fLog << err << "Cannot open file " << name << ": " << strerror(errno) << endl;
+        return;
+    }
 
     char c;
@@ -2424,7 +2459,9 @@
 
     gSystem->Unlink(name);
-    gSystem->Rename(name+".$$$", name);
-}
-
+    gSystem->Rename(tmp, name);
+}
+
+// --------------------------------------------------------------------------
+//
 void MStatusDisplay::PSToolsRange(TVirtualPS &vps, Float_t psw, Float_t psh) const
 {
@@ -2437,4 +2474,6 @@
 }
 
+// --------------------------------------------------------------------------
+//
 void MStatusDisplay::PSToolsTextNDC(TVirtualPS &vps, Double_t u, Double_t v, const char *string) const
 {
@@ -2449,4 +2488,90 @@
 // --------------------------------------------------------------------------
 //
+Int_t MStatusDisplay::InitWriteDisplay(Int_t num, TString &name, const TString &ext)
+{
+    SetStatusLine1(Form("Writing %s file...",ext.Data()));
+    SetStatusLine2("Please be patient!");
+
+    if (!CheckTabForCanvas(num))
+    {
+        SetStatusLine2("Failed!");
+        return 0;
+    }
+
+    AddExtension(name, ext, num);
+
+    if (num<0)
+        *fLog << inf << "Open " << ext << "-File: " << name << endl;
+
+    return num;
+}
+
+// --------------------------------------------------------------------------
+//
+TCanvas *MStatusDisplay::InitWriteTab(Int_t num, TString &name)
+{
+    const Int_t i = TMath::Abs(num);
+
+    TCanvas *c = GetCanvas(i);
+    if (!c)
+    {
+        if (num<0)
+            *fLog << inf << " - ";
+        *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
+        return 0;
+    }
+
+    SetStatusLine2(MString::Format("Tab #%d", i));
+
+    //
+    // Paint canvas into root file
+    //
+    if (num<0 && !name.IsNull())
+    {
+        Bool_t found = kFALSE;
+        if (name.Index("%%%%name%%%%"))
+        {
+            name.ReplaceAll("%%name%%", c->GetName());
+            found = kTRUE;
+        }
+
+        if (name.Index("%%%%tab%%%%"))
+        {
+            name.ReplaceAll("%%tab%%", MString::Format("%d", i));
+            found = kTRUE;
+        }
+
+        if (!found)
+            name.Insert(name.Last('.'), MString::Format("-%d", i));
+    }
+
+    if (num<0)
+        *fLog << inf << " - ";
+    *fLog << inf << "Writing Tab #" << i;
+
+    if (!name.IsNull())
+        *fLog << " to " << name;
+
+    *fLog << ": " << c->GetName() << "... " << flush;
+
+    return c;
+}
+
+// This is a stupid workaround to get rid of the damned clipping
+// of the text. Who the hell needs clipping?
+class MyCanvas : public TCanvas
+{
+public:
+    void Scale(Double_t val)
+    {
+        fAbsXlowNDC = -val;
+        fAbsYlowNDC = -val;
+        fAbsWNDC    = 1+2*val;
+        fAbsHNDC    = 1+2*val;
+    }
+};
+
+// --------------------------------------------------------------------------
+//
 // Write some VGF (vector graphics format). Currently PS, PDF and SVG
 // is available. Specified by ext.
@@ -2466,17 +2591,7 @@
 Int_t MStatusDisplay::SaveAsVGF(Int_t num, TString name, const TString addon, const TString ext)
 {
-    SetStatusLine1(Form("Writing %s file...",ext.Data()));
-    SetStatusLine2("");
-
-    if (!CheckTabForCanvas(num))
-    {
-        SetStatusLine2("Failed!");
+    num = InitWriteDisplay(num, name, ext);
+    if (num==0)
         return 0;
-    }
-
-    AddExtension(name, ext, num);
-
-    if (num<0)
-        *fLog << inf << "Open " << ext << "-File: " << name << endl;
 
     TPad       *padsav = (TPad*)gPad;
@@ -2490,4 +2605,5 @@
     if (!ext.CompareTo("ps", TString::kIgnoreCase))
     {
+        gStyle->SetColorModelPS(1);
         ps = new TPostScript(name, 112);
         type = 1;
@@ -2518,10 +2634,4 @@
 
     //
-    // Create a list to delete the canvas clones
-    //
-    TList l;
-    l.SetOwner();
-
-    //
     // Create some GUI elements for a page legend
     //
@@ -2533,4 +2643,310 @@
     // Maintain tab numbers
     //
+    Int_t from, to;
+    GetCanvasRange(from, to, num);
+
+    for (int i=from; i<to; i++)
+    {
+        TCanvas *c = InitWriteTab(num<0?-i:i);
+        if (c==0)
+            continue;
+
+        //
+        // Init page and page size, make sure, that the canvas in the file
+        // has the same Aspect Ratio than on the screen.
+        //
+        if (type==1 || i>from)
+            ps->NewPage();
+
+        //
+        // 28 is used here to scale the canvas into a height of 28,
+        // such that the page title can be set above the canvas...
+        //
+        Float_t psw = 28.0; // A4 - width  (29.7)
+        Float_t psh = 21.0; // A4 - height (21.0)
+
+        const Float_t cw = c->GetWw();
+        const Float_t ch = c->GetWh();
+
+        if (psw/psh>cw/ch)
+            psw = cw/ch*psh;
+        else
+            psh = ch/cw*psw;
+
+        PSToolsRange(*ps, psw, psh);
+
+        //
+        // Clone canvas and change background color and schedule for
+        // deletion
+        //
+        const Bool_t store = c->IsBatch();
+
+        c->SetBatch(kTRUE);
+        c->Paint();
+        c->SetBatch(store);
+
+        //
+        // Use the canvas as coordinate system for the overlaying text
+        //
+        gPad = c;
+        //n->cd();
+
+        const Double_t height = 0.015;
+
+        const Double_t off = 0.005;
+        const Double_t bot = height+off;
+        const Double_t top = 1-bot;
+
+        static_cast<MyCanvas*>(c)->Scale(bot);
+
+        // Separator Lines
+        line.PaintLineNDC(0.01, top, 0.99, top);
+        line.PaintLineNDC(0.01, bot, 0.99, bot);
+
+        //
+        // Print overlaying text (NDC = %)
+        //
+        // align phi col font size (11=left top)
+        const TString txt(addon.IsNull() ? fTitle : addon);
+
+        // Text Attributes
+        TAttText(11, 0, kBlack, 22, height).Copy(*ps);
+
+        // Text on top
+        ps->SetTextAlign(11); // left bottom
+        PSToolsTextNDC(*ps, 0.01, top+off, c->GetName());
+
+        ps->SetTextAlign(21); // cent bottom
+        PSToolsTextNDC(*ps, 0.50, top+off, TString("MARS V"MARSVER" - Modular Analysis and Reconstruction Software - ")+d.AsString());
+
+        ps->SetTextAlign(31); // right bottom
+        PSToolsTextNDC(*ps, 0.99, top+off, MString::Format("Page No.%i (%i)", page++, i));
+
+        // Text on bottom
+        ps->SetTextAlign(13); // left top
+        PSToolsTextNDC(*ps, 0.01, bot-off, c->GetTitle());
+
+        ps->SetTextAlign(23); // cent top
+        PSToolsTextNDC(*ps, 0.50, bot-off, txt);
+
+        ps->SetTextAlign(33); // right top
+        PSToolsTextNDC(*ps, 0.99, bot-off, MString::Format("(c) 2000-%d, Thomas Bretz", TDatime().GetYear()));
+
+        static_cast<MyCanvas*>(c)->Scale(0);
+
+        //
+        // Finish drawing page
+        //
+        *fLog << "done." << endl;
+    }
+
+    gPad = NULL; // Important!
+
+    ps->Close();
+    delete ps;
+
+#if ROOT_VERSION_CODE < ROOT_VERSION(5,12,00)
+    if (type==1)
+    {
+        SetStatusLine2("Updating header of PS file...");
+
+        if (num<0)
+            *fLog << inf3 << " - Updating header of PS file... " << flush;
+        UpdatePSHeader(name);
+        if (num<0)
+            *fLog << inf3 << "done." << endl;
+    }
+#endif
+
+    gVirtualPS = psave;
+    if (padsav)
+        padsav->cd();
+
+    if (num<0)
+        *fLog << inf << "done." << endl;
+
+    SetStatusLine2(MString::Format("Done (%dpages)", page-1));
+
+    return page-1;
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MStatusDisplay::SaveAsImage(Int_t num, TString name, TImage::EImageFileTypes type)
+{
+#if ROOT_VERSION_CODE < ROOT_VERSION(5,12,00)
+    if (gROOT->IsBatch())
+    {
+        *fLog << warn << "Sorry, writing image-files is not available in batch mode." << endl;
+        return 0;
+    }
+#endif
+
+    TString ext;
+    switch (type)
+    {
+    case TImage::kXpm:
+    case TImage::kZCompressedXpm:  ext = "xpm";     break;
+    case TImage::kPng:             ext = "png";     break;
+    case TImage::kJpeg:            ext = "jpg";     break;
+    case TImage::kGif:             ext = "gif";     break;
+    case TImage::kTiff:            ext = "tiff";    break;
+    case TImage::kBmp:             ext = "bmp";     break;
+    case TImage::kXml:             ext = "xml";     break;
+    //case TImage::kGZCompressedXpm: ext = "xpm.gz";  break;
+    //case TImage::kPpm:             ext = "ppm";     break;
+    //case TImage::kPnm:             ext = "pnm";     break;
+    //case TImage::kIco:             ext = "ico";     break;
+    //case TImage::kCur:             ext = "cur";     break;
+    //case TImage::kXcf:             ext = "xcf";     break;
+    //case TImage::kXbm:             ext = "xbm";     break;
+    //case TImage::kFits:            ext = "fits";    break;
+    //case TImage::kTga:             ext = "tga";     break;
+    default:
+        *fLog << warn << "Sorry, unknown or unsupported file type..." << endl;
+        return 0;
+    }
+
+    num = InitWriteDisplay(num, name, ext);
+    if (num==0)
+        return 0;
+
+    TPad *padsav = (TPad*)gPad;
+
+    Int_t counter = 0;
+
+    //
+    // Maintain tab numbers
+    //
+    Int_t from, to;
+    GetCanvasRange(from, to, num);
+
+    for (int i=from; i<to; i++)
+    {
+        TString writename(name);
+
+        TCanvas *c = InitWriteTab(num<0 ? -i : i, writename);
+        if (!c)
+            continue;
+
+        //
+        // Paint canvas into root file
+        //
+
+        // TImage *img = TImage::Create();
+        // img->FromPad(c);
+        // img->WriteImage(writename, type);
+        // delete img;
+
+        // FIXME: Not all file types are supported by Print()
+        c->Print(writename);
+
+        if (num<0)
+            *fLog << "done." << endl;
+
+        counter++;
+    }
+
+    if (padsav)
+        padsav->cd();
+
+    *fLog << inf << "done." << endl;
+
+    SetStatusLine2("Done.");
+
+    return counter>0;
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MStatusDisplay::SaveAsC(Int_t num, TString name)
+{
+    num = InitWriteDisplay(num, name, "C");
+    if (num==0)
+        return kFALSE;
+
+    TPad *padsav = (TPad*)gPad;
+
+    Int_t counter = 0;
+
+    //
+    // Maintain tab numbers
+    //
+    Int_t from, to;
+    GetCanvasRange(from, to, num);
+
+    for (int i=from; i<to; i++)
+    {
+        TString writename(name);
+
+        TCanvas *c = InitWriteTab(num<0 ? -i : i, writename);
+        if (!c)
+            continue;
+
+        //
+        // Clone canvas and change background color and schedule for
+        // deletion
+        //
+        c->SaveSource(writename, "");
+
+        if (num<0)
+            *fLog << "done." << endl;
+
+        counter++;
+    }
+
+    if (padsav)
+        padsav->cd();
+
+    *fLog << inf << "done." << endl;
+
+    SetStatusLine2("Done.");
+
+    return counter>0;
+}
+
+// --------------------------------------------------------------------------
+//
+// In case of num<0 all tabs are written into the PS file. If num>0
+// the canvas in the corresponding tab is written to the file.
+// Name is the name of the file (with or without extension).
+//
+// Returns the number of keys written.
+//
+// To write all tabs you can also use SaveAsPS(name)
+//
+Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name)
+{
+    num = InitWriteDisplay(num, name, "root");
+    if (num==0)
+        return -1;
+
+    TFile *fsave = gFile;
+    TFile file(name, "RECREATE", GetTitle(), 9);
+    const Int_t keys = Write(num);
+    gFile = fsave;
+
+    SetStatusLine2("Done.");
+
+    return keys;
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MStatusDisplay::SaveAsCSV(Int_t num, TString name, Char_t delim)
+{
+    num = InitWriteDisplay(num, name, "csv");
+    if (num==0)
+        return kFALSE;
+
+    ofstream fout(name);
+    if (!fout)
+    {
+        *fLog << err << "Cannot open file " << name << ": " << strerror(errno) << endl;
+        return kFALSE;
+    }
+
+    fout << 0 << delim << GetName() << delim << GetTitle() << endl;
+
     Int_t from, to;
     GetCanvasRange(from, to, num);
@@ -2547,387 +2963,14 @@
         }
 
-        SetStatusLine2(MString::Format("Tab #%d", i));
-
-        //
-        // Init page and page size, make sure, that the canvas in the file
-        // has the same Aspect Ratio than on the screen.
-        //
-        if (type==1 || i>from)
-            ps->NewPage();
-
-        //
-        // 28 is used here to scale the canvas into a height of 28,
-        // such that the page title can be set above the canvas...
-        //
-        Float_t psw = 28.0; // A4 - width  (29.7)
-        Float_t psh = 21.0; // A4 - height (21.0)
-
-        const Float_t cw = c->GetWw();
-        const Float_t ch = c->GetWh();
-
-        if (psw/psh>cw/ch)
-            psw = cw/ch*psh;
-        else
-            psh = ch/cw*psw;
-
-        PSToolsRange(*ps, psw, psh);
-
-        //
-        // Clone canvas and change background color and schedule for
-        // deletion
-        //
-        TCanvas *n = (TCanvas*)c->Clone();
-        CanvasSetFillColor(*n, kWhite);
-        l.Add(n);
-
-        //
-        // Paint canvas into root file
-        //
-        if (num<0)
-            *fLog << inf << " - ";
-        *fLog << inf << "Writing Tab #" << i << ": " << c->GetName() << " (" << c << ") ";
-        if (num>0)
-            *fLog << "to " << name;
-        *fLog << "... " << flush;
-
-        n->SetBatch(kTRUE);
-        n->Paint();
-
-        //
-        // Use the canvas as coordinate system for the overlaying text
-        //
-        gPad = n;
-        //n->cd();
-
-        //
-        // Print overlaying text (NDC = %)
-        //
-        // align phi col font size (11=left top)
-        TAttText(11, 0, kBlack, 22, 0.015).Copy(*ps);
-        PSToolsTextNDC(*ps, 0, 1.015, TString("  ")+n->GetName());
-        ps->SetTextAlign(21); // cent top
-        PSToolsTextNDC(*ps, 0.5, 1.015, TString("MARS V"MARSVER" - Modular Analysis and Reconstruction Software - ")+d.AsString());
-        ps->SetTextAlign(31); // right top
-        PSToolsTextNDC(*ps, 1, 1.015, MString::Format("Page No.%i (%i)  ", page++, i));
-        line.PaintLineNDC(0, 1.01, 1, 1.01);
-
-        TString txt(addon.IsNull() ? fTitle : addon);
-        if (!txt.IsNull())
-        {
-            line.PaintLineNDC(0, -0.00, 1, -0.00);
-            ps->SetTextAlign(11); // left top
-            PSToolsTextNDC(*ps, 0, -0.015, TString("  ")+txt);
-            ps->SetTextAlign(31); // right top
-            PSToolsTextNDC(*ps, 1, -0.015, Form("(c) 2000-%d, Thomas Bretz  ", TDatime().GetYear()));
-        }
-
-        //
-        // Finish drawing page
-        //
-        n->SetBatch(kFALSE);
-        *fLog << "done." << endl;
-    }
-
-    gPad = NULL; // Important!
-    l.Delete();
-
-    ps->Close();
-    delete ps;
-
-    if (type==1)
-    {
-        SetStatusLine2("Updating header of PS file...");
-
-        if (num<0)
-            *fLog << inf3 << " - Updating header of PS file... " << flush;
-        UpdatePSHeader(name);
-        if (num<0)
-            *fLog << inf3 << "done." << endl;
-    }
-
-    gVirtualPS = psave;
-    if (padsav)
-        padsav->cd();
-
-    if (num<0)
-        *fLog << inf << "done." << endl;
-
-    SetStatusLine2(MString::Format("Done (%dpages)", page-1));
-
-    return page-1;
-}
-
-Bool_t MStatusDisplay::SaveAsImage(Int_t num, TString name, TImage::EImageFileTypes type)
-{
-#if ROOT_VERSION_CODE < ROOT_VERSION(5,12,00)
-    if (gROOT->IsBatch())
-    {
-        *fLog << warn << "Sorry, writing image-files is not available in batch mode." << endl;
-        return 0;
-    }
-#endif
-
-    SetStatusLine1("Writing image file...");
-    SetStatusLine2("please be patient!");
-
-    if (!CheckTabForCanvas(num))
-    {
-        SetStatusLine2("Failed!");
-        return 0;
-    }
-
-    TString ext;
-    switch (type)
-    {
-    case TImage::kXpm:
-    case TImage::kZCompressedXpm:
-        ext = AddExtension(name, "xpm", num);
-        break;
-//    case TImage::kGZCompressedXpm:
-//        ext = AddExtension(name, "xpm.gz", num);
-//        break;
-    case TImage::kPng:
-        ext = AddExtension(name, "png", num);
-        break;
-    case TImage::kJpeg:
-        ext = AddExtension(name, "jpg", num);
-        break;
-    case TImage::kGif:
-        ext = AddExtension(name, "gif", num);
-        break;
-//    case TImage::kTiff:
-//        ext = AddExtension(name, "tiff", num);
-//        break;
-//    case TImage::kPpm:
-//        ext = AddExtension(name, "ppm", num);
-//        break;
-//    case TImage::kPnm:
-//        ext = AddExtension(name, "pnm", num);
-//        break;
-//    case TImage::kIco:
-//        ext = AddExtension(name, "ico", num);
-//        break;
-//    case TImage::kCur:
-//        ext = AddExtension(name, "cur", num);
-//        break;
-    case TImage::kBmp:
-        ext = AddExtension(name, "bmp", num);
-        break;
-//    case TImage::kXcf:
-//        ext = AddExtension(name, "xcf", num);
-//        break;
-//    case TImage::kXbm:
-//        ext = AddExtension(name, "xbm", num);
-//        break;
-//    case TImage::kFits:
-//        ext = AddExtension(name, "fits", num);
-//        break;
-//    case TImage::kTga:
-//        ext = AddExtension(name, "tga", num);
-//        break;
-    case TImage::kXml:
-        ext = AddExtension(name, "xml", num);
-        break;
-    default:
-        *fLog << warn << "Sorry, unknown or unsupported file type..." << endl;
-        return 0;
-    }
-
-    if (num<0)
-        *fLog << inf << "Writing " << ext << "-Files..." << endl;
-
-    TPad *padsav = (TPad*)gPad;
-
-    int page = 1;
-
-    //
-    // Maintain tab numbers
-    //
-    Int_t from, to;
-    GetCanvasRange(from, to, num);
-
-    for (int i=from; i<to; i++)
-    {
-        TCanvas *c;
-        if (!(c = GetCanvas(i)))
-        {
-            if (num<0)
-                *fLog << inf << " - ";
-            *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
-            continue;
-        }
-
-        SetStatusLine2(MString::Format("Tab #%d", i));
-
-        //
-        // Clone canvas and change background color and schedule for
-        // deletion
-        //
-        TCanvas *n = c;
-        //TCanvas *n = (TCanvas*)c->Clone();
-        //CanvasSetFillColor(*n, kWhite);
-
-        //
-        // Paint canvas into root file
-        //
-        TString writename = name;
-        if (num<0)
-        {
-            TString numname = "-";
-            numname += i;
-            writename.Insert(name.Last('.'), numname);
-        }
-        if (num<0)
-            *fLog << inf << " - ";
-        *fLog << inf << "Writing Tab #" << i << " to " << writename << ": " << c->GetName() << " (" << c << ") ";
-        if (num>0)
-            *fLog << "to " << name;
-        *fLog << "..." << flush;
-
-#if ROOT_VERSION_CODE < ROOT_VERSION(4,04,00)
-        n->Draw();
-
-        if (type==TImage::kGif)
-            n->SaveAs(writename); // FIXME: Seems not to work well in TImage! (root 3.10/02)
-        else
-        {
-            TImage *img = TImage::Create();
-            img->FromPad(n);
-            img->WriteImage(writename, type);
-            delete img;
-        }
-#else
-        //gROOT->SetBatch();
-        n->Print(writename);
-        //gROOT->SetBatch(kFALSE);
-#endif
-        // delete n;
-        if (num<0)
-            *fLog << "done." << endl;
-    }
-
-    if (padsav)
-        padsav->cd();
-
-    *fLog << inf << "done." << endl;
+        fout << i << delim << c->GetName() << delim << c->GetTitle() << endl;
+    }
 
     SetStatusLine2("Done.");
 
-    return page-1;
-}
-
-Bool_t MStatusDisplay::SaveAsC(Int_t num, TString name)
-{
-    SetStatusLine1("Writing C++ file...");
-    SetStatusLine2("");
-
-    if (!CheckTabForCanvas(num))
-    {
-        SetStatusLine2("Failed!");
-        return 0;
-    }
-
-    AddExtension(name, "C", num);
-
-    if (num<0)
-        *fLog << inf << "Writing C-Files..." << endl;
-
-    TPad *padsav = (TPad*)gPad;
-
-    int page = 1;
-
-    //
-    // Maintain tab numbers
-    //
-    Int_t from, to;
-    GetCanvasRange(from, to, num);
-
-    for (int i=from; i<to; i++)
-    {
-        TCanvas *c;
-        if (!(c = GetCanvas(i)))
-        {
-            if (num<0)
-                *fLog << inf << " - ";
-            *fLog << "Tab #" << i << " doesn't contain an embedded Canvas... skipped." << endl;
-            continue;
-        }
-
-        SetStatusLine2(MString::Format("Tab #%d", i));
-
-        //
-        // Clone canvas and change background color and schedule for
-        // deletion
-        //
-        TCanvas *n = (TCanvas*)c->Clone();
-        CanvasSetFillColor(*n, kWhite);
-
-        //
-        // Paint canvas into root file
-        //
-        TString writename = name;
-        if (num<0)
-        {
-            TString numname = "-";
-            numname += i;
-            writename.Insert(name.Last('.'), numname);
-        }
-        if (num<0)
-            *fLog << inf << " - ";
-        *fLog << inf << "Writing Tab #" << i << " to " << writename << ": " << c->GetName() << " (" << n << ") ";
-        if (num>0)
-            *fLog << "to " << name;
-        *fLog << "..." << flush;
-
-        n->SaveSource(writename, "");
-        delete n;
-
-        if (num<0)
-            *fLog << "done." << endl;
-    }
-
-    if (padsav)
-        padsav->cd();
-
-    *fLog << inf << "done." << endl;
-
-    SetStatusLine2("Done.");
-
-    return page-1;
-}
-
-// --------------------------------------------------------------------------
-//
-// In case of num<0 all tabs are written into the PS file. If num>0
-// the canvas in the corresponding tab is written to the file.
-// Name is the name of the file (with or without extension).
-//
-// Returns the number of keys written.
-//
-// To write all tabs you can also use SaveAsPS(name)
-//
-Int_t MStatusDisplay::SaveAsRoot(Int_t num, TString name)
-{
-    SetStatusLine1("Writing root file...");
-    SetStatusLine2("");
-
-    if (!CheckTabForCanvas(num))
-    {
-        SetStatusLine2("Failed!");
-        return 0;
-    }
-
-    AddExtension(name, "root", num);
-
-    TFile *fsave = gFile;
-    TFile file(name, "RECREATE", "MARS - Status Window Contents", 9);
-    const Int_t keys = Write(num);
-    gFile = fsave;
-
-    SetStatusLine2("Done.");
-
-    return keys;
-}
-
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
 void MStatusDisplay::SaveAs(const char *c, const Option_t *o) const
 {
@@ -2946,15 +2989,17 @@
 Int_t MStatusDisplay::SaveAs(Int_t num, TString name)
 {
-    if (name.EndsWith(".root")) return SaveAsRoot(num, name);
-    if (name.EndsWith(".ps"))   return SaveAsPS(num, name);
-    if (name.EndsWith(".pdf"))  return SaveAsPDF(num, name);
-    if (name.EndsWith(".svg"))  return SaveAsSVG(num, name);
-    if (name.EndsWith(".gif"))  return SaveAsGIF(num, name);
-    if (name.EndsWith(".png"))  return SaveAsPNG(num, name);
-    if (name.EndsWith(".bmp"))  return SaveAsBMP(num, name);
-    if (name.EndsWith(".xml"))  return SaveAsXML(num, name);
-    if (name.EndsWith(".jpg"))  return SaveAsJPG(num, name);
-    if (name.EndsWith(".xpm"))  return SaveAsXPM(num, name);
-    if (name.EndsWith(".C"))    return SaveAsC(num, name);
+    if (name.EndsWith(".root")) return SaveAsRoot(num, name); // kFileSaveAsRoot
+    if (name.EndsWith(".ps"))   return SaveAsPS(num, name);   // kFileSaveAsPS
+    if (name.EndsWith(".pdf"))  return SaveAsPDF(num, name);  // kFileSaveAsPDF
+    if (name.EndsWith(".svg"))  return SaveAsSVG(num, name);  // kFileSaveAsSVG
+    if (name.EndsWith(".gif"))  return SaveAsGIF(num, name);  // kFileSaveAsGIF
+    if (name.EndsWith(".png"))  return SaveAsPNG(num, name);  // kFileSaveAsPNG
+    if (name.EndsWith(".bmp"))  return SaveAsBMP(num, name);  // kFileSaveAsBMP
+    if (name.EndsWith(".xml"))  return SaveAsXML(num, name);  // kFileSaveAsXML
+    if (name.EndsWith(".jpg"))  return SaveAsJPG(num, name);  // kFileSaveAsJPG
+    if (name.EndsWith(".xpm"))  return SaveAsXPM(num, name);  // kFileSaveAsXPM
+    if (name.EndsWith(".csv"))  return SaveAsCSV(num, name);  // kFileSaveAsCSV
+    if (name.EndsWith(".tiff")) return SaveAsTIFF(num, name); // kFileSaveAsTIFF
+    if (name.EndsWith(".C"))    return SaveAsC(num, name);    // kFileSaveAsC
     return -1;
 }
@@ -2978,4 +3023,6 @@
         "Bmp files",    "*.bmp",
         "Xml files",    "*.xml",
+        "Tiff files",   "*.tiff",
+        "Csv files",    "*.csv",
         "Macro files",  "*.C",
         "ROOT files",   "*.root",
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 8961)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 8962)
@@ -20,4 +20,5 @@
 class MLog;
 class MGList;
+class MStatusArray;
 class MParContainer;
 
@@ -46,5 +47,5 @@
         kFileSaveAsPS, kFileSaveAsPDF, kFileSaveAsSVG, kFileSaveAsRoot,
         kFileSaveAsPNG, kFileSaveAsGIF, kFileSaveAsJPG, kFileSaveAsXPM,
-        kFileSaveAsBMP, /*kFileSaveAsXCF, kFileSaveAsTIFF,*/
+        kFileSaveAsBMP, kFileSaveAsCSV, kFileSaveAsTIFF,
         kFileSaveAsXML, kFileSaveAsC, kFilePrint, kFilePrinterName,
         kFileClose, kFileExit, kFileReset,
@@ -54,5 +55,5 @@
         kTabSave, kTabSaveAs, kTabSaveAsPS, kTabSaveAsPDF, kTabSaveAsSVG,
         kTabSaveAsRoot, kTabSaveAsPNG, kTabSaveAsGIF, kTabSaveAsJPG,
-        kTabSaveAsXPM, kTabSaveAsBMP, /*kTabSaveAsXCF, kTabSaveAsTIFF,*/
+        kTabSaveAsXPM, kTabSaveAsBMP, kTabSaveAsCSV, kTabSaveAsTIFF,
         kTabSaveAsXML, kTabSaveAsC,
         kTabPrint, kTabNext, kTabPrevious, kTabRemove,
@@ -110,4 +111,5 @@
     TList *fBatch;          //!
 
+    // GUI setup
     void AddMenuBar();
     void AddUserFrame();
@@ -118,4 +120,5 @@
     void AddLogTab();
 
+    // GUI event handling
     Bool_t ProcessMessageCommandMenu(Long_t mp1);
     Bool_t ProcessMessageCommand(Long_t submsg, Long_t mp1, Long_t mp2);
@@ -125,23 +128,34 @@
     void   CloseWindow();
     Bool_t HandleConfigureNotify(Event_t *);
-    Bool_t HandleEvent(Event_t *event);
-
+
+    // Access to the tabs
     TGCompositeFrame *GetTabContainer(const char *name) const;
     TGTabElement     *GetTabTab(const char *name) const;
 
+    // Display update
     Bool_t HandleTimer(TTimer *timer=NULL);
     void UpdateTab(TGCompositeFrame *f);
     void UpdateMemory() const;
 
-    void DrawClonePad(TCanvas &newc, TCanvas &oldc) const;
-    void CanvasSetFillColor(TPad &c, Int_t col) const;
-    Bool_t Display(const TObjArray &list, const char *tab=0);
-
-    const TString &AddExtension(TString &name, const TString &ext, Int_t num=-1) const;
-
-    void UpdatePSHeader(const TString &name) const;
-
+    // Display helper functions
     void RemoveTab(int i);
     void SetStatusLine(const char *txt, Int_t idx);
+
+    // Drawing helper
+    void DrawClonePad(TCanvas &newc, TCanvas &oldc) const;
+    void GetCanvasRange(Int_t &from, Int_t &to, Int_t num=-1) const;
+
+    // MStatusArray interface
+    Bool_t Display(const TObjArray &list, const char *tab=0);
+    void FillArray(MStatusArray &list, Int_t num=-1) const;
+
+    // I/O helper function
+    const TString &AddExtension(TString &name, const TString &ext, Int_t num=-1) const;
+
+    TCanvas *InitWriteTab(Int_t num, TString &name);
+    TCanvas *InitWriteTab(Int_t num) { TString s; return InitWriteTab(num, s); }
+    Int_t    InitWriteDisplay(Int_t num, TString &name, const TString &ext);
+
+    void UpdatePSHeader(const TString &name) const;
 
     Bool_t SaveAsImage(Int_t num, TString name, TImage::EImageFileTypes type);
@@ -152,23 +166,9 @@
     TString PrintDialog(TString &p, TString &c, TString &t, const char *ext=0);
 
-    void GetCanvasRange(Int_t &from, Int_t &to, Int_t num=-1) const;
-
 public:
      MStatusDisplay(Int_t w=-1, Int_t h=-1, Long_t t=1000);
      virtual ~MStatusDisplay();
 
-     void SetLogStream(MLog *log, Bool_t enable=kFALSE);
-
-     void StartUpdate(Int_t millisec=-1);
-     void StopUpdate();
-     void SetUpdateTime(Long_t t);
-
-     void SetProgressBarPosition(Float_t p, Bool_t upd=kFALSE);
-     TGProgressBar *GetBar() const { return (TGProgressBar*)fBar; }
-
-     void SetStatusLine1(const char *txt) { SetStatusLine(txt, 0); }
-     void SetStatusLine2(const char *txt) { SetStatusLine(txt, 1); }
-     void SetStatusLine2(const MParContainer &cont);
-
+     // Name and title handling
      virtual void SetName(const char *name) { fName = name; }
      virtual void SetTitle(const char *title="") { fTitle = title; }
@@ -176,7 +176,5 @@
      virtual const char *GetTitle() const { return fTitle.Data(); }
 
-     TCanvas &AddTab(const char *name);
-     TGCompositeFrame *AddRawTab(const char *name);
-
+     // Getter / display access
      Bool_t   HasCanvas(const TCanvas *c) const;
      TCanvas *GetCanvas(int i) const;
@@ -184,30 +182,50 @@
      TVirtualPad *GetFullPad(const Int_t canvas, const Int_t pad);
 
-     Int_t Write(Int_t num, const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0) const;
-
-     Int_t Read(const char *name, const char *tab);
-     Int_t Read(const char *name="MStatusDisplay")
-     {
-         return Read(name, 0);
-     }
-     Int_t Write(const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0)
-     {
-         return Write(-1, name, option, bufsize);
-     }
-     Int_t Write(const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0) const
-     {
-         return Write(-1, name, option, bufsize);
-     }
-
      Bool_t CdCanvas(const TString &name);
-     void   Update() { HandleTimer(&fTimer); HandleTimer(&fLogTimer); }
-
-     void DrawClonePad(const char *tab, TCanvas &oldc)
-     {
-         DrawClonePad(AddTab(tab), oldc);
-     }
-
+     Bool_t CheckTabForCanvas(int num) const;
+
+     TObject *FindObjectInCanvas(const char *obj, const char *base, const char *canv) const;
+     TObject *FindObjectInCanvas(const char *obj, const char *canv) const { return FindObjectInCanvas(obj, obj, canv); }
+     TObject *FindObject(const char *obj, const char *base) const { return FindObjectInCanvas(obj, base, 0); }
+     TObject *FindObject(const char *obj) const { return FindObjectInCanvas(obj, obj, 0); }
+     TObject *FindObject(const TObject *o) const { return 0;  }
+
+     void PrintContent(Option_t *o="") const;
+
+     // Display Manipulation
+     TCanvas &AddTab(const char *name, const char *title=0);
+     TGCompositeFrame *AddRawTab(const char *name);
+
+     void SetProgressBarPosition(Float_t p, Bool_t upd=kFALSE);
+     TGProgressBar *GetBar() const { return (TGProgressBar*)fBar; }
+
+     void SetStatusLine1(const char *txt) { SetStatusLine(txt, 0); }
+     void SetStatusLine2(const char *txt) { SetStatusLine(txt, 1); }
+     void SetStatusLine2(const MParContainer &cont);
+
+     void Reset();
      void SetNoContextMenu(Bool_t flag=kTRUE);
 
+     // Update handling
+     void StartUpdate(Int_t millisec=-1);
+     void StopUpdate();
+     void SetUpdateTime(Long_t t);
+
+     void Update() { HandleTimer(&fTimer); HandleTimer(&fLogTimer); }
+
+     // Log stream interface
+     void SetLogStream(MLog *log, Bool_t enable=kFALSE);
+
+     // Size options
+     void SetCanvasWidth(UInt_t w);
+     void SetCanvasHeight(UInt_t h);
+
+     void SetDisplayWidth(UInt_t w);
+     void SetDisplayHeight(UInt_t h);
+
+     void SetOptimumSize();
+     void SetDisplaySize(UInt_t w, UInt_t h);
+
+     // Graphics output
      Int_t  SaveAsPS(TString name="",  const TString addon="") { return SaveAsVGF(-1, name, addon, "ps"); }
      Int_t  SaveAsPDF(TString name="", const TString addon="") { return SaveAsVGF(-1, name, addon, "pdf"); }
@@ -217,6 +235,5 @@
      Bool_t SaveAsXPM(TString name="")  { return SaveAsXPM(-1, name); }
      Bool_t SaveAsJPG(TString name="")  { return SaveAsJPG(-1, name); }
-     //Bool_t SaveAsTIFF(TString name="") { return SaveAsTIFF(-1, name); }
-     //Bool_t SaveAsXCF(TString name="")  { return SaveAsXCF(-1, name); }
+     Bool_t SaveAsTIFF(TString name="") { return SaveAsTIFF(-1, name); }
      Bool_t SaveAsBMP(TString name="")  { return SaveAsBMP(-1, name); }
      Bool_t SaveAsXML(TString name="")  { return SaveAsXML(-1, name); }
@@ -224,4 +241,6 @@
      Int_t  SaveAsRoot(TString name="") { return SaveAsRoot(-1, name); }
      Int_t  SaveAs(TString name)        { return SaveAs(-1, name); }
+
+     Bool_t SaveAsCSV(TString name="", Char_t delim='\t') { return SaveAsCSV(-1, name, delim); }
      Int_t  PrintPS() { return PrintPS(-1); }
 
@@ -235,6 +254,5 @@
      Bool_t SaveAsXPM(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kXpm); }
      Bool_t SaveAsJPG(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kJpeg); }
-     //Bool_t SaveAsTIFF(Int_t num, TString name="") { return SaveAsImage(num, name, TImage::kTiff); }
-     //Bool_t SaveAsXCF(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kXcf); }
+     Bool_t SaveAsTIFF(Int_t num, TString name="") { return SaveAsImage(num, name, TImage::kTiff); }
      Bool_t SaveAsBMP(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kBmp); }
      Bool_t SaveAsXML(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kXml); }
@@ -242,22 +260,25 @@
      Int_t  SaveAsRoot(Int_t num, TString name="");
      Int_t  SaveAs(Int_t num, TString name);
+
+     Bool_t SaveAsCSV(Int_t num, TString name="", Char_t delim='\t');
      Int_t  PrintPS(Int_t num, const char *p=0, const char *cmd=0, const char *tmp=0);
      Bool_t PrintLog(const char *p=0, const char *c=0);
+
      Bool_t SaveLogAsPS(const char *name) const;
 
-     // Size options
-     void SetCanvasWidth(UInt_t w);
-     void SetCanvasHeight(UInt_t h);
-
-     void SetDisplayWidth(UInt_t w);
-     void SetDisplayHeight(UInt_t h);
-
-     void SetOptimumSize();
-     void SetDisplaySize(UInt_t w, UInt_t h);
-
+     // I/O
      Int_t  SaveAs(Int_t num=-1);
      Int_t  Open(TString fname, const char *name="MStatusDisplay");
      Int_t  Open();
 
+     // Root I/O
+     Int_t Write(Int_t num, const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0) const;
+
+     Int_t Read(const char *name, const char *tab);
+     Int_t Read(const char *name="MStatusDisplay") { return Read(name, 0); }
+     Int_t Write(const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0) { return Write(-1, name, option, bufsize); }
+     Int_t Write(const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0) const { return Write(-1, name, option, bufsize); }
+
+     // Eventloop interface
      Status_t CheckStatus() const { return fStatus; }
      void ClearStatus() { fStatus = kLoopNone; }
@@ -266,9 +287,7 @@
      void UnLock() { if (fIsLocked>0) fIsLocked--; }
 
-     void Reset();
-
-     Bool_t CheckTabForCanvas(int num) const;
-
+     // GUI event handling
      void EventInfo(Int_t event, Int_t px, Int_t py, TObject *selected);
+     Bool_t HandleEvent(Event_t *event);
 
      // Public helper functions
Index: trunk/MagicSoft/Mars/showplot.cc
===================================================================
--- trunk/MagicSoft/Mars/showplot.cc	(revision 8961)
+++ trunk/MagicSoft/Mars/showplot.cc	(revision 8962)
@@ -75,5 +75,9 @@
     gLog << " Only the last size option given is taken into account." << endl;
     gLog << " Width or height is set according to height or width." << endl << endl;
-    gLog << " In batch mode display width and height and auto-size is ignored." << endl;
+    gLog << " In batch mode display width and height and auto-size is ignored." << endl << endl;
+    gLog << " If multiple files are written (e.g. a while display is written as png-files)" << endl;
+    gLog << " you can use %%name%% and %%tab%% in the name, which is then replaced by" << endl;
+    gLog << " the tab-name or tab.number respectively. If none of them are given a" << endl;
+    gLog << " minus and the tab.number is added in front of the extension." << endl << endl;
     gLog << "Printing:" << endl;
     gLog << " For more details see MStatusDisplay::PrintPS" << endl << endl;
