Text stuff: Bugfixes in Insert and Remove methods
Still not well tested. Also some way to trigger the layouts to adopt to the changed document paragraphs. Not yet via the new TextListener.
This commit is contained in:
parent
315dee6f22
commit
2c906df217
@ -92,6 +92,7 @@ Paragraph::Insert(int32 offset, const TextSpan& newSpan)
|
||||
if (offset - span.CharCount() < 0)
|
||||
break;
|
||||
offset -= span.CharCount();
|
||||
index++;
|
||||
}
|
||||
|
||||
if (fTextSpans.CountItems() == index)
|
||||
@ -139,25 +140,28 @@ Paragraph::Remove(int32 offset, int32 length)
|
||||
if (offset - span.CharCount() < 0)
|
||||
break;
|
||||
offset -= span.CharCount();
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= fTextSpans.CountItems())
|
||||
return false;
|
||||
|
||||
TextSpan span = fTextSpans.ItemAtFast(index).SubSpan(0, offset);
|
||||
|
||||
TextSpan span(fTextSpans.ItemAtFast(index));
|
||||
int32 removeLength = std::min(span.CharCount() - offset, length);
|
||||
span.Remove(offset, removeLength);
|
||||
fTextSpans.Replace(index, span);
|
||||
length -= removeLength;
|
||||
index += 1;
|
||||
if (index >= fTextSpans.CountItems())
|
||||
return true;
|
||||
|
||||
while (length > 0) {
|
||||
|
||||
// Remove more spans if necessary
|
||||
while (length > 0 && index < fTextSpans.CountItems()) {
|
||||
int32 spanLength = fTextSpans.ItemAtFast(index).CharCount();
|
||||
if (spanLength <= length) {
|
||||
fTextSpans.Remove(index);
|
||||
length -= spanLength;
|
||||
} else {
|
||||
// Reached last span
|
||||
int32 removeLength = std::min(length, spanLength);
|
||||
removeLength = std::min(length, spanLength);
|
||||
TextSpan lastSpan = fTextSpans.ItemAtFast(index).SubSpan(
|
||||
removeLength, spanLength - removeLength);
|
||||
// Try to merge with first span, otherwise replace span at index
|
||||
@ -172,6 +176,10 @@ Paragraph::Remove(int32 offset, int32 length)
|
||||
}
|
||||
}
|
||||
|
||||
// See if anything from the TextSpan at offset remained
|
||||
if (span.CharCount() == 0)
|
||||
fTextSpans.Remove(index - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ TextDocument::Remove(int32 textOffset, int32 length)
|
||||
|
||||
textOffset = 0;
|
||||
|
||||
while (length > 0) {
|
||||
while (length > 0 && index + 1 < fParagraphs.CountItems()) {
|
||||
const Paragraph& paragraph = ParagraphAt(index + 1);
|
||||
paragraphLength = paragraph.Length();
|
||||
// Remove paragraph in any case. If some of it remains, the last
|
||||
@ -238,10 +238,10 @@ TextDocument::ParagraphIndexFor(int32 textOffset, int32& paragraphOffset) const
|
||||
int32 count = fParagraphs.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
|
||||
paragraphOffset = textOffset - textLength;
|
||||
int32 paragraphLength = paragraph.Length();
|
||||
if (textLength + paragraphLength > textOffset)
|
||||
return i;
|
||||
paragraphOffset += paragraphLength;
|
||||
textLength += paragraphLength;
|
||||
}
|
||||
return -1;
|
||||
|
@ -61,6 +61,34 @@ TextDocumentLayout::SetTextDocument(const TextDocumentRef& document)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TextDocumentLayout::Invalidate()
|
||||
{
|
||||
InvalidateParagraphs(0, fParagraphLayouts.CountItems());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TextDocumentLayout::InvalidateParagraphs(int32 start, int32 count)
|
||||
{
|
||||
if (start < 0 || fDocument.Get() == NULL)
|
||||
return;
|
||||
|
||||
const ParagraphList& paragraphs = fDocument->Paragraphs();
|
||||
|
||||
while (count > 0) {
|
||||
if (start >= fParagraphLayouts.CountItems())
|
||||
break;
|
||||
|
||||
const Paragraph& paragraph = paragraphs.ItemAtFast(start);
|
||||
const ParagraphLayoutInfo& info = fParagraphLayouts.ItemAtFast(start);
|
||||
info.layout->SetParagraph(paragraph);
|
||||
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TextDocumentLayout::SetWidth(float width)
|
||||
{
|
||||
|
@ -78,6 +78,9 @@ public:
|
||||
void SetTextDocument(
|
||||
const TextDocumentRef& document);
|
||||
|
||||
void Invalidate();
|
||||
void InvalidateParagraphs(int32 start, int32 count);
|
||||
|
||||
void SetWidth(float width);
|
||||
float Width() const
|
||||
{ return fWidth; }
|
||||
|
@ -243,6 +243,9 @@ TextEditor::Insert(int32 offset, const BString& string)
|
||||
if (!fEditingEnabled || fDocument.Get() == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
// TODO: Via listener, and only affected paragraphs
|
||||
fLayout->Invalidate();
|
||||
|
||||
return fDocument->Insert(offset, string, fStyleAtCaret);
|
||||
}
|
||||
|
||||
@ -253,6 +256,9 @@ TextEditor::Remove(int32 offset, int32 length)
|
||||
if (!fEditingEnabled || fDocument.Get() == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
// TODO: Via listener, and only affected paragraphs
|
||||
fLayout->Invalidate();
|
||||
|
||||
return fDocument->Remove(offset, length);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user