X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b8e58b85d922b711726eaa3f897fb18812145be5..a0f4d36895556e3054e2256cb5f1787cc9fcf75c:/src/richtext/richtextbuffer.cpp?ds=sidebyside diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 64633cab6f..7d61b5e8a6 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -309,7 +309,8 @@ int wxRichTextCompositeObject::HitTest(wxDC& dc, const wxPoint& pt, long& textPo node = node->GetNext(); } - return wxRICHTEXT_HITTEST_NONE; + textPosition = GetRange().GetEnd()-1; + return wxRICHTEXT_HITTEST_AFTER|wxRICHTEXT_HITTEST_OUTSIDE; } /// Finds the absolute position and row height for the given character position @@ -959,7 +960,17 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraph(const wxString& text, wxTextAttr defaultCharStyle; wxTextAttr defaultParaStyle; - wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); + // If the default style is a named paragraph style, don't apply any character formatting + // to the initial text string. + if (GetDefaultStyle().HasParagraphStyleName() && GetStyleSheet()) + { + wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(GetDefaultStyle().GetParagraphStyleName()); + if (def) + defaultParaStyle = def->GetStyleMergedWithBase(GetStyleSheet()); + } + else + wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); + wxTextAttr* pStyle = paraStyle ? paraStyle : (wxTextAttr*) & defaultParaStyle; wxTextAttr* cStyle = & defaultCharStyle; @@ -982,7 +993,17 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text wxTextAttr defaultCharStyle; wxTextAttr defaultParaStyle; - wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); + + // If the default style is a named paragraph style, don't apply any character formatting + // to the initial text string. + if (GetDefaultStyle().HasParagraphStyleName() && GetStyleSheet()) + { + wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(GetDefaultStyle().GetParagraphStyleName()); + if (def) + defaultParaStyle = def->GetStyleMergedWithBase(GetStyleSheet()); + } + else + wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); wxTextAttr* pStyle = paraStyle ? paraStyle : (wxTextAttr*) & defaultParaStyle; wxTextAttr* cStyle = & defaultCharStyle; @@ -1007,15 +1028,18 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text wxChar ch = text[i]; if (ch == wxT('\n') || ch == wxT('\r')) { - wxRichTextPlainText* plainText = (wxRichTextPlainText*) para->GetChildren().GetFirst()->GetData(); - plainText->SetText(line); + if (i != (len-1)) + { + wxRichTextPlainText* plainText = (wxRichTextPlainText*) para->GetChildren().GetFirst()->GetData(); + plainText->SetText(line); - para = new wxRichTextParagraph(wxEmptyString, this, pStyle, cStyle); + para = new wxRichTextParagraph(wxEmptyString, this, pStyle, cStyle); - AppendChild(para); + AppendChild(para); - lastPara = para; - line = wxEmptyString; + lastPara = para; + line = wxEmptyString; + } } else line += ch; @@ -1045,7 +1069,17 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddImage(const wxImage& image, wxT wxTextAttr defaultCharStyle; wxTextAttr defaultParaStyle; - wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); + + // If the default style is a named paragraph style, don't apply any character formatting + // to the initial text string. + if (GetDefaultStyle().HasParagraphStyleName() && GetStyleSheet()) + { + wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(GetDefaultStyle().GetParagraphStyleName()); + if (def) + defaultParaStyle = def->GetStyleMergedWithBase(GetStyleSheet()); + } + else + wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle); wxTextAttr* pStyle = paraStyle ? paraStyle : (wxTextAttr*) & defaultParaStyle; wxTextAttr* cStyle = & defaultCharStyle; @@ -1073,6 +1107,8 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag wxRichTextParagraph* para = GetParagraphAtPosition(position); if (para) { + wxTextAttrEx originalAttr = para->GetAttributes(); + wxRichTextObjectList::compatibility_iterator node = m_children.Find(para); // Now split at this position, returning the object to insert the new @@ -1093,11 +1129,6 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag wxRichTextParagraph* firstPara = wxDynamicCast(firstParaNode->GetData(), wxRichTextParagraph); wxASSERT (firstPara != NULL); - // Apply the new paragraph attributes to the existing paragraph - wxTextAttr attr(para->GetAttributes()); - wxRichTextApplyStyle(attr, firstPara->GetAttributes()); - para->SetAttributes(attr); - wxRichTextObjectList::compatibility_iterator objectNode = firstPara->GetChildren().GetFirst(); while (objectNode) { @@ -1145,7 +1176,19 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag wxRichTextParagraph* firstPara = wxDynamicCast(firstParaNode->GetData(), wxRichTextParagraph); wxASSERT(firstPara != NULL); + if (!(fragment.GetAttributes().GetFlags() & wxTEXT_ATTR_KEEP_FIRST_PARA_STYLE)) + para->SetAttributes(firstPara->GetAttributes()); + + // Save empty paragraph attributes for appending later + // These are character attributes deliberately set for a new paragraph. Without this, + // we couldn't pass default attributes when appending a new paragraph. + wxTextAttrEx emptyParagraphAttributes; + wxRichTextObjectList::compatibility_iterator objectNode = firstPara->GetChildren().GetFirst(); + + if (objectNode && firstPara->GetChildren().GetCount() == 1 && objectNode->GetData()->IsEmpty()) + emptyParagraphAttributes = objectNode->GetData()->GetAttributes(); + while (objectNode) { wxRichTextObject* newObj = objectNode->GetData()->Clone(); @@ -1165,50 +1208,57 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag wxRichTextObjectList::compatibility_iterator i = fragment.GetChildren().GetFirst()->GetNext(); wxRichTextParagraph* finalPara = para; + bool needExtraPara = (!i || !fragment.GetPartialParagraph()); + // If there was only one paragraph, we need to insert a new one. - if (!i) + while (i) { - finalPara = new wxRichTextParagraph; + wxRichTextParagraph* para = wxDynamicCast(i->GetData(), wxRichTextParagraph); + wxASSERT( para != NULL ); - // TODO: These attributes should come from the subsequent paragraph - // when originally deleted, since the subsequent para takes on - // the previous para's attributes. - finalPara->SetAttributes(firstPara->GetAttributes()); + finalPara = (wxRichTextParagraph*) para->Clone(); if (nextParagraph) InsertChild(finalPara, nextParagraph); else AppendChild(finalPara); + + i = i->GetNext(); } - else while (i) - { - wxRichTextParagraph* para = wxDynamicCast(i->GetData(), wxRichTextParagraph); - wxASSERT( para != NULL ); - finalPara = (wxRichTextParagraph*) para->Clone(); + // If there was only one paragraph, or we have full paragraphs in our fragment, + // we need to insert a new one. + if (needExtraPara) + { + finalPara = new wxRichTextParagraph; if (nextParagraph) InsertChild(finalPara, nextParagraph); else AppendChild(finalPara); - - i = i->GetNext(); } // 4. Add back the remaining content. if (finalPara) { - finalPara->MoveFromList(savedObjects); + if (nextObject) + finalPara->MoveFromList(savedObjects); // Ensure there's at least one object if (finalPara->GetChildCount() == 0) { wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); + text->SetAttributes(emptyParagraphAttributes); finalPara->AppendChild(text); } } + if ((fragment.GetAttributes().GetFlags() & wxTEXT_ATTR_KEEP_FIRST_PARA_STYLE) && firstPara) + finalPara->SetAttributes(firstPara->GetAttributes()); + else if (finalPara && finalPara != para) + finalPara->SetAttributes(originalAttr); + return true; } } @@ -1392,6 +1442,7 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) { wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + wxRichTextParagraph* firstPara = NULL; while (node) { wxRichTextParagraph* obj = wxDynamicCast(node->GetData(), wxRichTextParagraph); @@ -1406,58 +1457,82 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) // Deletes the content of this object within the given range obj->DeleteRange(range); + wxRichTextRange thisRange = obj->GetRange(); + wxTextAttrEx thisAttr = obj->GetAttributes(); + // If the whole paragraph is within the range to delete, // delete the whole thing. - if (range.GetStart() <= obj->GetRange().GetStart() && range.GetEnd() >= obj->GetRange().GetEnd()) + if (range.GetStart() <= thisRange.GetStart() && range.GetEnd() >= thisRange.GetEnd()) { // Delete the whole object RemoveChild(obj, true); + obj = NULL; } + else if (!firstPara) + firstPara = obj; + // If the range includes the paragraph end, we need to join this // and the next paragraph. - else if (range.Contains(obj->GetRange().GetEnd())) + if (range.GetEnd() <= thisRange.GetEnd()) { // We need to move the objects from the next paragraph // to this paragraph - if (next) + wxRichTextParagraph* nextParagraph = NULL; + if ((range.GetEnd() < thisRange.GetEnd()) && obj) + nextParagraph = obj; + else { - wxRichTextParagraph* nextParagraph = wxDynamicCast(next->GetData(), wxRichTextParagraph); - next = next->GetNext(); - if (nextParagraph) - { - // Delete the stuff we need to delete - nextParagraph->DeleteRange(range); + // We're ending at the end of the paragraph, so merge the _next_ paragraph. + if (next) + nextParagraph = wxDynamicCast(next->GetData(), wxRichTextParagraph); + } - // Move the objects to the previous para - wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); + bool applyFinalParagraphStyle = firstPara && nextParagraph && nextParagraph != firstPara; - while (node1) - { - wxRichTextObject* obj1 = node1->GetData(); + wxTextAttrEx nextParaAttr; + if (applyFinalParagraphStyle) + { + // Special case when deleting the end of a paragraph - use _this_ paragraph's style, + // not the next one. + if (range.GetStart() == range.GetEnd() && range.GetStart() == thisRange.GetEnd()) + nextParaAttr = thisAttr; + else + nextParaAttr = nextParagraph->GetAttributes(); + } - // If the object is empty, optimise it out - if (obj1->IsEmpty()) - { - delete obj1; - } - else - { - obj->AppendChild(obj1); - } + if (firstPara && nextParagraph && firstPara != nextParagraph) + { + // Move the objects to the previous para + wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); - wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); - nextParagraph->GetChildren().Erase(node1); + while (node1) + { + wxRichTextObject* obj1 = node1->GetData(); - node1 = next1; - } + firstPara->AppendChild(obj1); - // Delete the paragraph - RemoveChild(nextParagraph, true); + wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); + nextParagraph->GetChildren().Erase(node1); + node1 = next1; } + + // Delete the paragraph + RemoveChild(nextParagraph, true); } + // Avoid empty paragraphs + if (firstPara && firstPara->GetChildren().GetCount() == 0) + { + wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); + firstPara->AppendChild(text); + } + + if (applyFinalParagraphStyle) + firstPara->SetAttributes(nextParaAttr); + + return true; } } @@ -1733,7 +1808,7 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const splitPoint ++; // Find last object - if (splitPoint == newPara->GetRange().GetEnd() || splitPoint == (newPara->GetRange().GetEnd() - 1)) + if (splitPoint == newPara->GetRange().GetEnd()) lastObject = newPara->GetChildren().GetLast()->GetData(); else // lastObject is set as a side-effect of splitting. It's @@ -3691,7 +3766,7 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition wxSize lineSize = line->GetSize(); wxRichTextRange lineRange = line->GetAbsoluteRange(); - if (pt.y >= linePos.y && pt.y <= linePos.y + lineSize.y) + if (pt.y <= linePos.y + lineSize.y) { if (pt.x < linePos.x) { @@ -4236,22 +4311,50 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR wxString str = m_text; wxString toRemove = wxRichTextLineBreakChar; str.Replace(toRemove, wxT(" ")); + if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) + str.MakeUpper(); long len = range.GetLength(); wxString stringChunk = str.Mid(range.GetStart() - offset, (size_t) len); - if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) - stringChunk.MakeUpper(); - - int charHeight = dc.GetCharHeight(); - - int x = rect.x; - int y = rect.y + (rect.height - charHeight - (descent - m_descent)); // Test for the optimized situations where all is selected, or none // is selected. - wxFont font(GetBuffer()->GetFontTable().FindFont(textAttr)); - wxCheckSetFont(dc, font); + wxFont textFont(GetBuffer()->GetFontTable().FindFont(textAttr)); + wxCheckSetFont(dc, textFont); + int charHeight = dc.GetCharHeight(); + + int x, y; + if ( textFont.Ok() ) + { + if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) ) + { + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + x = rect.x; + y = rect.y; + wxCheckSetFont(dc, textFont); + } + else if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) + { + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + x = rect.x; + int sub_height = static_cast( static_cast(charHeight) / wxSCRIPT_MUL_FACTOR); + y = rect.y + (rect.height - sub_height + (descent - m_descent)); + wxCheckSetFont(dc, textFont); + } + else + { + x = rect.x; + y = rect.y + (rect.height - charHeight - (descent - m_descent)); + } + } + else + { + x = rect.x; + y = rect.y + (rect.height - charHeight - (descent - m_descent)); + } // (a) All selected. if (selectionRange.GetStart() <= range.GetStart() && selectionRange.GetEnd() >= range.GetEnd()) @@ -4269,7 +4372,7 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR // (c) Part selected, part not // Let's draw unselected chunk, selected chunk, then unselected chunk. - dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); // 1. Initial unselected chunk, if any, up until start of selection. if (selectionRange.GetStart() > range.GetStart() && selectionRange.GetStart() <= range.GetEnd()) @@ -4386,7 +4489,7 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttr& attr, con wxCheckSetBrush(dc, wxBrush(highlightColour)); wxCheckSetPen(dc, wxPen(highlightColour)); dc.SetTextForeground(highlightTextColour); - dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); } else { @@ -4394,11 +4497,11 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttr& attr, con if (attr.HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR) && attr.GetBackgroundColour().IsOk()) { - dc.SetBackgroundMode(wxSOLID); + dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID); dc.SetTextBackground(attr.GetBackgroundColour()); } else - dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); } while (hasTabs) @@ -4506,8 +4609,24 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz // of line breaks - and we don't need it, since we'll calculate size within // formatted text by doing it in chunks according to the line ranges + bool bScript(false); wxFont font(GetBuffer()->GetFontTable().FindFont(textAttr)); - wxCheckSetFont(dc, font); + if (font.Ok()) + { + if ( textAttr.HasTextEffects() && ( (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) + || (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) ) + { + wxFont textFont = font; + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + wxCheckSetFont(dc, textFont); + bScript = true; + } + else + { + wxCheckSetFont(dc, font); + } + } int startPos = range.GetStart() - GetRange().GetStart(); long len = range.GetLength(); @@ -4575,8 +4694,13 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz } } } + dc.GetTextExtent(stringChunk, & w, & h, & descent); width += w; + + if ( bScript ) + dc.SetFont(font); + size = wxSize(width, dc.GetCharHeight()); return true; @@ -4662,6 +4786,7 @@ bool wxRichTextPlainText::Merge(wxRichTextObject* object) if (textObject) { m_text += textObject->GetText(); + wxRichTextApplyStyle(m_attributes, textObject->GetAttributes()); return true; } else @@ -4794,21 +4919,14 @@ bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagr action->GetNewParagraphs() = paragraphs; - if (p) - { - wxRichTextObjectList::compatibility_iterator node = m_children.GetLast(); - while (node) - { - wxRichTextParagraph* obj = (wxRichTextParagraph*) node->GetData(); - obj->SetAttributes(*p); - node = node->GetPrevious(); - } - } - action->SetPosition(pos); + wxRichTextRange range = wxRichTextRange(pos, pos + paragraphs.GetRange().GetEnd() - 1); + if (!paragraphs.GetPartialParagraph()) + range.SetEnd(range.GetEnd()+1); + // Set the range we'll need to delete in Undo - action->SetRange(wxRichTextRange(pos, pos + paragraphs.GetRange().GetEnd() - 1)); + action->SetRange(range); SubmitAction(action); @@ -4873,13 +4991,47 @@ bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int action->GetNewParagraphs().AppendChild(newPara); action->GetNewParagraphs().UpdateRanges(); action->GetNewParagraphs().SetPartialParagraph(false); - action->SetPosition(pos); + wxRichTextParagraph* para = GetParagraphAtPosition(pos, false); + long pos1 = pos; if (p) newPara->SetAttributes(*p); + if (flags & wxRICHTEXT_INSERT_INTERACTIVE) + { + if (para && para->GetRange().GetEnd() == pos) + pos1 ++; + if (newPara->GetAttributes().HasBulletNumber()) + newPara->GetAttributes().SetBulletNumber(newPara->GetAttributes().GetBulletNumber()+1); + } + + action->SetPosition(pos); + + // Use the default character style + // Use the default character style + if (!GetDefaultStyle().IsDefault() && newPara->GetChildren().GetFirst()) + { + // Check whether the default style merely reflects the paragraph/basic style, + // in which case don't apply it. + wxTextAttrEx defaultStyle(GetDefaultStyle()); + wxTextAttrEx toApply; + if (para) + { + wxRichTextAttr combinedAttr = para->GetCombinedAttributes(); + wxTextAttrEx newAttr; + // This filters out attributes that are accounted for by the current + // paragraph/basic style + wxRichTextApplyStyle(toApply, defaultStyle, & combinedAttr); + } + else + toApply = defaultStyle; + + if (!toApply.IsDefault()) + newPara->GetChildren().GetFirst()->GetData()->SetAttributes(toApply); + } + // Set the range we'll need to delete in Undo - action->SetRange(wxRichTextRange(pos, pos)); + action->SetRange(wxRichTextRange(pos1, pos1)); SubmitAction(action); @@ -4998,22 +5150,18 @@ bool wxRichTextBuffer::DeleteRangeWithUndo(const wxRichTextRange& range, wxRichT // Copy the fragment that we'll need to restore in Undo CopyFragment(range, action->GetOldParagraphs()); - // Special case: if there is only one (non-partial) paragraph, - // we must save the *next* paragraph's style, because that - // is the style we must apply when inserting the content back - // when undoing the delete. (This is because we're merging the - // paragraph with the previous paragraph and throwing away - // the style, and we need to restore it.) - if (!action->GetOldParagraphs().GetPartialParagraph() && action->GetOldParagraphs().GetChildCount() == 1) + // See if we're deleting a paragraph marker, in which case we need to + // make a note not to copy the attributes from the 2nd paragraph to the 1st. + if (range.GetStart() == range.GetEnd()) { - wxRichTextParagraph* lastPara = GetParagraphAtPosition(range.GetStart()); - if (lastPara) + wxRichTextParagraph* para = GetParagraphAtPosition(range.GetStart()); + if (para && para->GetRange().GetEnd() == range.GetEnd()) { - wxRichTextParagraph* nextPara = GetParagraphAtPosition(range.GetEnd()+1); - if (nextPara) + wxRichTextParagraph* nextPara = GetParagraphAtPosition(range.GetStart()+1); + if (nextPara && nextPara != para) { - wxRichTextParagraph* para = (wxRichTextParagraph*) action->GetOldParagraphs().GetChild(0); - para->SetAttributes(nextPara->GetAttributes()); + action->GetOldParagraphs().GetChildren().GetFirst()->GetData()->SetAttributes(nextPara->GetAttributes()); + action->GetOldParagraphs().GetAttributes().SetFlags(action->GetOldParagraphs().GetAttributes().GetFlags() | wxTEXT_ATTR_KEEP_FIRST_PARA_STYLE); } } } @@ -5031,7 +5179,7 @@ bool wxRichTextBuffer::BeginBatchUndo(const wxString& cmdName) wxASSERT(m_batchedCommand == NULL); if (m_batchedCommand) { - GetCommandProcessor()->Submit(m_batchedCommand); + GetCommandProcessor()->Store(m_batchedCommand); } m_batchedCommand = new wxRichTextCommand(cmdName); } @@ -5051,7 +5199,7 @@ bool wxRichTextBuffer::EndBatchUndo() if (m_batchedCommandDepth == 0) { - GetCommandProcessor()->Submit(m_batchedCommand); + GetCommandProcessor()->Store(m_batchedCommand); m_batchedCommand = NULL; } @@ -5062,7 +5210,15 @@ bool wxRichTextBuffer::EndBatchUndo() bool wxRichTextBuffer::SubmitAction(wxRichTextAction* action) { if (BatchingUndo() && m_batchedCommand && !SuppressingUndo()) + { + wxRichTextCommand* cmd = new wxRichTextCommand(action->GetName()); + cmd->AddAction(action); + cmd->Do(); + cmd->GetActions().Clear(); + delete cmd; + m_batchedCommand->AddAction(action); + } else { wxRichTextCommand* cmd = new wxRichTextCommand(action->GetName()); @@ -5628,6 +5784,8 @@ bool wxRichTextBuffer::PasteFromClipboard(long position) if (richTextBuffer) { InsertParagraphsWithUndo(position+1, *richTextBuffer, GetRichTextCtrl(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + if (GetRichTextCtrl()) + GetRichTextCtrl()->ShowPosition(position + richTextBuffer->GetRange().GetEnd()); delete richTextBuffer; } } @@ -5651,6 +5809,9 @@ bool wxRichTextBuffer::PasteFromClipboard(long position) #endif InsertTextWithUndo(position+1, text2, GetRichTextCtrl()); + if (GetRichTextCtrl()) + GetRichTextCtrl()->ShowPosition(position + text2.Length()); + success = true; } else if (wxTheClipboard->IsSupported(wxDF_BITMAP)) @@ -5907,7 +6068,7 @@ bool wxRichTextStdRenderer::DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& if (attr.GetTextColour().Ok()) dc.SetTextForeground(attr.GetTextColour()); - dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); int charHeight = dc.GetCharHeight(); wxCoord tw, th; @@ -6095,7 +6256,7 @@ bool wxRichTextAction::Do() wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint(); int lastY = firstVisiblePt.y + clientSize.y; - wxRichTextParagraph* para = m_buffer->GetParagraphAtPosition(GetPosition()); + wxRichTextParagraph* para = m_buffer->GetParagraphAtPosition(GetRange().GetStart()); wxRichTextObjectList::compatibility_iterator node = m_buffer->GetChildren().Find(para); while (node) { @@ -6128,9 +6289,9 @@ bool wxRichTextAction::Do() } #endif - m_buffer->InsertFragment(GetPosition(), m_newParagraphs); + m_buffer->InsertFragment(GetRange().GetStart(), m_newParagraphs); m_buffer->UpdateRanges(); - m_buffer->Invalidate(GetRange()); + m_buffer->Invalidate(wxRichTextRange(GetRange().GetStart()-1, GetRange().GetEnd())); long newCaretPosition = GetPosition() + m_newParagraphs.GetRange().GetLength(); @@ -6172,7 +6333,11 @@ bool wxRichTextAction::Do() m_buffer->UpdateRanges(); m_buffer->Invalidate(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart())); - UpdateAppearance(GetRange().GetStart()-1, true /* send update event */); + long caretPos = GetRange().GetStart()-1; + if (caretPos >= m_buffer->GetRange().GetEnd()) + caretPos --; + + UpdateAppearance(caretPos, true /* send update event */); wxRichTextEvent cmdEvent( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED,