]> git.saurik.com Git - wxWidgets.git/commitdiff
MSW fixes for wxLayout, part II: now breaking and merging line works too.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 3 Jun 1999 22:36:01 +0000 (22:36 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 3 Jun 1999 22:36:01 +0000 (22:36 +0000)
Scrolling still doesn't :-(

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

user/wxLayout/wxLayout.cpp
user/wxLayout/wxllist.cpp
user/wxLayout/wxllist.h
user/wxLayout/wxlparser.cpp
user/wxLayout/wxlparser.h
user/wxLayout/wxlwindow.cpp

index 41431fbe242d151396e170af84713a13693b565a..75459b8f59f41b14046cad43dfa6d3e39cdd7e37 100644 (file)
@@ -38,7 +38,7 @@ IMPLEMENT_APP(MyApp)
              ID_PRINT_SETUP_PS, ID_PAGE_SETUP_PS,ID_PREVIEW_PS,
              ID_WRAP, ID_NOWRAP, ID_PASTE, ID_COPY, ID_CUT, ID_FIND,
              ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT,
-             ID_TEST, ID_LONG_TEST };
+             ID_TEST, ID_LINEBREAKS_TEST, ID_LONG_TEST, ID_URL_TEST };
 
 
 IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
@@ -59,7 +59,8 @@ IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
 
 
 MyFrame::MyFrame(void) :
-   wxFrame( (wxFrame *) NULL, -1, (char *) "wxLayout", wxPoint(20,20), wxSize(600,360) )
+   wxFrame( (wxFrame *) NULL, -1, "wxLayout",
+             wxPoint(880,100), wxSize(256,256) )
 {
    CreateStatusBar( 2 );
 
@@ -80,24 +81,27 @@ MyFrame::MyFrame(void) :
    file_menu->Append(ID_PREVIEW_PS, "Print Preview PostScript", "Preview (PostScript)");
 #endif
    file_menu->AppendSeparator();
-   file_menu->Append( ID_TEXT, "Export Text");
-   file_menu->Append( ID_HTML, "Export HTML");
-   file_menu->Append( ID_QUIT, "Exit");
-   menu_bar->Append(file_menu, "File" );
+   file_menu->Append( ID_TEXT, "Export &Text");
+   file_menu->Append( ID_HTML, "Export &HTML");
+   file_menu->Append( ID_QUIT, "E&xit");
+   menu_bar->Append(file_menu, "&File" );
 
    wxMenu *edit_menu = new wxMenu;
-   edit_menu->Append( ID_CLEAR, "Clear");
-   edit_menu->Append( ID_ADD_SAMPLE, "Example");
-   edit_menu->Append( ID_LONG_TEST, "Add many lines");
+   edit_menu->Append( ID_CLEAR, "C&lear");
+   edit_menu->Append( ID_ADD_SAMPLE, "&Example");
+   edit_menu->Append( ID_LONG_TEST, "Add &many lines");
    edit_menu->AppendSeparator();
-   edit_menu->Append(ID_WRAP, "Wrap mode", "Activate wrapping at pixel 200.");
-   edit_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping.");
+   edit_menu->Append( ID_LINEBREAKS_TEST, "Add &several lines");
+   edit_menu->Append( ID_URL_TEST, "Insert an &URL");
    edit_menu->AppendSeparator();
-   edit_menu->Append(ID_COPY, "Copy", "Copy text to clipboard.");
-   edit_menu->Append(ID_CUT, "Cut", "Cut text to clipboard.");
-   edit_menu->Append(ID_PASTE,"Paste", "Paste text from clipboard.");
-   edit_menu->Append(ID_FIND, "Find", "Find text.");
-   menu_bar->Append(edit_menu, "Edit" );
+   edit_menu->Append(ID_WRAP, "&Wrap mode", "Activate wrapping at pixel 200.");
+   edit_menu->Append(ID_NOWRAP, "&No-wrap mode", "Deactivate wrapping.");
+   edit_menu->AppendSeparator();
+   edit_menu->Append(ID_COPY, "&Copy", "Copy text to clipboard.");
+   edit_menu->Append(ID_CUT, "Cu&t", "Cut text to clipboard.");
+   edit_menu->Append(ID_PASTE,"&Paste", "Paste text from clipboard.");
+   edit_menu->Append(ID_FIND, "&Find", "Find text.");
+   menu_bar->Append(edit_menu, "&Edit" );
 
 #ifndef __WXMSW__
    menu_bar->Show( TRUE );
@@ -191,8 +195,7 @@ MyFrame::AddSampleText(wxLayoutList *llist)
          fgets(buffer,1024,in);
          if(feof(in))
             break;
-         llist->Insert(buffer);
-         llist->LineBreak();
+         wxLayoutImportText(llist, buffer);
       }
    }
    llist->MoveCursorTo(wxPoint(0,0));
