Index: trunk/MagicSoft/Mars/mbase/MLog.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MLog.cc	(revision 7000)
+++ trunk/MagicSoft/Mars/mbase/MLog.cc	(revision 7001)
@@ -134,8 +134,8 @@
 #endif
 const char *const MLog::kBlue      = "\033[34m";
-const char *const MLog::kUnderline = "\033[4m";;
-const char *const MLog::kBlink     = "\033[5m";;
-const char *const MLog::kBright    = "\033[1m";;
-const char *const MLog::kDark      = "\033[2m";;
+const char *const MLog::kUnderline = "\033[4m";
+const char *const MLog::kBlink     = "\033[5m";
+const char *const MLog::kBright    = "\033[1m";
+const char *const MLog::kDark      = "\033[2m";
 
 //
@@ -488,5 +488,5 @@
     if (fDevice&eStdout)
     {
-        if (!TestBit(eNoColors))
+        if (!fIsNull && !TestBit(eNoColors))
             cout << kReset;
         cout.flush();
Index: trunk/MagicSoft/Mars/mbase/MLog.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MLog.h	(revision 7000)
+++ trunk/MagicSoft/Mars/mbase/MLog.h	(revision 7001)
@@ -129,4 +129,5 @@
     void operator=(TGTextView *out)     { SetOutputGui(out);  }
 
+    Bool_t IsNullOutput() const { return fIsNull; }
     Bool_t IsOutputDeviceEnabled(int i) const { return fDevice & i; }
 
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 7000)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc	(revision 7001)
@@ -33,5 +33,5 @@
 // To write gif files of C-Macros use SaveAsGif()/SaveAsPNG() or SaveAsC().
 // Direct printing to the default printer (via lpr) can be done by
-// PrintToLpr().
+// PrintPS().
 //
 // It has also to half status lines which can be used to display the status
@@ -64,4 +64,6 @@
 
 #include <TH1.h>                  // TH1::AddDirectory
+#include <TPDF.h>                 // TPDF
+#include <TSVG.h>                 // TSVG
 #include <TEnv.h>                 // TEnv
 #include <TLine.h>                // TLine
@@ -74,4 +76,5 @@
 #include <TDatime.h>              // TDatime
 #include <TRandom.h>              // TRandom
+#include <TRegexp.h>              // TRegexp
 #include <TThread.h>              // TThread::Self()
 #include <TBrowser.h>             // TBrowser
@@ -80,5 +83,4 @@
 #include <TMethodCall.h>          // TMethodCall
 
-//#include <TRint.h>                // gApplication, TRint::Class()
 #include <TInterpreter.h>         // gInterpreter
 
@@ -92,4 +94,5 @@
 #include <TGFileDialog.h>         // TGFileDialog
 #include <TGProgressBar.h>        // TGHProgressBar
+#include <TGTextEditDialogs.h>    // TGPrintDialog
 #include <TRootEmbeddedCanvas.h>  // TRootEmbeddedCanvas
 
@@ -245,26 +248,36 @@
     //
     MGPopupMenu *filemenu = new MGPopupMenu(gClient->GetRoot());
-    // filemenu->AddEntry("Save &As...", kFileSaveAs);
-    filemenu->AddEntry("New Can&vas",   kFileCanvas);
-    filemenu->AddEntry("New &Browser",  kFileBrowser);
+    filemenu->AddEntry("New &Canvas",       kFileCanvas);
+    filemenu->AddEntry("New &Browser",      kFileBrowser);
     filemenu->AddSeparator();
