]> git.saurik.com Git - wxWidgets.git/blobdiff - user/wxLayout/wxllist.cpp
1) wxGTK now use the new, native implementation of wxTreeCtrl.
[wxWidgets.git] / user / wxLayout / wxllist.cpp
index f563ce256537d7d260bb3bbe34a7eb447f010891..551321b13cc9a92ff60e411191d5d3babea4bbf8 100644 (file)
 #  include   <wx/dc.h>
 #  include   <wx/postscrp.h>
 #  include   <wx/print.h>
+#  include   <wx/log.h>
 #endif
 
 #define   BASELINESTRETCH   12
 
 #ifdef WXLAYOUT_DEBUG
-static const char *_t[] = { "invalid", "text", "cmd", "icon",
-                            "linebreak"};
+static const char *g_aTypeStrings[] = 
+{ 
+   "invalid", "text", "cmd", "icon", "linebreak"
+};
+   
+#  define   wxLayoutDebug        wxLogDebug
+#  define   WXL_VAR(x)           cerr << #x " = " << x ;
+#  define   WXL_DBG_POINT(p)     wxLogDebug(#p ": (%d, %d)", p.x, p.y)
+#  define   WXL_TRACE(f)         wxLogDebug(#f ": ")
+#  define   TypeString(t)        g_aTypeStrings[t]
 
 void
 wxLayoutObjectBase::Debug(void)
 {
    CoordType bl = 0;
-   cerr << _t[GetType()] << ": size=" << GetSize(&bl).x << ","
-        << GetSize(&bl).y << " bl=" << bl
+   wxLogDebug("%s: size = %dx%d, bl = %d",
+              TypeString(GetType()), GetSize(&bl).x, GetSize(&bl).y, bl)
 }
 
-#  define   WXL_VAR(x)   cerr << #x"=" << x << endl;
-#  define   WXL_DBG_POINT(p)   cerr << #p << ": " << p.x << ',' << p.y << endl
-#  define   WXL_TRACE(f)   cerr << #f":" << endl;
 #else 
 #  define   WXL_VAR(x)   
 #  define   WXL_DBG_POINT(p)   
-#  define   WXL_TRACE(f)   
+#  define   WXL_TRACE(f)
+#  define   ShowCurrentObject()
+#  define   TypeString(t)        ""
+inline void wxLayoutDebug(const char *, ...) { }
 #endif
 
+
 //-------------------------- wxLayoutObjectText
 
 wxLayoutObjectText::wxLayoutObjectText(const String &txt)
@@ -89,6 +99,7 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint position, CoordType baseLine,
    position.y += baseLine-m_BaseLine;
    if(draw)
       dc.DrawText(Str(m_Text),position.x,position.y);
+   // Don't remove this, important help for debugging layout.
 #   ifdef   WXLAYOUT_DEBUG
 //   dc.DrawRectangle(position.x, position.y, m_Width, m_Height);
 #   endif
@@ -99,14 +110,14 @@ void
 wxLayoutObjectText::Debug(void)
 {
    wxLayoutObjectBase::Debug();
-   cerr << " `" << m_Text << '\'';
+   wxLogDebug(" `%s`", m_Text.c_str());
 }
 #endif
 
 //-------------------------- wxLayoutObjectIcon
 
 wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon)
-                  : m_Icon(icon)
+   : m_Icon(icon)
 {
 }
 
@@ -193,9 +204,9 @@ wxLayoutList::~wxLayoutList()
 {
    if(m_DefaultSetting)
       delete m_DefaultSetting;
+   // no deletion of objects, they are owned by the list
 }
 
