aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-01-11 11:00:36 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-16 11:26:16 +0100
commiteca445fdf76ee59f7dae07f8833e2f00da26dd89 (patch)
tree3901db8f1b3771ead4ce590329ce4aa464e51dd2
parent5290b04325aa66f3f2934c9f143eee71d98a3249 (diff)
Avoid creating unnecessary copies of TextEdit's text data.
Delay rebuilding the text data from QTextDocument until it is actually requested rather than everytime the contents of the document change. Change-Id: Ibfdc9e9e0372010f0731fb02a223c8b59a67f2c3 Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--src/quick/items/qquicktextcontrol.cpp2
-rw-r--r--src/quick/items/qquicktextedit.cpp41
-rw-r--r--src/quick/items/qquicktextedit_p.h2
-rw-r--r--src/quick/items/qquicktextedit_p_p.h2
-rw-r--r--tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp6
5 files changed, 29 insertions, 24 deletions
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 4f9475f583..69a2a2766f 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -624,7 +624,7 @@ QQuickTextControl::QQuickTextControl(QTextDocument *doc, QObject *parent)
: QObject(*new QQuickTextControlPrivate, parent)
{
Q_D(QQuickTextControl);
- d->init(Qt::RichText, QString(), doc);
+ d->init(Qt::PlainText, QString(), doc);
}
QQuickTextControl::~QQuickTextControl()
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index e971ef7b5e..f56a21b4ad 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -127,13 +127,17 @@ QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
QString QQuickTextEdit::text() const
{
Q_D(const QQuickTextEdit);
-
+ if (!d->textCached) {
+ QQuickTextEditPrivate *d = const_cast<QQuickTextEditPrivate *>(d_func());
#ifndef QT_NO_TEXTHTMLPARSER
- if (d->richText)
- return d->control->toHtml();
- else
+ if (d->richText)
+ d->text = d->control->toHtml();
+ else
#endif
- return d->control->toPlainText();
+ d->text = d->control->toPlainText();
+ d->textCached = true;
+ }
+ return d->text;
}
/*!
@@ -320,21 +324,21 @@ void QQuickTextEdit::setTextFormat(TextFormat format)
Q_D(QQuickTextEdit);
if (format == d->format)
return;
+
bool wasRich = d->richText;
- d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
+ d->richText = format == RichText || (format == AutoText && (wasRich || Qt::mightBeRichText(text())));
+#ifndef QT_NO_TEXTHTMLPARSER
if (wasRich && !d->richText) {
- d->control->setPlainText(d->text);
+ d->control->setPlainText(!d->textCached ? d->control->toHtml() : d->text);
updateSize();
} else if (!wasRich && d->richText) {
-#ifndef QT_NO_TEXTHTMLPARSER
- d->control->setHtml(d->text);
-#else
- d->control->setPlainText(d->text);
-#endif
+ d->control->setHtml(!d->textCached ? d->control->toPlainText() : d->text);
updateSize();
d->useImageFallback = qmlEnableImageCache();
}
+#endif
+
d->format = format;
d->control->setAcceptRichText(d->format != PlainText);
emit textFormatChanged(d->format);
@@ -553,7 +557,7 @@ bool QQuickTextEditPrivate::determineHorizontalAlignment()
Q_Q(QQuickTextEdit);
if (hAlignImplicit && q->isComponentComplete()) {
bool alignToRight;
- if (text.isEmpty()) {
+ if (document->isEmpty()) {
const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
alignToRight = preeditText.isEmpty()
? qApp->inputPanel()->inputDirection() == Qt::RightToLeft
@@ -864,7 +868,7 @@ int QQuickTextEdit::cursorPosition() const
void QQuickTextEdit::setCursorPosition(int pos)
{
Q_D(QQuickTextEdit);
- if (pos < 0 || pos > d->text.length())
+ if (pos < 0 || pos >= d->document->characterCount()) // characterCount includes the terminating null.
return;
QTextCursor cursor = d->control->textCursor();
if (cursor.position() == pos && cursor.anchor() == pos)
@@ -1338,7 +1342,7 @@ void QQuickTextEdit::selectWord()
void QQuickTextEdit::select(int start, int end)
{
Q_D(QQuickTextEdit);
- if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length())
+ if (start < 0 || end < 0 || start >= d->document->characterCount() || end >= d->document->characterCount())
return;
QTextCursor cursor = d->control->textCursor();
cursor.beginEditBlock();
@@ -1359,12 +1363,11 @@ void QQuickTextEdit::select(int start, int end)
*/
bool QQuickTextEdit::isRightToLeft(int start, int end)
{
- Q_D(QQuickTextEdit);
if (start > end) {
qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
return false;
} else {
- return d->text.mid(start, end - start).isRightToLeft();
+ return getText(start, end).isRightToLeft();
}
}
@@ -1772,13 +1775,13 @@ void QQuickTextEditPrivate::init()
void QQuickTextEdit::q_textChanged()
{
Q_D(QQuickTextEdit);
- d->text = text();
+ d->textCached = false;
d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
d->determineHorizontalAlignment();
d->updateDefaultTextOption();
updateSize();
updateTotalLines();
- emit textChanged(d->text);
+ emit textChanged();
}
void QQuickTextEdit::moveCursorDelegate()
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index f37b7cd8ff..e127416535 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -227,7 +227,7 @@ public:
Q_INVOKABLE QString getFormattedText(int start, int end) const;
Q_SIGNALS:
- void textChanged(const QString &);
+ void textChanged();
void paintedSizeChanged();
void cursorPositionChanged();
void cursorRectangleChanged();
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index fe2172def6..bf7edf5f03 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -74,6 +74,7 @@ public:
documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
persistentSelection(true), requireImplicitWidth(false), selectByMouse(false), canPaste(false),
canPasteValid(false), hAlignImplicit(true), rightToLeftText(false), useImageFallback(false),
+ textCached(false),
textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0),
format(QQuickTextEdit::PlainText), document(0), wrapMode(QQuickTextEdit::NoWrap),
mouseSelectionMode(QQuickTextEdit::SelectCharacters),
@@ -114,6 +115,7 @@ public:
bool hAlignImplicit:1;
bool rightToLeftText:1;
bool useImageFallback:1;
+ bool textCached:1;
qreal textMargin;
int lastSelectionStart;
diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
index 40dc438c15..ba63e04cf3 100644
--- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
@@ -2077,7 +2077,7 @@ void tst_qquicktextedit::textInput()
QVERIFY(edit->hasActiveFocus() == true);
// test that input method event is committed and change signal is emitted
- QSignalSpy spy(edit, SIGNAL(textChanged(QString)));
+ QSignalSpy spy(edit, SIGNAL(textChanged()));
QInputMethodEvent event;
event.setCommitString( "Hello world!", 0, 0);
QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
@@ -2804,7 +2804,7 @@ void tst_qquicktextedit::insert()
QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged()));
QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
- QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString)));
+ QSignalSpy textSpy(textEdit, SIGNAL(textChanged()));
QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
textEdit->insert(insertPosition, insertText);
@@ -3049,7 +3049,7 @@ void tst_qquicktextedit::remove()
QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged()));
QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
- QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString)));
+ QSignalSpy textSpy(textEdit, SIGNAL(textChanged()));
QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
textEdit->remove(removeStart, removeEnd);