diff options
author | Jarno Malmari <ext-jarno.malmari@nokia.com> | 2010-12-23 16:56:53 +0200 |
---|---|---|
committer | Pekka Vuorela <pekka.ta.vuorela@nokia.com> | 2010-12-30 12:34:44 +0200 |
commit | f0be6883dfae636784f6a3f3a995d21db2bbe89c (patch) | |
tree | 66505f32838021a72dbce0091f926dac751941e5 | |
parent | 86e4cd86f444aa75f43ea5b587546ef28047302a (diff) |
Fixes: NB#192037, Multiline MTextedit doesn't expand to next line on word wrapping
RevBy: Pekka Vuorela
Details: Document text width and widget width were mixed up when
calculating sizeHint.
-rw-r--r-- | src/views/mtexteditview.cpp | 43 | ||||
-rw-r--r-- | src/views/mtexteditview_p.h | 2 | ||||
-rw-r--r-- | tests/ut_mtexteditview/ut_mtexteditview.cpp | 53 | ||||
-rw-r--r-- | tests/ut_mtexteditview/ut_mtexteditview.h | 1 |
4 files changed, 82 insertions, 17 deletions
diff --git a/src/views/mtexteditview.cpp b/src/views/mtexteditview.cpp index 3d4d727b..c81a9cfe 100644 --- a/src/views/mtexteditview.cpp +++ b/src/views/mtexteditview.cpp @@ -32,7 +32,6 @@ #include <QAbstractTextDocumentLayout> #include <QTimer> #include <QStyleOptionGraphicsItem> -#include <QDebug> #include "mfeedback.h" #include "mtextedit.h" @@ -453,7 +452,6 @@ QTextDocument *MTextEditViewPrivate::activeDocument() const (echoMode == MTextEditModel::PasswordEchoOnEdit && editActive == true) || maskedTextDocument == 0) { return document(); - } else { return maskedTextDocument; } @@ -1010,20 +1008,7 @@ QSizeF MTextEditView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) con } else { // multi line if (hint.width() > 0) { - /* To find out the preferred height, we need to set the text document width - * to the given constraint width. But we don't want this to trigger - * a documentsSizeChanged so we disconnect that signal and reconnect afterwards - */ - qreal oldWidth = d->document()->textWidth(); - disconnect(d->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), - d, SLOT(handleDocumentSizeChange(QSizeF))); - d->document()->setTextWidth(hint.width()); - hint.setHeight(d->document()->size().height() + - style()->paddingTop() + style()->paddingBottom()); - d->document()->setTextWidth(oldWidth); - connect(d->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), - d, SLOT(handleDocumentSizeChange(QSizeF))); - + hint.setHeight(d->heightForWidth(hint.width())); } else { //Use the current document width if we are given no constraints hint.setWidth(d->document()->size().width() + @@ -1056,6 +1041,31 @@ QSizeF MTextEditView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) con return hint; } +qreal MTextEditViewPrivate::heightForWidth(qreal width) const +{ + Q_Q(const MTextEditView); + /* To find out the preferred height, we need to set the text document width + * to the given constraint width. But we don't want this to trigger + * a documentsSizeChanged so we disconnect that signal and reconnect afterwards + */ + const qreal oldDocumentWidth = document()->textWidth(); + const qreal horizontalPadding = q->style()->paddingLeft() + q->style()->paddingRight(); + const qreal verticalPadding = q->style()->paddingTop() + q->style()->paddingBottom(); + + // Disconnect size change signal + disconnect(document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), + this, SLOT(handleDocumentSizeChange(QSizeF))); + + // Set temporary width to document and read in corresponding height for widget. + document()->setTextWidth(width - horizontalPadding); + const qreal height = document()->size().height() + verticalPadding; + + // Restore + document()->setTextWidth(oldDocumentWidth); + connect(document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), + this, SLOT(handleDocumentSizeChange(QSizeF))); + return height; +} void MTextEditView::changeEvent(QEvent *event) { @@ -1088,7 +1098,6 @@ void MTextEditView::cancelEvent(MCancelEvent *event) d, SLOT(playTextFieldSelectionFeedback())); } - QVariant MTextEditView::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const MTextEditView); diff --git a/src/views/mtexteditview_p.h b/src/views/mtexteditview_p.h index e90b76ff..7ba46b21 100644 --- a/src/views/mtexteditview_p.h +++ b/src/views/mtexteditview_p.h @@ -63,6 +63,8 @@ public: QTextDocument *activeDocument() const; + qreal heightForWidth(qreal width) const; + protected slots: void scrolling(); void hideUnmaskedText(); diff --git a/tests/ut_mtexteditview/ut_mtexteditview.cpp b/tests/ut_mtexteditview/ut_mtexteditview.cpp index 58966461..c92d5d09 100644 --- a/tests/ut_mtexteditview/ut_mtexteditview.cpp +++ b/tests/ut_mtexteditview/ut_mtexteditview.cpp @@ -19,6 +19,7 @@ #include "ut_mtexteditview.h" +#include <QGraphicsLinearLayout> #include <QGraphicsSceneMouseEvent> #include <QMetaType> #include <QSignalSpy> @@ -150,6 +151,58 @@ void Ut_MTextEditView::testGrowing() QCOMPARE(newSize.height(), oldSize.height()); } +void Ut_MTextEditView::testMultilineGrowsOnWordWrap() +{ + // Initialize multiline text edit with one row and that row full of text. + // Then insert one character so that text edit wraps into two lines. + // This test verifies a fix for a bug where the text edit did not grow even though + // QTextDocument was updated correctly. + + QString fullRowContent = "full row content"; + m_controller->setText(fullRowContent); + + const qreal horizontalPadding = m_subject->style()->paddingLeft() + m_subject->style()->paddingRight(); + QFontMetrics fm(m_controller->document()->defaultFont()); + qreal totalWidth = fm.width(fullRowContent) + + horizontalPadding + + m_controller->document()->documentMargin() * 2; + + m_controller->setPreferredWidth(totalWidth); + + QSizePolicy policy(m_controller->sizePolicy()); + policy.setVerticalPolicy(QSizePolicy::Preferred); + m_controller->setSizePolicy(policy); + + // Create container widget with vertical layout. + QGraphicsWidget container; + container.resize(totalWidth, 200); // vertically: enough + + QGraphicsLinearLayout *vlayout = new QGraphicsLinearLayout(Qt::Vertical, &container); + vlayout->setContentsMargins(0,0,0,0); + vlayout->addItem(m_controller); + vlayout->addStretch(); + + // Activate layout before retrieving size. + vlayout->activate(); + const QSizeF beforeInserting = m_controller->size(); + + // This causes word wrap to take place. + m_controller->textCursor().insertText("w"); + + // Activate layout before retrieving size. + vlayout->activate(); + const QSizeF afterInserting = m_controller->size(); + + // Detach from parent + vlayout->removeItem(m_controller); + m_controller->setParentItem(0); + m_controller->setLayout(0); + + qDebug() << "Size " << beforeInserting << " after inserting one extra character: " << afterInserting; + QVERIFY(afterInserting != beforeInserting); +} + + void Ut_MTextEditView::testInputMethodQuery() { m_appWindow->scene()->addItem(m_controller); diff --git a/tests/ut_mtexteditview/ut_mtexteditview.h b/tests/ut_mtexteditview/ut_mtexteditview.h index 64f72b56..ee5c0837 100644 --- a/tests/ut_mtexteditview/ut_mtexteditview.h +++ b/tests/ut_mtexteditview/ut_mtexteditview.h @@ -47,6 +47,7 @@ private slots: void testStyleUpdated(); void testResizeEvent(); void testGrowing(); + void testMultilineGrowsOnWordWrap(); void testInputMethodQuery(); void testMaskedCharacters(); void testUpdateScrollWhenTextChanged(); |