-
 void
 wxLayoutList::LineBreak(void)
 {
@@ -225,6 +236,7 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
 void
 wxLayoutList::SetFont(int family, int size, int style, int weight,
                       int underline, char const *fg, char const *bg)
+
 {
    wxColour const
       * cfg = NULL,
@@ -244,14 +256,15 @@ void
 wxLayoutList::GetSize(CoordType *max_x, CoordType *max_y,
                       CoordType *lineHeight)
 {
-   wxASSERT(max_x); wxASSERT(max_y); wxASSERT(lineHeight);
-   *max_x = m_MaxX;
-   *max_y = m_MaxY;
-   *lineHeight = m_LineHeight;
+   
+   if(max_x) *max_x = m_MaxX;
+   if(max_y) *max_y = m_MaxY;
+   if(lineHeight) *lineHeight = m_LineHeight;
 }
 
 wxLayoutObjectBase *
-wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
+wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const
+                   &findCoords, int pageNo, bool reallyDraw)
 {
    wxLayoutObjectList::iterator i;
 
@@ -273,10 +286,10 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
    CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
 
    // where to draw the cursor
-   wxPoint cursorPosition, cursorSize;
+   wxPoint
+      cursorPosition = wxPoint(0,0),
+      cursorSize = wxPoint(1,baseLineSkip);
    
-   // we trace the objects' cursor positions so we can draw the cursor
-   wxPoint cursor = wxPoint(0,0);
    // the cursor position inside the object
    CoordType cursorOffset = 0;
    // object under cursor
@@ -299,21 +312,16 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       int top, bottom, left, right;
    } margins;
 
-   if(
-#ifdef __WXMSW__
-      dc.IsKindOf(CLASSINFO(wxPrinterDC)) ||
-#endif
-      dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
+   int currentPage = 1;
+   
+   if(pageNo > 0)
    {
-      WXL_VAR(wxThePrintSetupData);
-      
       dc.GetSize(&pageWidth, &pageHeight);
-      dc.StartDoc(_("Printing..."));
-      dc.StartPage();
-      margins.top = (1*pageHeight)/10;    // 10%
-      margins.bottom = (9*pageHeight)/10; // 90%
-      margins.left = (1*pageWidth)/10;
-      margins.right = (9*pageWidth)/10;
+      WXL_VAR(pageHeight);
+      margins.top = 0;   //(1*pageHeight)/10;    // 10%
+      margins.bottom = pageHeight;// (9*pageHeight)/10; // 90%
+      margins.left = 0;  //(1*pageWidth)/10;
+      margins.right = pageWidth; //(9*pageWidth)/10;
    }
    else
    {
@@ -321,10 +329,9 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       margins.right = -1;
       margins.bottom = -1;
    }
-   position.y = margins.right;
+   position.y = margins.top;
    position.x = margins.left;
    
-   WXL_VAR(findObject); WXL_VAR(findCoords.x); WXL_VAR(findCoords.y);
    // if the cursorobject is a cmd, we need to find the first
    // printable object:
    while(cursorObject != end()
@@ -357,8 +364,14 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       type = (*i)->GetType();
 
       // to initialise sizes of objects, we need to call Draw
-      (*i)->Draw(dc, position, baseLine, draw);
-
+      if(draw && (pageNo == -1 || pageNo == currentPage))
+      {
+         (*i)->Draw(dc, position, baseLine, draw);
+#ifdef   WXLAYOUT_DEBUG
+         if(i == begin())
+            wxLogDebug("first position = (%d,%d)",(int) position.x, (int)position.y);
+#endif
+      }
       // update coordinates for next object:
       size = (*i)->GetSize(&objBaseLine);
       if(findObject && draw)  // we need to look for an object
@@ -375,38 +388,37 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       // draw the cursor
       if(m_Editable && draw && i == cursorObject)
       {
+         WXL_VAR((**cursorObject).GetType());
+         WXL_VAR(m_CursorPosition.x); WXL_VAR(m_CursorPosition.y);
          if(type == WXLO_TYPE_TEXT) // special treatment
          {
             long descent = 0l; long width, height;
             tobj = (wxLayoutObjectText *)*i;
             String  str = tobj->GetText();
-            WXL_VAR(m_CursorPosition.x); WXL_VAR(cursor.x);
+            WXL_VAR(m_CursorPosition.x);
             str = str.substr(0, cursorOffset);
-            WXL_VAR(str);
             dc.GetTextExtent(Str(str), &width,&height, &descent);
-            WXL_VAR(height);
-            WXL_VAR(width);
-            WXL_VAR(descent);
             cursorPosition = wxPoint(position.x+width,
-                                      position.y+(baseLineSkip-height));
+                                     position.y+(baseLineSkip-height));
             cursorSize = wxPoint(1, height);
-            //dc.DrawLine(position.x+width,
-            //            position.y+(baseLineSkip-height),
-            //            position.x+width, position.y+baseLineSkip);
          }
-         else
+         else if(type == WXLO_TYPE_LINEBREAK)
          {
-            if(type == WXLO_TYPE_LINEBREAK)
-               //dc.DrawLine(0, position.y+baseLineSkip, 0,               position.y+2*baseLineSkip);
-            {
-               cursorPosition = wxPoint(0, position.y);
-               cursorSize = wxPoint(1,baseLineSkip);
-            }
+            WXL_VAR(cursorOffset);
+            if(cursorOffset)
+               cursorPosition = wxPoint(0, position.y+baseLineSkip);
             else
-            {
-               cursorPosition = wxPoint(position.x, position.y);
-               cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
-            }
+               cursorPosition = wxPoint(0, position.y);
+            cursorSize = wxPoint(1,baseLineSkip);
+               
+         }
+         else
+         {
+            // this is not necessarily the most "beautiful" solution:
+            //cursorPosition = wxPoint(position.x, position.y);
+            //cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
+            cursorPosition = wxPoint(position.x+size.x, position.y+(size.y-baseLineSkip));
+            cursorSize = wxPoint(1, baseLineSkip);
          }
       }
 
@@ -441,17 +453,19 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
          {
             // if the this line needs to go onto a new page, we need
             // to change pages before drawing it:
-            if(margins.bottom != -1 && position.y > margins.bottom)
+            if(pageNo > 0 && position.y > margins.bottom)
             {
-               dc.EndPage();
+               currentPage++;
                position_HeadOfLine.y = margins.top;
-               dc.StartPage();
             }
-            // do this line again, this time drawing it
-            position = position_HeadOfLine;
-            draw = true;
-            i = headOfLine;
-            continue;
+            if(reallyDraw && (pageNo == -1 || pageNo == currentPage))
+            {
+               // do this line again, this time drawing it
+               position = position_HeadOfLine;
+               draw = true;
+               i = headOfLine;
+               continue;
+            }
          }
          else // we have drawn a line, so continue calculating next one
             draw = false;
@@ -471,7 +485,6 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       }
       i++;
    }
