summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorJiang Jiang <jiang.jiang@nokia.com>2010-12-15 15:11:45 +0100
committerJiang Jiang <jiang.jiang@nokia.com>2011-04-29 11:02:23 +0200
commit0f7cba14f612885151a95c590b23c5fe25efdd05 (patch)
tree5dd6063357b8f554cc729d4bffe9ced2c7b988f9 /tests/auto
parent028aa80d700ad8d6799202f1fa1beb919e6ee531 (diff)
Support visual cursor movement for BIDI text
Bidi input can in some contexts be more intuitive if the cursor works in visual way: pressing left arrow key always make cursor move one character to the left regardless the language of text, pressing right arrow key always make cursor move to the right. It is also the behavior of Mac OS X. Based on the above reason and requests from Symbian we implemented this support for visual movement in BIDI text. 3 public properties are added to QTextDocument, QTextLayout and QLineEdit respectively: - QTextDocument::defaultCursorMoveStyle can be used to control the cursor behavior in all widgets based on QTextDocument, like QTextEdit, QPlainTextEdit, etc. When set to QTextCursor:: Visual, it will enable visual movement for all the cursors in the corresponding text edit. Default is QTextCursor::Logical. - QTextLayout::cursorMoveStyle is used for low-level cursor manipulation. When set to Visual, it will enable visual movement behavior for all the cursor related methods, including cursorToX, xToCursor and drawCursor. Default is Logical. - QLineEdit::cursorMoveStyle is used to control cursor movement behavior in QLineEdit. Default is Logical.: Task-number: QTBUG-13859 Reviewed-by: Eskil (cherry picked from commit c480dd641f5d22d1ee72cb27bf39e24c6df65658)
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qcomplextext/tst_qcomplextext.cpp87
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp136
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp149
3 files changed, 371 insertions, 1 deletions
diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp
index 3d8e29057d..04943c5ceb 100644
--- a/tests/auto/qcomplextext/tst_qcomplextext.cpp
+++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp
@@ -71,6 +71,10 @@ private slots:
void bidiReorderString();
void bidiCursor_qtbug2795();
void bidiCursor_PDF();
+ void bidiCursorMovement_data();
+ void bidiCursorMovement();
+ void bidiCursorLogicalMovement_data();
+ void bidiCursorLogicalMovement();
};
tst_QComplexText::tst_QComplexText()
@@ -185,6 +189,89 @@ void tst_QComplexText::bidiCursor_qtbug2795()
QVERIFY(x1 == x2);
}
+void tst_QComplexText::bidiCursorMovement_data()
+{
+ QTest::addColumn<QString>("logical");
+ QTest::addColumn<int>("basicDir");
+
+ const LV *data = logical_visual;
+ while ( data->name ) {
+ //next we fill it with data
+ QTest::newRow( data->name )
+ << QString::fromUtf8( data->logical )
+ << (int) data->basicDir;
+ data++;
+ }
+}
+
+void tst_QComplexText::bidiCursorMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+
+ QTextLayout layout(logical);
+
+ QTextOption option = layout.textOption();
+ option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+ layout.setTextOption(option);
+ bool moved;
+ int oldPos, newPos = 0;
+ qreal x, newX;
+
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
+
+ newX = line.cursorToX(0);
+ do {
+ oldPos = newPos;
+ x = newX;
+ newX = line.cursorToX(oldPos);
+ if (basicDir == QChar::DirL) {
+ QVERIFY(newX >= x);
+ newPos = layout.rightCursorPosition(oldPos);
+ } else
+ {
+ QVERIFY(newX <= x);
+ newPos = layout.leftCursorPosition(oldPos);
+ }
+ moved = (oldPos != newPos);
+ } while (moved);
+}
+
+void tst_QComplexText::bidiCursorLogicalMovement_data()
+{
+ bidiCursorMovement_data();
+}
+
+void tst_QComplexText::bidiCursorLogicalMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+
+ QTextLayout layout(logical);
+
+ QTextOption option = layout.textOption();
+ option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+ layout.setTextOption(option);
+ bool moved;
+ int oldPos, newPos = 0;
+
+ do {
+ oldPos = newPos;
+ newPos = layout.nextCursorPosition(oldPos);
+ QVERIFY(newPos >= oldPos);
+ moved = (oldPos != newPos);
+ } while (moved);
+
+ do {
+ oldPos = newPos;
+ newPos = layout.previousCursorPosition(oldPos);
+ QVERIFY(newPos <= oldPos);
+ moved = (oldPos != newPos);
+ } while (moved);
+}
+
void tst_QComplexText::bidiCursor_PDF()
{
QString str = QString::fromUtf8("\342\200\252hello\342\200\254");
diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp
index 9176174cd8..f45481ca8a 100644
--- a/tests/auto/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp
@@ -282,6 +282,12 @@ private slots:
void validateAndSet();
#endif
+ void bidiVisualMovement_data();
+ void bidiVisualMovement();
+
+ void bidiLogicalMovement_data();
+ void bidiLogicalMovement();
+
protected slots:
#ifdef QT3_SUPPORT
void lostFocus();
@@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible()
}
+void tst_QLineEdit::bidiVisualMovement_data()
+{
+ QTest::addColumn<QString>("logical");
+ QTest::addColumn<int>("basicDir");
+ QTest::addColumn<IntList>("positionList");
+
+ QTest::newRow("Latin text")
+ << QString::fromUtf8("abc")
+ << (int) QChar::DirL
+ << (IntList() << 0 << 1 << 2 << 3);
+ QTest::newRow("Hebrew text, one item")
+ << QString::fromUtf8("\327\220\327\221\327\222")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 3);
+ QTest::newRow("Hebrew text after Latin text")
+ << QString::fromUtf8("abc\327\220\327\221\327\222")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+ QTest::newRow("Latin text after Hebrew text")
+ << QString::fromUtf8("\327\220\327\221\327\222abc")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+ QTest::newRow("LTR, 3 items")
+ << QString::fromUtf8("abc\327\220\327\221\327\222abc")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+ QTest::newRow("RTL, 3 items")
+ << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+ QTest::newRow("LTR, 4 items")
+ << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+ QTest::newRow("RTL, 4 items")
+ << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+}
+
+void tst_QLineEdit::bidiVisualMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+ QFETCH(IntList, positionList);
+
+ QLineEdit le;
+ le.setText(logical);
+
+ le.setCursorMoveStyle(QTextCursor::Visual);
+ le.setCursorPosition(0);
+
+ bool moved;
+ int i = 0, oldPos, newPos = 0;
+
+ do {
+ oldPos = newPos;
+ QVERIFY(oldPos == positionList[i]);
+ if (basicDir == QChar::DirL) {
+ QTest::keyClick(&le, Qt::Key_Right);
+ } else
+ QTest::keyClick(&le, Qt::Key_Left);
+ newPos = le.cursorPosition();
+ moved = (oldPos != newPos);
+ i++;
+ } while (moved);
+
+ QVERIFY(i == positionList.size());
+
+ do {
+ i--;
+ oldPos = newPos;
+ QVERIFY(oldPos == positionList[i]);
+ if (basicDir == QChar::DirL) {
+ QTest::keyClick(&le, Qt::Key_Left);
+ } else
+ {
+ QTest::keyClick(&le, Qt::Key_Right);
+ }
+ newPos = le.cursorPosition();
+ moved = (oldPos != newPos);
+ } while (moved && i >= 0);
+}
+
+void tst_QLineEdit::bidiLogicalMovement_data()
+{
+ bidiVisualMovement_data();
+}
+
+void tst_QLineEdit::bidiLogicalMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+
+ QLineEdit le;
+ le.setText(logical);
+
+ le.setCursorMoveStyle(QTextCursor::Logical);
+ le.setCursorPosition(0);
+
+ bool moved;
+ int i = 0, oldPos, newPos = 0;
+
+ do {
+ oldPos = newPos;
+ QVERIFY(oldPos == i);
+ if (basicDir == QChar::DirL) {
+ QTest::keyClick(&le, Qt::Key_Right);
+ } else
+ QTest::keyClick(&le, Qt::Key_Left);
+ newPos = le.cursorPosition();
+ moved = (oldPos != newPos);
+ i++;
+ } while (moved);
+
+ do {
+ i--;
+ oldPos = newPos;
+ QVERIFY(oldPos == i);
+ if (basicDir == QChar::DirL) {
+ QTest::keyClick(&le, Qt::Key_Left);
+ } else
+ {
+ QTest::keyClick(&le, Qt::Key_Right);
+ }
+ newPos = le.cursorPosition();
+ moved = (oldPos != newPos);
+ } while (moved && i >= 0);
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index 9ca17b9f5f..5a645937d7 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -42,7 +42,6 @@
#include <QtTest/QtTest>
-
#include <qtextedit.h>
#include <qtextcursor.h>
#include <qtextlist.h>
@@ -69,6 +68,7 @@ typedef QList<keyPairType> pairListType;
Q_DECLARE_METATYPE(pairListType);
Q_DECLARE_METATYPE(keyPairType);
Q_DECLARE_METATYPE(QList<bool>);
+Q_DECLARE_METATYPE(QList<int>);
#ifdef Q_WS_MAC
#include <Carbon/Carbon.h>
@@ -205,6 +205,11 @@ private slots:
#ifndef QT_NO_CONTEXTMENU
void taskQTBUG_7902_contextMenuCrash();
#endif
+ void bidiVisualMovement_data();
+ void bidiVisualMovement();
+
+ void bidiLogicalMovement_data();
+ void bidiLogicalMovement();
private:
void createSelection();
@@ -2235,5 +2240,147 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash()
}
#endif
+void tst_QTextEdit::bidiVisualMovement_data()
+{
+ QTest::addColumn<QString>("logical");
+ QTest::addColumn<int>("basicDir");
+ QTest::addColumn<QList<int> >("positionList");
+
+ QTest::newRow("Latin text")
+ << QString::fromUtf8("abc")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 3);
+ QTest::newRow("Hebrew text, one item")
+ << QString::fromUtf8("\327\220\327\221\327\222")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 3);
+ QTest::newRow("Hebrew text after Latin text")
+ << QString::fromUtf8("abc\327\220\327\221\327\222")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+ QTest::newRow("Latin text after Hebrew text")
+ << QString::fromUtf8("\327\220\327\221\327\222abc")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+ QTest::newRow("LTR, 3 items")
+ << QString::fromUtf8("abc\327\220\327\221\327\222abc")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+ QTest::newRow("RTL, 3 items")
+ << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+ QTest::newRow("LTR, 4 items")
+ << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
+ << (int) QChar::DirL
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+ QTest::newRow("RTL, 4 items")
+ << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
+ << (int) QChar::DirR
+ << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+}
+
+void tst_QTextEdit::bidiVisualMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+ QFETCH(QList<int>, positionList);
+
+ ed->setText(logical);
+
+ QTextOption option = ed->document()->defaultTextOption();
+ option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+ ed->document()->setDefaultTextOption(option);
+
+ ed->document()->setDefaultCursorMoveStyle(QTextCursor::Visual);
+ ed->moveCursor(QTextCursor::Start);
+ ed->show();
+
+ bool moved;
+ int i = 0, oldPos, newPos = 0;
+
+ do {
+ oldPos = newPos;
+ QVERIFY(oldPos == positionList[i]);
+ if (basicDir == QChar::DirL) {
+ ed->moveCursor(QTextCursor::Right);
+ } else
+ {
+ ed->moveCursor(QTextCursor::Left);
+ }
+ newPos = ed->textCursor().position();
+ moved = (oldPos != newPos);
+ i++;
+ } while (moved);
+
+ QVERIFY(i == positionList.size());
+
+ do {
+ i--;
+ oldPos = newPos;
+ QVERIFY(oldPos == positionList[i]);
+ if (basicDir == QChar::DirL) {
+ ed->moveCursor(QTextCursor::Left);
+ } else
+ {
+ ed->moveCursor(QTextCursor::Right);
+ }
+ newPos = ed->textCursor().position();
+ moved = (oldPos != newPos);
+ } while (moved && i >= 0);
+}
+
+void tst_QTextEdit::bidiLogicalMovement_data()
+{
+ bidiVisualMovement_data();
+}
+
+void tst_QTextEdit::bidiLogicalMovement()
+{
+ QFETCH(QString, logical);
+ QFETCH(int, basicDir);
+
+ ed->setText(logical);
+
+ QTextOption option = ed->document()->defaultTextOption();
+ option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+ ed->document()->setDefaultTextOption(option);
+
+ ed->document()->setDefaultCursorMoveStyle(QTextCursor::Logical);
+ ed->moveCursor(QTextCursor::Start);
+ ed->show();
+
+ bool moved;
+ int i = 0, oldPos, newPos = 0;
+
+ do {
+ oldPos = newPos;
+ QVERIFY(oldPos == i);
+ if (basicDir == QChar::DirL) {
+ ed->moveCursor(QTextCursor::Right);
+ } else
+ {
+ ed->moveCursor(QTextCursor::Left);
+ }
+ newPos = ed->textCursor().position();
+ moved = (oldPos != newPos);
+ i++;
+ } while (moved);
+
+ do {
+ i--;
+ oldPos = newPos;
+ QVERIFY(oldPos == i);
+ if (basicDir == QChar::DirL) {
+ ed->moveCursor(QTextCursor::Left);
+ } else
+ {
+ ed->moveCursor(QTextCursor::Right);
+ }
+ newPos = ed->textCursor().position();
+ moved = (oldPos != newPos);
+ } while (moved && i >= 0);
+}
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"