-    filemenu->AddEntry("Save status.&ps",   kFileSaveAsPS);
-    filemenu->AddEntry("Save status.&png",  kFileSaveAsPNG);
-    filemenu->AddEntry("Save status.&gif",  kFileSaveAsGIF);
-    filemenu->AddEntry("Save status.&jpg",  kFileSaveAsJPG);
-    filemenu->AddEntry("Save status.&xpm",  kFileSaveAsXPM);
-    filemenu->AddEntry("Save status.&C",    kFileSaveAsC);
-    filemenu->AddEntry("Save status.&root", kFileSaveAsRoot);
+
+    const TString fname(MString::Form("Save %s.", gROOT->GetName()));
+    MGPopupMenu *savemenu = new MGPopupMenu(gClient->GetRoot());
+    savemenu->AddEntry(MString::Form("%s&ps",  fname.Data()),  kFileSaveAsPS);
+    savemenu->AddEntry(MString::Form("%sp&df", fname.Data()),  kFileSaveAsPDF);
+    savemenu->AddEntry(MString::Form("%s&svg", fname.Data()),  kFileSaveAsSVG);
+    savemenu->AddSeparator();
+    savemenu->AddEntry(MString::Form("%sp&ng", fname.Data()),  kFileSaveAsPNG);
+    savemenu->AddEntry(MString::Form("%s&gif", fname.Data()),  kFileSaveAsGIF);
+    savemenu->AddEntry(MString::Form("%s&jpg", fname.Data()),  kFileSaveAsJPG);
+    savemenu->AddEntry(MString::Form("%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->AddSeparator();
+    savemenu->AddEntry(MString::Form("%s&C",    fname.Data()), kFileSaveAsC);
+    savemenu->AddEntry(MString::Form("%s&root", fname.Data()), kFileSaveAsRoot);
+    savemenu->Associate(this);
+
+    filemenu->AddEntry("&Open...",          kFileOpen);
+    filemenu->AddPopup("&Save", savemenu);
+    filemenu->AddEntry("Save &As...",       kFileSaveAs);
     filemenu->AddSeparator();
-    filemenu->AddEntry("&Open...",             kFileOpen);
-    filemenu->AddEntry("Save &As...",          kFileSaveAs);
+    filemenu->AddEntry("&Reset",            kFileReset);
     filemenu->AddSeparator();
-    filemenu->AddEntry("Re&set",               kFileReset);
+    filemenu->AddEntry("&Print",            kFilePrint);
     filemenu->AddSeparator();
-    filemenu->AddEntry("Print with &lpr",      kFilePrint);
-    //filemenu->AddEntry("Set printer &name",    kFilePrinterName);
-    filemenu->AddSeparator();
-    filemenu->AddEntry("C&lose", kFileClose);
-    filemenu->AddEntry("E&xit", kFileExit);
+    filemenu->AddEntry("C&lose",            kFileClose);
+    filemenu->AddEntry("E&xit",             kFileExit);
     filemenu->Associate(this);
 
@@ -273,20 +286,32 @@
     //
     MGPopupMenu *tabmenu = new MGPopupMenu(gClient->GetRoot());
-    tabmenu->AddEntry("Next [&+]",           kTabNext);
-    tabmenu->AddEntry("Previous [&-]",       kTabPrevious);
+    tabmenu->AddEntry("Next [&+]",          kTabNext);
+    tabmenu->AddEntry("Previous [&-]",      kTabPrevious);
     tabmenu->AddSeparator();
-    tabmenu->AddEntry("Save tab-i.&ps",   kTabSaveAsPS);
-    tabmenu->AddEntry("Save tab-i.&png",  kTabSaveAsPNG);
-    tabmenu->AddEntry("Save tab-i.&gif",  kTabSaveAsGIF);
-    tabmenu->AddEntry("Save tab-i.&jpg",  kTabSaveAsJPG);
-    tabmenu->AddEntry("Save tab-i.&xpm",  kTabSaveAsXPM);
-    tabmenu->AddEntry("Save tab-i.&C",    kTabSaveAsC);
-    tabmenu->AddEntry("Save tab-i.&root", kTabSaveAsRoot);
+
+    const TString fname2(MString::Form("Save %s-i.", gROOT->GetName()));
+    MGPopupMenu *savemenu2 = new MGPopupMenu(gClient->GetRoot());
+    savemenu2->AddEntry(MString::Form("%s&ps",  fname2.Data()),  kTabSaveAsPS);
+    savemenu2->AddEntry(MString::Form("%sp&df", fname2.Data()),  kTabSaveAsPDF);
+    savemenu2->AddEntry(MString::Form("%s&svg", fname2.Data()),  kTabSaveAsSVG);
+    savemenu2->AddSeparator();
+    savemenu2->AddEntry(MString::Form("%sp&ng", fname2.Data()),  kTabSaveAsPNG);
+    savemenu2->AddEntry(MString::Form("%s&gif", fname2.Data()),  kTabSaveAsGIF);
+    savemenu2->AddEntry(MString::Form("%s&jpg", fname2.Data()),  kTabSaveAsJPG);
+    savemenu2->AddEntry(MString::Form("%s&xpm", fname2.Data()),  kTabSaveAsXPM);
+    //savemenu->AddEntry("Save status.x&cf",  kFileSaveAsXCF);
+    //savemenu->AddEntry("Save status.&tiff", kFileSaveAsTIFF);
+    //savemenu->AddEntry("Save status.&bmp",  kFileSaveAsBMP);
+    savemenu2->AddSeparator();
+    savemenu2->AddEntry(MString::Form("%s&C",    fname2.Data()), kTabSaveAsC);
+    savemenu2->AddEntry(MString::Form("%s&root", fname2.Data()), kTabSaveAsRoot);
+    savemenu2->Associate(this);
+
+    tabmenu->AddPopup("&Save", savemenu2);
+    tabmenu->AddEntry("Save tab &As...",    kTabSaveAs);
     tabmenu->AddSeparator();
-    tabmenu->AddEntry("Save tab &As...",         kTabSaveAs);
+    tabmenu->AddEntry("&Remove",            kTabRemove);
     tabmenu->AddSeparator();
-    tabmenu->AddEntry("Re&move",             kTabRemove);
-    tabmenu->AddSeparator();
-    tabmenu->AddEntry("Print with &lpr",     kTabPrint);
+    tabmenu->AddEntry("&Print",             kTabPrint);
     tabmenu->Associate(this);
 
@@ -326,4 +351,6 @@
     logmenu->AddEntry("&Save",          kLogSave);
     logmenu->AddEntry("Save &append",   kLogAppend);
+    logmenu->AddSeparator();
+    logmenu->AddEntry("&Print",         kLogPrint);
     logmenu->Associate(this);
 
@@ -355,4 +382,6 @@
     // Add everything to autodel list
     //
+    fList->Add(savemenu);
+    fList->Add(savemenu2);
     fList->Add(filemenu);
     fList->Add(loopmenu);
@@ -1085,42 +1114,125 @@
 }
 
+TString MStatusDisplay::PrintDialog(TString &p, TString &c, TString &t, const char *ext)
+{
+    // If not in batch mode open a user dialog
+    if (!gROOT->IsBatch())
+    {
+        char *cprinter = StrDup(p);
+        char *ccmd     = StrDup(c);
+
+        Int_t rc=0;
+        new TGPrintDialog(fClient->GetRoot(), this, 400, 150, &cprinter, &ccmd, &rc);
+        if (rc)
+        {
+            p = cprinter; // default has been changed
+            c = ccmd;
+        }
+
+        delete [] cprinter;
+        delete [] ccmd;
+
+        if (!rc)
+            return "";
+    }
+
+
+    if (c.Contains("%f") && ext)
+    {
+        // Get temporary file name
+        TString name = "mars";
+
+        FILE *f = gSystem->TempFileName(name, t);
+        if (!f)
+        {
+            *fLog << warn << "MStatusDisplay::PrintDialog: Couldn't create temporary file in " << t << endl;
+            SetStatusLine2("failed!");
+            return "";
+        }
+        fclose(f);
+
+        // remove temp file
+        gSystem->Unlink(name);
+        name += ".";
+        name += ext;
+
+        t = name;
+    }
+
+    // compile command
+    TString cmd(c);
+
+    // if sprinter.IsNull we assume that everything around %p can
+    // be omitted and the program uses some kind of default
+    if (p.IsNull())
+    {
+        TString sub;
+        while (1)
+        {
+            sub = TString(cmd(TRegexp(" .*%p.* "))).Strip(TString::kBoth);
+            if (sub.IsNull())
+                break;
+
+            cmd.ReplaceAll(sub, "");
+        }
+    }
+
+    cmd.ReplaceAll("%p", p);
+    cmd.ReplaceAll("%f", t);
+
+    return cmd;
+}
+
 // --------------------------------------------------------------------------
 //
 // Saves the given canvas (pad) or all pads (num<0) as a temporary
-// postscript file and prints it using 'lpr'. If a printer name is set
-// via SetPrinter 'lpr -Pname' is used.
-//
-Int_t MStatusDisplay::PrintToLpr(Int_t num)
-{
-    TString name = "mars";
-
-    for (int i=0; i<6; i++)
-        name += (char)(gRandom->Uniform(25)+65);
-
-    name += ".ps";
-
-    const Int_t pages = SaveAsPS(num, name);
-
+// postscript file and prints it.
+//
+// The default command line c is: lpr -P%p %f
+//   %p: printer name
+//   %f: temporary file name
+//
+// The default printer name p is: <empty>
+//
+// Both can be changed in .rootrc by:
+//   PrintPS.Printer
+//   PrintPS.Command
+//
+// Ant the location of the temporary file t can by changed by
+//   Print.Directory
+// the default is the system default directory (normally /tmp)
+//
+Int_t MStatusDisplay::PrintPS(Int_t num, const char *p, const char *c, const char *t)
+{
+    static TString sprinter = gEnv->GetValue("PrintPS.Printer", p&&*p?p:"");
+    static TString scmd     = gEnv->GetValue("PrintPS.Command", c&&*c?c:"lpr -P%p %f");
+
+    TString tmp = gEnv->GetValue("Print.Directory", t&&*t?t:gSystem->TempDirectory());
+
+    TString cmd = PrintDialog(sprinter, scmd, tmp, "ps");
+    if (cmd.IsNull())
+        return 0;
+
+    // set status lines
     SetStatusLine1("Printing...");
     SetStatusLine2("");
 
+    // print to temporary file
+    const Int_t pages = SaveAsPS(num, tmp);
+
+    // check
     if (!pages)
     {
-        *fLog << warn << "MStatusDisplay::PrintToLpr: Sorry, couldn't save file as temporary postscript!" << endl;
+        *fLog << warn << "MStatusDisplay::Print: Sorry, couldn't save file as temporary postscript!" << endl;
         SetStatusLine2("Failed!");
         return 0;
     }
 
-    TString cmd="lpr ";
-    if (!fPrinter.IsNull())
-    {
-        cmd += "-P";
-        cmd += fPrinter;
-        cmd += " ";
-    }
-    cmd += name;
-
+    // execute command
+    *fLog << dbg << "Executing: " << cmd << endl;
     gSystem->Exec(cmd);
-    gSystem->Unlink(name);
+
+    // remove temporary file
+    gSystem->Unlink(tmp);
 
     SetStatusLine2(MString::Form("Done (%dpage(s))", pages));
@@ -1226,4 +1338,97 @@
 }
 
+Bool_t MStatusDisplay::SaveLogAsPS(const char *n) const
+{
+    TString name(n);
+    AddExtension(name, "ps");
+
+    // Code taken from TGTextEdit::Print
+    const TString pipe = MString::Form("a2ps -o%s", name.Data());
+    FILE *p = gSystem->OpenPipe(pipe, "w");
+    if (!p)
+    {
+        *fLog << err << "ERROR - Couldn't open pipe " << pipe << endl;
+        return kFALSE;
+    }
+
+    TGText *text = fLogBox->GetText();
+
+    char   *buf1, *buf2;
+    Long_t  len;
+    ULong_t i = 0;
+    TGLongPosition pos;
+
+    pos.fX = pos.fY = 0;
+    while (pos.fY < text->RowCount())
+    {
+        len = text->GetLineLength(pos.fY);
+        buf1 = text->GetLine(pos, len);
+        buf2 = new char[len + 2];
+        strncpy(buf2, buf1, (UInt_t)len);
+        buf2[len]   = '\n';
+        buf2[len+1] = '\0';
+        while (buf2[i] != '\0') {
+            if (buf2[i] == '\t') {
+                ULong_t j = i+1;
+                while (buf2[j] == 16 && buf2[j] != '\0')
+                    j++;
+                strcpy(buf2+i+1, buf2+j);
+            }
+            i++;
+        }
+        fwrite(buf2, sizeof(char), strlen(buf2)+1, p);
+
+        delete [] buf1;
+        delete [] buf2;
+        pos.fY++;
+    }
+    gSystem->ClosePipe(p);
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Print the log text.
+//
+// The default command line c is: a2ps -P%p
+//   %p: printer name
+//
+// The default printer name p is: <empty>
+//
+// Both can be changed in .rootrc by:
+//   PrintText.Printer
+//   PrintText.Command
+//
+Bool_t MStatusDisplay::PrintLog(const char *p, const char *c)
+{
+    static TString sprinter = gEnv->GetValue("PrintText.Printer", p&&*p?p:"");
+    static TString scmd     = gEnv->GetValue("PrintText.Command", c&&*c?c:"a2ps -P%p");
+
+    TString tmp;
+    TString cmd = PrintDialog(sprinter, scmd, tmp);
+    if (cmd.IsNull())
+        return kFALSE;
+
+    // set status lines
+    SetStatusLine1("Printing...");
+    SetStatusLine2("");
+
+    // print to temporary file
+    if (!SaveLogAsPS(cmd))
+    {
+        *fLog << warn << "MStatusDisplay::PrintLog: Sorry, couldn't create postscript!" << endl;
+        SetStatusLine2("Failed!");
+        return kFALSE;
+    }
+
+    // execute command
+    *fLog << dbg << "Executing: " << cmd << endl;
+    gSystem->Exec(cmd);
+
+    SetStatusLine2("Done.");
+
+    return kTRUE;
+}
+
 // --------------------------------------------------------------------------
 //
@@ -1267,4 +1472,12 @@
         return kTRUE;
 
+    case kFileSaveAsPDF:
+        SaveAsPDF();
+        return kTRUE;
+
+    case kFileSaveAsSVG:
+        SaveAsSVG();
+        return kTRUE;
+
     case kFileSaveAsPNG:
         SaveAsPNG();
@@ -1283,4 +1496,16 @@
         return kTRUE;
 
+    //case kFileSaveAsXCF:
+    //    SaveAsXCF();
+    //    return kTRUE;
+
+    //case kFileSaveAsTIFF:
+    //    SaveAsTIFF();
+    //    return kTRUE;
+
+    //case kFileSaveAsBMP:
+    //    SaveAsBMP();
+    //    return kTRUE;
+
     case kFileSaveAsC:
         SaveAsC();
@@ -1292,5 +1517,5 @@
 
     case kFilePrint:
-        PrintToLpr();
+        PrintPS();
         return kTRUE;
 
@@ -1303,4 +1528,12 @@
         return kTRUE;
 
+    case kTabSaveAsPDF:
+        SaveAsPDF(fTab->GetCurrent());
+        return kTRUE;
+
+    case kTabSaveAsSVG:
+        SaveAsSVG(fTab->GetCurrent());
+        return kTRUE;
+
     case kTabSaveAsPNG:
         SaveAsPNG(fTab->GetCurrent());
@@ -1319,4 +1552,16 @@
         return kTRUE;
 
+    //case kTabSaveAsXCF:
+    //    SaveAsXCF(fTab->GetCurrent());
+    //    return kTRUE;
+
+    //case kTabSaveAsBMP:
+    //    SaveAsBMP(fTab->GetCurrent());
+    //    return kTRUE;
+
+    //case kTabSaveAsTIFF:
+    //    SaveAsTIFF(fTab->GetCurrent());
+    //    return kTRUE;
+
     case kTabSaveAsC:
         SaveAsC(fTab->GetCurrent());
@@ -1328,5 +1573,5 @@
 
     case kTabPrint:
-        PrintToLpr(fTab->GetCurrent());
+        PrintPS(fTab->GetCurrent());
         return kTRUE;
 
@@ -1386,5 +1631,5 @@
         SetStatusLine2("");
         *fLog << inf << "Saving log... " << flush;
-        if (fLogBox->GetText()->Save("statusdisplay.log"))
+        if (fLogBox->GetText()->Save(MString::Form("%s.log", gROOT->GetName())))
         {
             *fLog << "done." << endl;
@@ -1402,5 +1647,5 @@
         SetStatusLine2("");
         *fLog << inf << "Appending log... " << flush;
-        if (fLogBox->GetText()->Append("statusdisplay.log"))
+        if (fLogBox->GetText()->Append(MString::Form("%s.log", gROOT->GetName())))
         {
             *fLog << "done." << endl;
@@ -1412,4 +1657,8 @@
             SetStatusLine2("Failed!");
         }
+        return kTRUE;
+
+    case kLogPrint:
+        PrintLog();
         return kTRUE;
 #ifdef DEBUG
@@ -1973,5 +2222,5 @@
     if (name.IsNull())
     {
-        name = "status";
+        name = gROOT->GetName();
         if (num>0)
         {
@@ -2042,57 +2291,32 @@
     gSystem->Unlink(name);
     gSystem->Rename(name+".$$$", name);
-/*
-    //
-    // Old style algorithm. Shifts blocks inside a single file --- SLOW!
-    //
-    const Int_t l = newstr.Length();
-
-    Long_t t[4]; // { id, size, flags, modtime }
-    gSystem->GetPathInfo(name, t, t+1, t+2, t+3);
-
-    char *c[2] = { new char[l], new char[l] };
-
-    fstream f(name, ios::in|ios::out);
-
-    TString str;
-    f >> str >> c[0][0];     // Read "%!PS-Adobe-2.0\n" (Mini Header)
-    f.read(c[0], l);
-    f.seekp(-l, ios::cur);
-    f.write(newstr, l);
-
-    int i=0;
-    while (1)
-    {
-        f.read(c[(i+1)%2], l);
-        f.seekp(-l, ios::cur);
-
-        if (f)
-        {
-            f.write(c[i%2],l);
-            i++;
-            i%=2;
-            continue;
-        }
-
-        const Int_t ssz   = str.Length()+1;        // Length of Mini-Header
-        const Int_t block = t[1]-ssz;              // Length of block to be shifted
-        const Int_t size  = block%l;               // Reminder
-        const Int_t pos   = (block/l)*l + ssz + 1; // Position to start writing
-
-        f.clear();
-        f.seekp(pos);
-        f.write(c[i%2], l);
-        f.write(c[(i+1)%2], size);
-        break;
-    }
-
-    delete c[1];
-    delete c[0];
-*/
-}
-
-// --------------------------------------------------------------------------
-//
-// In case of num<0 all tabs are written into the PS file. If num>0
+}
+
+void MStatusDisplay::PSToolsRange(TVirtualPS &vps, Float_t psw, Float_t psh) const
+{
+    if (vps.InheritsFrom(TPostScript::Class()))
+        static_cast<TPostScript&>(vps).Range(psw, psh);
+    // if (vps.InheritsFrom(TPDF::Class()))
+    //     static_cast<TPDF&>(vps).Range(psw/2, psh/2);
+    // if (vps.InheritsFrom(TSVG::Class()))
+    //     static_cast<TSVG&>(vps).Range(psw, psh);
+}
+
+void MStatusDisplay::PSToolsTextNDC(TVirtualPS &vps, Double_t u, Double_t v, const char *string) const
+{
+    if (vps.InheritsFrom(TPostScript::Class()))
+        static_cast<TPostScript&>(vps).TextNDC(u, v, string);
+    // if (vps.InheritsFrom(TPDF::Class()))
+    //    static_cast<TPDF&>(vps).TextNDC(u, v, string);
+    // if (vps.InheritsFrom(TSVG::Class()))
+    //    static_cast<TSVG&>(vps).TextNDC(u, v, string);
+}
+
+// --------------------------------------------------------------------------
+//
+// Write some VGF (vector graphics format). Currently PS, PDF and SVG
+// is available. Specified by ext.
+//
+// In case of num<0 all tabs are written into the VGF 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).
@@ -2100,5 +2324,5 @@
 // Returns the number of pages written.
 //
-// To write all tabs you can also use SaveAsPS(name)
+// To write all tabs you can also use SaveAsVGF(name, ext)
 //
 // If the third argument is given a bottom line is drawn with the text
@@ -2106,7 +2330,7 @@
 // fTitle (SetTitle) is not empty.
 //
-Int_t MStatusDisplay::SaveAsPS(Int_t num, TString name, const TString addon)
-{
-    SetStatusLine1("Writing Postscript file...");
+Int_t MStatusDisplay::SaveAsVGF(Int_t num, TString name, const TString addon, const TString ext)
+{
+    SetStatusLine1(Form("Writing %s file...",ext.Data()));
     SetStatusLine2("");
 
@@ -2117,8 +2341,8 @@
     }
 
-    AddExtension(name, "ps", num);
+    AddExtension(name, ext, num);
 
     if (num<0)
-        *fLog << inf << "Open ps-File: " << name << endl;
+        *fLog << inf << "Open " << ext << "-File: " << name << endl;
 
     TPad       *padsav = (TPad*)gPad;
@@ -2127,9 +2351,35 @@
     TDatime d;
 
-    TPostScript ps(name, 112);
-    ps.SetBit(TPad::kPrintingPS);
-    ps.PrintFast(13, "/nan {1} def ");
-
-    gVirtualPS = &ps;
+    Int_t type = -1;
+
+    TVirtualPS *ps =0;
+    if (!ext.CompareTo("ps", TString::kIgnoreCase))
+    {
+        ps = new TPostScript(name, 112);
+        type = 1;
+    }
+    if (!ext.CompareTo("pdf", TString::kIgnoreCase))
+    {
+        ps = new TPDF(name, 112);
+        type = 2;
+    }
+    if (!ext.CompareTo("svg", TString::kIgnoreCase))
+    {
+        ps = new TSVG(name, 112);
+        type = 3;
+    }
+
+    if (!ps)
+    {
+        *fLog << err << "Extension " << ext << " unknown..." << endl;
+        SetStatusLine2("Failed!");
+        return 0;
+    }
+
+    ps->SetBit(TPad::kPrintingPS);
+    if (type==1)
+        ps->PrintFast(13, "/nan {1} def ");
+
+    gVirtualPS = ps;
 
     //
@@ -2170,5 +2420,6 @@
         // has the same Aspect Ratio than on the screen.
         //
-        ps.NewPage();
+        if (i>from)
+            ps->NewPage();
 
         //
@@ -2176,5 +2427,5 @@
         // such that the page title can be set above the canvas...
         //
-        Float_t psw = 28.0; // A4 - width (29.7)
+        Float_t psw = 28.0; // A4 - width  (29.7)
         Float_t psh = 21.0; // A4 - height (21.0)
 
@@ -2187,5 +2438,5 @@
             psh = ch/cw*psw;
 
-        ps.Range(psw, psh); // A4
+        PSToolsRange(*ps, psw, psh);
 
         //
@@ -2219,13 +2470,13 @@
         // Print overlaying text (NDC = %)
         //
-        ps.SetTextColor(kBlack);
-        ps.SetTextSize(0.015);
-        ps.SetTextFont(22);
-        ps.SetTextAlign(11); // left top
-        ps.TextNDC(0, 1.015, TString("  ")+n->GetName());
-        ps.SetTextAlign(21); // cent top
-        ps.TextNDC(0.5, 1.015, TString("MARS - Magic Analysis and Reconstruction Software - ")+d.AsString());
-        ps.SetTextAlign(31); // right top
-        ps.TextNDC(1, 1.015, MString::Form("Page No.%i (%i)  ", page++, i));
+        ps->SetTextColor(kBlack);
+        ps->SetTextSize(0.015);
+        ps->SetTextFont(22);
+        ps->SetTextAlign(11); // left top
+        PSToolsTextNDC(*ps, 0, 1.015, TString("  ")+n->GetName());
+        ps->SetTextAlign(21); // cent top
+        PSToolsTextNDC(*ps, 0.5, 1.015, TString("MARS - Magic Analysis and Reconstruction Software - ")+d.AsString());
+        ps->SetTextAlign(31); // right top
+        PSToolsTextNDC(*ps, 1, 1.015, MString::Form("Page No.%i (%i)  ", page++, i));
         line.PaintLineNDC(0, 1.01, 1, 1.01);
 
@@ -2234,8 +2485,8 @@
         {
             line.PaintLineNDC(0, -0.00, 1, -0.00);
-            ps.SetTextAlign(11); // left top
-            ps.TextNDC(0, -0.015, TString("  ")+txt);
-            ps.SetTextAlign(31); // right top
-            ps.TextNDC(1, -0.015, "(c) 2000-2004, Thomas Bretz  ");
+            ps->SetTextAlign(11); // left top
+            PSToolsTextNDC(*ps, 0, -0.015, TString("  ")+txt);
+            ps->SetTextAlign(31); // right top
+            PSToolsTextNDC(*ps, 1, -0.015, "(c) 2000-2005, Thomas Bretz  ");
         }
 
@@ -2250,13 +2501,17 @@
     l.Delete();
 
-    ps.Close();
-
-    SetStatusLine2("Updating header of PS file...");
-
-    if (num<0)
-        *fLog << " - Updating header of PS file... " << flush;
-    UpdatePSHeader(name);
-    if (num<0)
-        *fLog << inf << "done." << endl;
+    ps->Close();
+    delete ps;
+
+    if (type==1)
+    {
+        SetStatusLine2("Updating header of PS file...");
+
+        if (num<0)
+            *fLog << " - Updating header of PS file... " << flush;
+        UpdatePSHeader(name);
+        if (num<0)
+            *fLog << inf << "done." << endl;
+    }
 
     gVirtualPS = psave;
@@ -2274,4 +2529,5 @@
 Bool_t MStatusDisplay::SaveAsImage(Int_t num, TString name, TImage::EImageFileTypes type)
 {
+//#if ROOT_VERSION_CODE < ROOT_VERSION(4,04,00)
     if (gROOT->IsBatch())
     {
@@ -2280,5 +2536,6 @@
         return 0;
     }
-    //SetStatusLine1("Writing GIF file...");
+//#endif
+
     SetStatusLine1("Writing image file... <please be patient>");
     SetStatusLine2("");
@@ -2306,6 +2563,9 @@
         ext = AddExtension(name, "jpg", num);
         break;
-//    case TImage::kXcf:
-//        ext = AddExtension(name, "xcf", num);
+    case TImage::kGif:
+        ext = AddExtension(name, "gif", num);
+        break;
+//    case TImage::kTiff:
+//        ext = AddExtension(name, "tiff", num);
 //        break;
 //    case TImage::kPpm:
@@ -2315,7 +2575,4 @@
 //        ext = AddExtension(name, "pnm", num);
 //        break;
-//    case TImage::kBmp:
-//        ext = AddExtension(name, "bmp", num);
-//        break;
 //    case TImage::kIco:
 //        ext = AddExtension(name, "ico", num);
@@ -2324,9 +2581,9 @@
 //        ext = AddExtension(name, "cur", num);
 //        break;
-    case TImage::kGif:
-        ext = AddExtension(name, "gif", num);
-        break;
-//    case TImage::kTiff:
-//        ext = AddExtension(name, "tif", num);
+//    case TImage::kBmp:
+//        ext = AddExtension(name, "bmp", num);
+//        break;
+//    case TImage::kXcf:
+//        ext = AddExtension(name, "xcf", num);
 //        break;
 //    case TImage::kXbm:
@@ -2397,5 +2654,7 @@
         *fLog << "..." << flush;
 
+#if ROOT_VERSION_CODE < ROOT_VERSION(4,04,00)
         c->Draw();
+
         if (type==TImage::kGif)
             c->SaveAs(writename); // FIXME: Seems not to work well in TImage! (root 3.10/02)
@@ -2407,5 +2666,7 @@
             delete img;
         }
-
+#else
+        c->Print(writename);
+#endif
         if (num<0)
             *fLog << "done." << endl;
@@ -2535,4 +2796,25 @@
 // --------------------------------------------------------------------------
 //
+// Determin File type to save file as by extension. Allowed extensions are:
+//   root, ps, pdf, svg, gif, png, jpg, xpm, C
+//
+// returns -1 if file type is unknown. Otherwise return value of SaveAs*
+//
+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(".jpg"))  return SaveAsJPG(num, name);
+    if (name.EndsWith(".xpm"))  return SaveAsXPM(num, name);
+    if (name.EndsWith(".C"))    return SaveAsC(num, name);
+    return -1;
+}
+
+// --------------------------------------------------------------------------
+//
 //  Opens a save as dialog
 //
@@ -2542,5 +2824,11 @@
     {
         "PostScript",   "*.ps",
+        "Acrobat pdf",  "*.pdf",
+        "SVG vector",   "*.svg",
         "Gif files",    "*.gif",
+        "Png files",    "*.png",
+        "Gif files",    "*.gif",
+        "Jpeg files",   "*.jpeg",
+        "Xpm files",    "*.xpm",
         "Macro files",  "*.C",
         "ROOT files",   "*.root",
@@ -2563,10 +2851,7 @@
     dir = fi.fIniDir;
 
-    const TString name(fi.fFilename);
-
-    if (name.EndsWith(".root")) return SaveAsRoot(num, name);
-    if (name.EndsWith(".ps"))   return SaveAsPS(num, name);
-    if (name.EndsWith(".gif"))  return SaveAsGIF(num, name);
-    if (name.EndsWith(".C"))    return SaveAsC(num, name);
+    const Int_t rc = SaveAs(num, fi.fFilename);
+    if (rc>=0)
+        return rc;
 
     Warning("MStatusDisplay::SaveAs", "Unknown Extension: %s", fi.fFilename);
Index: trunk/MagicSoft/Mars/mbase/MStatusDisplay.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 7000)
+++ trunk/MagicSoft/Mars/mbase/MStatusDisplay.h	(revision 7001)
@@ -26,4 +26,5 @@
 class TMutex;
 class TCanvas;
+class TVirtualPS;
 
 class TGTab;
@@ -42,13 +43,17 @@
     typedef enum {
         // kFile
-        kFileBrowser, kFileCanvas, kFileOpen, kFileSave, kFileSaveAs, kFileSaveAsPS,
-        kFileSaveAsRoot, kFileSaveAsPNG, kFileSaveAsGIF, kFileSaveAsJPG,
-        kFileSaveAsXPM, kFileSaveAsC, kFilePrint, kFilePrinterName,
+        kFileBrowser, kFileCanvas, kFileOpen, kFileSave, kFileSaveAs,
+        kFileSaveAsPS, kFileSaveAsPDF, kFileSaveAsSVG, kFileSaveAsRoot,
+        kFileSaveAsPNG, kFileSaveAsGIF, kFileSaveAsJPG, kFileSaveAsXPM,
+        /*kFileSaveAsBMP, kFileSaveAsXCF, kFileSaveAsTIFF,*/
+        kFileSaveAsC, kFilePrint, kFilePrinterName,
         kFileClose, kFileExit, kFileReset,
         // kLoop
         kLoopNone, kLoopStop,
         // kTab
-        kTabSave, kTabSaveAs, kTabSaveAsPS, kTabSaveAsRoot, kTabSaveAsPNG,
-        kTabSaveAsGIF, kTabSaveAsJPG, kTabSaveAsXPM, kTabSaveAsC,
+        kTabSave, kTabSaveAs, kTabSaveAsPS, kTabSaveAsPDF, kTabSaveAsSVG,
+        kTabSaveAsRoot, kTabSaveAsPNG, kTabSaveAsGIF, kTabSaveAsJPG,
+        kTabSaveAsXPM, /*kTabSaveAsBMP, kTabSaveAsXCF, kTabSaveAsTIFF,*/
+        kTabSaveAsC,
         kTabPrint, kTabNext, kTabPrevious, kTabRemove,
         // kSize
@@ -57,4 +62,5 @@
         // kLog
         kLogCopy, kLogClear, kLogSelect, kLogFind, kLogSave, kLogAppend,
+        kLogPrint,
         // kPic
         kPicMagic, kPicMars,
@@ -91,6 +97,4 @@
 
     Status_t fStatus;
-
-    TString fPrinter;
 
     Int_t fLogIdx;
@@ -134,5 +138,5 @@
     Bool_t Display(const TObjArray &list, const char *tab=0);
 
-    const TString &AddExtension(TString &name, const TString &ext, Int_t num) const;
+    const TString &AddExtension(TString &name, const TString &ext, Int_t num=-1) const;
 
     void UpdatePSHeader(const TString &name) const;
@@ -144,4 +148,10 @@
 
     Bool_t SaveAsImage(Int_t num, TString name, TImage::EImageFileTypes type);
+    Int_t  SaveAsVGF(Int_t num, TString name, const TString addon, const TString ext);
+
+    void PSToolsRange(TVirtualPS &vps, Float_t w, Float_t h) const;
+    void PSToolsTextNDC(TVirtualPS &vps, Double_t u, Double_t v, const char *string) const;
+    TString PrintDialog(TString &p, TString &c, TString &t, const char *ext=0);
+
 
 public:
@@ -161,6 +171,4 @@
      void SetStatusLine2(const char *txt) { SetStatusLine(txt, 1); }
      void SetStatusLine2(const MParContainer &cont);
-
-     void SetPrinter(const TString &lpr) { fPrinter = lpr; }
 
      virtual void SetName(const char *name) { fName = name; }
@@ -198,21 +206,35 @@
      void SetNoContextMenu(Bool_t flag=kTRUE);
 
-     Int_t  SaveAsPS(TString name="", const TString addon="") { return SaveAsPS(-1, name, addon); }
-     Bool_t SaveAsPNG(TString name="") { return SaveAsPNG(-1, name); }
-     Bool_t SaveAsGIF(TString name="") { return SaveAsGIF(-1, name); }
-     Bool_t SaveAsXPM(TString name="") { return SaveAsXPM(-1, name); }
-     Bool_t SaveAsJPG(TString name="") { return SaveAsJPG(-1, name); }
-     Bool_t SaveAsC(TString name="") { return SaveAsC(-1, name); }
+     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"); }
+     Int_t  SaveAsSVG(TString name="", const TString addon="") { return SaveAsVGF(-1, name, addon, "svg"); }
+     Bool_t SaveAsPNG(TString name="")  { return SaveAsPNG(-1, name); }
+     Bool_t SaveAsGIF(TString name="")  { return SaveAsGIF(-1, name); }
+     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 SaveAsBMP(TString name="")  { return SaveAsBMP(-1, name); }
+     Bool_t SaveAsC(TString name="")    { return SaveAsC(-1, name); }
      Int_t  SaveAsRoot(TString name="") { return SaveAsRoot(-1, name); }
-     Int_t  PrintToLpr() { return PrintToLpr(-1); }
-
-     Int_t  SaveAsPS(Int_t num, TString name="", const TString addon="");
-     Bool_t SaveAsPNG(Int_t num, TString name="") { return SaveAsImage(num, name, TImage::kPng); }
-     Bool_t SaveAsGIF(Int_t num, TString name="") { return SaveAsImage(num, name, TImage::kGif); }
-     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); }
+     Int_t  SaveAs(TString name)        { return SaveAs(-1, name); }
+     Int_t  PrintPS() { return PrintPS(-1); }
+
+     Int_t  SaveAsPS(Int_t num, TString name="",  const TString addon="") { return SaveAsVGF(num, name, addon, "ps"); }
+     Int_t  SaveAsPDF(Int_t num, TString name="", const TString addon="") { return SaveAsVGF(num, name, addon, "pdf"); }
+     Int_t  SaveAsSVG(Int_t num, TString name="", const TString addon="") { return SaveAsVGF(num, name, addon, "svg"); }
+     Bool_t SaveAsPNG(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kPng); }
+     Bool_t SaveAsGIF(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kGif); }
+     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 SaveAsBMP(Int_t num, TString name="")  { return SaveAsImage(num, name, TImage::kBmp); }
      Bool_t SaveAsC(Int_t num, TString name="");
      Int_t  SaveAsRoot(Int_t num, TString name="");
-     Int_t  PrintToLpr(Int_t num);
+     Int_t  SaveAs(Int_t num, TString name);
+     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;
 
      Int_t  SaveAs(Int_t num=-1);
