ROOT logo
// @(#)root/gui:$Id: TGText.cxx 31681 2009-12-08 15:58:57Z bellenot $
// Author: Fons Rademakers   26/04/98

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

    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.

    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

**************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGText                                                               //
//                                                                      //
// A TGText is a multi line text buffer. It allows the text to be       //
// loaded from file, saved to file and edited. It is used in the        //
// TGTextEdit widget. Single line text is handled by TGTextBuffer       //
// and the TGTextEntry widget.                                          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGText.h"
#include <ctype.h>

const Int_t kMaxLen = 8000;


ClassImp(TGTextLine)

//______________________________________________________________________________
TGTextLine::TGTextLine()
{
   // Create empty line of text (default ctor).

   fLength = 0;
   fString = 0;
   fPrev = fNext = 0;
}

//______________________________________________________________________________
TGTextLine::TGTextLine(TGTextLine *line)
{
   // Initialize line of text with other line of text (not copy ctor).

   fLength = line->GetLineLength();
   fString = 0;
   if (fLength > 0)
      fString = line->GetText(0, line->GetLineLength());
   fPrev = fNext = 0;
}

//______________________________________________________________________________
TGTextLine::TGTextLine(const char *string)
{
   // Initialize line of text with a const char*.

   if (string) {
      fLength = strlen(string);
      fString = new char[fLength+1];
      strcpy(fString, string);
   } else {
      fLength = 0;
      fString = 0;
   }
   fPrev = fNext = 0;
}

//______________________________________________________________________________
TGTextLine::TGTextLine(const TGTextLine& tl) :
  fString(tl.fString),
  fLength(tl.fLength),
  fPrev(tl.fPrev),
  fNext(tl.fNext)
{ 
   //copy constructor
}

//______________________________________________________________________________
TGTextLine& TGTextLine::operator=(const TGTextLine& tl)
{
   //assignment operator
   if(this!=&tl) {
      fString=tl.fString;
      fLength=tl.fLength;
      fPrev=tl.fPrev;
      fNext=tl.fNext;
   } 
   return *this;
}

//______________________________________________________________________________
TGTextLine::~TGTextLine()
{
   // Delete a line of text.

   if (fString)
      delete [] fString;
}

//______________________________________________________________________________
void TGTextLine::Clear()
{
   // Clear a line of text.

   if (fString)
      delete [] fString;
   fString = 0;
   fLength = 0;
}

//______________________________________________________________________________
void TGTextLine::DelText(ULong_t pos, ULong_t length)
{
   // Delete length chars from line starting at position pos.

   if (fLength == 0 || pos >= fLength)
      return;
   if (pos+length > fLength)
      length = fLength - pos;

   if (fLength - length <= 0) {
      delete [] fString;
      fLength = 0;
      fString = 0;
      return;
   }
   char *newstring = new char[fLength - length+1];
   strncpy(newstring, fString, (UInt_t)pos);
   strncpy(newstring+pos, fString+pos+length, UInt_t(fLength-pos-length));
   delete [] fString;
   fString = newstring;
   fLength = fLength - length;
   fString[fLength] = '\0';
}

//______________________________________________________________________________
void TGTextLine::InsText(ULong_t pos, const char *text)
{
   // Insert text in line starting at position pos.

   if (pos > fLength || !text)
      return;

   char *newstring = new char[strlen(text)+fLength+1];
   if (fString != 0)
      strncpy(newstring, fString, (UInt_t)pos);
   strcpy(newstring+pos, text);
   if (fString != 0 && fLength - pos  > 0)
      strncpy(newstring+pos+strlen(text), fString+pos, UInt_t(fLength-pos));
   fLength = fLength + strlen(text);
   delete [] fString;
   fString = newstring;
   fString[fLength] ='\0';
}

//______________________________________________________________________________
char *TGTextLine::GetText(ULong_t pos, ULong_t length)
{
   // Get length characters from line starting at pos. Returns 0
   // in case pos and length are out of range. The returned string
   // must be freed by the user.

   if (pos >= fLength) {
      return 0;
   }

   if (pos + length > (ULong_t)fString) {
      length = fLength - pos;
   }

   char *retstring = new char[length+1];
   retstring[length] = '\0';
   strncpy(retstring, fString+pos, (UInt_t)length);

   return retstring;
}

//______________________________________________________________________________
char *TGTextLine::GetWord(ULong_t pos)
{
   // Get word at position. Returned string must be deleted.

   if (pos >= fLength) {
      return 0;
   }

   Int_t start = (Int_t)pos;
   UInt_t end = (UInt_t)pos;
   UInt_t i = (UInt_t)pos;

   if (fString[i] == ' ' || fString[i] == '\t') {
      while (start >= 0) {
         if (fString[start] == ' ' || fString[start] == '\t') --start;
         else break;
      }
      ++start;
      while (end < fLength) {
         if (fString[end] == ' ' || fString[end] == '\t') ++end;
         else break;
      }
   } else if (isalnum(fString[i])) {
      while (start >= 0) {
         if (isalnum(fString[start])) --start;
         else break;
      }
      ++start;
      while (end < fLength) {
         if (isalnum(fString[end])) ++end;
         else break;
      }
   } else {
      while (start >= 0) {
         if (isalnum(fString[start]) || fString[start] == ' ' || fString[start] == '\t') {
            break;
         } else {
            --start;
         }
      }
      ++start;
      while (end < fLength) {
         if (isalnum(fString[end]) || fString[end] == ' ' || fString[end] == '\t') {
            break;
         } else {
            ++end;
         }
      }
   }

   UInt_t length = UInt_t(end - start);
   char *retstring = new char[length+1];
   retstring[length] = '\0';
   strncpy(retstring, fString+start, length);

   return retstring;
}

//______________________________________________________________________________
void TGTextLine::DelChar(ULong_t pos)
{
   // Delete a character from the line.

   char *newstring;
   if ((fLength <= 0) || (pos > fLength))
      return;
   newstring = new char[fLength];
   strncpy(newstring, fString, (UInt_t)pos-1);
   if (pos < fLength)
      strncpy(newstring+pos-1, fString+pos, UInt_t(fLength-pos+1));
   else
      newstring[pos-1] = 0;
   delete [] fString;
   fString = newstring;
   fLength--;
}

//______________________________________________________________________________
void TGTextLine::InsChar(ULong_t pos, char character)
{
   // Insert a character at the specified position.

   char *newstring;
   if (pos > fLength)
      return;
   newstring = new char[fLength+2];
   newstring[fLength+1] = '\0';
   if (fLength > 0)
      strncpy (newstring, fString, (UInt_t)pos);
   newstring[pos] = character;
   if (fLength - pos > 0)
      strncpy(newstring+pos+1, fString+pos, UInt_t(fLength-pos));
   delete [] fString;
   fString = newstring;
   fLength++;
}

//______________________________________________________________________________
char TGTextLine::GetChar(ULong_t pos)
{
   // Get a character at the specified position from the line.
   // Returns -1 if pos is out of range.

   if ((fLength <= 0) || (pos >= fLength))
      return -1;
   return fString[pos];
}


ClassImp(TGText)

//______________________________________________________________________________
TGText::TGText(const TGText& gt) :
  fFilename(gt.fFilename),
  fIsSaved(gt.fIsSaved),
  fFirst(gt.fFirst),
  fCurrent(gt.fCurrent),
  fCurrentRow(gt.fCurrentRow),
  fRowCount(gt.fRowCount),
  fColCount(gt.fColCount),
  fLongestLine(gt.fLongestLine)
{ 
   //copy constructor
}

//______________________________________________________________________________
TGText& TGText::operator=(const TGText& gt)
{
   //assignment operator
   if(this!=&gt) {
      fFilename=gt.fFilename;
      fIsSaved=gt.fIsSaved;
      fFirst=gt.fFirst;
      fCurrent=gt.fCurrent;
      fCurrentRow=gt.fCurrentRow;
      fRowCount=gt.fRowCount;
      fColCount=gt.fColCount;
      fLongestLine=gt.fLongestLine;
   } 
   return *this;
}

//______________________________________________________________________________
void TGText::Init()
{
   // Common initialization method.

   fFirst       = new TGTextLine;
   fCurrent     = fFirst;
   fCurrentRow  = 0;
   fColCount    = 0;
   fRowCount    = 1;
   fLongestLine = 0;
   fIsSaved     = kTRUE;
}

//______________________________________________________________________________
TGText::TGText()
{
   // Create default (empty) text buffer.

   Init();
}

