[haiku-commits] haiku: hrev49624 - src/apps/haikudepot/textview

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 6 Sep 2015 23:12:31 +0200 (CEST)

hrev49624 adds 5 changesets to branch 'master'
old head: ce27f9612e78bbb58c62bdc54c02bfc0e5172681
new head: 7d8d7785c17ab7a0bc5666100f1e149362bb4dd5
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=7d8d7785c17a+%5Ece27f9612e78

----------------------------------------------------------------------------

87136732d056: HaikuDepot: Fixed wording in a comment.

f6e5131227b4: TextDocumentTest: Make document editable.

4a96bcdafa42: Text frame work: Implement sending TextChangedEvents

TextDocument:
* Moved implementation of Remove() and Insert() into private methods.
* Reimplement all public Insert() methods and Remove() on top of Replace().
* In Replace(), send a TextChangedEvent. Added TODO for sending a
TextChangingEvent, although at this point, I am not sure if it will be
needed at all.

41bd20b06b0a: Text framework: Add TextListener in TextDocumentLayout...

... and invalidate based on TextChangedEvents. I am not yet sure whether
TextChangeEvent needs separate counts for removed and changed paragraphs.
It is most likely not yet correct and may either update too many paragraph
layouts or miss updating some at the end.

7d8d7785c17a: Text framework: Added TextEditor::Replace()

Call Replace() on TextDocument, so that there are not two edits later
on once UndoableEdit stuff is supported.

[ Stephan Aßmus <superstippi@xxxxxx> ]

----------------------------------------------------------------------------

8 files changed, 293 insertions(+), 187 deletions(-)
src/apps/haikudepot/List.h | 2 +-
src/apps/haikudepot/textview/TextDocument.cpp | 373 ++++++++++---------
src/apps/haikudepot/textview/TextDocument.h | 10 +
.../haikudepot/textview/TextDocumentLayout.cpp | 59 ++-
.../haikudepot/textview/TextDocumentLayout.h | 3 +-
.../haikudepot/textview/TextDocumentTest.cpp | 1 +
src/apps/haikudepot/textview/TextEditor.cpp | 30 +-
src/apps/haikudepot/textview/TextEditor.h | 2 +

############################################################################

Commit: 87136732d0563135ad98b82be828ef35d255ef52
URL: http://cgit.haiku-os.org/haiku/commit/?id=87136732d056
Author: Stephan Aßmus <superstippi@xxxxxx>
Date: Sun Sep 6 19:51:24 2015 UTC

HaikuDepot: Fixed wording in a comment.

----------------------------------------------------------------------------

diff --git a/src/apps/haikudepot/List.h b/src/apps/haikudepot/List.h
index a8d2829..3c2ce08 100644
--- a/src/apps/haikudepot/List.h
+++ b/src/apps/haikudepot/List.h
@@ -56,7 +56,7 @@ public:
// NOTE: Another option would be to use
// ItemType::operator=(const ItemType& other), but then
// we would need to be carefull which objects are
already
- // initialized. Also the ItemType requires to implement
the
+ // initialized. Also ItemType would be required to
implement the
// operator, while doing it this way requires only a
copy
// constructor.
_Resize(0);

############################################################################

Commit: f6e5131227b4d536f37b0d1985ea0c2c4fee7fa1
URL: http://cgit.haiku-os.org/haiku/commit/?id=f6e5131227b4
Author: Stephan Aßmus <superstippi@xxxxxx>
Date: Sun Sep 6 21:02:51 2015 UTC

TextDocumentTest: Make document editable.

----------------------------------------------------------------------------

diff --git a/src/apps/haikudepot/textview/TextDocumentTest.cpp
b/src/apps/haikudepot/textview/TextDocumentTest.cpp
index 1633268..2c68f12 100644
--- a/src/apps/haikudepot/textview/TextDocumentTest.cpp
+++ b/src/apps/haikudepot/textview/TextDocumentTest.cpp
@@ -116,6 +116,7 @@ TextDocumentTest::ReadyToRun()
);

documentView->SetTextDocument(document);
+ documentView->SetTextEditor(TextEditorRef(new TextEditor(), true));
documentView->MakeFocus();