-   dc.EndDoc();
    // draw the cursor
    if(m_Editable)
    {
@@ -489,38 +502,53 @@ wxLayoutList::Debug(void)
    CoordType               offs;
    wxLayoutObjectList::iterator i;
 
-   cerr <<
-      "------------------------debug start-------------------------" << endl;
+   wxLogDebug("------------------------debug start-------------------------"); 
    for(i = begin(); i != end(); i++)
-   {
       (*i)->Debug();
-      cerr << endl;
-   }
-   cerr <<
-      "-----------------------debug end----------------------------"
-        << endl;
-   // show current object:
-   cerr << "Cursor: "
-        << m_CursorPosition.x << ','
-        << m_CursorPosition.y;
+   wxLogDebug("-----------------------debug end----------------------------");
    
+   // show current object:
+   ShowCurrentObject();
    i = FindCurrentObject(&offs);
-   cerr << " line length: " << GetLineLength(i) << "  ";
+   wxLogDebug(" line length: %l", (long int) GetLineLength(i,offs));
    if(i == end())
    {
-      cerr << "<<no object found>>" << endl;
+      wxLogDebug("<<no object found>>");
       return;  // FIXME we should set cursor position to maximum allowed
       // value then
    }
    if((*i)->GetType() == WXLO_TYPE_TEXT)
+      wxLogDebug(" \"%s\", offs=%d",((wxLayoutObjectText *)(*i))->GetText().c_str(), (int) offs);
+   else
+      wxLogDebug(g_aTypeStrings[(*i)->GetType()]);
+
+}
+
+void
+wxLayoutList::ShowCurrentObject()
+{
+   CoordType offs;
+   wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
+
+   wxLayoutDebug("Cursor is at (%d, %d)",
+                 m_CursorPosition.x, m_CursorPosition.y);
+
+   i = FindCurrentObject(&offs);
+   wxLogDebug(" Line length: %d", GetLineLength(i));
+
+   if(i == end())
    {
-      cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
-           << offs << endl;
+      wxLogDebug("<<no object found>>");
+      return;  // FIXME we should set cursor position to maximum allowed
+// value then
    }
+   if((*i)->GetType() == WXLO_TYPE_TEXT)
+      wxLogDebug(" \"%s\", offs: %d",
+                 ((wxLayoutObjectText *)(*i))->GetText().c_str(), offs);
    else
-      cerr << ' ' << _t[(*i)->GetType()] << endl;
-
+      wxLogDebug(" %s", TypeString((*i)->GetType()));
 }
+
 #endif
 
 /******************** editing stuff ********************/
