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)
|
if (offset - span.CharCount() < 0)
|
||||||
break;
|
break;
|
||||||
offset -= span.CharCount();
|
offset -= span.CharCount();
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fTextSpans.CountItems() == index)
|
if (fTextSpans.CountItems() == index)
|
||||||
@ -139,25 +140,28 @@ Paragraph::Remove(int32 offset, int32 length)
|
|||||||
if (offset - span.CharCount() < 0)
|
if (offset - span.CharCount() < 0)
|
||||||
break;
|
break;
|
||||||
offset -= span.CharCount();
|
offset -= span.CharCount();
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index >= fTextSpans.CountItems())
|
if (index >= fTextSpans.CountItems())
|
||||||
return false;
|
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);
|
fTextSpans.Replace(index, span);
|
||||||
|
length -= removeLength;
|
||||||
index += 1;
|
index += 1;
|
||||||
if (index >= fTextSpans.CountItems())
|
|
||||||
return true;
|
// Remove more spans if necessary
|
||||||
|
while (length > 0 && index < fTextSpans.CountItems()) {
|
||||||
while (length > 0) {
|
|
||||||
int32 spanLength = fTextSpans.ItemAtFast(index).CharCount();
|
int32 spanLength = fTextSpans.ItemAtFast(index).CharCount();
|
||||||
if (spanLength <= length) {
|
if (spanLength <= length) {
|
||||||
fTextSpans.Remove(index);
|
fTextSpans.Remove(index);
|
||||||
length -= spanLength;
|
length -= spanLength;
|
||||||
} else {
|
} else {
|
||||||
// Reached last span
|
// Reached last span
|
||||||
int32 removeLength = std::min(length, spanLength);
|
removeLength = std::min(length, spanLength);
|
||||||
TextSpan lastSpan = fTextSpans.ItemAtFast(index).SubSpan(
|
TextSpan lastSpan = fTextSpans.ItemAtFast(index).SubSpan(
|
||||||
removeLength, spanLength - removeLength);
|
removeLength, spanLength - removeLength);
|
||||||
// Try to merge with first span, otherwise replace span at index
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ TextDocument::Remove(int32 textOffset, int32 length)
|
|||||||
|
|
||||||
textOffset = 0;
|
textOffset = 0;
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0 && index + 1 < fParagraphs.CountItems()) {
|
||||||
const Paragraph& paragraph = ParagraphAt(index + 1);
|
const Paragraph& paragraph = ParagraphAt(index + 1);
|
||||||
paragraphLength = paragraph.Length();
|
paragraphLength = paragraph.Length();
|
||||||
// Remove paragraph in any case. If some of it remains, the last
|
// 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();
|
int32 count = fParagraphs.CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
|
const Paragraph& paragraph = fParagraphs.ItemAtFast(i);
|
||||||
paragraphOffset = textOffset - textLength;
|
|
||||||
int32 paragraphLength = paragraph.Length();
|
int32 paragraphLength = paragraph.Length();
|
||||||
if (textLength + paragraphLength > textOffset)
|
if (textLength + paragraphLength > textOffset)
|
||||||
return i;
|
return i;
|
||||||
|
paragraphOffset += paragraphLength;
|
||||||
textLength += paragraphLength;
|
textLength += paragraphLength;
|
||||||
}
|
}
|
||||||
return -1;
|
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
|
void
|
||||||
TextDocumentLayout::SetWidth(float width)
|
TextDocumentLayout::SetWidth(float width)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,9 @@ public:
|
|||||||
void SetTextDocument(
|
void SetTextDocument(
|
||||||
const TextDocumentRef& document);
|
const TextDocumentRef& document);
|
||||||
|
|
||||||
|
void Invalidate();
|
||||||
|
void InvalidateParagraphs(int32 start, int32 count);
|
||||||
|
|
||||||
void SetWidth(float width);
|
void SetWidth(float width);
|
||||||
float Width() const
|
float Width() const
|
||||||
{ return fWidth; }
|
{ return fWidth; }
|
||||||
|
@ -243,6 +243,9 @@ TextEditor::Insert(int32 offset, const BString& string)
|
|||||||
if (!fEditingEnabled || fDocument.Get() == NULL)
|
if (!fEditingEnabled || fDocument.Get() == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
// TODO: Via listener, and only affected paragraphs
|
||||||
|
fLayout->Invalidate();
|
||||||
|
|
||||||
return fDocument->Insert(offset, string, fStyleAtCaret);
|
return fDocument->Insert(offset, string, fStyleAtCaret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,6 +256,9 @@ TextEditor::Remove(int32 offset, int32 length)
|
|||||||
if (!fEditingEnabled || fDocument.Get() == NULL)
|
if (!fEditingEnabled || fDocument.Get() == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
// TODO: Via listener, and only affected paragraphs
|
||||||
|
fLayout->Invalidate();
|
||||||
|
|
||||||
return fDocument->Remove(offset, length);
|
return fDocument->Remove(offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user