//______________________________________________________________________________
TGText::TGText(TGText *text)
{
   // Create text buffer and initialize with other text buffer.

   TGLongPosition pos, end;

   pos.fX = pos.fY = 0;
   end.fY = text->RowCount() - 1;
   end.fX = text->GetLineLength(end.fY) - 1;
   Init();
   InsText(pos, text, pos, end);
}

//______________________________________________________________________________
TGText::TGText(const char *string)
{
   // Create text buffer and initialize with single line string.

   TGLongPosition pos;

   pos.fX = pos.fY = 0;
   Init();
   InsText(pos, string);
}

//______________________________________________________________________________
TGText::~TGText()
{
   // Destroy text buffer.

   Clear();
   delete fFirst;
}

//______________________________________________________________________________
void TGText::Clear()
{
   // Clear text buffer.

   TGTextLine *travel = fFirst->fNext;
   TGTextLine *toDelete;
   while (travel != 0) {
      toDelete = travel;
      travel = travel->fNext;
      delete toDelete;
   }
   fFirst->Clear();
   fFirst->fNext = 0;
   fCurrent      = fFirst;
   fCurrentRow   = 0;
   fColCount     = 0;
   fRowCount     = 1;
   fLongestLine  = 0;
   fIsSaved      = kTRUE;
   fFilename     = "";
}