window->Show();

############################################################################

Commit: 4a96bcdafa42c26c252a8a2d1029fe96cea565ec
URL: http://cgit.haiku-os.org/haiku/commit/?id=4a96bcdafa42
Author: Stephan Aßmus <superstippi@xxxxxx>
Date: Sun Sep 6 21:03:34 2015 UTC

Text frame work: Implement sending TextChangedEvents

TextDocument:
* Moved implementation of Remove() and Insert() into private methods.
* Reimplement all public Insert() methods and Remove() on top of Replace().
* In Replace(), send a TextChangedEvent. Added TODO for sending a
TextChangingEvent, although at this point, I am not sure if it will be
needed at all.

----------------------------------------------------------------------------

diff --git a/src/apps/haikudepot/textview/TextDocument.cpp
b/src/apps/haikudepot/textview/TextDocument.cpp
index 3e2f115..ae15111 100644
--- a/src/apps/haikudepot/textview/TextDocument.cpp
+++ b/src/apps/haikudepot/textview/TextDocument.cpp
@@ -73,7 +73,7 @@ TextDocument::operator!=(const TextDocument& other) const
status_t
TextDocument::Insert(int32 textOffset, const BString& text)
{
- return Insert(textOffset, text, CharacterStyleAt(textOffset));
+ return Replace(textOffset, 0, text);
}


@@ -81,7 +81,7 @@ status_t
TextDocument::Insert(int32 textOffset, const BString& text,
const CharacterStyle& style)
{
- return Insert(textOffset, text, style, ParagraphStyleAt(textOffset));
+ return Replace(textOffset, 0, text, style);
}


@@ -89,90 +89,7 @@ status_t
TextDocument::Insert(int32 textOffset, const BString& text,
const CharacterStyle& characterStyle, const ParagraphStyle&
paragraphStyle)
{
- int32 paragraphOffset;
- int32 index = ParagraphIndexFor(textOffset, paragraphOffset);
- if (index < 0)
- return B_BAD_VALUE;
-
- textOffset -= paragraphOffset;
-
- bool hasLineBreaks = text.FindFirst('\n', 0) >= 0;
-
- if (hasLineBreaks) {
- // Split paragraph at textOffset
- Paragraph paragraph1(ParagraphAt(index).Style());
- Paragraph paragraph2(paragraphStyle);
- const TextSpanList& textSpans = ParagraphAt(index).TextSpans();
- int32 spanCount = textSpans.CountItems();
- for (int32 i = 0; i < spanCount; i++) {
- const TextSpan& span = textSpans.ItemAtFast(i);
- int32 spanLength = span.CountChars();
- if (textOffset >= spanLength) {
- paragraph1.Append(span);
- textOffset -= spanLength;
- } else if (textOffset > 0) {
- paragraph1.Append(
- span.SubSpan(0, textOffset));
- paragraph2.Append(
- span.SubSpan(textOffset, spanLength -
textOffset));
- textOffset = 0;
- } else {
- paragraph2.Append(span);
- }
- }
-
- fParagraphs.Remove(index);
-
- // Insert TextSpans, splitting 'text' into Paragraphs at line
breaks.
- int32 length = text.CountChars();
- int32 chunkStart = 0;
- while (chunkStart < length) {
- int32 chunkEnd = text.FindFirst('\n', chunkStart);
- bool foundLineBreak = chunkEnd >= chunkStart;
- if (foundLineBreak)
- chunkEnd++;
- else
- chunkEnd = length;
-
- BString chunk;
- text.CopyCharsInto(chunk, chunkStart, chunkEnd -
chunkStart);
- TextSpan span(chunk, characterStyle);
-
- if (foundLineBreak) {
- if (!paragraph1.Append(span))
- return B_NO_MEMORY;
- if (paragraph1.Length() > 0) {
- if (!fParagraphs.Add(paragraph1, index))
- return B_NO_MEMORY;
- index++;
- }
- paragraph1 = Paragraph(paragraphStyle);
- } else {
- if (!paragraph2.Prepend(span))
- return B_NO_MEMORY;
- }
-
- chunkStart = chunkEnd + 1;
- }
-
- if (paragraph2.IsEmpty()) {
- // Make sure Paragraph has at least one TextSpan, even
- // if its empty.
- const TextSpanList& spans = paragraph1.TextSpans();
- const TextSpan& span = spans.LastItem();
- paragraph2.Append(TextSpan("", span.Style()));
- }
-
- if (!fParagraphs.Add(paragraph2, index))
- return B_NO_MEMORY;
- } else {
- Paragraph paragraph(ParagraphAt(index));
- paragraph.Insert(textOffset, TextSpan(text, characterStyle));
- if (!fParagraphs.Replace(index, paragraph))
- return B_NO_MEMORY;
- }
-
- return B_OK;
+ return Replace(textOffset, 0, text, characterStyle, paragraphStyle);
}