@@ -547,8 +575,7 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
    wxLayoutObjectList::iterator i;
 
 #ifdef WXLAYOUT_DEBUG
-   cerr << "Looking for object at " << cpos->x << ',' << cpos->y <<
-      endl;
+   wxLayoutDebug("Looking for object at (%d, %d)", cpos->x, cpos->y);
 #endif
    for(i = begin(); i != end() && object.y <= cpos->y; i++)
    {
@@ -559,10 +586,10 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
          {
             if(cpos->x == object.x)
             {
-               *offset = 0;
+               if(offset) *offset = 0;
                return i;
             }
-            *offset=1;
+            if(offset) *offset=1;
             cpos->x = object.x;
             return i;
          }
@@ -570,13 +597,13 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
          {
             if(offset) *offset = cpos->x-object.x;
 #ifdef WXLAYOUT_DEBUG
-            cerr << "   found object at " << object.x << ',' <<
-               object.y << ", type:" << _t[(*i)->GetType()] <<endl;
+            wxLayoutDebug("   found object at (%d, %d), type: %s",
+                          object.x,  object.y, TypeString((*i)->GetType()));
 #endif      
             return i;
          }
       }
-      // no overlap, increment coordinates
+// no overlap, increment coordinates
       object.x += width;
       if((**i).GetType() == WXLO_TYPE_LINEBREAK)
       {
@@ -585,22 +612,22 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
       }
    }
 #ifdef WXLAYOUT_DEBUG
-   cerr << "   not found" << endl;
+   wxLayoutDebug("   not found");
 #endif
-   // return last object, coordinates of that one:
+// return last object, coordinates of that one:
    i = tail();
    if(i == end())
       return i;
    if((**i).GetType()==WXLO_TYPE_LINEBREAK)
    {
       if(offset)
-         *offset = (cpos.x > object.x) : 1 : 0;
+         *offset = 1;
       return i;
    }
    cpos->x = object.x; // would be the coordinate of next object
    cpos->y = object.y;
    cpos->x += width; // last object's width
-   if(*offset)  *offset = cpos->x-object.x
+   if(*offset)  *offset = cpos->x-object.x;
    return i; // not found
 }
 
@@ -619,26 +646,33 @@ wxLayoutList::FindCurrentObject(CoordType *offset)
    return obj;
 }
 
-void
+bool
 wxLayoutList::MoveCursor(int dx, int dy)
 {
    CoordType offs, lineLength;
    wxLayoutObjectList::iterator i;
 
+   bool rc = true; // have we moved?
 
    if(dy > 0 && m_CursorPosition.y < m_MaxLine)
       m_CursorPosition.y += dy;
    else if(dy < 0 && m_CursorPosition.y > 0)
       m_CursorPosition.y += dy; // dy is negative
    if(m_CursorPosition.y < 0)
+   {
       m_CursorPosition.y = 0;
+      rc = false;
+   }
    else if (m_CursorPosition.y > m_MaxLine)
+   {
       m_CursorPosition.y = m_MaxLine;
+      rc = false;
+   }
    
    while(dx > 0)
    {
       i = FindCurrentObject(&offs);
-      lineLength = GetLineLength(i);
+      lineLength = GetLineLength(i,offs);
       if(m_CursorPosition.x < lineLength)
       {
          m_CursorPosition.x ++;
@@ -654,7 +688,10 @@ wxLayoutList::MoveCursor(int dx, int dy)
             dx--;
          }
          else
+         {
+            rc = false;
             break; // cannot move there
+         }
       }
    }
    while(dx < 0)
@@ -671,41 +708,30 @@ wxLayoutList::MoveCursor(int dx, int dy)
             m_CursorPosition.y --;
             m_CursorPosition.x = 0;
             i = FindCurrentObject(&offs);
-            lineLength = GetLineLength(i);
+            lineLength = GetLineLength(i,offs);
             m_CursorPosition.x = lineLength;
             dx++;
             continue;
          }
          else
+         {
+            rc = false;
             break; // cannot move left any more
+         }
       }
    }
-   // final adjustment:
+// final adjustment:
    i = FindCurrentObject(&offs);
-   lineLength = GetLineLength(i);
+   lineLength = GetLineLength(i,offs);
    if(m_CursorPosition.x > lineLength)
