X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0745f3641015a626949345f4515a9741177fd402..7c3c990ecf8be60d40e6b6ac3835064daee321aa:/src/richtext/richtextbuffer.cpp diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index ae5b2c223b..91aafbfd9e 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; @@ -1048,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; @@ -1145,7 +1176,8 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag wxRichTextParagraph* firstPara = wxDynamicCast(firstParaNode->GetData(), wxRichTextParagraph); wxASSERT(firstPara != NULL); - para->SetAttributes(firstPara->GetAttributes()); + 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, @@ -1222,7 +1254,9 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParag } } - if (finalPara && finalPara != para) + 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; @@ -1424,6 +1458,7 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& 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. @@ -1457,7 +1492,14 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) wxTextAttrEx nextParaAttr; if (applyFinalParagraphStyle) - nextParaAttr = nextParagraph->GetAttributes(); + { + // 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 (firstPara && nextParagraph && firstPara != nextParagraph) { @@ -1468,15 +1510,7 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) { wxRichTextObject* obj1 = node1->GetData(); - // If the object is empty, optimise it out - if (obj1->IsEmpty()) - { - delete obj1; - } - else - { - firstPara->AppendChild(obj1); - } + firstPara->AppendChild(obj1); wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); nextParagraph->GetChildren().Erase(node1); @@ -1488,6 +1522,13 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) 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); @@ -1767,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 @@ -3725,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) { @@ -4904,17 +4945,19 @@ bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int 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); - if (p) - newPara->SetAttributes(*p); - // Use the default character style // Use the default character style if (!GetDefaultStyle().IsDefault() && newPara->GetChildren().GetFirst()) @@ -5058,22 +5101,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); } } } @@ -5696,6 +5735,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; } } @@ -5719,6 +5760,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)) @@ -6240,7 +6284,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,