@@ -182,83 +99,7 @@ TextDocument::Insert(int32 textOffset, const BString& text,
status_t
TextDocument::Remove(int32 textOffset, int32 length)
{
- if (length == 0)
- return B_OK;
-
- int32 paragraphOffset;
- int32 index = ParagraphIndexFor(textOffset, paragraphOffset);
- if (index < 0)
- return B_BAD_VALUE;
-
- textOffset -= paragraphOffset;
-
- // The paragraph at the text offset remains, even if the offset is at
- // the beginning of that paragraph. The idea is that the selection start
- // stays visually in the same place. Therefore, the paragraph at that
- // offset has to keep the paragraph style from that paragraph.
-
- Paragraph resultParagraph(ParagraphAt(index));
- int32 paragraphLength = resultParagraph.Length();
- if (textOffset == 0 && length > paragraphLength) {
- length -= paragraphLength;
- paragraphLength = 0;
- resultParagraph.Clear();
- } else {
- int32 removeLength = std::min(length, paragraphLength -
textOffset);
- resultParagraph.Remove(textOffset, removeLength);
- paragraphLength -= removeLength;
- length -= removeLength;
- }
-
- if (textOffset == paragraphLength && length == 0
- && index + 1 < fParagraphs.CountItems()) {
- // Line break between paragraphs got removed. Shift the next
- // paragraph's text spans into the resulting one.
-
- const TextSpanList& textSpans = ParagraphAt(index +
1).TextSpans();
- int32 spanCount = textSpans.CountItems();
- for (int32 i = 0; i < spanCount; i++) {
- const TextSpan& span = textSpans.ItemAtFast(i);
- resultParagraph.Append(span);
- }
- fParagraphs.Remove(index + 1);
- }
-
- textOffset = 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
- // paragraph to remove is reached, and the remaining spans are
- // transfered to the result parahraph.
- if (length >= paragraphLength) {
- length -= paragraphLength;
- fParagraphs.Remove(index);
- } else {
- // Last paragraph reached
- int32 removedLength = std::min(length, paragraphLength);
- Paragraph newParagraph(paragraph);
- fParagraphs.Remove(index + 1);
-
- if (!newParagraph.Remove(0, removedLength))
- return B_NO_MEMORY;
-
- // Transfer remaining spans to resultParagraph
- const TextSpanList& textSpans =
newParagraph.TextSpans();
- int32 spanCount = textSpans.CountItems();
- for (int32 i = 0; i < spanCount; i++) {
- const TextSpan& span = textSpans.ItemAtFast(i);
- resultParagraph.Append(span);
- }
-
- break;
- }
- }
-
- fParagraphs.Replace(index, resultParagraph);
-
- return B_OK;
+ return Replace(textOffset, length, BString());
}


@@ -285,11 +126,21 @@ status_t
TextDocument::Replace(int32 textOffset, int32 length, const BString& text,
const CharacterStyle& characterStyle, const ParagraphStyle&
paragraphStyle)
{
- status_t ret = Remove(textOffset, length);
+ int32 firstParagraph = 0;
+ int32 paragraphCount = 0;
+
+ // TODO: Call _NotifyTextChanging() before any change happened
+
+ status_t ret = _Remove(textOffset, length, firstParagraph,
paragraphCount);
if (ret != B_OK)
return ret;

- return Insert(textOffset, text, characterStyle, paragraphStyle);
+ ret = _Insert(textOffset, text, characterStyle, paragraphStyle,
+ firstParagraph, paragraphCount);
+
+ _NotifyTextChanged(TextChangedEvent(firstParagraph, paragraphCount));
+
+ return ret;
}


