Fix left alignment of native RTL pre-edit text.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Fri, 20 May 2011 04:22:39 +0000 (14:22 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 7 Sep 2011 03:56:53 +0000 (05:56 +0200)
If there is no committed text in a TextInput or TextEdit determine
if the pre-edit text is right to left before falling back to the
global keyboard settings.

Change-Id: I7e5568e936341602b8faf7be120f9a770c115f48
Task-number: QMLNG-72
Reviewed-by: Michael Brasser
Reviewed-on: http://codereview.qt.nokia.com/4176
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
12 files changed:
src/declarative/items/qsgtextedit.cpp
src/declarative/items/qsgtextinput.cpp
src/qtquick1/graphicsitems/qdeclarativetextedit.cpp
src/qtquick1/graphicsitems/qdeclarativetextinput.cpp
tests/auto/declarative/qsgtextedit/data/horizontalAlignment_RightToLeft.qml
tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp
tests/auto/declarative/qsgtextinput/data/horizontalAlignment_RightToLeft.qml
tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
tests/auto/qtquick1/qdeclarativetextedit/data/horizontalAlignment_RightToLeft.qml
tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
tests/auto/qtquick1/qdeclarativetextinput/data/horizontalAlignment_RightToLeft.qml
tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp

index eeeaa20..4855036 100644 (file)
@@ -551,7 +551,15 @@ bool QSGTextEditPrivate::determineHorizontalAlignment()
 {
     Q_Q(QSGTextEdit);
     if (hAlignImplicit && q->isComponentComplete()) {
-        bool alignToRight = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
+        bool alignToRight;
+        if (text.isEmpty()) {
+            const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
+            alignToRight = preeditText.isEmpty()
+                    ? QApplication::keyboardInputDirection() == Qt::RightToLeft
+                    : preeditText.isRightToLeft();
+        } else {
+            alignToRight = rightToLeftText;
+        }
         return setHAlign(alignToRight ? QSGTextEdit::AlignRight : QSGTextEdit::AlignLeft);
     }
     return false;
@@ -1661,6 +1669,7 @@ void QSGTextEdit::q_textChanged()
 void QSGTextEdit::moveCursorDelegate()
 {
     Q_D(QSGTextEdit);
+    d->determineHorizontalAlignment();
     updateMicroFocus();
     emit cursorRectangleChanged();
     if(!d->cursor)
index 01e5173..951d765 100644 (file)
@@ -405,7 +405,11 @@ bool QSGTextInputPrivate::determineHorizontalAlignment()
     if (hAlignImplicit) {
         // if no explicit alignment has been set, follow the natural layout direction of the text
         QString text = control->text();
-        bool isRightToLeft = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft();
+        if (text.isEmpty())
+            text = control->preeditAreaText();
+        bool isRightToLeft = text.isEmpty()
+                ? QApplication::keyboardInputDirection() == Qt::RightToLeft
+                : text.isRightToLeft();
         return setHAlign(isRightToLeft ? QSGTextInput::AlignRight : QSGTextInput::AlignLeft);
     }
     return false;
@@ -1918,6 +1922,7 @@ void QSGTextInput::cursorPosChanged()
 void QSGTextInput::updateCursorRectangle()
 {
     Q_D(QSGTextInput);
+    d->determineHorizontalAlignment();
     d->updateHorizontalScroll();
     updateRect();//TODO: Only update rect between pos's
     updateMicroFocus();
index 3610515..d97d8d6 100644 (file)
@@ -552,7 +552,15 @@ bool QDeclarative1TextEditPrivate::determineHorizontalAlignment()
 {
     Q_Q(QDeclarative1TextEdit);
     if (hAlignImplicit && q->isComponentComplete()) {
-        bool alignToRight = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
+        bool alignToRight;
+        if (text.isEmpty()) {
+            const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
+            alignToRight = preeditText.isEmpty()
+                    ? QApplication::keyboardInputDirection() == Qt::RightToLeft
+                    : preeditText.isRightToLeft();
+        } else {
+            alignToRight = rightToLeftText;
+        }
         return setHAlign(alignToRight ? QDeclarative1TextEdit::AlignRight : QDeclarative1TextEdit::AlignLeft);
     }
     return false;
@@ -1588,6 +1596,7 @@ void QDeclarative1TextEdit::q_textChanged()
 void QDeclarative1TextEdit::moveCursorDelegate()
 {
     Q_D(QDeclarative1TextEdit);
+    d->determineHorizontalAlignment();
     updateMicroFocus();
     emit cursorRectangleChanged();
     if(!d->cursor)
index c61a3ff..85f564e 100644 (file)
@@ -413,7 +413,11 @@ bool QDeclarative1TextInputPrivate::determineHorizontalAlignment()
     if (hAlignImplicit) {
         // if no explicit alignment has been set, follow the natural layout direction of the text
         QString text = control->text();
-        bool isRightToLeft = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft();
+        if (text.isEmpty())
+            text = control->preeditAreaText();
+        bool isRightToLeft = text.isEmpty()
+                ? QApplication::keyboardInputDirection() == Qt::RightToLeft
+                : text.isRightToLeft();
         return setHAlign(isRightToLeft ? QDeclarative1TextInput::AlignRight : QDeclarative1TextInput::AlignLeft);
     }
     return false;
@@ -1918,6 +1922,7 @@ void QDeclarative1TextInput::cursorPosChanged()
 void QDeclarative1TextInput::updateCursorRectangle()
 {
     Q_D(QDeclarative1TextInput);
+    d->determineHorizontalAlignment();
     d->updateHorizontalScroll();
     updateRect();//TODO: Only update rect between pos's
     updateMicroFocus();
index 74592fe..4cd9236 100644 (file)
@@ -18,6 +18,7 @@ Rectangle {
             objectName: "text"
             anchors.fill: parent
             text: top.text
+            focus: true
         }
     }
 }
index fdbedae..a452528 100644 (file)
@@ -492,6 +492,8 @@ void tst_qsgtextedit::hAlign_RightToLeft()
     QVERIFY(textEdit != 0);
     canvas.show();
 
+    const QString rtlText = textEdit->text();
+
     // implicit alignment should follow the reading direction of text
     QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
     QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
@@ -568,6 +570,16 @@ void tst_qsgtextedit::hAlign_RightToLeft()
     QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
     QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
 
+    QApplication::setActiveWindow(&canvas);
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&canvas));
+
+    textEdit->setText(QString());
+    { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
+
 #ifndef Q_OS_MAC    // QTBUG-18040
     // empty text with implicit alignment follows the system locale-based
     // keyboard input direction from QApplication::keyboardInputDirection
index 15fbabe..5f88025 100644 (file)
@@ -18,6 +18,7 @@ Rectangle {
             objectName: "text"
             anchors.fill: parent
             text: top.text
+            focus: true
         }
     }
 }
index 1ada689..d91a0c0 100644 (file)
@@ -1088,6 +1088,8 @@ void tst_qsgtextinput::horizontalAlignment_RightToLeft()
     QVERIFY(textInput != 0);
     canvas.show();
 
+    const QString rtlText = textInput->text();
+
     QSGTextInputPrivate *textInputPrivate = QSGTextInputPrivate::get(textInput);
     QVERIFY(textInputPrivate != 0);
     QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
@@ -1152,6 +1154,17 @@ void tst_qsgtextinput::horizontalAlignment_RightToLeft()
     QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
     QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
 
+    QApplication::setActiveWindow(&canvas);
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&canvas));
+
+    // If there is no commited text, the preedit text should determine the alignment.
+    textInput->setText(QString());
+    { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
+
 #ifndef Q_OS_MAC    // QTBUG-18040
     // empty text with implicit alignment follows the system locale-based
     // keyboard input direction from QApplication::keyboardInputDirection
index 43ea8d8..6e739bf 100644 (file)
@@ -18,6 +18,7 @@ Rectangle {
             objectName: "text"
             anchors.fill: parent
             text: top.text
+            focus: true
         }
     }
 }