-      m_CursorPosition.x = lineLength;
-      
-#ifdef   WXLAYOUT_DEBUG
-   i = FindCurrentObject(&offs);
-   cerr << "Cursor: "
-        << m_CursorPosition.x << ','
-        << m_CursorPosition.y;
-
-   if(i == end())
-   {
-      cerr << "<<no object found>>" << endl;
-      return;  // FIXME we should set cursor position to maximum allowed
-      // value then
-   }
-   if((*i)->GetType() == WXLO_TYPE_TEXT)
    {
-      cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
-           << offs << endl;
+      m_CursorPosition.x = lineLength;
+      rc = false;
    }
-   else
-      cerr << ' ' << _t[(*i)->GetType()] << endl;
+#ifdef   WXLAYOUT_DEBUG
+   ShowCurrentObject();
 #endif
+   return rc;
 }
 
 void
@@ -728,8 +754,8 @@ wxLayoutList::Delete(CoordType count)
       if(i == end())
          return; // we cannot delete anything more
 
-      /* Here we need to treat linebreaks differently.
-         If offs==0 we are before the linebreak, otherwise behind.  */
+/* Here we need to treat linebreaks differently.
+   If offs==0 we are before the linebreak, otherwise behind.  */
       if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
       {
          if(offs == 0)
@@ -750,8 +776,8 @@ wxLayoutList::Delete(CoordType count)
       {
          wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
          CoordType len = tobj->CountPositions();
-         // If we find the end of a text object, this means that we
-         // have to delete from the object following it.
+// If we find the end of a text object, this means that we
+// have to delete from the object following it.
          if(len == offs)
          {
             i++;
@@ -771,11 +797,23 @@ wxLayoutList::Delete(CoordType count)
             return; // we are done
          }
       }
-      else // all other objects: delete the object
+      else// all other objects: delete the object
+// this only works as expected  if the non-text object has 0/1
+// as offset values. Not tested with "longer" objects.
       {
          CoordType len = (*i)->CountPositions();
-         erase(i); // after this, i is the iterator for the following object
-         count = count > len ? count -= len : 0;
+         if(offs == 0)
+         {
+            count = count > len ? count -= len : 0;
+            erase(i); // after this, i is the iterator for the following object
+            continue;
+         }
+         else // delete the following object
+         {
+            i++; // we increment and continue as normal
+            offs=0;
+            goto startover; 
+         }
       }
    }
    while(count && i != end());      
@@ -794,24 +832,24 @@ wxLayoutList::Insert(wxLayoutObjectBase *obj)
       push_back(obj);
    else if(offs == 0)
       insert(i,obj);