@@ -300,6 +303,19 @@ void MyFrame::OnCommand( wxCommandEvent &event )
       m_lwin->Refresh();
       break;
    }
+
+   case ID_LINEBREAKS_TEST:
+      wxLayoutImportText(m_lwin->GetLayoutList(),
+                         "This is a text\n"
+                         "with embedded line\n"
+                         "breaks.\n");
+      break;
+
+   case ID_URL_TEST:
+      // VZ: this doesn't work, of course, but I think it should -
+      //     wxLayoutWindow should have a flag m_highlightUrls and do it itself
+      //     (instead of doing it manually like M does now)
+      m_lwin->GetLayoutList()->Insert("http://www.wxwindows.org/");
    }
 };
 
index 906aead71a11c6d338f5533e793eda2a67b7eab3..f0e15342f63cedf6ecd51dcb442677ecb501d2f6 100644 (file)
@@ -75,7 +75,7 @@
 //       waste time looking for it right now. Search for occurences of
 //       MSW_CORRECTION to find all the places where I did it.
 #ifdef __WXMSW__
-   static const int MSW_CORRECTION = 10;
+   static const int MSW_CORRECTION = 5;
 #else
    static const int MSW_CORRECTION = 0;
 #endif
@@ -278,10 +278,16 @@ wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList *llist)
 {
    long descent = 0l;
 
+   // now this is done in wxLayoutLine::Layout(), but this code might be
+   // reenabled later - in principle, it's more efficient
+#if 0
    CoordType widthOld = m_Width,
              heightOld = m_Height;
+#endif // 0
+
    dc.GetTextExtent(m_Text, &m_Width, &m_Height, &descent);
 
+#if 0
    if ( widthOld != m_Width || heightOld != m_Height )
    {
       // as the text length changed, it must be refreshed
@@ -302,6 +308,7 @@ wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList *llist)
       llist->SetUpdateRect(position.x + widthOld + MSW_CORRECTION,
                            position.y + heightOld + MSW_CORRECTION);
    }
+#endif // 0
 
    m_Bottom = descent;
    m_Top = m_Height - m_Bottom;
@@ -582,7 +589,7 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist)
    m_LineNumber = 0;
    m_Width = m_Height = 0;
    m_Length = 0;
-   m_Dirty = true;
+   MarkDirty(0);
    m_Previous = prev;
    m_Next = NULL;
    RecalculatePosition(llist);
@@ -610,6 +617,8 @@ wxLayoutLine::RecalculatePosition(wxLayoutList *llist)
 {
    wxASSERT(m_Previous || GetLineNumber() == 0);
 
+   wxPoint posOld(m_Position);
+
    if(m_Previous)
    {
       m_Position = m_Previous->GetPosition();
@@ -617,7 +626,18 @@ wxLayoutLine::RecalculatePosition(wxLayoutList *llist)
    }
    else
       m_Position = wxPoint(0,0);
-   llist->SetUpdateRect(m_Position);
+
+   if ( m_Position != posOld )
+   {
+       // the whole line moved and must be repainted
+       llist->SetUpdateRect(m_Position);
+       llist->SetUpdateRect(m_Position.x + GetWidth() + MSW_CORRECTION,
+                            m_Position.y + GetHeight() + MSW_CORRECTION);
+       llist->SetUpdateRect(posOld);
+       llist->SetUpdateRect(posOld.x + GetWidth() + MSW_CORRECTION,
+                            posOld.y + GetHeight() + MSW_CORRECTION);
+   }
+
    return m_Position;
 }
 
@@ -740,11 +760,8 @@ wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
    wxASSERT(xpos >= 0);
    wxASSERT(obj != NULL);
 
-   // in any case, the object is going to belong to this line
-   obj->AttachToLine(this);
+   MarkDirty(xpos);
 
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
    CoordType offset;
    wxLOiterator i = FindObject(xpos, &offset);
    if(i == NULLIT)
