]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextbuffer.cpp
Copy recently added wxGenericValidator fields in Copy().
[wxWidgets.git] / src / richtext / richtextbuffer.cpp
index 83c74a023f623235353cfda01fe39042d3ac5776..946c96c1a75bcd06f4ca1a43743631fc3373076e 100644 (file)
@@ -8,7 +8,7 @@
 // Copyright:   (c) Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
-wxRICHTEXT_NONE
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -116,6 +116,14 @@ public:
     // Get floating objects
     bool GetFloatingObjects(wxRichTextObjectList& objects) const;
 
+    // Delete a float
+    bool DeleteFloat(wxRichTextObject* obj);
+
+    // Do we have this float already?
+    bool HasFloat(wxRichTextObject* obj);
+
+    bool HasFloats() const { return m_left.GetCount() >0 || m_right.GetCount() > 0; }
+
     static int SearchAdjacentRect(const wxRichTextFloatRectMapArray& array, int point);
 
     static int GetWidthFromFloatRect(const wxRichTextFloatRectMapArray& array, int index, int startY, int endY);
@@ -134,6 +142,50 @@ private:
     wxRichTextParagraph* m_para;
 };
 
+// Delete a float
+bool wxRichTextFloatCollector::DeleteFloat(wxRichTextObject* obj)
+{
+    size_t i;
+    for (i = 0; i < m_left.GetCount(); i++)
+    {
+        if (m_left[i]->anchor == obj)
+        {
+            m_left.RemoveAt(i);
+            return true;
+        }
+    }
+    for (i = 0; i < m_right.GetCount(); i++)
+    {
+        if (m_right[i]->anchor == obj)
+        {
+            m_right.RemoveAt(i);
+            return true;
+        }
+    }
+    return false;
+}
+
+// Do we have this float already?
+bool wxRichTextFloatCollector::HasFloat(wxRichTextObject* obj)
+{
+    size_t i;
+    for (i = 0; i < m_left.GetCount(); i++)
+    {
+        if (m_left[i]->anchor == obj)
+        {
+            return true;
+        }
+    }
+    for (i = 0; i < m_right.GetCount(); i++)
+    {
+        if (m_right[i]->anchor == obj)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 // Get floating objects
 bool wxRichTextFloatCollector::GetFloatingObjects(wxRichTextObjectList& objects) const
 {
@@ -1026,7 +1078,7 @@ bool wxRichTextObject::LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer,
         // If a paragraph, align the whole paragraph.
         // Problem with this: if we're limited by a floating object, a line may be centered
         // w.r.t. the smaller resulting box rather than the actual available width.
-        if (attr.HasAlignment())
+        if (attr.HasAlignment() && !GetContainer()->GetFloatCollector()->HasFloats()) // FIXME: aligning whole paragraph not compatible with floating objects
         {
             // centering, right-justification
             if (GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
@@ -1619,14 +1671,17 @@ void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj)
     m_defaultAttributes = obj.m_defaultAttributes;
 }
 
-// Gather information about floating objects
+// Gather information about floating objects; only gather floats for those paragraphs that
+// will not be formatted again due to optimization, after which floats will be gathered per-paragraph
+// during layout.
 bool wxRichTextParagraphLayoutBox::UpdateFloatingObjects(const wxRect& availableRect, wxRichTextObject* untilObj)
 {
     if (m_floatCollector != NULL)
         delete m_floatCollector;
     m_floatCollector = new wxRichTextFloatCollector(availableRect);
     wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
-    while (node && node->GetData() != untilObj)
+    // Only gather floats up to the point we'll start formatting paragraphs.
+    while (untilObj && node && node->GetData() != untilObj)
     {
         wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph);
         wxASSERT (child != NULL);
@@ -1681,7 +1736,7 @@ int wxRichTextParagraphLayoutBox::HitTest(wxDC& dc, const wxPoint& pt, long& tex
         return wxRICHTEXT_HITTEST_NONE;
 
     int ret = wxRICHTEXT_HITTEST_NONE;
-    if (m_floatCollector)
+    if (m_floatCollector && (flags & wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS) == 0)
         ret = m_floatCollector->HitTest(dc, pt, textPosition, obj, flags);
 
     if (ret == wxRICHTEXT_HITTEST_NONE)
@@ -1852,6 +1907,8 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl
         }
     }
 
+    // Gather information about only those floating objects that will not be formatted,
+    // after which floats will be gathered per-paragraph during layout.
     UpdateFloatingObjects(availableSpace, node ? node->GetData() : (wxRichTextObject*) NULL);
 
     // A way to force speedy rest-of-buffer layout (the 'else' below)
@@ -1862,7 +1919,8 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl
         // Assume this box only contains paragraphs
 
         wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph);
-        wxCHECK_MSG( child, false, wxT("Unknown object in layout") );
+        // Unsure if this is needed
+        // wxCHECK_MSG( child, false, wxT("Unknown object in layout") );
 
         if (child && child->IsShown())
         {
@@ -2579,49 +2637,61 @@ bool wxRichTextParagraphLayoutBox::CopyFragment(const wxRichTextRange& range, wx
     // Now top and tail the first and last paragraphs in our new fragment (which might be the same).
     if (!fragment.IsEmpty())
     {
-        wxRichTextRange topTailRange(range);
-
         wxRichTextParagraph* firstPara = wxDynamicCast(fragment.GetChildren().GetFirst()->GetData(), wxRichTextParagraph);
         wxASSERT( firstPara != NULL );
 
+        wxRichTextParagraph* lastPara = wxDynamicCast(fragment.GetChildren().GetLast()->GetData(), wxRichTextParagraph);
+        wxASSERT( lastPara != NULL );
+
+        if (!firstPara || !lastPara)
+            return false;
+
+        bool isFragment = (range.GetEnd() < lastPara->GetRange().GetEnd());
+
+        long firstPos = firstPara->GetRange().GetStart();
+
+        // Adjust for renumbering from zero
+        wxRichTextRange topTailRange(range.GetStart() - firstPos, range.GetEnd() - firstPos);
+
+        long end;
+        fragment.CalculateRange(0, end);
+
         // Chop off the start of the paragraph
-        if (topTailRange.GetStart() > firstPara->GetRange().GetStart())
+        if (topTailRange.GetStart() > 0)
         {
-            wxRichTextRange r(firstPara->GetRange().GetStart(), topTailRange.GetStart()-1);
+            wxRichTextRange r(0, topTailRange.GetStart()-1);
             firstPara->DeleteRange(r);
 
             // Make sure the numbering is correct
-            long end;
-            fragment.CalculateRange(firstPara->GetRange().GetStart(), end);
+            fragment.CalculateRange(0, end);
 
             // Now, we've deleted some positions, so adjust the range
             // accordingly.
-            topTailRange.SetEnd(topTailRange.GetEnd() - r.GetLength());
+            topTailRange.SetStart(range.GetLength());
+            topTailRange.SetEnd(fragment.GetOwnRange().GetEnd());
+        }
+        else
+        {
+            topTailRange.SetStart(range.GetLength());
+            topTailRange.SetEnd(fragment.GetOwnRange().GetEnd());
         }
 
-        wxRichTextParagraph* lastPara = wxDynamicCast(fragment.GetChildren().GetLast()->GetData(), wxRichTextParagraph);
-        wxASSERT( lastPara != NULL );
-
-        if (topTailRange.GetEnd() < (lastPara->GetRange().GetEnd()-1))
+        if (topTailRange.GetStart() < (lastPara->GetRange().GetEnd()-1))
         {
-            wxRichTextRange r(topTailRange.GetEnd()+1, lastPara->GetRange().GetEnd()-1); /* -1 since actual text ends 1 position before end of para marker */
-            lastPara->DeleteRange(r);
+            lastPara->DeleteRange(topTailRange);
 
             // Make sure the numbering is correct
             long end;
-            fragment.CalculateRange(firstPara->GetRange().GetStart(), end);
+            fragment.CalculateRange(0, end);
 
             // We only have part of a paragraph at the end
             fragment.SetPartialParagraph(true);
         }
         else
         {
-            if (topTailRange.GetEnd() == (lastPara->GetRange().GetEnd() - 1))
-                // We have a partial paragraph (don't save last new paragraph marker)
-                fragment.SetPartialParagraph(true);
-            else
-                // We have a complete paragraph
-                fragment.SetPartialParagraph(false);
+            // We have a partial paragraph (don't save last new paragraph marker)
+            // or complete paragraph
+            fragment.SetPartialParagraph(isFragment);
         }
     }
 
@@ -2862,7 +2932,7 @@ wxString wxRichTextParagraphLayoutBox::GetTextForRange(const wxRichTextRange& ra
 /// Get all the text
 wxString wxRichTextParagraphLayoutBox::GetText() const
 {
-    return GetTextForRange(GetRange());
+    return GetTextForRange(GetOwnRange());
 }
 
 /// Get the paragraph by number
@@ -4250,7 +4320,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     // Deal with floating objects firstly before the normal layout
     wxRichTextBuffer* buffer = GetBuffer();
     wxASSERT(buffer);
-    wxRichTextFloatCollector* collector = buffer->GetFloatCollector();
+    wxRichTextFloatCollector* collector = GetContainer()->GetFloatCollector();
     wxASSERT(collector);
     LayoutFloat(dc, rect, style, collector);
 
@@ -4268,7 +4338,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     int lineSpacing = 0;
 
     // Let's assume line spacing of 10 is normal, 15 is 1.5, 20 is 2, etc.
-    if (attr.HasLineSpacing() && attr.GetLineSpacing() > 0 && attr.GetFont().Ok())
+    if (attr.HasLineSpacing() && attr.GetLineSpacing() > 0 && attr.GetFont().IsOk())
     {
         wxCheckSetFont(dc, attr.GetFont());
         lineSpacing = (int) (double(dc.GetCharHeight()) * (double(attr.GetLineSpacing())/10.0 - 1.0));
@@ -4302,25 +4372,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     wxRichTextObjectList::compatibility_iterator node;
 
 #if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
-#if 0
-    node = m_children.GetFirst();
-    while (node)
-    {
-        wxRichTextObject* child = node->GetData();
-        if (child->IsTopLevel())
-        {
-            //child->SetCachedSize(wxDefaultSize);
-            wxRect availableChildRect = AdjustAvailableSpace(dc, GetBuffer(), GetAttributes(), child->GetAttributes(), rect);
-
-            // Hm, can't do this here, we surely need to take into account indents, margins, floating images etc.
-            // So need to call layout lower down.
-            child->Layout(dc, availableChildRect, style);
-        }
-
-        node = node->GetNext();
-    }
-#endif
-
     wxUnusedVar(style);
     wxArrayInt partialExtents;
 
@@ -4328,7 +4379,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     int paraDescent = 0;
 
     // This calculates the partial text extents
-    GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents);
+    GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, rect.GetPosition(), & partialExtents);
 #else
     node = m_children.GetFirst();
     while (node)
@@ -4403,7 +4454,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
             // lays out the object again using the minimum size
             // The position will be determined by its location in its line,
             // and not by the child's actual position.
-            child->LayoutToBestSize(dc, GetBuffer(),
+            child->LayoutToBestSize(dc, buffer,
                     GetAttributes(), child->GetAttributes(), availableRect, style);
 
             if (oldSize != child->GetCachedSize())
@@ -4487,7 +4538,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
                     // Lays out the object first with a given amount of space, and then if no width was specified in attr,
                     // lays out the object again using the minimum size
                     child->Invalidate(wxRICHTEXT_ALL);
-                    child->LayoutToBestSize(dc, GetBuffer(),
+                    child->LayoutToBestSize(dc, buffer,
                                 GetAttributes(), child->GetAttributes(), availableRect, style);
                     childSize = child->GetCachedSize();
                     childDescent = child->GetDescent();
@@ -4581,9 +4632,9 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
             maxAscent = wxMax(actualSize.y-childDescent, maxAscent);
             lineHeight = maxDescent + maxAscent;
 
-            if (lineHeight == 0 && GetBuffer())
+            if (lineHeight == 0 && buffer)
             {
-                wxFont font(GetBuffer()->GetFontTable().FindFont(attr));
+                wxFont font(buffer->GetFontTable().FindFont(attr));
                 wxCheckSetFont(dc, font);
                 lineHeight = dc.GetCharHeight();
             }
@@ -4653,44 +4704,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
         }
     }
 
-    wxASSERT(!(lastCompletedEndPos != -1 && lastCompletedEndPos < GetRange().GetEnd()-1));
-
-#if 0
-    // Add the last line - it's the current pos -> last para pos
-    // Substract -1 because the last position is always the end-paragraph position.
-    if (lastCompletedEndPos <= GetRange().GetEnd()-1)
-    {
-        currentPosition.x = availableRect.x - rect.x;
-
-        wxRichTextLine* line = AllocateLine(lineCount);
-
-        wxRichTextRange actualRange(lastCompletedEndPos+1, GetRange().GetEnd()-1);
-
-        // Set relative range so we won't have to change line ranges when paragraphs are moved
-        line->SetRange(wxRichTextRange(actualRange.GetStart() - GetRange().GetStart(), actualRange.GetEnd() - GetRange().GetStart()));
-
-        line->SetPosition(currentPosition);
-
-        if (lineHeight == 0 && GetBuffer())
-        {
-            wxFont font(GetBuffer()->GetFontTable().FindFont(attr));
-            wxCheckSetFont(dc, font);
-            lineHeight = dc.GetCharHeight();
-        }
-        if (maxDescent == 0)
-        {
-            int w, h;
-            dc.GetTextExtent(wxT("X"), & w, &h, & maxDescent);
-        }
-
-        line->SetSize(wxSize(currentWidth, lineHeight));
-        line->SetDescent(maxDescent);
-        maxWidth = wxMax(maxWidth, currentWidth+startOffset);
-        currentPosition.y += lineHeight;
-        currentPosition.y += lineSpacing;
-        lineCount ++;
-    }
-#endif
+    //wxASSERT(!(lastCompletedEndPos != -1 && lastCompletedEndPos < GetRange().GetEnd()-1));
 
     // Remove remaining unused line objects, if any
     ClearUnusedLines(lineCount);
@@ -4699,7 +4713,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     {
         wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
         contentRect = wxRect(wxPoint(0, 0), wxSize(maxWidth, currentPosition.y + spaceAfterPara));
-        GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+        GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
         SetCachedSize(marginRect.GetSize());
     }
 
@@ -4709,7 +4723,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     {
         wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
         contentRect = wxRect(wxPoint(0, 0), wxSize(paraSize.x, currentPosition.y + spaceAfterPara));
-        GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+        GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
         SetMaxSize(marginRect.GetSize());
     }
 
@@ -4736,7 +4750,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
 
         wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
         contentRect = wxRect(wxPoint(0, 0), wxSize(minWidth, currentPosition.y + spaceAfterPara));
-        GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+        GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
         SetMinSize(marginRect.GetSize());
     }
 
@@ -4786,45 +4800,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
     return true;
 }
 
-#if 0
-/// Apply paragraph styles, such as centering, to wrapped lines
-/// TODO: take into account box attributes
-void wxRichTextParagraph::ApplyParagraphStyle(const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc)
-{
-    if (!attr.HasAlignment())
-        return;
-
-    wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst();
-    while (node)
-    {
-        wxRichTextLine* line = node->GetData();
-
-        wxPoint pos = line->GetPosition();
-        wxSize size = line->GetSize();
-
-        // centering, right-justification
-        if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
-        {
-            int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
-            // Subtract paragraph position because lines are relative to
-            // the paragraph.
-            pos.x = rect.x - GetPosition().x + (rect.GetWidth() - rightIndent - size.x)/2;
-            line->SetPosition(pos);
-        }
-        else if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
-        {
-            int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
-            // Subtract paragraph position because lines are relative to
-            // the paragraph.
-            pos.x = (rect.x - GetPosition().x) + rect.GetWidth() - size.x - rightIndent;
-            line->SetPosition(pos);
-        }
-
-        node = node->GetNext();
-    }
-}
-#endif
-
 /// Apply paragraph styles, such as centering, to wrapped lines
 /// TODO: take into account box attributes, possibly
 void wxRichTextParagraph::ApplyParagraphStyle(wxRichTextLine* line, const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc)
@@ -5282,7 +5257,7 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition
                 int paraDescent;
 
                 // This calculates the partial text extents
-                GetRangeSize(lineRange, paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED, wxPoint(0,0), & partialExtents);
+                GetRangeSize(lineRange, paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED, linePos, & partialExtents);
 
                 int lastX = linePos.x;
                 size_t i;
@@ -5799,7 +5774,7 @@ void wxRichTextParagraph::LayoutFloat(wxDC& dc, const wxRect& rect, int style, w
     while (node)
     {
         wxRichTextObject* anchored = node->GetData();
-        if (anchored && anchored->IsFloating())
+        if (anchored && anchored->IsFloating() && !floatCollector->HasFloat(anchored))
         {
             wxSize size;
             int descent, x = 0;
@@ -5974,7 +5949,7 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
     int charHeight = dc.GetCharHeight();
 
     int x, y;
-    if ( textFont.Ok() )
+    if ( textFont.IsOk() )
     {
         if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) )
         {
@@ -6273,7 +6248,7 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz
 
     bool bScript(false);
     wxFont font(GetBuffer()->GetFontTable().FindFont(textAttr));
-    if (font.Ok())
+    if (font.IsOk())
     {
         if ( textAttr.HasTextEffects() && ( (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT)
             || (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) )
@@ -6639,34 +6614,12 @@ bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagr
 }
 
 /// Submit command to insert paragraphs
-bool wxRichTextParagraphLayoutBox::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags)
+bool wxRichTextParagraphLayoutBox::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int WXUNUSED(flags))
 {
     wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, buffer, this, ctrl, false);
 
-    wxRichTextAttr attr(buffer->GetDefaultStyle());
-
-    wxRichTextAttr* p = NULL;
-    wxRichTextAttr paraAttr;
-    if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE)
-    {
-        paraAttr = GetStyleForNewParagraph(buffer, pos);
-        if (!paraAttr.IsDefault())
-            p = & paraAttr;
-    }
-    else
-        p = & attr;
-
     action->GetNewParagraphs() = paragraphs;
 
-    if (p && !p->IsDefault())
-    {
-        for (wxRichTextObjectList::compatibility_iterator node = action->GetNewParagraphs().GetChildren().GetFirst(); node; node = node->GetNext())
-        {
-            wxRichTextObject* child = node->GetData();
-            child->SetAttributes(*p);
-        }
-    }
-
     action->SetPosition(pos);
 
     wxRichTextRange range = wxRichTextRange(pos, pos + paragraphs.GetOwnRange().GetEnd() - 1);
@@ -6706,13 +6659,13 @@ bool wxRichTextParagraphLayoutBox::InsertTextWithUndo(long pos, const wxString&
 
     int length = action->GetNewParagraphs().GetOwnRange().GetLength();
 
-    if (text.length() > 0 && text.Last() != wxT('\n'))
+    if (!text.empty() && text.Last() != wxT('\n'))
     {
         // Don't count the newline when undoing
         length --;
         action->GetNewParagraphs().SetPartialParagraph(true);
     }
-    else if (text.length() > 0 && text.Last() == wxT('\n'))
+    else if (!text.empty() && text.Last() == wxT('\n'))
         length --;
 
     action->SetPosition(pos);
@@ -7780,11 +7733,11 @@ bool wxRichTextBuffer::SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet)
 {
     wxRichTextStyleSheet* oldSheet = GetStyleSheet();
 
-    wxWindowID id = wxID_ANY;
+    wxWindowID winid = wxID_ANY;
     if (GetRichTextCtrl())
-        id = GetRichTextCtrl()->GetId();
+        winid = GetRichTextCtrl()->GetId();
 
-    wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, id);
+    wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, winid);
     event.SetEventObject(GetRichTextCtrl());
     event.SetContainer(GetRichTextCtrl()->GetFocusObject());
     event.SetOldStyleSheet(oldSheet);
@@ -7839,7 +7792,7 @@ int wxRichTextBuffer::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, w
 
 bool wxRichTextStdRenderer::DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& bulletAttr, const wxRect& rect)
 {
-    if (bulletAttr.GetTextColour().Ok())
+    if (bulletAttr.GetTextColour().IsOk())
     {
         wxCheckSetPen(dc, wxPen(bulletAttr.GetTextColour()));
         wxCheckSetBrush(dc, wxBrush(bulletAttr.GetTextColour()));
@@ -7939,7 +7892,7 @@ bool wxRichTextStdRenderer::DrawTextBullet(wxRichTextParagraph* paragraph, wxDC&
 
         wxCheckSetFont(dc, font);
 
-        if (attr.GetTextColour().Ok())
+        if (attr.GetTextColour().IsOk())
             dc.SetTextForeground(attr.GetTextColour());
 
         dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
@@ -8668,8 +8621,6 @@ bool wxRichTextTable::Layout(wxDC& dc, const wxRect& rect, int style)
             wxRichTextCell* cell = GetCell(j, i);
             if (cell->IsShown())
             {
-                wxASSERT(colWidths[i] > 0);
-
                 // Get max specified cell height
                 // Don't handle percentages for height
                 if (cell->GetAttributes().GetTextBoxAttr().GetHeight().IsValid() && cell->GetAttributes().GetTextBoxAttr().GetHeight().GetUnits() != wxTEXT_ATTR_UNITS_PERCENTAGE)
@@ -8952,7 +8903,7 @@ wxRichTextCell* wxRichTextTable::GetCell(int row, int col) const
         return wxDynamicCast(obj, wxRichTextCell);
     }
     else
-        return false;
+        return NULL;
 }
 
 // Returns a selection object specifying the selections between start and end character positions.
@@ -9803,7 +9754,11 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
                 m_ctrl->Refresh(false);
 
             m_ctrl->PositionCaret();
-            m_ctrl->SetDefaultStyleToCursorStyle();
+
+            // This causes styles to persist when doing programmatic
+            // content creation except when Freeze/Thaw is used, so
+            // disable this and check for the consequences.
+            // m_ctrl->SetDefaultStyleToCursorStyle();
 
             if (sendUpdateEvent)
                 wxTextCtrl::SendTextUpdatedEvent(m_ctrl);
@@ -10198,7 +10153,7 @@ IMPLEMENT_CLASS(wxRichTextFileHandler, wxObject)
 bool wxRichTextFileHandler::LoadFile(wxRichTextBuffer *buffer, const wxString& filename)
 {
     wxFFileInputStream stream(filename);
-    if (stream.Ok())
+    if (stream.IsOk())
         return LoadFile(buffer, stream);
 
     return false;
@@ -10207,7 +10162,7 @@ bool wxRichTextFileHandler::LoadFile(wxRichTextBuffer *buffer, const wxString& f
 bool wxRichTextFileHandler::SaveFile(wxRichTextBuffer *buffer, const wxString& filename)
 {
     wxFFileOutputStream stream(filename);
-    if (stream.Ok())
+    if (stream.IsOk())
         return SaveFile(buffer, stream);
 
     return false;
@@ -10462,8 +10417,13 @@ bool wxRichTextImageBlock::Load(wxImage& image)
 // Write data in hex to a stream
 bool wxRichTextImageBlock::WriteHex(wxOutputStream& stream)
 {
-    const int bufSize = 512;
-    char buf[bufSize+1];
+    if (m_dataSize == 0)
+        return true;
+
+    int bufSize = 100000;
+    if (int(2*m_dataSize) < bufSize)
+        bufSize = 2*m_dataSize;
+    char* buf = new char[bufSize+1];
 
     int left = m_dataSize;
     int n, i, j;
@@ -10489,6 +10449,7 @@ bool wxRichTextImageBlock::WriteHex(wxOutputStream& stream)
         buf[n] = 0;
         stream.Write((const char*) buf, n);
     }
+    delete[] buf;
     return true;
 }
 
@@ -10535,7 +10496,7 @@ unsigned char* wxRichTextImageBlock::ReadBlock(wxInputStream& stream, size_t siz
 unsigned char* wxRichTextImageBlock::ReadBlock(const wxString& filename, size_t size)
 {
     wxFileInputStream stream(filename);
-    if (!stream.Ok())
+    if (!stream.IsOk())
         return NULL;
 
     return ReadBlock(stream, size);
@@ -10553,7 +10514,7 @@ bool wxRichTextImageBlock::WriteBlock(wxOutputStream& stream, unsigned char* blo
 bool wxRichTextImageBlock::WriteBlock(const wxString& filename, unsigned char* block, size_t size)
 {
     wxFileOutputStream outStream(filename);
-    if (!outStream.Ok())
+    if (!outStream.IsOk())
         return false;
 
     return WriteBlock(outStream, block, size);