@@ -382,7 +233,7 @@ int32
TextDocument::Length() const
{
// TODO: Could be O(1) if the Paragraphs were wrapped in classes that
- // knew there text offset in the document.
+ // knew their text offset in the document.
int32 textLength = 0;
int32 count = fParagraphs.CountItems();
for (int32 i = 0; i < count; i++) {
@@ -530,6 +381,196 @@ TextDocument::RemoveUndoListener(const
UndoableEditListenerRef& listener)
}


+// #pragma mark - private
+
+
+status_t
+TextDocument::_Insert(int32 textOffset, const BString& text,
+ const CharacterStyle& characterStyle, const ParagraphStyle&
paragraphStyle,
+ int32& index, int32& paragraphCount)
+{
+ int32 paragraphOffset;
+ index = ParagraphIndexFor(textOffset, paragraphOffset);
+ if (index < 0)
+ return B_BAD_VALUE;
+
+ if (text.Length() == 0)
+ return B_OK;
+
+ textOffset -= paragraphOffset;
+
+ bool hasLineBreaks = text.FindFirst('\n', 0) >= 0;
+
+ if (hasLineBreaks) {
+ // Split paragraph at textOffset
+ Paragraph paragraph1(ParagraphAt(index).Style());
+ Paragraph paragraph2(paragraphStyle);
+ const TextSpanList& textSpans = ParagraphAt(index).TextSpans();
+ int32 spanCount = textSpans.CountItems();
+ for (int32 i = 0; i < spanCount; i++) {
+ const TextSpan& span = textSpans.ItemAtFast(i);
+ int32 spanLength = span.CountChars();
+ if (textOffset >= spanLength) {
+ paragraph1.Append(span);
+ textOffset -= spanLength;
+ } else if (textOffset > 0) {
+ paragraph1.Append(
+ span.SubSpan(0, textOffset));
+ paragraph2.Append(
+ span.SubSpan(textOffset, spanLength -
textOffset));
+ textOffset = 0;
+ } else {
+ paragraph2.Append(span);
+ }
+ }
+
+ fParagraphs.Remove(index);
+
+ // Insert TextSpans, splitting 'text' into Paragraphs at line
breaks.
+ int32 length = text.CountChars();
+ int32 chunkStart = 0;
+ while (chunkStart < length) {
+ int32 chunkEnd = text.FindFirst('\n', chunkStart);
+ bool foundLineBreak = chunkEnd >= chunkStart;
+ if (foundLineBreak)
+ chunkEnd++;
+ else
+ chunkEnd = length;
+
+ BString chunk;
+ text.CopyCharsInto(chunk, chunkStart, chunkEnd -
chunkStart);
+ TextSpan span(chunk, characterStyle);
+
+ if (foundLineBreak) {
+ if (!paragraph1.Append(span))
+ return B_NO_MEMORY;
+ if (paragraph1.Length() > 0) {
+ if (!fParagraphs.Add(paragraph1, index))
+ return B_NO_MEMORY;
+ index++;
+ }
+ paragraph1 = Paragraph(paragraphStyle);
+ } else {
+ if (!paragraph2.Prepend(span))
+ return B_NO_MEMORY;
+ }
+
+ chunkStart = chunkEnd + 1;
+ }
+
+ if (paragraph2.IsEmpty()) {
+ // Make sure Paragraph has at least one TextSpan, even
+ // if its empty.
+ const TextSpanList& spans = paragraph1.TextSpans();
+ const TextSpan& span = spans.LastItem();
+ paragraph2.Append(TextSpan("", span.Style()));
+ }
+
+ if (!fParagraphs.Add(paragraph2, index))
+ return B_NO_MEMORY;
+ paragraphCount++;
+ } else {
+ Paragraph paragraph(ParagraphAt(index));
+ paragraph.Insert(textOffset, TextSpan(text, characterStyle));
+ if (!fParagraphs.Replace(index, paragraph))
+ return B_NO_MEMORY;
+ paragraphCount++;
+ }
+
+ return B_OK;
+}
+
+
+status_t
+TextDocument::_Remove(int32 textOffset, int32 length, int32& index,
+ int32& paragraphCount)
+{
+ if (length == 0)
+ return B_OK;
+
+ int32 paragraphOffset;
+ index = ParagraphIndexFor(textOffset, paragraphOffset);
+ if (index < 0)
+ return B_BAD_VALUE;
+
+ textOffset -= paragraphOffset;
+ paragraphCount++;
+
+ // The paragraph at the text offset remains, even if the offset is at
+ // the beginning of that paragraph. The idea is that the selection start
+ // stays visually in the same place. Therefore, the paragraph at that
+ // offset has to keep the paragraph style from that paragraph.
+
+ Paragraph resultParagraph(ParagraphAt(index));
+ int32 paragraphLength = resultParagraph.Length();
+ if (textOffset == 0 && length > paragraphLength) {
+ length -= paragraphLength;
+ paragraphLength = 0;
+ resultParagraph.Clear();
+ } else {
+ int32 removeLength = std::min(length, paragraphLength -
textOffset);
+ resultParagraph.Remove(textOffset, removeLength);
+ paragraphLength -= removeLength;
+ length -= removeLength;
+ }
+
+ if (textOffset == paragraphLength && length == 0
+ && index + 1 < fParagraphs.CountItems()) {
+ // Line break between paragraphs got removed. Shift the next
+ // paragraph's text spans into the resulting one.
+
+ const TextSpanList& textSpans = ParagraphAt(index +
1).TextSpans();
+ int32 spanCount = textSpans.CountItems();
+ for (int32 i = 0; i < spanCount; i++) {
+ const TextSpan& span = textSpans.ItemAtFast(i);
+ resultParagraph.Append(span);
+ }
+ fParagraphs.Remove(index + 1);
+ paragraphCount++;
+ }
+
+ textOffset = 0;
+
+ while (length > 0 && index + 1 < fParagraphs.CountItems()) {
+ paragraphCount++;
+ const Paragraph& paragraph = ParagraphAt(index + 1);
+ paragraphLength = paragraph.Length();
+ // Remove paragraph in any case. If some of it remains, the last
+ // paragraph to remove is reached, and the remaining spans are
+ // transfered to the result parahraph.
+ if (length >= paragraphLength) {
+ length -= paragraphLength;
+ fParagraphs.Remove(index);
+ } else {
+ // Last paragraph reached
+ int32 removedLength = std::min(length, paragraphLength);
+ Paragraph newParagraph(paragraph);
+ fParagraphs.Remove(index + 1);
+
+ if (!newParagraph.Remove(0, removedLength))
+ return B_NO_MEMORY;
+
+ // Transfer remaining spans to resultParagraph
+ const TextSpanList& textSpans =
newParagraph.TextSpans();
+ int32 spanCount = textSpans.CountItems();
+ for (int32 i = 0; i < spanCount; i++) {
+ const TextSpan& span = textSpans.ItemAtFast(i);
+ resultParagraph.Append(span);
+ }
+
+ break;
+ }
+ }
+
+ fParagraphs.Replace(index, resultParagraph);
+
+ return B_OK;
+}
+
+
+// #pragma mark - notifications
+
+
void
TextDocument::_NotifyTextChanging(TextChangingEvent& event) const
{
diff --git a/src/apps/haikudepot/textview/TextDocument.h
b/src/apps/haikudepot/textview/TextDocument.h
index e86d295..6db9fb9 100644
--- a/src/apps/haikudepot/textview/TextDocument.h
+++ b/src/apps/haikudepot/textview/TextDocument.h
@@ -91,6 +91,16 @@ public:
const
UndoableEditListenerRef& listener);

private:
+ status_t _Insert(int32
textOffset, const BString& text,
+ const
CharacterStyle& characterStyle,
+ const
ParagraphStyle& paragraphStyle,
+ int32&
firstParagraph,
+ int32&
paragraphCount);
+ status_t _Remove(int32
textOffset, int32 length,
+ int32&
firstParagraph,
+ int32&
paragraphCount);
+
+private:
void _NotifyTextChanging(

TextChangingEvent& event) const;
void _NotifyTextChanged(

############################################################################

Commit: 41bd20b06b0a569dfd75b0d036ff0487b44481a7
URL: http://cgit.haiku-os.org/haiku/commit/?id=41bd20b06b0a
Author: Stephan Aßmus <superstippi@xxxxxx>
Date: Sun Sep 6 21:07:09 2015 UTC

Text framework: Add TextListener in TextDocumentLayout...

... and invalidate based on TextChangedEvents. I am not yet sure whether
TextChangeEvent needs separate counts for removed and changed paragraphs.
It is most likely not yet correct and may either update too many paragraph
layouts or miss updating some at the end.

----------------------------------------------------------------------------

diff --git a/src/apps/haikudepot/textview/TextDocumentLayout.cpp
b/src/apps/haikudepot/textview/TextDocumentLayout.cpp
index 6ed09b4..f998e36 100644
--- a/src/apps/haikudepot/textview/TextDocumentLayout.cpp
+++ b/src/apps/haikudepot/textview/TextDocumentLayout.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2013-2015, Stephan Aßmus <superstippi@xxxxxx>.
* All rights reserved. Distributed under the terms of the MIT License.
*/

@@ -11,12 +11,40 @@
#include <View.h>


+class LayoutTextListener : public TextListener {
+public:
+ LayoutTextListener(TextDocumentLayout* layout)
+ :
+ fLayout(layout)
+ {
+ }
+
+ virtual void TextChanging(TextChangingEvent& event)
+ {
+ }
+
+ virtual void TextChanged(const TextChangedEvent& event)
+ {
+ printf("TextChanged(%" B_PRIi32 ", %" B_PRIi32 ")\n",
+ event.FirstChangedParagraph(),
+ event.ChangedParagraphCount());
+ fLayout->InvalidateParagraphs(event.FirstChangedParagraph(),
+ event.ChangedParagraphCount());
+ }
+
+private:
+ TextDocumentLayout* fLayout;
+};
+
+
+
TextDocumentLayout::TextDocumentLayout()
:
fWidth(0.0f),
fLayoutValid(false),

fDocument(),
+ fTextListener(new(std::nothrow) LayoutTextListener(this), true),
fParagraphLayouts()
{
}
@@ -27,10 +55,11 @@ TextDocumentLayout::TextDocumentLayout(const
TextDocumentRef& document)
fWidth(0.0f),
fLayoutValid(false),

- fDocument(document),
+ fDocument(),
+ fTextListener(new(std::nothrow) LayoutTextListener(this), true),
fParagraphLayouts()
{
- _Init();
+ SetTextDocument(document);
}


@@ -40,24 +69,35 @@ TextDocumentLayout::TextDocumentLayout(const
TextDocumentLayout& other)
fLayoutValid(other.fLayoutValid),

fDocument(other.fDocument),
+ fTextListener(new(std::nothrow) LayoutTextListener(this), true),
fParagraphLayouts(other.fParagraphLayouts)
{
+ if (fDocument.Get() != NULL)
+ fDocument->AddListener(fTextListener);
}


TextDocumentLayout::~TextDocumentLayout()
{
+ SetTextDocument(NULL);
}


void
TextDocumentLayout::SetTextDocument(const TextDocumentRef& document)
{
- if (fDocument != document) {
- fDocument = document;
- _Init();
- fLayoutValid = false;
- }
+ if (fDocument == document)
+ return;
+
+ if (fDocument.Get() != NULL)
+ fDocument->RemoveListener(fTextListener);
+
+ fDocument = document;
+ _Init();
+ fLayoutValid = false;
+
+ if (fDocument.Get() != NULL)
+ fDocument->AddListener(fTextListener);
}


@@ -297,6 +337,9 @@ TextDocumentLayout::_Init()
{
fParagraphLayouts.Clear();

+ if (fDocument.Get() == NULL)
+ return;
+
const ParagraphList& paragraphs = fDocument->Paragraphs();

int paragraphCount = paragraphs.CountItems();
diff --git a/src/apps/haikudepot/textview/TextDocumentLayout.h
b/src/apps/haikudepot/textview/TextDocumentLayout.h
index b7bcb86..6f111e7 100644
--- a/src/apps/haikudepot/textview/TextDocumentLayout.h
+++ b/src/apps/haikudepot/textview/TextDocumentLayout.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2013-2015, Stephan Aßmus <superstippi@xxxxxx>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef TEXT_DOCUMENT_LAYOUT_H
@@ -124,6 +124,7 @@ private:
bool fLayoutValid;

TextDocumentRef fDocument;
+ TextListenerRef fTextListener;
ParagraphLayoutList fParagraphLayouts;
};


############################################################################

Revision: hrev49624
Commit: 7d8d7785c17ab7a0bc5666100f1e149362bb4dd5
URL: http://cgit.haiku-os.org/haiku/commit/?id=7d8d7785c17a
Author: Stephan Aßmus <superstippi@xxxxxx>
Date: Sun Sep 6 21:09:36 2015 UTC

Text framework: Added TextEditor::Replace()

Call Replace() on TextDocument, so that there are not two edits later
on once UndoableEdit stuff is supported.

----------------------------------------------------------------------------

diff --git a/src/apps/haikudepot/textview/TextEditor.cpp
b/src/apps/haikudepot/textview/TextEditor.cpp
index fd57c7e..bfd46ba 100644
--- a/src/apps/haikudepot/textview/TextEditor.cpp
+++ b/src/apps/haikudepot/textview/TextEditor.cpp
@@ -240,11 +240,7 @@ TextEditor::KeyDown(KeyEvent event)
// Handle null-termintating the string
BString text(event.bytes, event.length);

- // Remove selection, if any
- if (HasSelection())
- Remove(SelectionStart(),
SelectionLength());
-
- Insert(fSelection.Caret(), text);
+ Replace(SelectionStart(), SelectionLength(),
text);
}
break;
}
@@ -260,9 +256,6 @@ TextEditor::Insert(int32 offset, const BString& string)
status_t ret = fDocument->Insert(offset, string, fStyleAtCaret);