@@ -796,11 +813,12 @@ wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
 }
 
 bool
-wxLayoutLine::Insert(CoordType xpos, wxString text)
+wxLayoutLine::Insert(CoordType xpos, const wxString& text)
 {
    wxASSERT(xpos >= 0);
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
+
+   MarkDirty(xpos);
+
    CoordType offset;
    wxLOiterator i = FindObject(xpos, &offset);
    if(i != NULLIT && (**i).GetType() == WXLO_TYPE_TEXT)
@@ -808,11 +826,14 @@ wxLayoutLine::Insert(CoordType xpos, wxString text)
       wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
       tobj->GetText().insert(offset, text);
       m_Length += text.Length();
-
-      return true;
    }
    else
-      return Insert(xpos, new wxLayoutObjectText(text));
+   {
+      if ( !Insert(xpos, new wxLayoutObjectText(text)) )
+         return false;
+   }
+
+   return true;
 }
 
 CoordType
@@ -822,8 +843,7 @@ wxLayoutLine::Delete(CoordType xpos, CoordType npos)
 
    wxASSERT(xpos >= 0);
    wxASSERT(npos >= 0);
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
+   MarkDirty(xpos);
    wxLOiterator i = FindObject(xpos, &offset);
    while(npos > 0)
    {
@@ -878,8 +898,7 @@ wxLayoutLine::DeleteWord(CoordType xpos)
 {
    wxASSERT(xpos >= 0);
    CoordType offset;
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
+   MarkDirty(xpos);
 
    wxLOiterator i = FindObject(xpos, &offset);
 
@@ -984,23 +1003,29 @@ wxLayoutLine::Layout(wxDC &dc,
 {
    wxLayoutObjectList::iterator i;
 
+   // when a line becomes dirty, we redraw it from the place where it was
+   // changed till the end of line (because the following wxLayoutObjects are
+   // moved when the preceding one changes) - calculate the update rectangle.
+   CoordType updateTop = m_Position.y,
+             updateLeft = -1,
+             updateWidth = m_Width,
+             updateHeight = m_Height;
+
    CoordType
-      oldWidth = m_Width,
-      oldHeight = m_Height;
-   CoordType
-      topHeight, bottomHeight;  // above and below baseline
+      topHeight = 0,
+      bottomHeight = 0;  // above and below baseline
    CoordType
-      objHeight = 0,
-      objTopHeight, objBottomHeight;
+      objTopHeight, objBottomHeight; // above and below baseline
    CoordType
       len, count = 0;
-   m_Height = 0; m_BaseLine = 0;
+
+   CoordType heightOld = m_Height;
+
+   m_Height = 0;
    m_Width = 0;
-   topHeight = 0; bottomHeight = 0;
-   wxPoint size;
-   bool cursorFound = false;
+   m_BaseLine = 0;
 
-   m_Dirty = false;
+   bool cursorFound = false;
 
    if(cursorPos)
    {
@@ -1013,15 +1038,17 @@ wxLayoutLine::Layout(wxDC &dc,
    //llist->ApplyStyle(&m_StyleInfo, dc);
    for(i = m_ObjectList.begin(); i != NULLIT; i++)
    {
-      (**i).Layout(dc, llist);
-      size = (**i).GetSize(&objTopHeight, &objBottomHeight);
+      wxLayoutObject *obj = *i;
+      obj->Layout(dc, llist);
+      wxPoint sizeObj = obj->GetSize(&objTopHeight, &objBottomHeight);
 
       if(cursorPos && ! cursorFound)
-      {  // we need to check whether the text cursor is here
-         len = (**i).GetLength();
+      {
+         // we need to check whether the text cursor is here
+         len = obj->GetLength();
          if(count <= cx && count+len > cx)
          {
-            if((**i).GetType() == WXLO_TYPE_TEXT)
+            if(obj->GetType() == WXLO_TYPE_TEXT)
             {
                len = cx - count; // pos in object
                CoordType width, height, descent;
@@ -1030,7 +1057,7 @@ wxLayoutLine::Layout(wxDC &dc,
                cursorPos->x += width;
                cursorPos->y = m_Position.y;
                wxString str;
-               if(len < (**i).GetLength())
+               if(len < obj->GetLength())
                   str = (*(wxLayoutObjectText*)*i).GetText().substr(len,1);
                else
                   str = WXLO_CURSORCHAR;
@@ -1038,15 +1065,16 @@ wxLayoutLine::Layout(wxDC &dc,
                wxASSERT(cursorSize);
                // Just in case some joker inserted an empty string object:
                if(width == 0) width = WXLO_MINIMUM_CURSOR_WIDTH;
-               if(height == 0) height = objHeight;
+               if(height == 0) height = sizeObj.y;
                cursorSize->x = width;
                cursorSize->y = height;
                cursorFound = true; // no more checks
             }
             else
-            { // on some other object
+            {
+               // on some other object
                CoordType top, bottom; // unused
-               *cursorSize = (**i).GetSize(&top,&bottom);
+               *cursorSize = obj->GetSize(&top,&bottom);
                cursorPos->y = m_Position.y;
                cursorFound = true; // no more checks
             }
@@ -1054,28 +1082,43 @@ wxLayoutLine::Layout(wxDC &dc,
          else
          {
             count += len;
-            cursorPos->x += (**i).GetWidth();
+            cursorPos->x += obj->GetWidth();
          }
       } // cursor finding
-      objHeight = size.y;
-      m_Width += size.x;
-      if(objHeight > m_Height) m_Height = objHeight;
-      if(objTopHeight > topHeight) topHeight = objTopHeight;
-      if(objBottomHeight > bottomHeight) bottomHeight = objBottomHeight;
+
+      m_Width += sizeObj.x;
+      if(sizeObj.y > m_Height)
+      {
+         m_Height = sizeObj.y;
+      }
+
+      if(objTopHeight > topHeight)
+         topHeight = objTopHeight;
+      if(objBottomHeight > bottomHeight)
+         bottomHeight = objBottomHeight;
    }
 
-   // special case of a line which becomes empty (after deletion, for example):
-   // we should invalidate the screen space it occupied (usually this happens
-   // from wxLayoutObject::Layout called in the loop above)
-   if ( m_ObjectList.empty() )
+   if ( IsDirty() )
    {
-      wxPoint position(GetPosition());
-      llist->SetUpdateRect(position.x + oldWidth + MSW_CORRECTION,
-                           position.y + oldHeight + MSW_CORRECTION);
+      if ( updateHeight < m_Height )
+         updateHeight = m_Height;
+      if ( updateWidth < m_Width )
+         updateWidth = m_Width;
+
+      // update all line if we don't know where to start from
+      if ( updateLeft == -1 )
+          updateLeft = 0;
+
+      llist->SetUpdateRect(updateLeft, updateTop);
+      llist->SetUpdateRect(updateLeft + updateWidth + MSW_CORRECTION,
+                           updateTop + updateHeight + MSW_CORRECTION);
    }
 
    if(topHeight + bottomHeight > m_Height)
+   {
       m_Height = topHeight+bottomHeight;
+   }
+
    m_BaseLine = topHeight;
 
    if(m_Height == 0)
@@ -1086,10 +1129,12 @@ wxLayoutLine::Layout(wxDC &dc,
       m_BaseLine = m_Height - descent;
    }
 
-
    // tell next line about coordinate change
-   if(m_Next && objHeight != oldHeight)
+   if(m_Next && m_Height != heightOld)
+   {
+      // FIXME isn't this done in RecalculatePositions() below anyhow?
       m_Next->RecalculatePositions(0, llist);
+   }
 
    // We need to check whether we found a valid cursor size:
    if(cursorPos)
@@ -1106,7 +1151,10 @@ wxLayoutLine::Layout(wxDC &dc,
       if(m_BaseLine >= cursorSize->y) // the normal case anyway
          cursorPos->y += m_BaseLine-cursorSize->y;
    }
+
    RecalculatePositions(1, llist);
+
+   MarkClean();
 }
 
 
@@ -1114,8 +1162,8 @@ wxLayoutLine *
 wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
 {
    wxASSERT(xpos >= 0);
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
+
+   MarkDirty(xpos);
 
    /* If we are at the begin of a line, we want to move all other
       lines down and stay with the cursor where we are. However, if we
@@ -1157,13 +1205,17 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
       i++; // don't move this object to the new list
    }
    else
+   {
       if(offset > 0)
          i++; // move objects from here to new list
+   }
 
    while(i != m_ObjectList.end())
    {
-      newLine->Append(*i);
-      m_Length -= (**i).GetLength();
+      wxLayoutObject *obj = *i;
+      newLine->Append(obj);
+      m_Length -= obj->GetLength();
+
       m_ObjectList.remove(i); // remove without deleting it
    }
    if(m_Next)
@@ -1178,8 +1230,8 @@ wxLayoutLine::MergeNextLine(wxLayoutList *llist)
    wxCHECK_RET(GetNextLine(),"wxLayout internal error: no next line to merge");
    wxLayoutObjectList &list = GetNextLine()->m_ObjectList;
    wxLOiterator i;
-   //FIXME: this could be optimised, for now be prudent:
-   m_Dirty = true;
+
+   MarkDirty(GetWidth());
 
    wxLayoutObject *last = NULL;
    for(i = list.begin(); i != list.end();)
@@ -1200,7 +1252,6 @@ wxLayoutLine::MergeNextLine(wxLayoutList *llist)
       else
       {
          // just append the object "as was"
-         current->UnattachFromLine();
          Append(current);
 
          list.remove(i); // remove without deleting it
@@ -1211,13 +1262,24 @@ wxLayoutLine::MergeNextLine(wxLayoutList *llist)
    wxLayoutLine *oldnext = GetNextLine();
    wxLayoutLine *nextLine = oldnext->GetNextLine();
    SetNext(nextLine);
-   delete oldnext;
    if ( nextLine )
    {
       nextLine->MoveLines(-1);
    }
+   else
+   {
+       // this is now done in Delete(), but if this function is ever called
+       // from elsewhere, we might have to move refresh code back here (in
+       // order not to duplicate it)
+#if 0
+       wxPoint pos(oldnext->GetPosition());
+       llist->SetUpdateRect(pos);
+       llist->SetUpdateRect(pos.x + oldnext->GetWidth() + MSW_CORRECTION,
+                            pos.y + oldnext->GetHeight() + MSW_CORRECTION);
+#endif // 0
+   }
 
-   // no RecalculatePositions needed - called from Delete() anyhow
+   delete oldnext;
 }
 
 CoordType
@@ -1613,12 +1675,20 @@ bool
 wxLayoutList::Insert(wxString const &text)
 {
    wxASSERT(m_CursorLine);
+   wxASSERT_MSG( text.Find('\n') == wxNOT_FOUND, "use wxLayoutImportText!" );
+
+   if ( !text )
+       return true;
 
    AddCursorPosToUpdateRect();
 
-   m_CursorLine->Insert(m_CursorPos.x, text);
+   if ( !m_CursorLine->Insert(m_CursorPos.x, text) )
+      return false;
+
    m_CursorPos.x += text.Length();
-   m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
+
+   m_CursorLine->RecalculatePositions(0, this);
+
    return true;
 }
 
@@ -1634,7 +1704,9 @@ wxLayoutList::Insert(wxLayoutObject *obj)
 
    m_CursorLine->Insert(m_CursorPos.x, obj);
    m_CursorPos.x += obj->GetLength();
-   m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
+
+   m_CursorLine->RecalculatePositions(0, this);
+
    return true;
 }
 
@@ -1710,7 +1782,9 @@ wxLayoutList::WrapLine(CoordType column)
       LineBreak();
       Delete(1); // delete the space
       m_CursorPos.x = newpos;
-      m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
+
+      m_CursorLine->RecalculatePositions(1, this);
+
       return true;
    }
 }
@@ -1762,9 +1836,19 @@ wxLayoutList::Delete(CoordType npos)
                wasMerged = true;
                wxLayoutLine *next = m_CursorLine->GetNextLine();
                if ( next )
+               {
                   totalHeight += next->GetHeight();
-               m_CursorLine->MergeNextLine(this);
-               left--;
+                  totalWidth += next->GetWidth();
+
+                  m_CursorLine->MergeNextLine(this);
+                  left--;
+               }
+               else
+               {
+                  wxFAIL_MSG("can't delete all this");
+
+                  return false;
+               }
             }
          }
       }
@@ -1776,6 +1860,7 @@ wxLayoutList::Delete(CoordType npos)
    if ( wasMerged )
    {
       wxPoint position(m_CursorLine->GetPosition());
+      SetUpdateRect(position);
       SetUpdateRect(position.x + totalWidth + MSW_CORRECTION,
                     position.y + totalHeight + MSW_CORRECTION);
    }
@@ -1850,11 +1935,13 @@ wxLayoutList::GetCursorScreenPos(wxDC &dc)
 void
 wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll)
 {
-   wxLayoutLine *line = m_FirstLine;
-
    // first, make sure everything is calculated - this might not be
    // needed, optimise it later
    ApplyStyle(&m_DefaultSetting, dc);
+
+   // FIXME this is completely wrong - we should start by first *visible* line
+   //       (and stop on the last one) instead of looping over all lines!!
+   wxLayoutLine *line = m_FirstLine;
    while(line)
    {
       if(forceAll || line->IsDirty())
@@ -1865,10 +1952,13 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll)
                          (wxPoint *)&m_CursorSize, m_CursorPos.x);
          else
             line->Layout(dc, this);
-         // little    condition to speed up redrawing:
-         if(bottom != -1 && line->GetPosition().y > bottom) break;
+
+         // little condition to speed up redrawing:
+         if(bottom != -1 && line->GetPosition().y > bottom)
+             break;
       }
-      line->RecalculatePositions(1,this);
+
+      line->RecalculatePositions(1, this);
       line = line->GetNextLine();
    }
 
@@ -1924,14 +2014,22 @@ wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos,
    wxLayoutLine *line = m_FirstLine;
    wxPoint p;
 
-   // we need to run a layout here to get font sizes right :-(
    ApplyStyle(&m_DefaultSetting, dc);
    while(line)
    {
       p = line->GetPosition();
       if(p.y <= pos.y && p.y+line->GetHeight() >= pos.y)
          break;
+#if 0
+      // we need to run a layout here to get font sizes right :-(
+
+      // VZ: we can't call Layout() from here because it marks the line as
+      //     clean and it is not refreshed when it's called from wxLayoutList::
+      //     Layout() - if we really need to do this, we should introduce an
+      //     extra argument to Layout() to prevent the line from MarkClean()ing
+      //     itself here
       line->Layout(dc, this);
+#endif
       line = line->GetNextLine();
    }
    if(line == NULL)
index 630596b8dfc309f557665f1b1563d22a4dad6f7d..c354b2ffb384fd20b628fd20d16093fa26f8c970 100644 (file)
@@ -162,7 +162,7 @@ public:
    virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const { return 0; }
 
    /// constructor
-   wxLayoutObject() { m_UserData = NULL; m_Line = NULL; }
+   wxLayoutObject() { m_UserData = NULL; }
    /// delete the user data
    virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
 
@@ -183,20 +183,6 @@ public:
             m_UserData->IncRef();
       }
 
-   /// returns the line we belong to (or NULL)
-   wxLayoutLine *GetLine() const { return m_Line; }
-
-   /// attaches this object to the given line, it's an error to reattach us
-   void AttachToLine(wxLayoutLine *line)
-   {
-       wxASSERT_MSG( !m_Line, "this layout object already belongs to a line" );
-
-       m_Line = line;
-   }
-
-   /// unattaches the object (should reattach it immediately afterwards!)
-   void UnattachFromLine() { if ( m_Line ) m_Line = (wxLayoutLine *)NULL; }
-
    /** Return the user data.
     Increments the object's reference count. When no longer needed,
     caller must call DecRef() on the pointer returned.
@@ -221,9 +207,6 @@ public:
 protected:
    /// optional data for application's use
    UserData *m_UserData;
-
-   /// the line of the text we belong to or NULL if we're not shown on screen
-   wxLayoutLine *m_Line;
 };
 
 /// Define a list type of wxLayoutObject pointers.
@@ -472,7 +455,7 @@ public:
        @param text  the text to insert
        @return true if that xpos existed and the object was inserted
    */
-   bool Insert(CoordType xpos, wxString text);
+   bool Insert(CoordType xpos, const wxString& text);
 
    /** This function appends an object to the line.
        @param obj  the object to insert
@@ -481,7 +464,6 @@ public:
       {
          wxASSERT(obj);
 
-         obj->AttachToLine(this);
          m_ObjectList.push_back(obj);
          m_Length += obj->GetLength();
       }
@@ -665,7 +647,19 @@ public:
    /// Returns dirty state
    bool IsDirty(void) const { return m_Dirty; }
    /// Marks line as diry.
-   void MarkDirty(void) { m_Dirty = true; }
+   void MarkDirty(CoordType left = -1)
+   {
+      if ( left != -1 )
+      {
+         if ( m_updateLeft == -1 || left < m_updateLeft )
+            m_updateLeft = left;
+      }
+
+      m_Dirty = true;
+   }
+   /// Reset the dirty flag
+   void MarkClean() { m_Dirty = false; m_updateLeft = -1; }
+
 private:
    /// Destructor is private. Use DeleteLine() to remove it.
    ~wxLayoutLine();
@@ -706,6 +700,8 @@ private:
    wxLayoutObjectList m_ObjectList;
    /// Have we been changed since the last layout?
    bool m_Dirty;
+   /// The coordinate of the left boundary of the update rectangle (if m_Dirty)
+   CoordType m_updateLeft;
    /// Pointer to previous line if it exists.
    wxLayoutLine *m_Previous;
    /// Pointer to next line if it exists.
index 3370fd5fc74bb9ef364fd58ec1664e55d510ca49..022a9c7954d2a00fae4ff70e7086ef79b5d5d944 100644 (file)
 
 #define   BASE_SIZE 12
 
-inline static bool IsEndOfLine(const char *p, int mode)
+inline static bool IsEndOfLine(const char *p)
 {
-   // in addition to Unix EOL convention we also (but not instead) understand
-   // the DOS one under Windows
-   return
-      (mode == WXLO_EXPORT_WITH_CRLF) ?
-      ((*p == '\r') && (*(p + 1) == '\n')) 
-      :
-      (((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
+   // the end of line is either just '\n' or "\r\n" - we understand both (even
+   // though the second is used only under DOS/Windows) to be able to import
+   // DOS text files even under Unix
+   return (*p == '\n') || ((*p == '\r') && (*(p + 1) == '\n'));
 }
 
-void wxLayoutImportText(wxLayoutList *list, wxString const &str, int withflag)
+void wxLayoutImportText(wxLayoutList *list, wxString const &str)
 {
-   if(str.Length() == 0)
+   if ( !str )
       return;
-   char * cptr = (char *)str.c_str(); // string gets changed only temporarily
+
+   // we change the string temporarily inside this function
+   wxString& s = (wxString &)str; // const_cast
+
+   char * cptr = s.GetWriteBuf(s.Len());
    const char * begin = cptr;
    char  backup;
-   
+
    for(;;)
    {
       begin = cptr;
-      while( *cptr && !IsEndOfLine(cptr, withflag) )
+      while( *cptr && !IsEndOfLine(cptr) )
          cptr++;
       backup = *cptr;
       *cptr = '\0';
@@ -58,7 +59,7 @@ void wxLayoutImportText(wxLayoutList *list, wxString const &str, int withflag)
       *cptr = backup;
 
       // check if it's the end of this line
-      if ( IsEndOfLine(cptr, withflag) )
+      if ( IsEndOfLine(cptr) )
       {
          // if it was "\r\n", skip the following '\n'
          if ( *cptr == '\r' )
@@ -69,6 +70,8 @@ void wxLayoutImportText(wxLayoutList *list, wxString const &str, int withflag)
          break;
       cptr++;
    }
+
+   s.UngetWriteBuf();
 }
 
 static
@@ -77,11 +80,11 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
 {
    static char buffer[20];
    wxString html;
-   
+
    wxLayoutStyleInfo *si = cmd.GetStyle();
 
    int size, sizecount;
-   
+
    html += "<font ";
 
    if(si->m_fg_valid)
@@ -97,7 +100,7 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
       sprintf(buffer,"\"#%02X%02X%02X\"", si->m_bg.Red(),si->m_bg.Green(),si->m_bg.Blue());
       html += buffer;
    }
-   
+
    switch(si->family)
    {
    case wxSWISS:
@@ -139,7 +142,7 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
 
    if(si->style == wxSLANT)
       si->style = wxITALIC; // the same for html
-   
+
    if((si->style == wxITALIC) && ( (!styleInfo) || (styleInfo->style != wxITALIC)))
       html += "<i>";
    else
@@ -151,9 +154,9 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
    else if(si->underline == false && ( styleInfo && styleInfo->underline))
       html += "</u>";
 
-   
+
    *styleInfo = *si; // update last style info
-   
+
    return html;
 }
 
@@ -165,7 +168,7 @@ wxLayoutExportStatus::wxLayoutExportStatus(wxLayoutList *list)
    m_line = list->GetFirstLine();
    m_iterator = m_line->GetFirstObject();
 }
-   
+
 
 
 #define   WXLO_IS_TEXT(type) \
@@ -179,7 +182,7 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
 {
    wxASSERT(status);
    wxLayoutExportObject * export;
-   
+
    if(status->m_iterator == NULLIT) // end of line
    {
       if(!status->m_line || status->m_line->GetNextLine() == NULL)
@@ -234,7 +237,7 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
             break; // end of list
       }
       if(! status->m_line)  // reached end of list, fall through
-         break; 
+         break;
       type = (** status->m_iterator).GetType();
       if(type == WXLO_TYPE_ICON)
          break;
index 571a8749d972ed943abeead99e52affbb7ab0bd4..a594885d08c74ea74edab7cc25a2b0712f03fab1 100644 (file)
@@ -18,8 +18,8 @@
 
 enum wxLayoutExportType
 {
-   WXLO_EXPORT_TEXT,        
-   WXLO_EXPORT_HTML,        
+   WXLO_EXPORT_TEXT,
+   WXLO_EXPORT_HTML,
    WXLO_EXPORT_OBJECT,
    // this can be caused by empty lines:
    WXLO_EXPORT_EMPTYLINE
@@ -62,24 +62,17 @@ struct wxLayoutExportStatus
 };
 
 #ifdef OS_WIN
-/// import text into a wxLayoutList (including linefeeds):
-void wxLayoutImportText(wxLayoutList *list, wxString const &str,
-                        int withflag = WXLO_EXPORT_WITH_CRLF);
+    #define WXLO_DEFAULT_EXPORT_MODE WXLO_EXPORT_WITH_CRLF
+#else // Unix
+    #define WXLO_DEFAULT_EXPORT_MODE WXLO_EXPORT_WITH_LF_ONLY
+#endif // Win/Unix
 
-wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
-                                     int mode = WXLO_EXPORT_AS_TEXT,
-                                     int flags =
-                                     WXLO_EXPORT_WITH_CRLF); 
-#else
 /// import text into a wxLayoutList (including linefeeds):
-void wxLayoutImportText(wxLayoutList *list, wxString const &str,
-                        int withflag = WXLO_EXPORT_WITH_LF_ONLY);
+void wxLayoutImportText(wxLayoutList *list, wxString const &str);
 
 /// export text in a given format
 wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
                                      int mode = WXLO_EXPORT_AS_TEXT,
-                                     int flags =
-                                     WXLO_EXPORT_WITH_LF_ONLY);
-#endif
+                                     int flags = WXLO_DEFAULT_EXPORT_MODE);
 
 #endif //WXLPARSER_H
index 093db74fa4ce1b8f052876e9e26f3dda5e4a1a42..0cd45c2c93299546cd50b7c2a4b56da3f46041c0 100644 (file)
 #   include "gui/wxlparser.h"
 #else
 #   ifdef   __WXMSW__
-#       include <windows.h>
-#       undef FindWindow
-#       undef GetCharWidth
-#       undef StartDoc
+#       include <wx/msw/private.h>
 #   endif
 
 #   include "wxlwindow.h"
@@ -153,9 +150,13 @@ wxLayoutWindow::MSWGetDlgCode()
 void
 wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
 {
-   wxPaintDC dc( this );
+   wxClientDC dc( this );
    PrepareDC( dc );
-   SetFocus();
+   if ( eventId != WXLOWIN_MENU_MOUSEMOVE )
+   {
+       // moving the mouse in a window shouldn't give it the focus!
+      SetFocus();
+   }
 
    wxPoint findPos;
    findPos.x = dc.DeviceToLogicalX(event.GetX());
@@ -512,10 +513,13 @@ wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event))  // or: OnDraw(wxDC& dc)
 void
 wxLayoutWindow::DoPaint(const wxRect *updateRect)
 {
-#ifdef __WXGTK__
+#ifndef __WXMSW__
    InternalPaint(updateRect);
 #else
    Refresh(FALSE, updateRect); // Causes bad flicker under wxGTK!!!
+
+   if ( !::UpdateWindow(GetHwnd()) )
+      wxLogLastError("UpdateWindow");
 #endif
 }
 
@@ -876,12 +880,12 @@ void
 wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = true;
-//FIXME: need argument   DoPaint(); // to repaint the cursor
+   ev.Skip();
 }
 
 void
 wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = false;
-//FIXME: need argument   DoPaint(); // to repaint the cursor
+   ev.Skip();
 }