-   // do we have to split a text object?
+// do we have to split a text object?
    else if((*i)->GetType() == WXLO_TYPE_TEXT && offs != (*i)->CountPositions())
    {
       wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
 #ifdef WXLAYOUT_DEBUG
-      cerr << "text: '" << tobj->GetText() << "'" << endl;
+      wxLayoutDebug("text: %s", tobj->GetText().c_str());
       WXL_VAR(offs);
 #endif
       String left = tobj->GetText().substr(0,offs); // get part before cursor
-      WXL_VAR(left);
+      WXL_VAR(left.c_str());
       tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half
-      WXL_VAR(tobj->GetText());
+      WXL_VAR(tobj->GetText().c_str());
       insert(i,obj);
       insert(i,new wxLayoutObjectText(left)); // inserts before
    }
    else
    {
-     // all other cases, append after object:
+// all other cases, append after object:
       wxLayoutObjectList::iterator j = i; // we want to apend after this object
       j++;
       if(j != end())
@@ -829,6 +867,8 @@ void
 wxLayoutList::Insert(String const &text)
 {
    wxLayoutObjectText *tobj = NULL;
+   wxLayoutObjectList::iterator j;
+
    WXL_TRACE(Insert(text));
 
    if(! m_Editable)
@@ -837,22 +877,59 @@ wxLayoutList::Insert(String const &text)
    CoordType offs;
    wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
 
-   if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
-   {  // insert into an existing text object:
+   if(i == end())
+   {
+      Insert(new wxLayoutObjectText(text));
+      return;
+   }
+
+   switch((**i).GetType())
+   {
+   case WXLO_TYPE_TEXT:
+// insert into an existing text object:
       WXL_TRACE(inserting into existing object);
       tobj = (wxLayoutObjectText *)*i ;
       wxASSERT(tobj);
       tobj->GetText().insert(offs,text);
-   }
-   else      // check whether the previous object is text:
-   {
-      wxLayoutObjectList::iterator j = i;
-      j--;
+      break;
+   case WXLO_TYPE_LINEBREAK:
+   default:
+      j = i;
+      if(offs == 0) // try to append to previous object
+      {
+         j--;
+         if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
+         {
+            tobj = (wxLayoutObjectText *)*j;
+            tobj->GetText()+=text;
+         }
+         else
+            insert(i,new wxLayoutObjectText(text));
+      }
+      else // cursor after linebreak
+      {
+         j++;
+         if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
+         {
+            tobj = (wxLayoutObjectText *)*j;
+            tobj->GetText()=text+tobj->GetText();
+         }
+         else
+         {
+            if(j == end())
+               push_back(new wxLayoutObjectText(text));
+            else
+               insert(j,new wxLayoutObjectText(text));
+         }
+      }
+      break;
+#if 0
+   default:
+      j = i; j--;
       WXL_TRACE(checking previous object);
-      if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
+      if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
       {
-         tobj = (wxLayoutObjectText *)*i;
-         wxASSERT(tobj);
+         tobj = (wxLayoutObjectText *)*j;
          tobj->GetText()+=text;
       }
       else  // insert a new text object
@@ -861,24 +938,28 @@ wxLayoutList::Insert(String const &text)
          Insert(new wxLayoutObjectText(text));  //FIXME not too optimal, slow
          return;  // position gets incremented in Insert(obj)
       }
+#endif
    }
    m_CursorPosition.x += strlen(text.c_str());
 }
 
 CoordType
-wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
+wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i, CoordType offs)
 {
    if(i == end())
       return 0;
 
    CoordType len = 0;
 
-   // search backwards for beginning of line:
+   if(offs == 0 && (**i).GetType() == WXLO_TYPE_LINEBREAK)
+// we are before a linebrak
+      return 0;
+// search backwards for beginning of line:
    while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
       i--;
    if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
       i++;
-   // now we can start counting:
+// now we can start counting:
    while(i != end() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
    {
       len += (*i)->CountPositions();
@@ -896,7 +977,7 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
    while(i != end()) // == while valid
       erase(i);
 
-   // set defaults
+// set defaults
    m_FontPtSize = size;
    m_FontUnderline = false;
    m_FontFamily = family;
@@ -922,3 +1003,79 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
                         m_FontWeight,m_FontUnderline,
                         m_ColourFG, m_ColourBG);
 }
+
+
+
+/******************** printing stuff ********************/
+
+bool wxLayoutPrintout::OnPrintPage(int page)
+{
+  wxDC *dc = GetDC();
+  if (dc)
+  {
+     m_llist->Draw(*dc,false,wxPoint(0,0),page);
+     return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+bool wxLayoutPrintout::OnBeginDocument(int startPage, int endPage)
+{
+  if (!wxPrintout::OnBeginDocument(startPage, endPage))
+    return FALSE;
+
+  return TRUE;
+}
+
+void wxLayoutPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
+{
+
+   // This code doesn't work, because we don't have a DC yet.
+   // How on earth are we supposed to calculate the number of pages then?
+   *minPage = 0;    // set this to 0 to disable editing of page numbers 
+   *maxPage = 100;
+
+   *selPageFrom = 0; // set this to 0 to hide page number controls
+   *selPageTo = 100;  
+
+//   *minPage = 1;
+//   *maxPage = 32000;
+
+//   *selPageFrom = 1;
+//   *selPageTo = 1;
+
+#if 0
+   CoordType height;
+   int pageWidth, pageHeight;
+
+   wxDC *dc = GetDC();
+   wxASSERT(dc);
+
+   dc->GetSize(&pageWidth, &pageHeight);
+// don't draw but just recalculate sizes:
+   m_llist->Draw(*dc,false,wxPoint(0,0),-1,false);
+   m_llist->GetSize(NULL,&height,NULL);
+   
+   *minPage = 1;
+   *maxPage = height/pageHeight+1;
+
+   *selPageFrom = 1;
+   *selPageTo = *maxPage;
+   m_maxPage = *maxPage;
+#endif
+   
+}
+
+bool wxLayoutPrintout::HasPage(int pageNum)
+{
+   return pageNum <= 5; // for testing
+//   return m_maxPage >= pageNum;
+}
+
+
+wxLayoutPrintout *
+wxLayoutList::MakePrintout(wxString const &name)
+{
+   return new wxLayoutPrintout(*this,name);
+}