index e74ad44..bd8dab0 100644 (file)
@@ -454,6 +454,8 @@ void tst_qdeclarativetextedit::hAlign_RightToLeft()
     QVERIFY(textEdit != 0);
     canvas->show();
 
+    const QString rtlText = textEdit->text();
+
     // implicit alignment should follow the reading direction of text
     QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
     QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
@@ -530,6 +532,16 @@ void tst_qdeclarativetextedit::hAlign_RightToLeft()
     QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
     QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
 
+    QApplication::setActiveWindow(canvas);
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+    textEdit->setText(QString());
+    { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
+    QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
+    QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
+
 #ifndef Q_OS_MAC    // QTBUG-18040
     // empty text with implicit alignment follows the system locale-based
     // keyboard input direction from QApplication::keyboardInputDirection
index b11535e..7f27bbe 100644 (file)
@@ -18,6 +18,7 @@ Rectangle {
             objectName: "text"
             anchors.fill: parent
             text: top.text
+            focus: true
         }
     }
 }
index fe77312..eb08b2a 100644 (file)
@@ -1202,6 +1202,8 @@ void tst_qdeclarativetextinput::horizontalAlignment_RightToLeft()
     QVERIFY(textInput != 0);
     canvas->show();
 
+    const QString rtlText = textInput->text();
+
     QDeclarative1TextInputPrivate *textInputPrivate = QDeclarative1TextInputPrivate::get(textInput);
     QVERIFY(textInputPrivate != 0);
     QVERIFY(-textInputPrivate->hscroll > canvas->width()/2);
@@ -1266,6 +1268,17 @@ void tst_qdeclarativetextinput::horizontalAlignment_RightToLeft()
     QCOMPARE(textInput->hAlign(), QDeclarative1TextInput::AlignLeft);
     QVERIFY(-textInputPrivate->hscroll < canvas->width()/2);
 
+    QApplication::setActiveWindow(canvas);
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+    // If there is no commited text, the preedit text should determine the alignment.
+    textInput->setText(QString());
+    { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
+    QCOMPARE(textInput->hAlign(), QDeclarative1TextInput::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
+    QCOMPARE(textInput->hAlign(), QDeclarative1TextInput::AlignLeft);
+
 #ifndef Q_OS_MAC    // QTBUG-18040
     // empty text with implicit alignment follows the system locale-based
     // keyboard input direction from QApplication::keyboardInputDirection