if (ret == B_OK) {
- // TODO: Via listener, and only affected paragraphs
- fLayout->Invalidate();
-
_SetCaretOffset(offset + string.CountChars(), true, false,
true);

fDocument->PrintToStream();
@@ -281,9 +274,6 @@ TextEditor::Remove(int32 offset, int32 length)
status_t ret = fDocument->Remove(offset, length);

if (ret == B_OK) {
- // TODO: Via listener, and only affected paragraphs
- fLayout->Invalidate();
-
_SetCaretOffset(offset, true, false, true);

fDocument->PrintToStream();
@@ -293,6 +283,24 @@ TextEditor::Remove(int32 offset, int32 length)
}


+status_t
+TextEditor::Replace(int32 offset, int32 length, const BString& string)
+{
+ if (!fEditingEnabled || fDocument.Get() == NULL)
+ return B_ERROR;
+
+ status_t ret = fDocument->Replace(offset, length, string);
+
+ if (ret == B_OK) {
+ _SetCaretOffset(offset + string.CountChars(), true, false,
true);
+
+ fDocument->PrintToStream();
+ }
+
+ return ret;
+}
+
+
// #pragma mark -


diff --git a/src/apps/haikudepot/textview/TextEditor.h
b/src/apps/haikudepot/textview/TextEditor.h
index 842654b..b26ac3e 100644
--- a/src/apps/haikudepot/textview/TextEditor.h
+++ b/src/apps/haikudepot/textview/TextEditor.h
@@ -61,6 +61,8 @@ public:

virtual status_t Insert(int32 offset, const
BString& string);
virtual status_t Remove(int32 offset, int32
length);
+ virtual status_t Replace(int32 offset, int32
length,
+ const
BString& string);

void LineUp(bool select);
void LineDown(bool select);


Other related posts:

  • » [haiku-commits] haiku: hrev49624 - src/apps/haikudepot/textview - superstippi