Index: trunk/MagicSoft/Mars/mbase/BaseLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/BaseLinkDef.h	(revision 2173)
+++ trunk/MagicSoft/Mars/mbase/BaseLinkDef.h	(revision 2178)
@@ -16,4 +16,5 @@
 
 #pragma link C++ class MIter+;
+#pragma link C++ class MDirIter+;
 
 #pragma link C++ class MTask+;
Index: trunk/MagicSoft/Mars/mbase/MDirIter.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MDirIter.cc	(revision 2178)
+++ trunk/MagicSoft/Mars/mbase/MDirIter.cc	(revision 2178)
@@ -0,0 +1,312 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz, 6/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2003
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  MDirIter
+//
+// Iterator for files in several directories (with filters)
+//
+// Use this class if you want to get all filenames in a directory
+// one-by-one.
+//
+// You can specify more than one directory (also recursivly) and you
+// can use filters (eg. *.root)
+//
+// Here is an example which will print all *.root files in the current
+// directory and all its subdirectories and all Gamma*.root files in
+// the directory ../data.
+//
+// ------------------------------------------------------------------------
+//
+//  // Instatiate the iterator
+//  MDirIter Next();
+//
+//  // Add the current directory (for *.root files) and recursive
+//  // directories with the same filter
+//  Next.AddDirectory(".", "*.root", kTRUE);
+//  // Add the directory ../data, too (filter only Gamma*.root files)
+//  Next.AddDirectory("../data", "Gamma*.root");
+//
+//  TString name;
+//  while (!(name=Next()).IsNull())
+//     cout << name << endl;
+//
+// ------------------------------------------------------------------------
+//
+// WARNING: If you specify relative directories (like in the example) the
+//          result may depend on the current working directory! Better use
+//          absolute paths.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MDirIter.h"
+
+#include <iostream>
+
+#include <TNamed.h>
+#include <TRegexp.h>
+#include <TSystem.h>
+
+ClassImp(MDirIter);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+//  Add a directory, eg dir="../data"
+//  Using a filter (wildcards) will only return files matching this filter.
+//  recursive is the number of recursive directories (use 0 for none and -1
+//  for all)
+//  Returns the number of directories added.
+//  If a directory is added using a filter and the directory is already
+//  existing without a filter the filter is replaced.
+//  If any directory to be added is already existing with a different
+//  filter a new entry is created, eg:
+//   already existing:  ../data <*.root>
+//   new entry:         ../data <G*>
+//  The filters are or'ed.
+//
+Int_t MDirIter::AddDirectory(const char *d, const char *filter, Int_t recursive)
+{
+    TString dir = d;
+
+    // Sanity check
+    if (dir.IsNull())
+        return 0;
+
+#if ROOT_VERSION_CODE < ROOT_VERSION(3,05,05)
+    if (dir[dir.Length()-1]!='/')
+        dir += '/';
+#else
+    if (!dir.EndsWith("/"))
+        dir += '/';
+#endif
+    gSystem->ExpandPathName(dir);
+
+    // Try to find dir in the list of existing dirs
+    TObject *o = fList.FindObject(dir);
+    if (o)
+    {
+        const TString t(o->GetTitle());
+
+        // Check whether the existing dir has an associated filter
+        if (t.IsNull())
+        {
+            // Replace old filter by new one
+            ((TNamed*)o)->SetTitle(filter);
+            return 0;
+        }
+
+        // If the filters are the same no action is taken
+        if (t==filter)
+            return 0;
+    }
+
+    fList.Add(new TNamed((const char*)dir, filter ? filter : ""));
+
+    // No recuresive directories, return
+    if (recursive==0)
+        return 1;
+
+    Int_t rc = 1;
+
+    // Create an iterator to iterate over all entries in the directory
+    MDirIter Next(dir);
+
+    TString c;
+    while (!(c=Next(kTRUE)).IsNull())
+    {
+        // Do not process . and .. entries
+        if (c.EndsWith("/.") || c.EndsWith("/.."))
+            continue;
+
+        // If entry is a directory add it with a lowere recursivity
+        if (IsDir(c)==0)
+            rc += AddDirectory(c, filter, recursive-1);
+    }
+    return rc;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return the pointer to the current directory. If the pointer is NULL
+//  a new directory is opened. If no new directory can be opened NULL is
+//  returned.
+//
+void *MDirIter::Open()
+{
+    // Check whether a directory is already open
+    if (fDirPtr)
+        return fDirPtr;
+
+    // Get Next entry of list
+    fCurrentPath=fNext();
+
+    // Open directory if new entry was found
+    return fCurrentPath ? gSystem->OpenDirectory(fCurrentPath->GetName()) : NULL;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Close directory is opened. Set fDirPtr=NULL
+//
+void MDirIter::Close()
+{
+    if (fDirPtr)
+        gSystem->FreeDirectory(fDirPtr);
+    fDirPtr = NULL;
+}
+
+TString MDirIter::ConcatFileName(const char *dir, const char *name) const
+{
+    return TString(dir)+name;
+}
+
+// --------------------------------------------------------------------------
+//
+// Check whether the given name n matches the filter f.
+// Filters are of the form TRegexp(f, kTRUE)
+//
+Bool_t MDirIter::MatchFilter(const TString &n, const TString &f) const
+{
+    return f.IsNull() || !n(TRegexp(f, kTRUE)).IsNull();
+}
+
+// --------------------------------------------------------------------------
+//
+// Check whether fqp is a directory.
+// Returns -1 if fqp couldn't be accesed, 0 if it is a directory,
+// 1 otherwise
+//
+Int_t MDirIter::IsDir(const char *fqp) const
+{
+    Long_t t[4];
+    if (gSystem->GetPathInfo(fqp, t, t+1, t+2, t+3))
+        return -1;
+
+    if (t[2]==3)
+        return 0;
+
+    return 1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Check whether the current entry in the directory n is valid or not.
+// Entries must:
+//  - not be . or ..
+//  - match the associated filter
+//  - match the global filter
+//  - not be a directory
+//  - have read permission
+//
+Bool_t MDirIter::Check(const TString n) const
+{
+    // Check . and ..
+    if (n=="." || n=="..")
+        return kFALSE;
+
+    // Check associated filter
+    if (!MatchFilter(n, fCurrentPath->GetTitle()))
+        return kFALSE;
+
+    // Check global filter
+    if (!MatchFilter(n, fFilter))
+        return kFALSE;
+
+    // Check for file or directory
+    const TString fqp = ConcatFileName(fCurrentPath->GetName(), n);
+    if (IsDir(fqp)<=0)
+        return kFALSE;
+
+    // Check for rread perissions
+    return !gSystem->AccessPathName(fqp, kReadPermission);
+}
+
+// --------------------------------------------------------------------------
+//
+// Return the Next file in the directory which is valid (see Check())
+// nocheck==1 returns the next entry unchecked
+//
+TString MDirIter::Next(Bool_t nocheck)
+{
+    fDirPtr = Open();
+    if (!fDirPtr)
+        return "";
+
+    // Get next entry in dir, if existing check validity
+    const char *n = gSystem->GetDirEntry(fDirPtr);
+    if (n)
+        return nocheck || Check(n) ? ConcatFileName(fCurrentPath->GetName(), n) : Next();
+
+    // Otherwise close directory and try to get next entry
+    Close();
+    return Next();
+}
+
+// --------------------------------------------------------------------------
+//
+// Print a single entry in the list
+//
+void MDirIter::PrintEntry(const TObject &o) const
+{
+    TString p = o.GetName();
+    TString f = o.GetTitle();
+    cout << p;
+    if (!f.IsNull())
+        cout << " <" << f << ">";
+    cout << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Print all scheduled directories. If "all" is specified also all
+// matching entries are printed.
+//
+void MDirIter::Print(const Option_t *o)
+{
+    TString s(o);
+    if (!s.Contains("all", TString::kIgnoreCase))
+    {
+        TIter Next(&fList);
+        TObject *o=NULL;
+        while ((o=Next()))
+            PrintEntry(*o);
+        return;
+    }
+
+    MDirIter Next(*this);
+    TString name;
+    TString d;
+    while (!(name=Next()).IsNull())
+    {
+        const TString p = Next.fCurrentPath->GetName();
+        if (p!=d)
+        {
+            d=p;
+            PrintEntry(*Next.fCurrentPath);
+        }
+        cout << " " << name << endl;
+    }
+}
Index: trunk/MagicSoft/Mars/mbase/MDirIter.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MDirIter.h	(revision 2178)
+++ trunk/MagicSoft/Mars/mbase/MDirIter.h	(revision 2178)
@@ -0,0 +1,67 @@
+#ifndef MARS_MDirIter
+#define MARS_MDirIter
+
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
+#endif
+
+class MDirIter : public TObject
+{
+private:
+    TObjArray fList;
+    TString   fFilter;
+
+    TIter     fNext;        //!
+    void     *fDirPtr;      //!
+    TObject  *fCurrentPath; //!
+
+    void   *Open();
+    void    Close();
+    Bool_t  Check(const TString n) const;
+    Int_t   IsDir(const char *dir) const;
+    Bool_t  MatchFilter(const TString &n, const TString &n) const;
+    TString ConcatFileName(const char *dir, const char *name) const;
+    void    PrintEntry(const TObject &o) const;
+
+public:
+    MDirIter() : fNext(&fList), fDirPtr(NULL)
+    {
+        fList.SetOwner();
+    }
+    MDirIter(MDirIter &dir) : fNext(&fList), fDirPtr(NULL)
+    {
+        fList.SetOwner();
+
+        TObject *o=NULL;
+        TIter Next(&dir.fList);
+        while ((o=Next()))
+            AddDirectory(o->GetName(), o->GetTitle());
+    }
+    MDirIter(const char *dir, const char *filter="") : fNext(&fList), fDirPtr(NULL)
+    {
+        fList.SetOwner();
+        AddDirectory(dir, filter);
+    }
+    ~MDirIter()
+    {
+        Close();
+    }
+
+    Int_t AddDirectory(const char *dir, const char *filter="", Int_t recursive=0);
+    void  Reset()
+    {
+        Close();
+        fNext.Reset();
+    }
+
+    TString Next(Bool_t nocheck=kFALSE);
+    TString operator()(Bool_t nocheck=kFALSE) { return Next(nocheck); }
+
+    void SetFilter(const char *f="") { fFilter = f; }
+
+    void Print(const Option_t *o="");
+
+    ClassDef(MDirIter, 1) // Iterator for files in several directories (with filters)
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mbase/MParList.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 2173)
+++ trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 2178)
@@ -472,5 +472,7 @@
     if (!pcont)
     {
-        *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "' (Maybe no def. constructor)" << endl;
+        *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "' Possible reasons:" << endl;
+        *fLog << " - Class has no default constructor." << endl;
+        *fLog << " - An abstract member functions of a base class is not overwritten." << endl;
         return NULL;
     }
Index: trunk/MagicSoft/Mars/mbase/MTaskInteractive.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MTaskInteractive.cc	(revision 2173)
+++ trunk/MagicSoft/Mars/mbase/MTaskInteractive.cc	(revision 2178)
@@ -26,4 +26,12 @@
 //
 // MTaskInteractive
+//
+// If you want to create a new task inside a macro you will have to compile
+// your macro using macro.C++, because the root interpreter cannot use
+// uncompiled classes. To workaround this problem you can write simple
+// funcions (which can be handled by CINT) and use MTaskInteractive.
+//
+// This is a simple way to develop new code in a macro without need
+// to compile it.
 //
 //  Input Containers:
@@ -77,5 +85,7 @@
 
     Long_t result;
-    fCall[no]->Execute(params, result);
+    fCall[no]->SetParamPtrs(params);
+    fCall[no]->Execute(result);
+
     return result;
 }
Index: trunk/MagicSoft/Mars/mbase/MTaskList.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MTaskList.cc	(revision 2173)
+++ trunk/MagicSoft/Mars/mbase/MTaskList.cc	(revision 2178)
@@ -60,4 +60,5 @@
 
 #include <TClass.h>
+#include <TSystem.h>        // gSystem
 #include <TOrdCollection.h>
 
@@ -365,4 +366,7 @@
 
         case kTRUE:
+            // Handle GUI events (display changes, mouse clicks)
+            if (fDisplay)
+                gSystem->ProcessEvents();
             continue;
 
@@ -461,4 +465,5 @@
             //
             rc = kFALSE;
+            *fLog << inf << task->GetDescriptor() << " has stopped execution of " << GetDescriptor() << "." << endl;
             break;
 
@@ -531,4 +536,8 @@
         if (!task->CallPostProcess())
             return kFALSE;
+
+        // Handle GUI events (display changes, mouse clicks)
+        if (fDisplay)
+            gSystem->ProcessEvents();
     }
 
Index: trunk/MagicSoft/Mars/mbase/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mbase/Makefile	(revision 2173)
+++ trunk/MagicSoft/Mars/mbase/Makefile	(revision 2178)
@@ -43,4 +43,5 @@
            MEvtLoop.cc \
            MIter.cc \
+           MDirIter.cc \
            MGList.cc \
            MGTask.cc \
