ROOT logo
// @(#)root/gui:$Id: TRecorder.h 29094 2009-06-19 10:02:24Z bellenot $
// Author: Katerina Opocenska   11/09/2008

/*************************************************************************
* Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#ifndef ROOT_TRecorder
#define ROOT_TRecorder

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  ROOT EVENT RECORDING SYSTEM                                         //
// ==================================================================   //
//                                                                      //
//  TRecorder class provides interface for recording and replaying      //
//  events in ROOT.                                                     //
//  Recorded events are:                                                //
//  - Commands typed by user in commandline ('new TCanvas')             //
//  - GUI events (mouse movement, button clicks, ...)                   //
//                                                                      //
//  All the recorded events from one session are stored in one TFile    //
//  and can be replayed again anytime.                                  //
//                                                                      //
//  Recording                                                           //
//  ==================================================================  //
//                                                                      //
//  1] To start recording                                               //
//                                                                      //
//    TRecorder r(const char *filename, "NEW")                          //
//    TRecorder r(const char *filename, "RECREATE")                     //
//                                                                      //
//    or:                                                               //
//                                                                      //
//    TRecorder *recorder = new TRecorder;                              //
//    recorder->Start(const char *filename, ...)                        //
//                                                                      //
//    -filename      Name of ROOT file in which to save                 //
//                   recorded events.                                   //
//                                                                      //
//  2] To stop recording                                                //
//                                                                      //
//    recorder->Stop()                                                  //
//                                                                      //
//                                                                      //
//  IMPORTANT:                                                          //
//  State capturing is part of recording. It means that if you want to  //
//  record events for some object (window), creation of this object     //
//  must be also recorded.                                              //
//                                                                      //
//    Example:                                                          //
//    --------                                                          //
//    t = new TRecorder();          // Create a new recorder            //
//    t->Start("logfile.root");     // ! Start recording first          //
//                                                                      //
//    c = new TCanvas();            // ! Then, create an object         //
//    c->Dump();                    // Work with that object            //
//                                                                      //
//    t->Stop();                    // Stop recording                   //
//                                                                      //
//  It is strongly recommended to start recording with empty ROOT       //
//  environment, at least with no previously created ROOT GUI.          //
//  This ensures that only events for well known windows are stored.    //
//  Events for windows, which were not created during recording,        //
//  cannot be replayed.                                                 //
//                                                                      //
//  Replaying                                                           //
//  =================================================================== //
//                                                                      //
//  1] To start replaying                                               //
//                                                                      //
//    TRecorder r(const char *filename)                                 //
//    TRecorder r(const char *filename, "READ")                         //
//                                                                      //
//    or:                                                               //
//                                                                      //
//    TRecorder *recorder = new TRecorder;                              //
//    recorder->Replay(const char *filename,                            //
//                      Bool_t showMouseCursor = kTRUE);                //
//                                                                      //
//    -filename         A name of file with recorded events             //
//                      previously created with TRecorder::Start        //
//                                                                      //
//    -showMouseCursor  If kTRUE, mouse cursor is replayed as well.     //
//                      In that case it is not recommended to use mouse //
//                      during replaying.                               //
//                                                                      //
//  In general, it is not recommended to use mouse to change positions  //
//  and states of ROOT windows during replaying.                        //
//                                                                      //
//  IMPORTANT:                                                          //
//  The state of ROOT environment before replaying of some events       //
//  must be exactly the same as before recording them.                  //
//  Therefore it is strongly recommended to start both recording        //
//  and replaying with empty ROOT environment.                          //
//                                                                      //
//  2] To pause replaying                                               //
//                                                                      //
//    recorder->Pause()                                                 //
//                                                                      //
//    Replaying is stopped until recorder->Resume() is called.          //
//                                                                      //
//                                                                      //
//  3] To resume paused replaying                                       //
//                                                                      //
//    recorder->Resume()                                                //
//                                                                      //
//    Resumes previously stopped replaying.                             //
//                                                                      //
//                                                                      //
//  4] To stop replaying before its end                                 //
//                                                                      //
//    recorder->Stop()                                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_Riostream
#include "Riostream.h"
#endif
#ifndef ROOT_TApplication
#include "TApplication.h"
#endif
#ifndef ROOT_TError
#include "TError.h"
#endif
#ifndef ROOT_TTimer
#include "TTimer.h"
#endif
#ifndef ROOT_TGClient
#include "TGClient.h"
#endif
#ifndef ROOT_TGFrame
#include "TGFrame.h"
#endif
#ifndef ROOT_TCanvas
#include "TCanvas.h"
#endif
#ifndef ROOT_THashList
#include "THashList.h"
#endif

#include <time.h>

class TMutex;
class TTree;
class TFile;
class TGPictureButton;
class TGCheckButton;
class TGLabel;
class TRecorderState;

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecEvent                                                           //
//                                                                      //
//  Abstract class that defines interface for a class storing           //
//  information about 1 ROOT event.                                     //
//  Time of event is stored and this event can be replayed.             //
//  Classes TRecCmdEvent and TRecGuiEvent implements this interface     //
//  for command line and GUI events respectively.                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TRecEvent : public TObject
{
private:
   TTime   fEventTime;          // Time of original event execution

public:
   //---- Types of events recorded in ROOT.
   enum ERecEventType {
      kCmdEvent,     // Commandline event
      kGuiEvent,    // GUI event
      kExtraEvent
   };

   // Replays (executes) the stored event again
   virtual void ReplayEvent(Bool_t showMouseCursor = kTRUE) = 0;

   // Returns what kind of event it stores
   virtual ERecEventType GetType() const = 0;

   virtual TTime GetTime() const {
      // Returns time of original execution of stored event
      return fEventTime;
   }

   virtual void SetTime(TTime t) {
      // Sets time of event execution
      fEventTime = t;
   }

   ClassDef(TRecEvent,1) // Abstract class. Defines basic interface for storing information about ROOT events
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecCmdEvent                                                        //
//                                                                      //
//  Class used for storing information about 1 commandline event.       //
//  It means 1 command typed in by user in the commandline,             //
//  e.g 'new TCanvas'.                                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TRecCmdEvent : public TRecEvent
{
private:
   TString fText;             // Text of stored command

public:
   TRecCmdEvent() {
      // Creates new empty  TRecCmdEvent
   }

   void SetText(const char *text) {
      // Saves text of a command
      fText = text;
   }

   const char *GetText() const {
      // Returns stored text of the command
      return fText.Data();
   }

   virtual ERecEventType GetType() const {
      // Returns what kind of event it stores (commandline event)
      return TRecEvent::kCmdEvent;
   }

   virtual void ReplayEvent(Bool_t) {
      // Stored command is executed again
      cout << GetText() << endl;
      gApplication->ProcessLine(GetText());
   }

   ClassDef(TRecCmdEvent,1) // Class stores information about 1 commandline event (= 1 command typed by user in commandline)
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecExtraEvent                                                      //
//                                                                      //
//  Class used for storing information about 1 extra event.             //
//  It means 1 TPaveLabel or 1 TLatex event produced in the Canvas      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecExtraEvent : public TRecEvent
{
private:
   TString fText;             // Text of stored command

public:
   TRecExtraEvent() {
      // Creates new empty  TRecExtraEvent
   }

   void SetText(TString text) {
      // Saves text of a command (PaveLabel or Text)
      fText = text;
   }

   TString GetText() const {
      // Returns stored text of the command
      return fText;
   }

   virtual ERecEventType GetType() const {
      // Returns what kind of event it stores (Especial event)
      return TRecEvent::kExtraEvent;
   }

   virtual void ReplayEvent(Bool_t) {
      // Stored event is executed again

      gApplication->ProcessLine(GetText());
   }

   ClassDef(TRecExtraEvent,1) // Class stores information about extra events
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecGuiEvent                                                        //
//                                                                      //
//  Class used for storing information about 1 GUI event in ROOT.       //
//  For list of possible GUI events see EGEventType.                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TRecGuiEvent : public TRecEvent
{
protected:
   friend class TRecorderInactive;
   friend class TRecorderPaused;
   friend class TRecorderRecording;
   friend class TRecorderReplaying;

   EGEventType    fType;            // Type of event (see EGEventType)
   Window_t       fWindow;          // Window ID which reported event is relative to
   Time_t         fTime;            // Time event occured in ms
   Int_t          fX;               // Pointer x coordinate in event window
   Int_t          fY;               // Pointer y coordinate in event window
   Int_t          fXRoot;           // x coordinate relative to root
   Int_t          fYRoot;           // y coordinate relative to root
   UInt_t         fCode;            // Key or button code
   UInt_t         fState;           // Key or button mask
   UInt_t         fWidth;           // Width of exposed area
   UInt_t         fHeight;          // Height of exposed area
   Int_t          fCount;           // If non-zero, at least this many more exposes
   Bool_t         fSendEvent;       // True if event came from SendEvent
   Handle_t       fHandle;          // General resource handle (used for atoms or windows)
   Int_t          fFormat;          // Next fields only used by kClientMessageEvent
   Long_t         fUser[5];         // 5 longs can be used by client message events
                                    // NOTE: only [0], [1] and [2] may be used.
                                    // [1] and [2] may contain > 32 bit quantities
                                    // (i.e. pointers on 64 bit machines)
   Window_t       fMasked;          // If non-zero, event recorded in HandleMaskEvent()

public:
   //---- Types of kConfigureNotify GUI event
   enum EConfigureNotifyType {
      kCNMove       = 0,      // Movement of a window (Linux)
      kCNResize     = 1,      // Resize of a window (Linux)
      kCNMoveResize = 2,      // Movement, resize or both (Windows)
      kCNFilter     = 3       // Not replaybale (filtered event).
   };

   virtual ERecEventType GetType() const {
      // Returns what kind of event it stores (GUI event)
      return TRecEvent::kGuiEvent;
   }

   virtual void    ReplayEvent(Bool_t showMouseCursor = kTRUE);
   static Event_t *CreateEvent(TRecGuiEvent *ge);

   ClassDef(TRecGuiEvent,1) // Class stores information about 1 GUI event in ROOT
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecWinPair                                                         //
//                                                                      //
//  Class used for storing of window IDs mapping.                       //
//  Remapping of window IDs is needed for replaying events.             //
//  - ID of original window is stored in fKey.                          //
//  - ID of a new window is stored in fValue.                           //
//                                                                      //
//  Whenever an event is replayed, its referenced window ID is changed  //
//  from original to a new one according to the appropriate mapping.    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TRecWinPair : public TObject
{
protected:
   friend class TRecorderReplaying;

   Window_t    fKey;    // ID of original window (for which an event was originally recorded)
   Window_t    fValue;  // ID of a new window (for which an event is being replayed)

public:
   // Creates a new key-value mapping of window IDs
   TRecWinPair(Window_t key, Window_t value): fKey(key), fValue(value) {}

   ClassDef(TRecWinPair,1) // Class used for storing of window IDs mapping. Needed for replaying events.
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorder                                                           //
//                                                                      //
//  Class provides direct recorder/replayer interface for a user.       //
//  See 'ROOT EVENT RECORDING SYSTEM' for more information abou usage.  //
//                                                                      //
//  Implementation uses C++ design pattern State. Funcionality of       //
//  recorder is divided into 4 classes according to the current         //
//  state of recorder.                                                  //
//                                                                      //
//  Internally, there is a pointer to TRecorderState object.            //
//  This object changes whenever state of recorder is changed.          //
//  States of recorder are the following:                               //
//                                                                      //
//  - INACTIVE  Implemented in TRecorderInactive class.                 //
//              Default state after TRecorder object is created.        //
//                                                                      //
//  - RECORDING Implemented in TRecorderRecording class.                //
//                                                                      //
//  - REPLAYING Implemented in TRecorderReplaying class.                //
//                                                                      //
//  - PAUSED    Implemented in TRecorderPause class.                    //
//              Pause of replaying.                                     //
//                                                                      //
//  Every command for TRecorder is just passed                          //
//  to TRecordeState object.                                            //
//  Depending on the current state of recorder, this command is passed  //
//  to some of the above mentioned classes and if valid, handled there. //
//                                                                      //
//  [TRecorder.JPG]                                                     //
//                                                                      //
//  Switching between states is not possible from outside. States are   //
//  switched directly by state objects via:                             //
//                                                                      //
//  ChangeState(TRecorderState* newstate, Bool_t deletePreviousState);  //
//                                                                      //
//  When recorder is switched to a new state, the old state object is   //
//  typically deleted. The only exception is switching from REPLAYING   //
//  state to PAUSED state. The previous state (REPLAYING) is not        //
//  deleted in order to be used again after TRecorder::Resume call.     //
//                                                                      //
//  STATE TRANSITIONS:                                                  //
//  ------------------                                                  //
//                                                                      //
//  INACTIVE  -> RECORDING via TRecorder::Start (Starts recording)      //
//  RECORDING -> INACTIVE  via TRecorder::Stop  (Stops recording)       //
//                                                                      //
//  INACTIVE  -> REPLAYING via TRecorder::Replay     (Starts replaying) //
//  REPLAYING -> INACTIVE  via TRecorder::ReplayStop (Stops replaying)  //
//                                                                      //
//  REPLAYING -> PAUSED    via TRecorder::Pause  (Pause replaying)      //
//  PAUSED    -> REPLAYING via TRecorder::Resume (Resumes replaying)    //
//                                                                      //
//  PAUSED    -> INACTIVE  via TRecorder::ReplayStop (Stops paused      //
//                                                    replaying)        //
//                                                                      //
// [TRecorderStates.JPG]                                                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorder : public TObject
{
private:
   TRecorderState *fRecorderState;   //! Current state of recorder

protected:
   friend class TRecorderState;
   friend class TRecorderInactive;
   friend class TRecorderPaused;
   friend class TRecorderRecording;
   friend class TRecorderReplaying;

   TString      fFilename;           // Events file name 
   // Changes state to the new one.
   // See class documentation for information about state changing.
   void  ChangeState(TRecorderState* newstate, Bool_t deletePreviousState = kTRUE);

public:
   //---- Modes of replaying. Only kRealtime implemented so far
   enum EReplayModes {
      kRealtime
   };
   //---- States of recorder. In every moment, recorder is in right
   // one of these states.
   enum ERecorderState {
      kInactive,
      kRecording,
      kPaused,
      kReplaying
   };

   // Creates recorder and sets its state as INACTIVE
   TRecorder();
   TRecorder(const char *filename, Option_t *option = "READ");

   // Deletes recorder together with its current state
   virtual ~TRecorder();

   void Browse(TBrowser *);

   // Starts recording of events to the given file
   void Start(const char *filename, Option_t *option = "RECREATE", Window_t *w = 0, Int_t winCount = 0);

   // Stops recording of events
   void Stop(Bool_t guiCommand = kFALSE);

   // Replays recorded events from given file
   Bool_t Replay(const char *filename, Bool_t showMouseCursor = kTRUE, TRecorder::EReplayModes mode = kRealtime);

   // Replays recorded events from current file
   void Replay() { Replay(fFilename); }   // *MENU*

   // Pauses replaying
   void Pause();

   // Resumes paused replaying
   void Resume();

   // Stops (cancels) replaying
   void ReplayStop();

   // Prints out the list of recorded commandline events
   void ListCmd(const char *filename);

   // Prints out the list of recorded GUI events
   void ListGui(const char *filename);

   // Gets current state of recorder
   virtual TRecorder::ERecorderState GetState() const;

   // Saves all the canvases previous to the TRecorder
   void PrevCanvases(const char *filename, Option_t *option);

   ClassDef(TRecorder,2) // Class provides direct recorder/replayer interface for a user.
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorderState                                                      //
//                                                                      //
//  Abstract class that defines interface for a state of recorder.      //
//  Inherited classes are:                                              //
//  - TRecorderInactive                                                 //
//  - TRecorderRecording                                                //
//  - TRecorderReplaying                                                //
//  - TRecorderPaused                                                   //
//                                                                      //
//  See TRecorder for more information about creating, using,           //
//  changing and deleting states.                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorderState
{
protected:
   friend class TRecorder;
   void ChangeState(TRecorder *r, TRecorderState *s, Bool_t deletePreviousState) { r->ChangeState(s, deletePreviousState); }

public:
   virtual ~TRecorderState() {}
   virtual void   Start(TRecorder *, const char *, Option_t *, Window_t *, Int_t) {}
   virtual void   Stop(TRecorder *, Bool_t ) {}
   virtual Bool_t Replay(TRecorder *, const char *, Bool_t, TRecorder::EReplayModes) { return false; }
   virtual void   Pause(TRecorder *) {}
   virtual void   Resume(TRecorder *) {}
   virtual void   ReplayStop(TRecorder *) {}

   virtual void   ListCmd(const char *) {}
   virtual void   ListGui(const char *) {}

   virtual void   PrevCanvases(const char *, Option_t *) {}

   virtual TRecorder::ERecorderState GetState() const = 0;

   ClassDef(TRecorderState, 0) // Abstract class that defines interface for a state of recorder
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorderReplaying                                                  //
//                                                                      //
//  Represents state of TRecorder when replaying previously recorded    //
//  events.                                                             //
//                                                                      //
//  Not intended to be used by a user directly.                         //
//  [Replaying.JPG]                                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorderReplaying : public TRecorderState
{
private:
   virtual  ~TRecorderReplaying();
   Bool_t   PrepareNextEvent();
   Bool_t   RemapWindowReferences();
   Bool_t   CanOverlap();

   Bool_t   FilterEvent(TRecGuiEvent *e);

   TRecorder  *fRecorder;  // Reference to recorder (owner of this state) is kept in order to switch
                           // recorder to INACTIVE state after replaying is finished

   TFile      *fFile;      // ROOT file which the recorded events are being read from


   TCanvas    *fCanv;      // Used to record the previous canvases


   TTimer     *fTimer;     // Timer used for replaying

   TTree      *fWinTree;   // TTree with recorded windows (=registered during recording)
   TTree      *fGuiTree;   // TTree with recorded GUI events
   TTree      *fCmdTree;   // TTree with recorded commandline events
   TTree      *fExtraTree; // TTree with recorded extra events (PaveLabels and Texts)

   ULong64_t       fWin;            // Window ID being currenty mapped
   TRecGuiEvent   *fGuiEvent;       // GUI event being currently replayed
   TRecCmdEvent   *fCmdEvent;       // Commandline event being currently replayed
   TRecExtraEvent *fExtraEvent;     // Extra event being currently replayed

   Int_t       fRegWinCounter;      // Counter of registered windows when replaying
   Int_t       fGuiTreeCounter;     // Counter of GUI events that have been replayed
   Int_t       fCmdTreeCounter;     // Counter of commandline events that have been replayed
   Int_t       fExtraTreeCounter;   // Counter of extra events that have been replayed

   Int_t       fWinTreeEntries;     // Number of registered windows during _recording_

   TMutex      *fMutex;

   TList      *fWindowList;         // List of TRecWinPair objects. Mapping of window IDs is stored here.

   TRecEvent  *fNextEvent;          // The next event that is going to be replayed (GUI event or commandline)

   TTime       fPreviousEventTime;  // Execution time of the previously replayed event.
                                          // It is used for computing time difference between two events.

   Bool_t      fWaitingForWindow;   // Signalizes that we wait for a window to be registered in order
                                    // to replay the next event fNextEvent.
                                    // Registraion of windows can last different time when recording and replaying.
                                    // If there is an event ready to be replayed but the corresponding windows has not been yet
                                    // registered, we wait (postopone fNextEvent) until it is registered.

   Bool_t      fEventReplayed;      // Signalizes that the last event sent to the replaying has been already replayed.
                                    // Sometimes an execution of an event can take more time than during recording.
                                    // This ensures that the next event is sent to replaying AFTER
                                    // the replaying of the previous one finishes and not earlier.
                                    // Exceptions: ButtonPress and ButtonRelease events (See TRecorderReplaying::CanBeOverlapped)

   Bool_t      fShowMouseCursor;    // Specifies if mouse cursor should be also replayed

   Bool_t      fFilterStatusBar;    // Special flag to filter status bar element

protected:
   friend class TRecorderInactive;
   friend class TRecorderPaused;

   TRecorderReplaying(const char *filename);
   Bool_t     Initialize(TRecorder *r, Bool_t showMouseCursor, TRecorder::EReplayModes mode);

public:
   virtual TRecorder::ERecorderState GetState() const { return TRecorder::kReplaying; }

   virtual void   Pause(TRecorder *r);
   virtual void   Continue();
   virtual void   ReplayStop(TRecorder *r);

   void           RegisterWindow(Window_t w);   //SLOT
   void           ReplayRealtime();             //SLOT

   ClassDef(TRecorderReplaying, 0) // Represents state of TRecorder when replaying
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorderRecording                                                  //
//                                                                      //
//  Represents state of TRecorder when recording events.                //
//                                                                      //
//  Not intended to be used by a user directly.                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorderRecording: public TRecorderState
{
private:
   virtual ~TRecorderRecording();
   Bool_t  IsFiltered(Window_t id);
   void    SetTypeOfConfigureNotify(Event_t *e);
   void    CopyEvent(Event_t *e, Window_t wid);

   TRecorder          *fRecorder;         // Reference to recorder (owner of this state) is kept in order to switch
                                          // recorder back to INACTIVE state after recording is finished

   TFile              *fFile;             // ROOT file to store recorded events in
   TTimer             *fTimer;            // Timer used for recording
   ULong_t             fBeginPave;        // TLatex/TPaveLabel edition starting time

   TTree              *fWinTree;          // TTree with registered windows
   TTree              *fGuiTree;          // TTree with recorded GUI events
   TTree              *fCmdTree;          // TTree with recorded commandline events
   TTree              *fExtraTree;        // TTree with recorded extra events (PaveLabels and Texts)

   ULong64_t           fWin;              // The newest registered window to be stored in TTree
   TRecGuiEvent       *fGuiEvent;         // The newest GUI event to be stored in TTree
   TRecCmdEvent       *fCmdEvent;         // The newest commandline event to be stored in TTree
   TRecExtraEvent     *fExtraEvent;       // The newest extra event to be stored in TTree

   Bool_t              fCmdEventPending;  // Indication if there is a still pending commandline event that should be stored.
                                          // Commandline events are stored with 1 event delay to ensure skipping
                                          // the last event 'TRecorder::Stop' that is not supposed to be recorded

   Int_t               fRegWinCounter;    // Counter of registered ROOT windows.
                                          // It is increased every time when a new window is registered

   Int_t               fFilteredIdsCount; // Only when GUI for recorder is used: Count of windows in GUI recorder
   Window_t           *fFilteredIds;      // Only when GUI for recorer is used: IDs of windows that creates that GUI.
                                          // Events for GUI recorder are not recorded.
   Bool_t              fFilterEventPave;  // Special flag to filter events during the pave recording

protected:
   friend class TRecorderInactive;
   TRecorderRecording(TRecorder *r, const char *filename, Option_t *option, Window_t *w, Int_t winCount);

   Bool_t StartRecording();

public:
   virtual TRecorder::ERecorderState GetState() const { return TRecorder::kRecording; }

   virtual void Stop(TRecorder *r, Bool_t guiCommand);

   void  RegisterWindow(Window_t w);               //SLOT
   void  RecordCmdEvent(const char* line);         //SLOT
   void  RecordGuiEvent(Event_t* e, Window_t wid); //SLOT
   void  RecordGuiCNEvent(Event_t* e);             //SLOT
   void  RecordPave(const TObject* obj);           //SLOT
   void  RecordText(const TObject* obj);           //SLOT
   void  FilterEventPave();                        //SLOT
   void  StartEditing();                           //SLOT

   void  RecordExtraEvent(TString line, ULong_t ExtTime);

   ClassDef(TRecorderRecording, 0) // Represents state of TRecorder when recording events
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorderInactive                                                   //
//                                                                      //
//  Represents state of TRecorder just after its creation.              //
//  Nor recording neither replaying is being executed in this state.    //
//                                                                      //
//  Not intended to be used by a user directly.                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorderInactive : public TRecorderState
{

private:
   TSeqCollection *fCollect;

public:
   virtual        ~TRecorderInactive() {}
   TRecorderInactive(){}

   virtual void   ListCmd(const char *filename);
   virtual void   ListGui(const char *filename);

   virtual void   Start(TRecorder *r, const char *filename, Option_t *option, Window_t *w = 0, Int_t winCount = 0);
   virtual Bool_t Replay(TRecorder *r, const char *filename, Bool_t showMouseCursor, TRecorder::EReplayModes mode);

   virtual TRecorder::ERecorderState GetState() const { return TRecorder::kInactive; }

   static void    DumpRootEvent(TRecGuiEvent *e, Int_t n);
   static long    DisplayValid(Long_t n) { return ( n < 0 ? -1 : n); }

   void PrevCanvases(const char *filename, Option_t *option);

   ClassDef(TRecorderInactive, 0) // Represents state of TRecorder after its creation
};

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRecorderPaused                                                     //
//                                                                      //
//  Represents state of TRecorder when replaying was paused             //
//  by a user.                                                          //
//  The paused replaying is remembered and after Resume call can        //
//  be continued again.                                                 //
//                                                                      //
//  Not intended to be used by a user directly.                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TRecorderPaused: public TRecorderState
{
private:
   virtual ~TRecorderPaused() {}

   TRecorderReplaying       *fReplayingState;      // Replaying that is paused

protected:
   friend class TRecorderReplaying;
   TRecorderPaused(TRecorderReplaying *state);

public:
   virtual TRecorder::ERecorderState GetState() const { return TRecorder::kPaused; }

   virtual void Resume(TRecorder *r);
   virtual void ReplayStop(TRecorder *r);

   ClassDef(TRecorderPaused, 0) // Represents state of TRecorder when paused
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TGRecorder                                                          //
//                                                                      //
//  Provides GUI for TRecorder class.                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
class TGRecorder : public TGMainFrame
{
private:
   TRecorder          *fRecorder;          // Recorder

   TGPictureButton    *fStartStop;         // Button for start and stop of recording
   TGPictureButton    *fReplay;            // Button for start of replaying

   TGLabel            *fStatus;            // Label with actual status
   TGLabel            *fTimeDisplay;       // Label with time counter
   TGCheckButton      *fCursorCheckBox;    // Check box "Show mouse cursor" for replaying

   TTimer             *fTimer;             // Timer for handling GUI of recorder
   time_t              fStart, fElapsed;   // playing/recording time

   static const Int_t  fgWidgetsCount = 12;            // Number of windows in GUI recorder
   Window_t            fFilteredIds[fgWidgetsCount];   // IDs of these windows in GUI recorder

   void                SetDefault();

public:
   TGRecorder(const TGWindow *p = 0, UInt_t w = 230, UInt_t h = 150);
   virtual ~TGRecorder();

   void StartStop();
   void Update();
   void Replay();

   ClassDef(TGRecorder,0) // GUI class of the event recorder.
};

#endif // ROOT_TRecorder

 TRecorder.h:1
 TRecorder.h:2
 TRecorder.h:3
 TRecorder.h:4
 TRecorder.h:5
 TRecorder.h:6
 TRecorder.h:7
 TRecorder.h:8
 TRecorder.h:9
 TRecorder.h:10
 TRecorder.h:11
 TRecorder.h:12
 TRecorder.h:13
 TRecorder.h:14
 TRecorder.h:15
 TRecorder.h:16
 TRecorder.h:17
 TRecorder.h:18
 TRecorder.h:19
 TRecorder.h:20
 TRecorder.h:21
 TRecorder.h:22
 TRecorder.h:23
 TRecorder.h:24
 TRecorder.h:25
 TRecorder.h:26
 TRecorder.h:27
 TRecorder.h:28
 TRecorder.h:29
 TRecorder.h:30
 TRecorder.h:31
 TRecorder.h:32
 TRecorder.h:33
 TRecorder.h:34
 TRecorder.h:35
 TRecorder.h:36
 TRecorder.h:37
 TRecorder.h:38
 TRecorder.h:39
 TRecorder.h:40
 TRecorder.h:41
 TRecorder.h:42
 TRecorder.h:43
 TRecorder.h:44
 TRecorder.h:45
 TRecorder.h:46
 TRecorder.h:47
 TRecorder.h:48
 TRecorder.h:49
 TRecorder.h:50
 TRecorder.h:51
 TRecorder.h:52
 TRecorder.h:53
 TRecorder.h:54
 TRecorder.h:55
 TRecorder.h:56
 TRecorder.h:57
 TRecorder.h:58
 TRecorder.h:59
 TRecorder.h:60
 TRecorder.h:61
 TRecorder.h:62
 TRecorder.h:63
 TRecorder.h:64
 TRecorder.h:65
 TRecorder.h:66
 TRecorder.h:67
 TRecorder.h:68
 TRecorder.h:69
 TRecorder.h:70
 TRecorder.h:71
 TRecorder.h:72
 TRecorder.h:73
 TRecorder.h:74
 TRecorder.h:75
 TRecorder.h:76
 TRecorder.h:77
 TRecorder.h:78
 TRecorder.h:79
 TRecorder.h:80
 TRecorder.h:81
 TRecorder.h:82
 TRecorder.h:83
 TRecorder.h:84
 TRecorder.h:85
 TRecorder.h:86
 TRecorder.h:87
 TRecorder.h:88
 TRecorder.h:89
 TRecorder.h:90
 TRecorder.h:91
 TRecorder.h:92
 TRecorder.h:93
 TRecorder.h:94
 TRecorder.h:95
 TRecorder.h:96
 TRecorder.h:97
 TRecorder.h:98
 TRecorder.h:99
 TRecorder.h:100
 TRecorder.h:101
 TRecorder.h:102
 TRecorder.h:103
 TRecorder.h:104
 TRecorder.h:105
 TRecorder.h:106
 TRecorder.h:107
 TRecorder.h:108
 TRecorder.h:109
 TRecorder.h:110
 TRecorder.h:111
 TRecorder.h:112
 TRecorder.h:113
 TRecorder.h:114
 TRecorder.h:115
 TRecorder.h:116
 TRecorder.h:117
 TRecorder.h:118
 TRecorder.h:119
 TRecorder.h:120
 TRecorder.h:121
 TRecorder.h:122
 TRecorder.h:123
 TRecorder.h:124
 TRecorder.h:125
 TRecorder.h:126
 TRecorder.h:127
 TRecorder.h:128
 TRecorder.h:129
 TRecorder.h:130
 TRecorder.h:131
 TRecorder.h:132
 TRecorder.h:133
 TRecorder.h:134
 TRecorder.h:135
 TRecorder.h:136
 TRecorder.h:137
 TRecorder.h:138
 TRecorder.h:139
 TRecorder.h:140
 TRecorder.h:141
 TRecorder.h:142
 TRecorder.h:143
 TRecorder.h:144
 TRecorder.h:145
 TRecorder.h:146
 TRecorder.h:147
 TRecorder.h:148
 TRecorder.h:149
 TRecorder.h:150
 TRecorder.h:151
 TRecorder.h:152
 TRecorder.h:153
 TRecorder.h:154
 TRecorder.h:155
 TRecorder.h:156
 TRecorder.h:157
 TRecorder.h:158
 TRecorder.h:159
 TRecorder.h:160
 TRecorder.h:161
 TRecorder.h:162
 TRecorder.h:163
 TRecorder.h:164
 TRecorder.h:165
 TRecorder.h:166
 TRecorder.h:167
 TRecorder.h:168
 TRecorder.h:169
 TRecorder.h:170
 TRecorder.h:171
 TRecorder.h:172
 TRecorder.h:173
 TRecorder.h:174
 TRecorder.h:175
 TRecorder.h:176
 TRecorder.h:177
 TRecorder.h:178
 TRecorder.h:179
 TRecorder.h:180
 TRecorder.h:181
 TRecorder.h:182
 TRecorder.h:183
 TRecorder.h:184
 TRecorder.h:185
 TRecorder.h:186
 TRecorder.h:187
 TRecorder.h:188
 TRecorder.h:189
 TRecorder.h:190
 TRecorder.h:191
 TRecorder.h:192
 TRecorder.h:193
 TRecorder.h:194
 TRecorder.h:195
 TRecorder.h:196
 TRecorder.h:197
 TRecorder.h:198
 TRecorder.h:199
 TRecorder.h:200
 TRecorder.h:201
 TRecorder.h:202
 TRecorder.h:203
 TRecorder.h:204
 TRecorder.h:205
 TRecorder.h:206
 TRecorder.h:207
 TRecorder.h:208
 TRecorder.h:209
 TRecorder.h:210
 TRecorder.h:211
 TRecorder.h:212
 TRecorder.h:213
 TRecorder.h:214
 TRecorder.h:215
 TRecorder.h:216
 TRecorder.h:217
 TRecorder.h:218
 TRecorder.h:219
 TRecorder.h:220
 TRecorder.h:221
 TRecorder.h:222
 TRecorder.h:223
 TRecorder.h:224
 TRecorder.h:225
 TRecorder.h:226
 TRecorder.h:227
 TRecorder.h:228
 TRecorder.h:229
 TRecorder.h:230
 TRecorder.h:231
 TRecorder.h:232
 TRecorder.h:233
 TRecorder.h:234
 TRecorder.h:235
 TRecorder.h:236
 TRecorder.h:237
 TRecorder.h:238
 TRecorder.h:239
 TRecorder.h:240
 TRecorder.h:241
 TRecorder.h:242
 TRecorder.h:243
 TRecorder.h:244
 TRecorder.h:245
 TRecorder.h:246
 TRecorder.h:247
 TRecorder.h:248
 TRecorder.h:249
 TRecorder.h:250
 TRecorder.h:251
 TRecorder.h:252
 TRecorder.h:253
 TRecorder.h:254
 TRecorder.h:255
 TRecorder.h:256
 TRecorder.h:257
 TRecorder.h:258
 TRecorder.h:259
 TRecorder.h:260
 TRecorder.h:261
 TRecorder.h:262
 TRecorder.h:263
 TRecorder.h:264
 TRecorder.h:265
 TRecorder.h:266
 TRecorder.h:267
 TRecorder.h:268
 TRecorder.h:269
 TRecorder.h:270
 TRecorder.h:271
 TRecorder.h:272
 TRecorder.h:273
 TRecorder.h:274
 TRecorder.h:275
 TRecorder.h:276
 TRecorder.h:277
 TRecorder.h:278
 TRecorder.h:279
 TRecorder.h:280
 TRecorder.h:281
 TRecorder.h:282
 TRecorder.h:283
 TRecorder.h:284
 TRecorder.h:285
 TRecorder.h:286
 TRecorder.h:287
 TRecorder.h:288
 TRecorder.h:289
 TRecorder.h:290
 TRecorder.h:291
 TRecorder.h:292
 TRecorder.h:293
 TRecorder.h:294
 TRecorder.h:295
 TRecorder.h:296
 TRecorder.h:297
 TRecorder.h:298
 TRecorder.h:299
 TRecorder.h:300
 TRecorder.h:301
 TRecorder.h:302
 TRecorder.h:303
 TRecorder.h:304
 TRecorder.h:305
 TRecorder.h:306
 TRecorder.h:307
 TRecorder.h:308
 TRecorder.h:309
 TRecorder.h:310
 TRecorder.h:311
 TRecorder.h:312
 TRecorder.h:313
 TRecorder.h:314
 TRecorder.h:315
 TRecorder.h:316
 TRecorder.h:317
 TRecorder.h:318
 TRecorder.h:319
 TRecorder.h:320
 TRecorder.h:321
 TRecorder.h:322
 TRecorder.h:323
 TRecorder.h:324
 TRecorder.h:325
 TRecorder.h:326
 TRecorder.h:327
 TRecorder.h:328
 TRecorder.h:329
 TRecorder.h:330
 TRecorder.h:331
 TRecorder.h:332
 TRecorder.h:333
 TRecorder.h:334
 TRecorder.h:335
 TRecorder.h:336
 TRecorder.h:337
 TRecorder.h:338
 TRecorder.h:339
 TRecorder.h:340
 TRecorder.h:341
 TRecorder.h:342
 TRecorder.h:343
 TRecorder.h:344
 TRecorder.h:345
 TRecorder.h:346
 TRecorder.h:347
 TRecorder.h:348
 TRecorder.h:349
 TRecorder.h:350
 TRecorder.h:351
 TRecorder.h:352
 TRecorder.h:353
 TRecorder.h:354
 TRecorder.h:355
 TRecorder.h:356
 TRecorder.h:357
 TRecorder.h:358
 TRecorder.h:359
 TRecorder.h:360
 TRecorder.h:361
 TRecorder.h:362
 TRecorder.h:363
 TRecorder.h:364
 TRecorder.h:365
 TRecorder.h:366
 TRecorder.h:367
 TRecorder.h:368
 TRecorder.h:369
 TRecorder.h:370
 TRecorder.h:371
 TRecorder.h:372
 TRecorder.h:373
 TRecorder.h:374
 TRecorder.h:375
 TRecorder.h:376
 TRecorder.h:377
 TRecorder.h:378
 TRecorder.h:379
 TRecorder.h:380
 TRecorder.h:381
 TRecorder.h:382
 TRecorder.h:383
 TRecorder.h:384
 TRecorder.h:385
 TRecorder.h:386
 TRecorder.h:387
 TRecorder.h:388
 TRecorder.h:389
 TRecorder.h:390
 TRecorder.h:391
 TRecorder.h:392
 TRecorder.h:393
 TRecorder.h:394
 TRecorder.h:395
 TRecorder.h:396
 TRecorder.h:397
 TRecorder.h:398
 TRecorder.h:399
 TRecorder.h:400
 TRecorder.h:401
 TRecorder.h:402
 TRecorder.h:403
 TRecorder.h:404
 TRecorder.h:405
 TRecorder.h:406
 TRecorder.h:407
 TRecorder.h:408
 TRecorder.h:409
 TRecorder.h:410
 TRecorder.h:411
 TRecorder.h:412
 TRecorder.h:413
 TRecorder.h:414
 TRecorder.h:415
 TRecorder.h:416
 TRecorder.h:417
 TRecorder.h:418
 TRecorder.h:419
 TRecorder.h:420
 TRecorder.h:421
 TRecorder.h:422
 TRecorder.h:423
 TRecorder.h:424
 TRecorder.h:425
 TRecorder.h:426
 TRecorder.h:427
 TRecorder.h:428
 TRecorder.h:429
 TRecorder.h:430
 TRecorder.h:431
 TRecorder.h:432
 TRecorder.h:433
 TRecorder.h:434
 TRecorder.h:435
 TRecorder.h:436
 TRecorder.h:437
 TRecorder.h:438
 TRecorder.h:439
 TRecorder.h:440
 TRecorder.h:441
 TRecorder.h:442
 TRecorder.h:443
 TRecorder.h:444
 TRecorder.h:445
 TRecorder.h:446
 TRecorder.h:447
 TRecorder.h:448
 TRecorder.h:449
 TRecorder.h:450
 TRecorder.h:451
 TRecorder.h:452
 TRecorder.h:453
 TRecorder.h:454
 TRecorder.h:455
 TRecorder.h:456
 TRecorder.h:457
 TRecorder.h:458
 TRecorder.h:459
 TRecorder.h:460
 TRecorder.h:461
 TRecorder.h:462
 TRecorder.h:463
 TRecorder.h:464
 TRecorder.h:465
 TRecorder.h:466
 TRecorder.h:467
 TRecorder.h:468
 TRecorder.h:469
 TRecorder.h:470
 TRecorder.h:471
 TRecorder.h:472
 TRecorder.h:473
 TRecorder.h:474
 TRecorder.h:475
 TRecorder.h:476
 TRecorder.h:477
 TRecorder.h:478
 TRecorder.h:479
 TRecorder.h:480
 TRecorder.h:481
 TRecorder.h:482
 TRecorder.h:483
 TRecorder.h:484
 TRecorder.h:485
 TRecorder.h:486
 TRecorder.h:487
 TRecorder.h:488
 TRecorder.h:489
 TRecorder.h:490
 TRecorder.h:491
 TRecorder.h:492
 TRecorder.h:493
 TRecorder.h:494
 TRecorder.h:495
 TRecorder.h:496
 TRecorder.h:497
 TRecorder.h:498
 TRecorder.h:499
 TRecorder.h:500
 TRecorder.h:501
 TRecorder.h:502
 TRecorder.h:503
 TRecorder.h:504
 TRecorder.h:505
 TRecorder.h:506
 TRecorder.h:507
 TRecorder.h:508
 TRecorder.h:509
 TRecorder.h:510
 TRecorder.h:511
 TRecorder.h:512
 TRecorder.h:513
 TRecorder.h:514
 TRecorder.h:515
 TRecorder.h:516
 TRecorder.h:517
 TRecorder.h:518
 TRecorder.h:519
 TRecorder.h:520
 TRecorder.h:521
 TRecorder.h:522
 TRecorder.h:523
 TRecorder.h:524
 TRecorder.h:525
 TRecorder.h:526
 TRecorder.h:527
 TRecorder.h:528
 TRecorder.h:529
 TRecorder.h:530
 TRecorder.h:531
 TRecorder.h:532
 TRecorder.h:533
 TRecorder.h:534
 TRecorder.h:535
 TRecorder.h:536
 TRecorder.h:537
 TRecorder.h:538
 TRecorder.h:539
 TRecorder.h:540
 TRecorder.h:541
 TRecorder.h:542
 TRecorder.h:543
 TRecorder.h:544
 TRecorder.h:545
 TRecorder.h:546
 TRecorder.h:547
 TRecorder.h:548
 TRecorder.h:549
 TRecorder.h:550
 TRecorder.h:551
 TRecorder.h:552
 TRecorder.h:553
 TRecorder.h:554
 TRecorder.h:555
 TRecorder.h:556
 TRecorder.h:557
 TRecorder.h:558
 TRecorder.h:559
 TRecorder.h:560
 TRecorder.h:561
 TRecorder.h:562
 TRecorder.h:563
 TRecorder.h:564
 TRecorder.h:565
 TRecorder.h:566
 TRecorder.h:567
 TRecorder.h:568
 TRecorder.h:569
 TRecorder.h:570
 TRecorder.h:571
 TRecorder.h:572
 TRecorder.h:573
 TRecorder.h:574
 TRecorder.h:575
 TRecorder.h:576
 TRecorder.h:577
 TRecorder.h:578
 TRecorder.h:579
 TRecorder.h:580
 TRecorder.h:581
 TRecorder.h:582
 TRecorder.h:583
 TRecorder.h:584
 TRecorder.h:585
 TRecorder.h:586
 TRecorder.h:587
 TRecorder.h:588
 TRecorder.h:589
 TRecorder.h:590
 TRecorder.h:591
 TRecorder.h:592
 TRecorder.h:593
 TRecorder.h:594
 TRecorder.h:595
 TRecorder.h:596
 TRecorder.h:597
 TRecorder.h:598
 TRecorder.h:599
 TRecorder.h:600
 TRecorder.h:601
 TRecorder.h:602
 TRecorder.h:603
 TRecorder.h:604
 TRecorder.h:605
 TRecorder.h:606
 TRecorder.h:607
 TRecorder.h:608
 TRecorder.h:609
 TRecorder.h:610
 TRecorder.h:611
 TRecorder.h:612
 TRecorder.h:613
 TRecorder.h:614
 TRecorder.h:615
 TRecorder.h:616
 TRecorder.h:617
 TRecorder.h:618
 TRecorder.h:619
 TRecorder.h:620
 TRecorder.h:621
 TRecorder.h:622
 TRecorder.h:623
 TRecorder.h:624
 TRecorder.h:625
 TRecorder.h:626
 TRecorder.h:627
 TRecorder.h:628
 TRecorder.h:629
 TRecorder.h:630
 TRecorder.h:631
 TRecorder.h:632
 TRecorder.h:633
 TRecorder.h:634
 TRecorder.h:635
 TRecorder.h:636
 TRecorder.h:637
 TRecorder.h:638
 TRecorder.h:639
 TRecorder.h:640
 TRecorder.h:641
 TRecorder.h:642
 TRecorder.h:643
 TRecorder.h:644
 TRecorder.h:645
 TRecorder.h:646
 TRecorder.h:647
 TRecorder.h:648
 TRecorder.h:649
 TRecorder.h:650
 TRecorder.h:651
 TRecorder.h:652
 TRecorder.h:653
 TRecorder.h:654
 TRecorder.h:655
 TRecorder.h:656
 TRecorder.h:657
 TRecorder.h:658
 TRecorder.h:659
 TRecorder.h:660
 TRecorder.h:661
 TRecorder.h:662
 TRecorder.h:663
 TRecorder.h:664
 TRecorder.h:665
 TRecorder.h:666
 TRecorder.h:667
 TRecorder.h:668
 TRecorder.h:669
 TRecorder.h:670
 TRecorder.h:671
 TRecorder.h:672
 TRecorder.h:673
 TRecorder.h:674
 TRecorder.h:675
 TRecorder.h:676
 TRecorder.h:677
 TRecorder.h:678
 TRecorder.h:679
 TRecorder.h:680
 TRecorder.h:681
 TRecorder.h:682
 TRecorder.h:683
 TRecorder.h:684
 TRecorder.h:685
 TRecorder.h:686
 TRecorder.h:687
 TRecorder.h:688
 TRecorder.h:689
 TRecorder.h:690
 TRecorder.h:691
 TRecorder.h:692
 TRecorder.h:693
 TRecorder.h:694
 TRecorder.h:695
 TRecorder.h:696
 TRecorder.h:697
 TRecorder.h:698
 TRecorder.h:699
 TRecorder.h:700
 TRecorder.h:701
 TRecorder.h:702
 TRecorder.h:703
 TRecorder.h:704
 TRecorder.h:705
 TRecorder.h:706
 TRecorder.h:707
 TRecorder.h:708
 TRecorder.h:709
 TRecorder.h:710
 TRecorder.h:711
 TRecorder.h:712
 TRecorder.h:713
 TRecorder.h:714
 TRecorder.h:715
 TRecorder.h:716
 TRecorder.h:717
 TRecorder.h:718
 TRecorder.h:719
 TRecorder.h:720
 TRecorder.h:721
 TRecorder.h:722
 TRecorder.h:723
 TRecorder.h:724
 TRecorder.h:725
 TRecorder.h:726
 TRecorder.h:727
 TRecorder.h:728
 TRecorder.h:729
 TRecorder.h:730
 TRecorder.h:731
 TRecorder.h:732
 TRecorder.h:733
 TRecorder.h:734
 TRecorder.h:735
 TRecorder.h:736
 TRecorder.h:737
 TRecorder.h:738
 TRecorder.h:739
 TRecorder.h:740
 TRecorder.h:741
 TRecorder.h:742
 TRecorder.h:743
 TRecorder.h:744
 TRecorder.h:745
 TRecorder.h:746
 TRecorder.h:747
 TRecorder.h:748
 TRecorder.h:749
 TRecorder.h:750
 TRecorder.h:751
 TRecorder.h:752
 TRecorder.h:753
 TRecorder.h:754
 TRecorder.h:755
 TRecorder.h:756
 TRecorder.h:757
 TRecorder.h:758
 TRecorder.h:759
 TRecorder.h:760
 TRecorder.h:761
 TRecorder.h:762
 TRecorder.h:763
 TRecorder.h:764
 TRecorder.h:765
 TRecorder.h:766
 TRecorder.h:767
 TRecorder.h:768
 TRecorder.h:769
 TRecorder.h:770
 TRecorder.h:771
 TRecorder.h:772
 TRecorder.h:773
 TRecorder.h:774
 TRecorder.h:775
 TRecorder.h:776
 TRecorder.h:777
 TRecorder.h:778
 TRecorder.h:779
 TRecorder.h:780
 TRecorder.h:781
 TRecorder.h:782
 TRecorder.h:783
 TRecorder.h:784
 TRecorder.h:785
 TRecorder.h:786
 TRecorder.h:787
 TRecorder.h:788
 TRecorder.h:789
 TRecorder.h:790
 TRecorder.h:791
 TRecorder.h:792
 TRecorder.h:793
 TRecorder.h:794
 TRecorder.h:795
 TRecorder.h:796
 TRecorder.h:797
 TRecorder.h:798
 TRecorder.h:799
 TRecorder.h:800
 TRecorder.h:801
 TRecorder.h:802
 TRecorder.h:803
 TRecorder.h:804
 TRecorder.h:805
 TRecorder.h:806
 TRecorder.h:807
 TRecorder.h:808
 TRecorder.h:809
 TRecorder.h:810
 TRecorder.h:811
 TRecorder.h:812
 TRecorder.h:813
 TRecorder.h:814
 TRecorder.h:815
 TRecorder.h:816
 TRecorder.h:817
 TRecorder.h:818
 TRecorder.h:819
 TRecorder.h:820
 TRecorder.h:821
 TRecorder.h:822