From: Pekka Vuorela Date: Tue, 24 Apr 2012 13:46:27 +0000 (+0300) Subject: TextEdit to honor input direction on neutral text X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=70e17b48e751c9a9f9d456404c8df61cb5080037;p=konrad%2Fqtdeclarative.git TextEdit to honor input direction on neutral text Text with neutral direction, such as e.g. plain spaces, do not need to make text left aligned on arabic input method. Change-Id: I9aab5244ec47cf80fb2ba0f83e7087430eb2c7bb Reviewed-by: Joona Petrell --- diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index fc02815..0e5023f 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -537,20 +537,39 @@ bool QQuickTextEditPrivate::setHAlign(QQuickTextEdit::HAlignment alignment, bool return false; } + +Qt::LayoutDirection QQuickTextEditPrivate::textDirection(const QString &text) const +{ + const QChar *character = text.constData(); + while (!character->isNull()) { + switch (character->direction()) { + case QChar::DirL: + return Qt::LeftToRight; + case QChar::DirR: + case QChar::DirAL: + case QChar::DirAN: + return Qt::RightToLeft; + default: + break; + } + character++; + } + return Qt::LayoutDirectionAuto; +} + bool QQuickTextEditPrivate::determineHorizontalAlignment() { Q_Q(QQuickTextEdit); if (hAlignImplicit && q->isComponentComplete()) { - bool alignToRight; - if (document->isEmpty()) { + Qt::LayoutDirection direction = contentDirection; + if (direction == Qt::LayoutDirectionAuto) { const QString preeditText = control->textCursor().block().layout()->preeditAreaText(); - alignToRight = preeditText.isEmpty() - ? qApp->inputMethod()->inputDirection() == Qt::RightToLeft - : preeditText.isRightToLeft(); - } else { - alignToRight = rightToLeftText; + direction = textDirection(preeditText); } - return setHAlign(alignToRight ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft); + if (direction == Qt::LayoutDirectionAuto) + direction = qGuiApp->inputMethod()->inputDirection(); + + return setHAlign(direction == Qt::RightToLeft ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft); } return false; } @@ -1781,7 +1800,11 @@ void QQuickTextEdit::q_textChanged() { Q_D(QQuickTextEdit); d->textCached = false; - d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft(); + for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) { + d->contentDirection = d->textDirection(it.text()); + if (d->contentDirection != Qt::LayoutDirectionAuto) + break; + } d->determineHorizontalAlignment(); d->updateDefaultTextOption(); updateSize(); @@ -2016,24 +2039,34 @@ void QQuickTextEditPrivate::updateDefaultTextOption() Q_Q(QQuickTextEdit); QTextOption opt = document->defaultTextOption(); int oldAlignment = opt.alignment(); + Qt::LayoutDirection oldTextDirection = opt.textDirection(); QQuickTextEdit::HAlignment horizontalAlignment = q->effectiveHAlign(); - if (rightToLeftText) { + if (contentDirection == Qt::RightToLeft) { if (horizontalAlignment == QQuickTextEdit::AlignLeft) horizontalAlignment = QQuickTextEdit::AlignRight; else if (horizontalAlignment == QQuickTextEdit::AlignRight) horizontalAlignment = QQuickTextEdit::AlignLeft; } - opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign)); + if (!hAlignImplicit) + opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign)); + else + opt.setAlignment(Qt::Alignment(vAlign)); + + if (contentDirection == Qt::LayoutDirectionAuto) { + opt.setTextDirection(qGuiApp->inputMethod()->inputDirection()); + } else { + opt.setTextDirection(contentDirection); + } QTextOption::WrapMode oldWrapMode = opt.wrapMode(); opt.setWrapMode(QTextOption::WrapMode(wrapMode)); opt.setUseDesignMetrics(true); - if (oldWrapMode == opt.wrapMode() && oldAlignment == opt.alignment()) - return; - - document->setDefaultTextOption(opt); + if (oldWrapMode != opt.wrapMode() || oldAlignment != opt.alignment() + || oldTextDirection != opt.textDirection()) { + document->setDefaultTextOption(opt); + } } diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index f0a35d5..e556367 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -73,12 +73,13 @@ public: , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0) , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop) , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap) + , contentDirection(Qt::LayoutDirectionAuto) , mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone) , updateType(UpdatePaintNode) , documentDirty(true), dirty(false), richText(false), cursorVisible(false) , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false) , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true) - , rightToLeftText(false), textCached(false), inLayout(false) + , textCached(false), inLayout(false) { } @@ -93,6 +94,7 @@ public: bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign = false); void mirrorChange(); qreal getImplicitWidth() const; + Qt::LayoutDirection textDirection(const QString &text) const; QColor color; QColor selectionColor; @@ -127,6 +129,7 @@ public: QQuickTextEdit::VAlignment vAlign; QQuickTextEdit::TextFormat format; QQuickTextEdit::WrapMode wrapMode; + Qt::LayoutDirection contentDirection; QQuickTextEdit::SelectionMode mouseSelectionMode; Qt::InputMethodHints inputMethodHints; UpdateType updateType; @@ -142,7 +145,6 @@ public: bool canPaste:1; bool canPasteValid:1; bool hAlignImplicit:1; - bool rightToLeftText:1; bool textCached:1; bool inLayout:1; }; diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 0bc48c9..51b04cf 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -751,6 +751,16 @@ void tst_qquicktextedit::hAlign_RightToLeft() QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + // neutral text follows also input method direction + textEdit->resetHAlign(); + textEdit->setText(" ()((=<>"); + platformInputContext.setInputDirection(Qt::LeftToRight); + QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignLeft); + QVERIFY(textEdit->cursorRectangle().left() < canvas.width()/2); + platformInputContext.setInputDirection(Qt::RightToLeft); + QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->cursorRectangle().left() > canvas.width()/2); + // set input direction while having content platformInputContext.setInputDirection(Qt::LeftToRight); textEdit->setText("a");