diff --git a/src/apps/haiku-depot/textview/Paragraph.cpp b/src/apps/haiku-depot/textview/Paragraph.cpp index 07fb11e694..df968254a5 100644 --- a/src/apps/haiku-depot/textview/Paragraph.cpp +++ b/src/apps/haiku-depot/textview/Paragraph.cpp @@ -5,6 +5,8 @@ #include "Paragraph.h" +#include + Paragraph::Paragraph() : @@ -149,3 +151,47 @@ Paragraph::IsEmpty() const { return fTextSpans.CountItems() == 0; } + + +BString +Paragraph::GetText(int32 start, int32 length) const +{ + if (start < 0) + start = 0; + + BString text; + + int32 count = fTextSpans.CountItems(); + for (int32 i = 0; i < count; i++) { + const TextSpan& span = fTextSpans.ItemAtFast(i); + int32 spanLength = span.CharCount(); + if (spanLength == 0) + continue; + if (start > spanLength) { + // Skip span if its before start + start -= spanLength; + continue; + } + + // Remaining span length after start + spanLength -= start; + int32 copyLength = std::min(spanLength, length); + + if (start == 0 && length == spanLength) { + text << span.Text(); + } else { + BString subString; + span.Text().CopyCharsInto(subString, start, copyLength); + text << subString; + } + + length -= copyLength; + if (length == 0) + break; + + // Next span is copied from its beginning + start = 0; + } + + return text; +} diff --git a/src/apps/haiku-depot/textview/Paragraph.h b/src/apps/haiku-depot/textview/Paragraph.h index 2c8ead001c..98d4fd1afd 100644 --- a/src/apps/haiku-depot/textview/Paragraph.h +++ b/src/apps/haiku-depot/textview/Paragraph.h @@ -37,6 +37,8 @@ public: int32 Length() const; bool IsEmpty() const; + BString GetText(int32 start, int32 length) const; + private: ParagraphStyle fStyle; TextSpanList fTextSpans; diff --git a/src/apps/haiku-depot/textview/TextDocument.cpp b/src/apps/haiku-depot/textview/TextDocument.cpp index 2ec8e0b6d4..58b0dcdbb2 100644 --- a/src/apps/haiku-depot/textview/TextDocument.cpp +++ b/src/apps/haiku-depot/textview/TextDocument.cpp @@ -5,6 +5,8 @@ #include "TextDocument.h" +#include + TextDocument::TextDocument() : @@ -172,9 +174,11 @@ TextDocument::ParagraphAt(int32 textOffset, int32& paragraphOffset) const int32 count = fParagraphs.CountItems(); for (int32 i = 0; i < count; i++) { const Paragraph& paragraph = fParagraphs.ItemAtFast(i); - paragraphOffset = textLength; - if (textLength + paragraph.Length() > textOffset) + paragraphOffset = textOffset - textLength; + int32 paragraphLength = paragraph.Length(); + if (textLength + paragraphLength > textOffset) return paragraph; + textLength += paragraphLength; } return fEmptyLastParagraph; } @@ -211,3 +215,41 @@ TextDocument::Length() const } +BString +TextDocument::GetText(int32 start, int32 length) const +{ + if (start < 0) + start = 0; + + BString text; + + int32 count = fParagraphs.CountItems(); + for (int32 i = 0; i < count; i++) { + const Paragraph& paragraph = fParagraphs.ItemAtFast(i); + int32 paragraphLength = paragraph.Length(); + if (paragraphLength == 0) + continue; + if (start > paragraphLength) { + // Skip paragraph if its before start + start -= paragraphLength; + continue; + } + + // Remaining paragraph length after start + paragraphLength -= start; + int32 copyLength = std::min(paragraphLength, length); + + text << paragraph.GetText(start, copyLength); + + length -= copyLength; + if (length == 0) + break; + else if (i < count - 1) + text << '\n'; + + // Next paragraph is copied from its beginning + start = 0; + } + + return text; +} diff --git a/src/apps/haiku-depot/textview/TextDocument.h b/src/apps/haiku-depot/textview/TextDocument.h index 7ccc5c2fb7..6f385f8371 100644 --- a/src/apps/haiku-depot/textview/TextDocument.h +++ b/src/apps/haiku-depot/textview/TextDocument.h @@ -65,6 +65,8 @@ public: // Query information int32 Length() const; + BString GetText(int32 start, int32 length) const; + private: ParagraphList fParagraphs; Paragraph fEmptyLastParagraph;