//______________________________________________________________________________
Bool_t TGText::Load(const char *fn, Long_t startpos, Long_t length)
{
   // Load text from file fn. Startpos is the begin from where to
   // load the file and length is the number of characters to read
   // from the file.

   Bool_t      isFirst = kTRUE;
   Bool_t      finished = kFALSE;
   Long_t      count, charcount, i, cnt;
   FILE       *fp;
   char        buf[kMaxLen], c, *src, *dst, *buffer, *buf2;
   TGTextLine *travel, *temp;

   travel = fFirst;

   if (!(fp = fopen(fn, "r"))) return kFALSE;
   i = 0;
   fseek(fp, startpos, SEEK_SET);
   charcount = 0;
   while (fgets(buf, kMaxLen, fp)) {
      if ((length != -1) && (charcount+(Int_t)strlen(buf) > length)) {
         count = length - charcount;
         finished = kTRUE;
      } else
         count = kMaxLen;
      charcount += strlen(buf);
      buf2 = new char[count+1];
      buf2[count] = '\0';
      src = buf;
      dst = buf2;
      cnt = 0;
      while ((c = *src++)) {
         // Don't put CR or NL in buffer
         if (c == 0x0D || c == 0x0A)
            break;
         // Expand tabs
         else if (c == 0x09) {
            *dst++ = '\t';
            while (((dst-buf2) & 0x7) && (cnt++ < count-1))
               *dst++ = 16;  //*dst++ = ' ';
         } else
            *dst++ = c;
         if (cnt++ >= count-1) break;
      }
      *dst = '\0';
      temp = new TGTextLine;
      buffer = new char[strlen(buf2)+1];
      strcpy(buffer, buf2);
      temp->fLength = strlen(buf2);
      temp->fString = buffer;
      temp->fNext = temp->fPrev = 0;
      if (isFirst) {
         delete fFirst;
         fFirst   = temp;
         fCurrent = temp;
         travel   = fFirst;
         isFirst  = kFALSE;
      } else {
         travel->fNext = temp;
         temp->fPrev   = travel;
         travel        = travel->fNext;
      }
      ++i;
      delete [] buf2;
      if (finished)
         break;
   }
   fclose(fp);

   // Remember the number of lines
   fRowCount = i;
   if (fRowCount == 0)
      fRowCount++;
   fIsSaved  = kTRUE;
   fFilename = fn;
   LongestLine();

   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::LoadBuffer(const char *txtbuf)
{
   // Load a 0 terminated buffer. Lines will be split at '\n'.

   Bool_t      isFirst = kTRUE;
   Bool_t      finished = kFALSE, lastnl = kFALSE;
   Long_t      i, cnt;
   TGTextLine *travel, *temp;
   char        buf[kMaxLen], c, *src, *dst, *buffer, *buf2, *s;
   const char *tbuf = txtbuf;

   travel = fFirst;

   if (!tbuf || !strlen(tbuf))
      return kFALSE;

   i = 0;
next:
   if ((s = (char*)strchr(tbuf, '\n'))) {
      if (s-tbuf+1 >= kMaxLen-1) {
         strncpy(buf, tbuf, kMaxLen-2);
         buf[kMaxLen-2] = '\n';
         buf[kMaxLen-1] = 0;
      } else {
         strncpy(buf, tbuf, s-tbuf+1);
         buf[s-tbuf+1] = 0;
      }
      tbuf = s+1;
   } else {
      if ((Int_t)strlen(tbuf) >= kMaxLen) {
         strncpy(buf, tbuf, kMaxLen-1);
         buf[kMaxLen-1] = 0;
      } else
         strcpy(buf, tbuf);
      finished = kTRUE;
   }

   buf2 = new char[kMaxLen+1];
   buf2[kMaxLen] = '\0';
   src = buf;
   dst = buf2;
   cnt = 0;
   while ((c = *src++)) {
      // Don't put CR or NL in buffer
      if (c == 0x0D || c == 0x0A)
         break;
      // Expand tabs
      else if (c == 0x09) {
         *dst++ = '\t';
         while (((dst-buf2) & 0x7) && (cnt++ < kMaxLen-1))
            *dst++ = 16;  //*dst++ = ' ';
      } else
         *dst++ = c;
      if (cnt++ >= kMaxLen-1) break;
   }
   *dst = '\0';
   temp = new TGTextLine;
   buffer = new char[strlen(buf2)+1];
   strcpy(buffer, buf2);
   temp->fLength = strlen(buf2);
   temp->fString = buffer;
   temp->fNext = temp->fPrev = 0;
   if (isFirst) {
      delete fFirst;
      fFirst   = temp;
      fCurrent = temp;
      travel   = fFirst;
      isFirst  = kFALSE;
   } else {
      travel->fNext = temp;
      temp->fPrev   = travel;
      travel        = travel->fNext;
   }
   ++i;
   delete [] buf2;

   // make sure that \n generates a single empty line in the TGText
   if (!lastnl && !*tbuf && *(tbuf-1) == '\n') {
      tbuf--;
      lastnl = kTRUE;
   }

   if (!finished && tbuf && strlen(tbuf))
      goto next;

   // Remember the number of lines
   fRowCount = i;
   if (fRowCount == 0)
      fRowCount++;
   fIsSaved  = kTRUE;
   fFilename = "";
   LongestLine();

   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::Save(const char *fn)
{
   // Save text buffer to file fn.

   char *buffer;
   TGTextLine *travel = fFirst;
   FILE *fp;
   if (!(fp = fopen(fn, "w"))) return kFALSE;

   while (travel) {
      ULong_t i = 0;
      buffer = new char[travel->fLength+2];
      strncpy(buffer, travel->fString, (UInt_t)travel->fLength);
      buffer[travel->fLength]   = '\n';
      buffer[travel->fLength+1] = '\0';
      while (buffer[i] != '\0') {
         if (buffer[i] == '\t') {
            ULong_t j = i+1;
            while (buffer[j] == 16 && buffer[j] != '\0')
               j++;
            strcpy(buffer+i+1, buffer+j);
         }
         i++;
      }
      if (fputs(buffer, fp) == EOF) {
         delete [] buffer;
         fclose(fp);
         return kFALSE;
      }
      delete [] buffer;
      travel = travel->fNext;
   }
   fIsSaved = kTRUE;
   fFilename = fn;
   fclose(fp);

   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::Append(const char *fn)
{
   // Append buffer to file fn.

   char *buffer;
   TGTextLine *travel = fFirst;
   FILE *fp;
   if (!(fp = fopen(fn, "a"))) return kFALSE;

   while (travel) {
      ULong_t i = 0;
      buffer = new char[travel->fLength+2];
      strncpy(buffer, travel->fString, (UInt_t)travel->fLength);
      buffer[travel->fLength]   = '\n';
      buffer[travel->fLength+1] = '\0';
      while (buffer[i] != '\0') {
         if (buffer[i] == '\t') {
            ULong_t j = i+1;
            while (buffer[j] == 16 && buffer[j] != '\0')
               j++;
            strcpy(buffer+i+1, buffer+j);
         }
         i++;
      }
      if (fputs(buffer, fp) == EOF) {
         delete [] buffer;
         fclose(fp);
         return kFALSE;
      }
      delete [] buffer;
      travel = travel->fNext;
   }
   fIsSaved = kTRUE;
   fclose(fp);

   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::DelChar(TGLongPosition pos)
{
   // Delete character at specified position pos.

   if ((pos.fY >= fRowCount) || (pos.fY < 0))
      return kFALSE;

   if (!SetCurrentRow(pos.fY)) return kFALSE;
   fCurrent->DelChar(pos.fX);

   fIsSaved = kFALSE;
   LongestLine();
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::InsChar(TGLongPosition pos, char c)
{
   // Insert character c at the specified position pos.

   if ((pos.fY >= fRowCount) || (pos.fY < 0) || (pos.fX < 0))
      return kFALSE;

   if (!SetCurrentRow(pos.fY)) return kFALSE;
   fCurrent->InsChar(pos.fX, c);

   fIsSaved = kFALSE;
   LongestLine();
   return kTRUE;
}

//______________________________________________________________________________
char TGText::GetChar(TGLongPosition pos)
{
   // Get character a position pos. If charcater not valid return -1.

   if (pos.fY >= fRowCount)
      return -1;

   if (!SetCurrentRow(pos.fY)) return -1;
   return fCurrent->GetChar(pos.fX);
}

//______________________________________________________________________________
Bool_t TGText::DelText(TGLongPosition start, TGLongPosition end)
{
   // Delete text between start and end positions. Returns false in
   // case of failure (start and end not being within bounds).

   if ((start.fY < 0) || (start.fY >= fRowCount) ||
       (end.fY < 0)   || (end.fY >= fRowCount)) {
      return kFALSE;
   }

   if ((end.fX < 0) || (end.fX > GetLineLength(end.fY))) {
      return kFALSE;
   }

   char *tempbuffer;

   if (!SetCurrentRow(start.fY)) return kFALSE;

   if (start.fY == end.fY) {
      fCurrent->DelText(start.fX, end.fX-start.fX+1);
      return kTRUE;
   }
   fCurrent->DelText(start.fX, fCurrent->fLength-start.fX);
   SetCurrentRow(fCurrentRow+1);
   for (Long_t i = start.fY+1; i < end.fY; i++) {
      DelLine(fCurrentRow);
   }

   tempbuffer = fCurrent->GetText(end.fX+1, fCurrent->fLength-end.fX-1);
   DelLine(fCurrentRow);
   SetCurrentRow(start.fY);
   if (tempbuffer) {
      fCurrent->InsText(fCurrent->GetLineLength(), tempbuffer);
      delete [] tempbuffer;
   } else {
      if (fCurrent->fNext) {
         fCurrent->InsText(fCurrent->fLength, fCurrent->fNext->fString);
         DelLine(fCurrentRow+1);
         SetCurrentRow(start.fY);
      }
   }

   fIsSaved = kFALSE;
   LongestLine();
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::InsText(TGLongPosition ins_pos, TGText *src,
                       TGLongPosition start_src, TGLongPosition end_src)
{
   // Insert src text from start_src to end_src into text at position ins_pos.
   // Returns false in case of failure (start_src, end_src out of range for
   // src, and ins_pos out of range for this).

   /*
   if ((start_src.fY < 0) || (start_src.fY >= src->RowCount()) ||
       (end_src.fY < 0)   || (end_src.fY >= src->RowCount()))
      return kFALSE;
   if ((start_src.fX < 0) || (start_src.fX > src->GetLineLength(start_src.fY)) ||
       (end_src.fX < 0)   || (end_src.fX > src->GetLineLength(end_src.fY)))
      return kFALSE;
   if ((ins_pos.fY < 0) || (ins_pos.fY > fRowCount))
      return kFALSE;
   if ((ins_pos.fX < 0) || (ins_pos.fX > GetLineLength(ins_pos.fY)))
      return kFALSE;
   */
   if (ins_pos.fY > fRowCount)
      return kFALSE;

   TGLongPosition pos;
   ULong_t len;
   char *lineString;
   char *restString;
   TGTextLine *following;

   if (ins_pos.fY == fRowCount) {  // for appending text
      pos.fY = fRowCount - 1;
      pos.fX = GetLineLength(pos.fY);
      BreakLine(pos);  // current row is set by this
   } else {
      // otherwise going to the desired row
      if (!SetCurrentRow(ins_pos.fY)) return kFALSE;
   }

   // preparing first line to be inserted
   restString = fCurrent->GetText(ins_pos.fX, fCurrent->fLength - ins_pos.fX);
   fCurrent->DelText(ins_pos.fX, fCurrent->fLength - ins_pos.fX);
   following = fCurrent->fNext;
   // inserting first line
   if (start_src.fY == end_src.fY) {
      len = end_src.fX - start_src.fX+1;
   } else {
      len = src->GetLineLength(start_src.fY) - start_src.fX;
   }

   if (len > 0) {
      lineString = src->GetLine(start_src, len);
      fCurrent->InsText(ins_pos.fX, lineString);
      delete [] lineString;
   }
   // [...] inserting possible lines
   pos.fY = start_src.fY+1;
   pos.fX = 0;
   for ( ; pos.fY < end_src.fY; pos.fY++) {
      Int_t llen = src->GetLineLength(pos.fY);
      lineString = src->GetLine(pos, llen > 0 ? llen : 0);
      fCurrent->fNext = new TGTextLine(lineString);
      fCurrent->fNext->fPrev = fCurrent;
      fCurrent = fCurrent->fNext;
      fRowCount++;
      fCurrentRow++;
      delete [] lineString;
   }
   // last line of inserted text is as special as first line
   if (start_src.fY != end_src.fY) {
      pos.fY = end_src.fY;
      pos.fX = 0;
      lineString = src->GetLine(pos, end_src.fX+1);
      fCurrent->fNext = new TGTextLine(lineString);
      fCurrent->fNext->fPrev = fCurrent;
      fCurrent = fCurrent->fNext;
      fRowCount++;
      fCurrentRow++;
      delete [] lineString;
   }
   // ok, now we have to add the rest of the first destination line
   if (restString) {
#if 0
      if (ins_pos.fX == 0) {
         fCurrent->fNext = new TGTextLine(restString);
         fCurrent->fNext->fPrev = fCurrent;
         fCurrent = fCurrent->fNext;
         fRowCount++;
         fCurrentRow++;
      } else
#endif
         fCurrent->InsText(fCurrent->fLength, restString);
      delete [] restString;
   }
   // now re-linking the rest of the origin text
   fCurrent->fNext = following;
   if (fCurrent->fNext) {
      fCurrent->fNext->fPrev = fCurrent;
   }

   LongestLine();
   fIsSaved = kFALSE;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::InsText(TGLongPosition pos, const char *buffer)
{
   // Insert single line at specified position. Return false in case position
   // is out of bounds.

   if (pos.fY < 0 || pos.fY > fRowCount) {
      return kFALSE;
   }

   if (pos.fY == fRowCount) {
      SetCurrentRow(fRowCount-1);
      fCurrent->fNext = new TGTextLine(buffer);
      fCurrent->fNext->fPrev = fCurrent;
      fRowCount++;
   } else {
      SetCurrentRow(pos.fY);
      fCurrent->InsText(pos.fX, buffer);
   }
   LongestLine();
   fIsSaved = kFALSE;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::AddText(TGText *text)
{
   // Add another text buffer to this buffer.

   TGLongPosition end, start_src, end_src;

   end.fY = fRowCount;
   end.fX = 0;
   start_src.fX = start_src.fY = 0;
   end_src.fY   = text->RowCount()-1;
   end_src.fX   = text->GetLineLength(end_src.fY)-1;
   fIsSaved     = kFALSE;
   return InsText(end, text, start_src, end_src);
}

//______________________________________________________________________________
Bool_t TGText::InsLine(ULong_t pos, const char *string)
{
   // Insert string before specified position.
   // Returns false if insertion failed.

   TGTextLine *previous, *newline;
   if ((Long_t)pos > fRowCount) {
      return kFALSE;
   }
   if ((Long_t)pos < fRowCount) {
      SetCurrentRow(pos);
   } else {
      SetCurrentRow(fRowCount-1);
   }

   if (!fCurrent) return kFALSE;

   previous = fCurrent->fPrev;
   newline = new TGTextLine(string);
   newline->fPrev = previous;
   if (previous) {
      previous->fNext = newline;
   } else {
      fFirst = newline;
   }

   newline->fNext = fCurrent;
   fCurrent->fPrev = newline;
   fRowCount++;
   fCurrentRow++;

   LongestLine();
   fIsSaved = kFALSE;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TGText::DelLine(ULong_t pos)
{
   // Delete specified row. Returns false if row does not exist.

   if (!SetCurrentRow(pos) || (fRowCount == 1)) {
      return kFALSE;
   }

   TGTextLine *travel = fCurrent;
   if (travel == fFirst) {
      fFirst = fFirst->fNext;
      fFirst->fPrev = 0;
   } else {
      travel->fPrev->fNext = travel->fNext;
      if (travel->fNext) {
         travel->fNext->fPrev = travel->fPrev;
         fCurrent = fCurrent->fNext;
      } else {
         fCurrent = fCurrent->fPrev;
         fCurrentRow--;
      }
   }
   delete travel;

   fRowCount--;
   fIsSaved = kFALSE;
   LongestLine();

   return kTRUE;
}

//______________________________________________________________________________
char *TGText::GetLine(TGLongPosition pos, ULong_t length)
{
   // Return string at position pos. Returns 0 in case pos is not valid.
   // The returned string must be deleted by the user.

   if (SetCurrentRow(pos.fY)) {
      return fCurrent->GetText(pos.fX, length);
   }
   return 0;
}

//______________________________________________________________________________
Bool_t TGText::BreakLine(TGLongPosition pos)
{
   // Break line at position pos. Returns false if pos is not valid.

   if (!SetCurrentRow(pos.fY))
      return kFALSE;
   if ((pos.fX < 0) || (pos.fX > (Long_t)fCurrent->fLength))
      return kFALSE;

   TGTextLine *temp;
   char *tempbuffer;
   if (pos.fX < (Long_t)fCurrent->fLength) {
      tempbuffer = fCurrent->GetText(pos.fX, fCurrent->fLength-pos.fX);
      temp = new TGTextLine(tempbuffer);
      fCurrent->DelText(pos.fX, fCurrent->fLength - pos.fX);
      delete [] tempbuffer;
   } else {
      temp = new TGTextLine;
   }
   temp->fPrev = fCurrent;
   temp->fNext = fCurrent->fNext;
   fCurrent->fNext = temp;
   if (temp->fNext) {
      temp->fNext->fPrev = temp;
   }

   fIsSaved = kFALSE;
   fRowCount++;
   fCurrentRow++;
   fCurrent = fCurrent->fNext;
   LongestLine();
   return kTRUE;
}

//______________________________________________________________________________
Long_t TGText::GetLineLength(Long_t row)
{
   // Get length of specified line. Returns -1 if row does not exist.

   if (!SetCurrentRow(row)) {
      return -1;
   }
   return (Long_t)fCurrent->GetLineLength();
}

//______________________________________________________________________________
Bool_t TGText::SetCurrentRow(Long_t row)
{
   // Make specified row the current row. Returns false if row does not exist.
   // In which case fCurrent is not changed or set to the last valid line.

   Long_t count;
   if ((row < 0) || (row >= fRowCount)) {
      return kFALSE;
   }
   if (row > fCurrentRow) {
      for (count = fCurrentRow; count < row; count++) {
         if (!fCurrent->fNext) {
            fCurrentRow = count;
            return kFALSE;
         }
         fCurrent = fCurrent->fNext;
      }
   } else {
      if (fCurrentRow == row)
         return kTRUE;
      for (count = fCurrentRow; count > row; count--) {
         if (!fCurrent->fPrev) {
            fCurrentRow = count;
            return kFALSE;
         }
         fCurrent = fCurrent->fPrev;
      }
   }
   fCurrentRow = row;
   return kTRUE;
}

//______________________________________________________________________________
void TGText::ReTab(Long_t row)
{
   // Redo all tabs in a line. Needed after a new tab is inserted.

   if (!SetCurrentRow(row)) {
      return;
   }

   // first remove all special tab characters (16)
   char *buffer;
   ULong_t i = 0;

   buffer = fCurrent->fString;
   while (buffer[i] != '\0') {
      if (buffer[i] == '\t') {
         ULong_t j = i+1;
         while (buffer[j] == 16 && buffer[j] != '\0') {
            j++;
         }
         strcpy(buffer+i+1, buffer+j);
      }
      i++;
   }

   char   c, *src, *dst, *buf2;
   Long_t cnt;

   buf2 = new char[kMaxLen+1];
   buf2[kMaxLen] = '\0';
   src = buffer;
   dst = buf2;
   cnt = 0;
   while ((c = *src++)) {
      // Expand tabs
      if (c == 0x09) {
         *dst++ = '\t';
         while (((dst-buf2) & 0x7) && (cnt++ < kMaxLen-1)) {
            *dst++ = 16;
         }
      } else {
         *dst++ = c;
      }
      if (cnt++ >= kMaxLen-1) break;
   }
   *dst = '\0';

   fCurrent->fString = buf2;
   fCurrent->fLength = strlen(buf2);

   delete [] buffer;
}

//______________________________________________________________________________
Bool_t TGText::Search(TGLongPosition *foundPos, TGLongPosition start,
                      const char *searchString,
                      Bool_t direction, Bool_t caseSensitive)
{
   // Search for string searchString starting at the specified position going
   // in forward (direction = true) or backward direction. Returns true if
   // found and foundPos is set accordingly.

   if (!SetCurrentRow(start.fY))
      return kFALSE;

   Ssiz_t x = kNPOS;

   if (direction) {
      while(1) {
         TString s = fCurrent->fString;
         x = s.Index(searchString, (Ssiz_t)start.fX,
                     caseSensitive ? TString::kExact : TString::kIgnoreCase);
         if (x != kNPOS) {
            foundPos->fX = x;
            foundPos->fY = fCurrentRow;
            return kTRUE;
         }
         if (!SetCurrentRow(fCurrentRow+1))
            break;
         start.fX = 0;
      }
   } else {
      while(1) {
         TString s = fCurrent->fString;
         for (int i = (int)start.fX; i >= 0; i--) {
            x = s.Index(searchString, (Ssiz_t)i,
                        caseSensitive ? TString::kExact : TString::kIgnoreCase);
            if (x >= start.fX) {
               x = kNPOS;
               continue;
            }
            if (x != kNPOS) {
               break;
            }
         }
         if (x != kNPOS) {
            foundPos->fX = x;
            foundPos->fY = fCurrentRow;
            return kTRUE;
         }
         if (!SetCurrentRow(fCurrentRow-1)) {
            break;
         }
         start.fX = fCurrent->fLength;
      }
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGText::Replace(TGLongPosition start, const char *oldText, const char *newText,
                       Bool_t direction, Bool_t caseSensitive)
{
   // Replace oldText by newText. Returns false if nothing replaced.

   if (!SetCurrentRow(start.fY)) {
      return kFALSE;
   }

   TGLongPosition foundPos;
   if (!Search(&foundPos, start, oldText, direction, caseSensitive)) {
      return kFALSE;
   }

   TGLongPosition delEnd;
   delEnd.fY = foundPos.fY;
   delEnd.fX = foundPos.fX + strlen(oldText) - 1;
   DelText(foundPos, delEnd);
   InsText(foundPos, newText);
   return kTRUE;
}

//______________________________________________________________________________
void TGText::LongestLine()
{
   // Set fLongestLine.

   Long_t line_count = 0;
   TGTextLine *travel = fFirst;
   fColCount = 0;
   while (travel) {
      if ((Long_t)travel->fLength > fColCount) {
         fColCount = travel->fLength;
         fLongestLine = line_count;
      }
      travel = travel->fNext;
      line_count++;
   }
}

//______________________________________________________________________________
TString TGText::AsString()
{
   // Returns content as ROOT string

   TString ret;

   Long_t line_count = 0;
   TGTextLine *travel = fFirst;
   fColCount = 0;

   while (travel) {
      if ((Long_t)travel->fLength > fColCount) {
         fColCount = travel->fLength;
         fLongestLine = line_count;
      }
      ret += travel->GetText();
      travel = travel->fNext;
      if (travel) ret += '\n';
      line_count++;
   }

   return ret;
}
 TGText.cxx:1
 TGText.cxx:2
 TGText.cxx:3
 TGText.cxx:4
 TGText.cxx:5
 TGText.cxx:6
 TGText.cxx:7
 TGText.cxx:8
 TGText.cxx:9
 TGText.cxx:10
 TGText.cxx:11
 TGText.cxx:12
 TGText.cxx:13
 TGText.cxx:14
 TGText.cxx:15
 TGText.cxx:16
 TGText.cxx:17
 TGText.cxx:18
 TGText.cxx:19
 TGText.cxx:20
 TGText.cxx:21
 TGText.cxx:22
 TGText.cxx:23
 TGText.cxx:24
 TGText.cxx:25
 TGText.cxx:26
 TGText.cxx:27
 TGText.cxx:28
 TGText.cxx:29
 TGText.cxx:30
 TGText.cxx:31
 TGText.cxx:32
 TGText.cxx:33
 TGText.cxx:34
 TGText.cxx:35
 TGText.cxx:36
 TGText.cxx:37
 TGText.cxx:38
 TGText.cxx:39
 TGText.cxx:40
 TGText.cxx:41
 TGText.cxx:42
 TGText.cxx:43
 TGText.cxx:44
 TGText.cxx:45
 TGText.cxx:46
 TGText.cxx:47
 TGText.cxx:48
 TGText.cxx:49
 TGText.cxx:50
 TGText.cxx:51
 TGText.cxx:52
 TGText.cxx:53
 TGText.cxx:54
 TGText.cxx:55
 TGText.cxx:56
 TGText.cxx:57
 TGText.cxx:58
 TGText.cxx:59
 TGText.cxx:60
 TGText.cxx:61
 TGText.cxx:62
 TGText.cxx:63
 TGText.cxx:64
 TGText.cxx:65
 TGText.cxx:66
 TGText.cxx:67
 TGText.cxx:68
 TGText.cxx:69
 TGText.cxx:70
 TGText.cxx:71
 TGText.cxx:72
 TGText.cxx:73
 TGText.cxx:74
 TGText.cxx:75
 TGText.cxx:76
 TGText.cxx:77
 TGText.cxx:78
 TGText.cxx:79
 TGText.cxx:80
 TGText.cxx:81
 TGText.cxx:82
 TGText.cxx:83
 TGText.cxx:84
 TGText.cxx:85
 TGText.cxx:86
 TGText.cxx:87
 TGText.cxx:88
 TGText.cxx:89
 TGText.cxx:90
 TGText.cxx:91
 TGText.cxx:92
 TGText.cxx:93
 TGText.cxx:94
 TGText.cxx:95
 TGText.cxx:96
 TGText.cxx:97
 TGText.cxx:98
 TGText.cxx:99
 TGText.cxx:100
 TGText.cxx:101
 TGText.cxx:102
 TGText.cxx:103
 TGText.cxx:104
 TGText.cxx:105
 TGText.cxx:106
 TGText.cxx:107
 TGText.cxx:108
 TGText.cxx:109
 TGText.cxx:110
 TGText.cxx:111
 TGText.cxx:112
 TGText.cxx:113
 TGText.cxx:114
 TGText.cxx:115
 TGText.cxx:116
 TGText.cxx:117
 TGText.cxx:118
 TGText.cxx:119
 TGText.cxx:120
 TGText.cxx:121
 TGText.cxx:122
 TGText.cxx:123
 TGText.cxx:124
 TGText.cxx:125
 TGText.cxx:126
 TGText.cxx:127
 TGText.cxx:128
 TGText.cxx:129
 TGText.cxx:130
 TGText.cxx:131
 TGText.cxx:132
 TGText.cxx:133
 TGText.cxx:134
 TGText.cxx:135
 TGText.cxx:136
 TGText.cxx:137
 TGText.cxx:138
 TGText.cxx:139
 TGText.cxx:140
 TGText.cxx:141
 TGText.cxx:142
 TGText.cxx:143
 TGText.cxx:144
 TGText.cxx:145
 TGText.cxx:146
 TGText.cxx:147
 TGText.cxx:148
 TGText.cxx:149
 TGText.cxx:150
 TGText.cxx:151
 TGText.cxx:152
 TGText.cxx:153
 TGText.cxx:154
 TGText.cxx:155
 TGText.cxx:156
 TGText.cxx:157
 TGText.cxx:158
 TGText.cxx:159
 TGText.cxx:160
 TGText.cxx:161
 TGText.cxx:162
 TGText.cxx:163
 TGText.cxx:164
 TGText.cxx:165
 TGText.cxx:166
 TGText.cxx:167
 TGText.cxx:168
 TGText.cxx:169
 TGText.cxx:170
 TGText.cxx:171
 TGText.cxx:172
 TGText.cxx:173
 TGText.cxx:174
 TGText.cxx:175
 TGText.cxx:176
 TGText.cxx:177
 TGText.cxx:178
 TGText.cxx:179
 TGText.cxx:180
 TGText.cxx:181
 TGText.cxx:182
 TGText.cxx:183
 TGText.cxx:184
 TGText.cxx:185
 TGText.cxx:186
 TGText.cxx:187
 TGText.cxx:188
 TGText.cxx:189
 TGText.cxx:190
 TGText.cxx:191
 TGText.cxx:192
 TGText.cxx:193
 TGText.cxx:194
 TGText.cxx:195
 TGText.cxx:196
 TGText.cxx:197
 TGText.cxx:198
 TGText.cxx:199
 TGText.cxx:200
 TGText.cxx:201
 TGText.cxx:202
 TGText.cxx:203
 TGText.cxx:204
 TGText.cxx:205
 TGText.cxx:206
 TGText.cxx:207
 TGText.cxx:208
 TGText.cxx:209
 TGText.cxx:210
 TGText.cxx:211
 TGText.cxx:212
 TGText.cxx:213
 TGText.cxx:214
 TGText.cxx:215
 TGText.cxx:216
 TGText.cxx:217
 TGText.cxx:218
 TGText.cxx:219
 TGText.cxx:220
 TGText.cxx:221
 TGText.cxx:222
 TGText.cxx:223
 TGText.cxx:224
 TGText.cxx:225
 TGText.cxx:226
 TGText.cxx:227
 TGText.cxx:228
 TGText.cxx:229
 TGText.cxx:230
 TGText.cxx:231
 TGText.cxx:232
 TGText.cxx:233
 TGText.cxx:234
 TGText.cxx:235
 TGText.cxx:236
 TGText.cxx:237
 TGText.cxx:238
 TGText.cxx:239
 TGText.cxx:240
 TGText.cxx:241
 TGText.cxx:242
 TGText.cxx:243
 TGText.cxx:244
 TGText.cxx:245
 TGText.cxx:246
 TGText.cxx:247
 TGText.cxx:248
 TGText.cxx:249
 TGText.cxx:250
 TGText.cxx:251
 TGText.cxx:252
 TGText.cxx:253
 TGText.cxx:254
 TGText.cxx:255
 TGText.cxx:256
 TGText.cxx:257
 TGText.cxx:258
 TGText.cxx:259
 TGText.cxx:260
 TGText.cxx:261
 TGText.cxx:262
 TGText.cxx:263
 TGText.cxx:264
 TGText.cxx:265
 TGText.cxx:266
 TGText.cxx:267
 TGText.cxx:268
 TGText.cxx:269
 TGText.cxx:270
 TGText.cxx:271
 TGText.cxx:272
 TGText.cxx:273
 TGText.cxx:274
 TGText.cxx:275
 TGText.cxx:276
 TGText.cxx:277
 TGText.cxx:278
 TGText.cxx:279
 TGText.cxx:280
 TGText.cxx:281
 TGText.cxx:282
 TGText.cxx:283
 TGText.cxx:284
 TGText.cxx:285
 TGText.cxx:286
 TGText.cxx:287
 TGText.cxx:288
 TGText.cxx:289
 TGText.cxx:290
 TGText.cxx:291
 TGText.cxx:292
 TGText.cxx:293
 TGText.cxx:294
 TGText.cxx:295
 TGText.cxx:296
 TGText.cxx:297
 TGText.cxx:298
 TGText.cxx:299
 TGText.cxx:300
 TGText.cxx:301
 TGText.cxx:302
 TGText.cxx:303
 TGText.cxx:304
 TGText.cxx:305
 TGText.cxx:306
 TGText.cxx:307
 TGText.cxx:308
 TGText.cxx:309
 TGText.cxx:310
 TGText.cxx:311
 TGText.cxx:312
 TGText.cxx:313
 TGText.cxx:314
 TGText.cxx:315
 TGText.cxx:316
 TGText.cxx:317
 TGText.cxx:318
 TGText.cxx:319
 TGText.cxx:320
 TGText.cxx:321
 TGText.cxx:322
 TGText.cxx:323
 TGText.cxx:324
 TGText.cxx:325
 TGText.cxx:326
 TGText.cxx:327
 TGText.cxx:328
 TGText.cxx:329
 TGText.cxx:330
 TGText.cxx:331
 TGText.cxx:332
 TGText.cxx:333
 TGText.cxx:334
 TGText.cxx:335
 TGText.cxx:336
 TGText.cxx:337
 TGText.cxx:338
 TGText.cxx:339
 TGText.cxx:340
 TGText.cxx:341
 TGText.cxx:342
 TGText.cxx:343
 TGText.cxx:344
 TGText.cxx:345
 TGText.cxx:346
 TGText.cxx:347
 TGText.cxx:348
 TGText.cxx:349
 TGText.cxx:350
 TGText.cxx:351
 TGText.cxx:352
 TGText.cxx:353
 TGText.cxx:354
 TGText.cxx:355
 TGText.cxx:356
 TGText.cxx:357
 TGText.cxx:358
 TGText.cxx:359
 TGText.cxx:360
 TGText.cxx:361
 TGText.cxx:362
 TGText.cxx:363
 TGText.cxx:364
 TGText.cxx:365
 TGText.cxx:366
 TGText.cxx:367
 TGText.cxx:368
 TGText.cxx:369
 TGText.cxx:370
 TGText.cxx:371
 TGText.cxx:372
 TGText.cxx:373
 TGText.cxx:374
 TGText.cxx:375
 TGText.cxx:376
 TGText.cxx:377
 TGText.cxx:378
 TGText.cxx:379
 TGText.cxx:380
 TGText.cxx:381
 TGText.cxx:382
 TGText.cxx:383
 TGText.cxx:384
 TGText.cxx:385
 TGText.cxx:386
 TGText.cxx:387
 TGText.cxx:388
 TGText.cxx:389
 TGText.cxx:390
 TGText.cxx:391
 TGText.cxx:392
 TGText.cxx:393
 TGText.cxx:394
 TGText.cxx:395
 TGText.cxx:396
 TGText.cxx:397
 TGText.cxx:398
 TGText.cxx:399
 TGText.cxx:400
 TGText.cxx:401
 TGText.cxx:402
 TGText.cxx:403
 TGText.cxx:404
 TGText.cxx:405
 TGText.cxx:406
 TGText.cxx:407
 TGText.cxx:408
 TGText.cxx:409
 TGText.cxx:410
 TGText.cxx:411
 TGText.cxx:412
 TGText.cxx:413
 TGText.cxx:414
 TGText.cxx:415
 TGText.cxx:416
 TGText.cxx:417
 TGText.cxx:418
 TGText.cxx:419
 TGText.cxx:420
 TGText.cxx:421
 TGText.cxx:422
 TGText.cxx:423
 TGText.cxx:424
 TGText.cxx:425
 TGText.cxx:426
 TGText.cxx:427
 TGText.cxx:428
 TGText.cxx:429
 TGText.cxx:430
 TGText.cxx:431
 TGText.cxx:432
 TGText.cxx:433
 TGText.cxx:434
 TGText.cxx:435
 TGText.cxx:436
 TGText.cxx:437
 TGText.cxx:438
 TGText.cxx:439
 TGText.cxx:440
 TGText.cxx:441
 TGText.cxx:442
 TGText.cxx:443
 TGText.cxx:444
 TGText.cxx:445
 TGText.cxx:446
 TGText.cxx:447
 TGText.cxx:448
 TGText.cxx:449
 TGText.cxx:450
 TGText.cxx:451
 TGText.cxx:452
 TGText.cxx:453
 TGText.cxx:454
 TGText.cxx:455
 TGText.cxx:456
 TGText.cxx:457
 TGText.cxx:458
 TGText.cxx:459
 TGText.cxx:460
 TGText.cxx:461
 TGText.cxx:462
 TGText.cxx:463
 TGText.cxx:464
 TGText.cxx:465
 TGText.cxx:466
 TGText.cxx:467
 TGText.cxx:468
 TGText.cxx:469
 TGText.cxx:470
 TGText.cxx:471
 TGText.cxx:472
 TGText.cxx:473
 TGText.cxx:474
 TGText.cxx:475
 TGText.cxx:476
 TGText.cxx:477
 TGText.cxx:478
 TGText.cxx:479
 TGText.cxx:480
 TGText.cxx:481
 TGText.cxx:482
 TGText.cxx:483
 TGText.cxx:484
 TGText.cxx:485
 TGText.cxx:486
 TGText.cxx:487
 TGText.cxx:488
 TGText.cxx:489
 TGText.cxx:490
 TGText.cxx:491
 TGText.cxx:492
 TGText.cxx:493
 TGText.cxx:494
 TGText.cxx:495
 TGText.cxx:496
 TGText.cxx:497
 TGText.cxx:498
 TGText.cxx:499
 TGText.cxx:500
 TGText.cxx:501
 TGText.cxx:502
 TGText.cxx:503
 TGText.cxx:504
 TGText.cxx:505
 TGText.cxx:506
 TGText.cxx:507
 TGText.cxx:508
 TGText.cxx:509
 TGText.cxx:510
 TGText.cxx:511
 TGText.cxx:512
 TGText.cxx:513
 TGText.cxx:514
 TGText.cxx:515
 TGText.cxx:516
 TGText.cxx:517
 TGText.cxx:518
 TGText.cxx:519
 TGText.cxx:520
 TGText.cxx:521
 TGText.cxx:522
 TGText.cxx:523
 TGText.cxx:524
 TGText.cxx:525
 TGText.cxx:526
 TGText.cxx:527
 TGText.cxx:528
 TGText.cxx:529
 TGText.cxx:530
 TGText.cxx:531
 TGText.cxx:532
 TGText.cxx:533
 TGText.cxx:534
 TGText.cxx:535
 TGText.cxx:536
 TGText.cxx:537
 TGText.cxx:538
 TGText.cxx:539
 TGText.cxx:540
 TGText.cxx:541
 TGText.cxx:542
 TGText.cxx:543
 TGText.cxx:544
 TGText.cxx:545
 TGText.cxx:546
 TGText.cxx:547
 TGText.cxx:548
 TGText.cxx:549
 TGText.cxx:550
 TGText.cxx:551
 TGText.cxx:552
 TGText.cxx:553
 TGText.cxx:554
 TGText.cxx:555
 TGText.cxx:556
 TGText.cxx:557
 TGText.cxx:558
 TGText.cxx:559
 TGText.cxx:560
 TGText.cxx:561
 TGText.cxx:562
 TGText.cxx:563
 TGText.cxx:564
 TGText.cxx:565
 TGText.cxx:566
 TGText.cxx:567
 TGText.cxx:568
 TGText.cxx:569
 TGText.cxx:570
 TGText.cxx:571
 TGText.cxx:572
 TGText.cxx:573
 TGText.cxx:574
 TGText.cxx:575
 TGText.cxx:576
 TGText.cxx:577
 TGText.cxx:578
 TGText.cxx:579
 TGText.cxx:580
 TGText.cxx:581
 TGText.cxx:582
 TGText.cxx:583
 TGText.cxx:584
 TGText.cxx:585
 TGText.cxx:586
 TGText.cxx:587
 TGText.cxx:588
 TGText.cxx:589
 TGText.cxx:590
 TGText.cxx:591
 TGText.cxx:592
 TGText.cxx:593
 TGText.cxx:594
 TGText.cxx:595
 TGText.cxx:596
 TGText.cxx:597
 TGText.cxx:598
 TGText.cxx:599
 TGText.cxx:600
 TGText.cxx:601
 TGText.cxx:602
 TGText.cxx:603
 TGText.cxx:604
 TGText.cxx:605
 TGText.cxx:606
 TGText.cxx:607
 TGText.cxx:608
 TGText.cxx:609
 TGText.cxx:610
 TGText.cxx:611
 TGText.cxx:612
 TGText.cxx:613
 TGText.cxx:614
 TGText.cxx:615
 TGText.cxx:616
 TGText.cxx:617
 TGText.cxx:618
 TGText.cxx:619
 TGText.cxx:620
 TGText.cxx:621
 TGText.cxx:622
 TGText.cxx:623
 TGText.cxx:624
 TGText.cxx:625
 TGText.cxx:626
 TGText.cxx:627
 TGText.cxx:628
 TGText.cxx:629
 TGText.cxx:630
 TGText.cxx:631
 TGText.cxx:632
 TGText.cxx:633
 TGText.cxx:634
 TGText.cxx:635
 TGText.cxx:636
 TGText.cxx:637
 TGText.cxx:638
 TGText.cxx:639
 TGText.cxx:640
 TGText.cxx:641
 TGText.cxx:642
 TGText.cxx:643
 TGText.cxx:644
 TGText.cxx:645
 TGText.cxx:646
 TGText.cxx:647
 TGText.cxx:648
 TGText.cxx:649
 TGText.cxx:650
 TGText.cxx:651
 TGText.cxx:652
 TGText.cxx:653
 TGText.cxx:654
 TGText.cxx:655
 TGText.cxx:656
 TGText.cxx:657
 TGText.cxx:658
 TGText.cxx:659
 TGText.cxx:660
 TGText.cxx:661
 TGText.cxx:662
 TGText.cxx:663
 TGText.cxx:664
 TGText.cxx:665
 TGText.cxx:666
 TGText.cxx:667
 TGText.cxx:668
 TGText.cxx:669
 TGText.cxx:670
 TGText.cxx:671
 TGText.cxx:672
 TGText.cxx:673
 TGText.cxx:674
 TGText.cxx:675
 TGText.cxx:676
 TGText.cxx:677
 TGText.cxx:678
 TGText.cxx:679
 TGText.cxx:680
 TGText.cxx:681
 TGText.cxx:682
 TGText.cxx:683
 TGText.cxx:684
 TGText.cxx:685
 TGText.cxx:686
 TGText.cxx:687
 TGText.cxx:688
 TGText.cxx:689
 TGText.cxx:690
 TGText.cxx:691
 TGText.cxx:692
 TGText.cxx:693
 TGText.cxx:694
 TGText.cxx:695
 TGText.cxx:696
 TGText.cxx:697
 TGText.cxx:698
 TGText.cxx:699
 TGText.cxx:700
 TGText.cxx:701
 TGText.cxx:702
 TGText.cxx:703
 TGText.cxx:704
 TGText.cxx:705
 TGText.cxx:706
 TGText.cxx:707
 TGText.cxx:708
 TGText.cxx:709
 TGText.cxx:710
 TGText.cxx:711
 TGText.cxx:712
 TGText.cxx:713
 TGText.cxx:714
 TGText.cxx:715
 TGText.cxx:716
 TGText.cxx:717
 TGText.cxx:718
 TGText.cxx:719
 TGText.cxx:720
 TGText.cxx:721
 TGText.cxx:722
 TGText.cxx:723
 TGText.cxx:724
 TGText.cxx:725
 TGText.cxx:726
 TGText.cxx:727
 TGText.cxx:728
 TGText.cxx:729
 TGText.cxx:730
 TGText.cxx:731
 TGText.cxx:732
 TGText.cxx:733
 TGText.cxx:734
 TGText.cxx:735
 TGText.cxx:736
 TGText.cxx:737
 TGText.cxx:738
 TGText.cxx:739
 TGText.cxx:740
 TGText.cxx:741
 TGText.cxx:742
 TGText.cxx:743
 TGText.cxx:744
 TGText.cxx:745
 TGText.cxx:746
 TGText.cxx:747
 TGText.cxx:748
 TGText.cxx:749
 TGText.cxx:750
 TGText.cxx:751
 TGText.cxx:752
 TGText.cxx:753
 TGText.cxx:754
 TGText.cxx:755
 TGText.cxx:756
 TGText.cxx:757
 TGText.cxx:758
 TGText.cxx:759
 TGText.cxx:760
 TGText.cxx:761
 TGText.cxx:762
 TGText.cxx:763
 TGText.cxx:764
 TGText.cxx:765
 TGText.cxx:766
 TGText.cxx:767
 TGText.cxx:768
 TGText.cxx:769
 TGText.cxx:770
 TGText.cxx:771
 TGText.cxx:772
 TGText.cxx:773
 TGText.cxx:774
 TGText.cxx:775
 TGText.cxx:776
 TGText.cxx:777
 TGText.cxx:778
 TGText.cxx:779
 TGText.cxx:780
 TGText.cxx:781
 TGText.cxx:782
 TGText.cxx:783
 TGText.cxx:784
 TGText.cxx:785
 TGText.cxx:786
 TGText.cxx:787
 TGText.cxx:788
 TGText.cxx:789
 TGText.cxx:790
 TGText.cxx:791
 TGText.cxx:792
 TGText.cxx:793
 TGText.cxx:794
 TGText.cxx:795
 TGText.cxx:796
 TGText.cxx:797
 TGText.cxx:798
 TGText.cxx:799
 TGText.cxx:800
 TGText.cxx:801
 TGText.cxx:802
 TGText.cxx:803
 TGText.cxx:804
 TGText.cxx:805
 TGText.cxx:806
 TGText.cxx:807
 TGText.cxx:808
 TGText.cxx:809
 TGText.cxx:810
 TGText.cxx:811
 TGText.cxx:812
 TGText.cxx:813
 TGText.cxx:814
 TGText.cxx:815
 TGText.cxx:816
 TGText.cxx:817
 TGText.cxx:818
 TGText.cxx:819
 TGText.cxx:820
 TGText.cxx:821
 TGText.cxx:822
 TGText.cxx:823
 TGText.cxx:824
 TGText.cxx:825
 TGText.cxx:826
 TGText.cxx:827
 TGText.cxx:828
 TGText.cxx:829
 TGText.cxx:830
 TGText.cxx:831
 TGText.cxx:832
 TGText.cxx:833
 TGText.cxx:834
 TGText.cxx:835
 TGText.cxx:836
 TGText.cxx:837
 TGText.cxx:838
 TGText.cxx:839
 TGText.cxx:840
 TGText.cxx:841
 TGText.cxx:842
 TGText.cxx:843
 TGText.cxx:844
 TGText.cxx:845
 TGText.cxx:846
 TGText.cxx:847
 TGText.cxx:848
 TGText.cxx:849
 TGText.cxx:850
 TGText.cxx:851
 TGText.cxx:852
 TGText.cxx:853
 TGText.cxx:854
 TGText.cxx:855
 TGText.cxx:856
 TGText.cxx:857
 TGText.cxx:858
 TGText.cxx:859
 TGText.cxx:860
 TGText.cxx:861
 TGText.cxx:862
 TGText.cxx:863
 TGText.cxx:864
 TGText.cxx:865
 TGText.cxx:866
 TGText.cxx:867
 TGText.cxx:868
 TGText.cxx:869
 TGText.cxx:870
 TGText.cxx:871
 TGText.cxx:872
 TGText.cxx:873
 TGText.cxx:874
 TGText.cxx:875
 TGText.cxx:876
 TGText.cxx:877
 TGText.cxx:878
 TGText.cxx:879
 TGText.cxx:880
 TGText.cxx:881
 TGText.cxx:882
 TGText.cxx:883
 TGText.cxx:884
 TGText.cxx:885
 TGText.cxx:886
 TGText.cxx:887
 TGText.cxx:888
 TGText.cxx:889
 TGText.cxx:890
 TGText.cxx:891
 TGText.cxx:892
 TGText.cxx:893
 TGText.cxx:894
 TGText.cxx:895
 TGText.cxx:896
 TGText.cxx:897
 TGText.cxx:898
 TGText.cxx:899
 TGText.cxx:900
 TGText.cxx:901
 TGText.cxx:902
 TGText.cxx:903
 TGText.cxx:904
 TGText.cxx:905
 TGText.cxx:906
 TGText.cxx:907
 TGText.cxx:908
 TGText.cxx:909
 TGText.cxx:910
 TGText.cxx:911
 TGText.cxx:912
 TGText.cxx:913
 TGText.cxx:914
 TGText.cxx:915
 TGText.cxx:916
 TGText.cxx:917
 TGText.cxx:918
 TGText.cxx:919
 TGText.cxx:920
 TGText.cxx:921
 TGText.cxx:922
 TGText.cxx:923
 TGText.cxx:924
 TGText.cxx:925
 TGText.cxx:926
 TGText.cxx:927
 TGText.cxx:928
 TGText.cxx:929
 TGText.cxx:930
 TGText.cxx:931
 TGText.cxx:932
 TGText.cxx:933
 TGText.cxx:934
 TGText.cxx:935
 TGText.cxx:936
 TGText.cxx:937
 TGText.cxx:938
 TGText.cxx:939
 TGText.cxx:940
 TGText.cxx:941
 TGText.cxx:942
 TGText.cxx:943
 TGText.cxx:944
 TGText.cxx:945
 TGText.cxx:946
 TGText.cxx:947
 TGText.cxx:948
 TGText.cxx:949
 TGText.cxx:950
 TGText.cxx:951
 TGText.cxx:952
 TGText.cxx:953
 TGText.cxx:954
 TGText.cxx:955
 TGText.cxx:956
 TGText.cxx:957
 TGText.cxx:958
 TGText.cxx:959
 TGText.cxx:960
 TGText.cxx:961
 TGText.cxx:962
 TGText.cxx:963
 TGText.cxx:964
 TGText.cxx:965
 TGText.cxx:966
 TGText.cxx:967
 TGText.cxx:968
 TGText.cxx:969
 TGText.cxx:970
 TGText.cxx:971
 TGText.cxx:972
 TGText.cxx:973
 TGText.cxx:974
 TGText.cxx:975
 TGText.cxx:976
 TGText.cxx:977
 TGText.cxx:978
 TGText.cxx:979
 TGText.cxx:980
 TGText.cxx:981
 TGText.cxx:982
 TGText.cxx:983
 TGText.cxx:984
 TGText.cxx:985
 TGText.cxx:986
 TGText.cxx:987
 TGText.cxx:988
 TGText.cxx:989
 TGText.cxx:990
 TGText.cxx:991
 TGText.cxx:992
 TGText.cxx:993
 TGText.cxx:994
 TGText.cxx:995
 TGText.cxx:996
 TGText.cxx:997
 TGText.cxx:998
 TGText.cxx:999
 TGText.cxx:1000
 TGText.cxx:1001
 TGText.cxx:1002
 TGText.cxx:1003
 TGText.cxx:1004
 TGText.cxx:1005
 TGText.cxx:1006
 TGText.cxx:1007
 TGText.cxx:1008
 TGText.cxx:1009
 TGText.cxx:1010
 TGText.cxx:1011
 TGText.cxx:1012
 TGText.cxx:1013
 TGText.cxx:1014
 TGText.cxx:1015
 TGText.cxx:1016
 TGText.cxx:1017
 TGText.cxx:1018
 TGText.cxx:1019
 TGText.cxx:1020
 TGText.cxx:1021
 TGText.cxx:1022
 TGText.cxx:1023
 TGText.cxx:1024
 TGText.cxx:1025
 TGText.cxx:1026
 TGText.cxx:1027
 TGText.cxx:1028
 TGText.cxx:1029
 TGText.cxx:1030
 TGText.cxx:1031
 TGText.cxx:1032
 TGText.cxx:1033
 TGText.cxx:1034
 TGText.cxx:1035
 TGText.cxx:1036
 TGText.cxx:1037
 TGText.cxx:1038
 TGText.cxx:1039
 TGText.cxx:1040
 TGText.cxx:1041
 TGText.cxx:1042
 TGText.cxx:1043
 TGText.cxx:1044
 TGText.cxx:1045
 TGText.cxx:1046
 TGText.cxx:1047
 TGText.cxx:1048
 TGText.cxx:1049
 TGText.cxx:1050
 TGText.cxx:1051
 TGText.cxx:1052
 TGText.cxx:1053
 TGText.cxx:1054
 TGText.cxx:1055
 TGText.cxx:1056
 TGText.cxx:1057
 TGText.cxx:1058
 TGText.cxx:1059
 TGText.cxx:1060
 TGText.cxx:1061
 TGText.cxx:1062
 TGText.cxx:1063
 TGText.cxx:1064
 TGText.cxx:1065
 TGText.cxx:1066
 TGText.cxx:1067
 TGText.cxx:1068
 TGText.cxx:1069
 TGText.cxx:1070
 TGText.cxx:1071
 TGText.cxx:1072
 TGText.cxx:1073
 TGText.cxx:1074
 TGText.cxx:1075
 TGText.cxx:1076
 TGText.cxx:1077
 TGText.cxx:1078
 TGText.cxx:1079
 TGText.cxx:1080
 TGText.cxx:1081
 TGText.cxx:1082
 TGText.cxx:1083
 TGText.cxx:1084
 TGText.cxx:1085
 TGText.cxx:1086
 TGText.cxx:1087
 TGText.cxx:1088
 TGText.cxx:1089
 TGText.cxx:1090
 TGText.cxx:1091
 TGText.cxx:1092
 TGText.cxx:1093
 TGText.cxx:1094
 TGText.cxx:1095
 TGText.cxx:1096
 TGText.cxx:1097
 TGText.cxx:1098
 TGText.cxx:1099
 TGText.cxx:1100
 TGText.cxx:1101
 TGText.cxx:1102
 TGText.cxx:1103
 TGText.cxx:1104
 TGText.cxx:1105
 TGText.cxx:1106
 TGText.cxx:1107
 TGText.cxx:1108
 TGText.cxx:1109
 TGText.cxx:1110
 TGText.cxx:1111
 TGText.cxx:1112
 TGText.cxx:1113
 TGText.cxx:1114
 TGText.cxx:1115
 TGText.cxx:1116
 TGText.cxx:1117
 TGText.cxx:1118
 TGText.cxx:1119
 TGText.cxx:1120
 TGText.cxx:1121
 TGText.cxx:1122
 TGText.cxx:1123
 TGText.cxx:1124
 TGText.cxx:1125
 TGText.cxx:1126
 TGText.cxx:1127
 TGText.cxx:1128
 TGText.cxx:1129
 TGText.cxx:1130
 TGText.cxx:1131
 TGText.cxx:1132
 TGText.cxx:1133
 TGText.cxx:1134
 TGText.cxx:1135
 TGText.cxx:1136
 TGText.cxx:1137
 TGText.cxx:1138
 TGText.cxx:1139
 TGText.cxx:1140
 TGText.cxx:1141
 TGText.cxx:1142
 TGText.cxx:1143
 TGText.cxx:1144
 TGText.cxx:1145
 TGText.cxx:1146
 TGText.cxx:1147
 TGText.cxx:1148
 TGText.cxx:1149
 TGText.cxx:1150
 TGText.cxx:1151
 TGText.cxx:1152
 TGText.cxx:1153
 TGText.cxx:1154
 TGText.cxx:1155
 TGText.cxx:1156
 TGText.cxx:1157
 TGText.cxx:1158
 TGText.cxx:1159
 TGText.cxx:1160
 TGText.cxx:1161
 TGText.cxx:1162
 TGText.cxx:1163
 TGText.cxx:1164
 TGText.cxx:1165
 TGText.cxx:1166
 TGText.cxx:1167
 TGText.cxx:1168
 TGText.cxx:1169
 TGText.cxx:1170
 TGText.cxx:1171
 TGText.cxx:1172
 TGText.cxx:1173
 TGText.cxx:1174
 TGText.cxx:1175
 TGText.cxx:1176
 TGText.cxx:1177
 TGText.cxx:1178
 TGText.cxx:1179
 TGText.cxx:1180
 TGText.cxx:1181
 TGText.cxx:1182
 TGText.cxx:1183
 TGText.cxx:1184
 TGText.cxx:1185
 TGText.cxx:1186
 TGText.cxx:1187
 TGText.cxx:1188
 TGText.cxx:1189
 TGText.cxx:1190
 TGText.cxx:1191
 TGText.cxx:1192
 TGText.cxx:1193
 TGText.cxx:1194
 TGText.cxx:1195
 TGText.cxx:1196
 TGText.cxx:1197
 TGText.cxx:1198
 TGText.cxx:1199
 TGText.cxx:1200
 TGText.cxx:1201
 TGText.cxx:1202
 TGText.cxx:1203
 TGText.cxx:1204
 TGText.cxx:1205
 TGText.cxx:1206
 TGText.cxx:1207
 TGText.cxx:1208
 TGText.cxx:1209
 TGText.cxx:1210
 TGText.cxx:1211
 TGText.cxx:1212
 TGText.cxx:1213
 TGText.cxx:1214
 TGText.cxx:1215
 TGText.cxx:1216
 TGText.cxx:1217
 TGText.cxx:1218
 TGText.cxx:1219
 TGText.cxx:1220
 TGText.cxx:1221
 TGText.cxx:1222
 TGText.cxx:1223
 TGText.cxx:1224
 TGText.cxx:1225
 TGText.cxx:1226
 TGText.cxx:1227
 TGText.cxx:1228
 TGText.cxx:1229
 TGText.cxx:1230
 TGText.cxx:1231
 TGText.cxx:1232
 TGText.cxx:1233
 TGText.cxx:1234
 TGText.cxx:1235
 TGText.cxx:1236
 TGText.cxx:1237
 TGText.cxx:1238
 TGText.cxx:1239