diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 6bbf1be0e3d..766d9792cdd 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -269,25 +269,7 @@ void QTextCursorPrivate::adjustCursor(QTextCursor::MoveOperation m) QTextTableCell c_position = table->cellAt(position); QTextTableCell c_anchor = table->cellAt(adjusted_anchor); if (c_position != c_anchor) { - bool before; - int col_position = c_position.column(); - int col_anchor = c_anchor.column(); - if (col_position == col_anchor) { - before = c_position.row() < c_anchor.row(); - } else { - before = col_position < col_anchor; - } - - // adjust to cell boundaries - if (m <= QTextCursor::WordLeft) { - position = c_position.firstPosition(); - if (!before) - --position; - } else { - position = c_position.lastPosition(); - if (before) - ++position; - } + position = c_position.firstPosition(); if (position < adjusted_anchor) adjusted_anchor = c_anchor.lastPosition(); else @@ -391,6 +373,17 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor int newPosition = position; + if (mode == QTextCursor::KeepAnchor && complexSelectionTable() != 0) { + if ((op >= QTextCursor::EndOfLine && op <= QTextCursor::NextWord) + || (op >= QTextCursor::Right && op <= QTextCursor::WordRight)) { + QTextTable *t = qobject_cast(priv->frameAt(position)); + Q_ASSERT(t); // as we have already made sure we have a complex selection + QTextTableCell cell_pos = t->cellAt(position); + if (cell_pos.column() + cell_pos.columnSpan() != t->columns()) + op = QTextCursor::NextCell; + } + } + if (x == -1 && !priv->isInEditBlock() && (op == QTextCursor::Up || op == QTextCursor::Down)) setX(); diff --git a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp index ca0feec2bf2..09b9a06a1d6 100644 --- a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp @@ -872,27 +872,147 @@ void tst_QTextCursor::tableMovement() void tst_QTextCursor::selectionsInTable() { - QTextTable *table = cursor.insertTable(2, 2); - table->cellAt(0, 0).firstCursorPosition().insertText("First"); - table->cellAt(0, 1).firstCursorPosition().insertText("Second"); - table->cellAt(1, 0).firstCursorPosition().insertText("Third"); - table->cellAt(1, 1).firstCursorPosition().insertText("Fourth"); + QTextTable *table = cursor.insertTable(3, 3); + table->cellAt(0, 0).firstCursorPosition().insertText("A a"); // first = 1 + table->cellAt(0, 1).firstCursorPosition().insertText("B b"); // first = 5 + table->cellAt(0, 2).firstCursorPosition().insertText("C c"); // first = 9 + table->cellAt(1, 0).firstCursorPosition().insertText("D d"); // first = 13 + table->cellAt(1, 1).firstCursorPosition().insertText("E e"); // first = 17 + table->cellAt(1, 2).firstCursorPosition().insertText("F f"); // first = 21 + table->cellAt(2, 0).firstCursorPosition().insertText("G g"); // first = 25 + table->cellAt(2, 1).firstCursorPosition().insertText("H h"); // first = 29 + table->cellAt(2, 2).firstCursorPosition().insertText("I i"); // first = 33 cursor = table->cellAt(0, 0).lastCursorPosition(); + QCOMPARE(cursor.position(), 4); + QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor) == false); + QCOMPARE(cursor.position(), 1); cursor = table->cellAt(1, 0).lastCursorPosition(); + QCOMPARE(cursor.position(), 16); + QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor) == false); + QCOMPARE(cursor.position(), 13); - cursor = table->cellAt(0, 1).firstCursorPosition(); + cursor = table->cellAt(0, 2).firstCursorPosition(); + QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor) == false); - cursor = table->cellAt(1, 1).firstCursorPosition(); + cursor = table->cellAt(1, 2).firstCursorPosition(); + QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)); QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor) == false); + + // Next let's test selecting entire cells one at a time + cursor = table->cellAt(0, 0).firstCursorPosition(); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 9); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 13); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 17); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 21); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 25); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 29); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 33); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor) == false); + + // And now lets walk all the way back + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 29); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 25); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 21); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 17); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 13); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 9); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 1); + QVERIFY(cursor.movePosition(QTextCursor::PreviousCell, QTextCursor::KeepAnchor) == false); + + QTextCursor::MoveOperation leftMovements[5] = { + QTextCursor::PreviousBlock + , QTextCursor::PreviousCharacter + , QTextCursor::PreviousWord + , QTextCursor::Left + , QTextCursor::WordLeft + }; + + QTextCursor::MoveOperation rightMovements[5] = { + QTextCursor::NextBlock + , QTextCursor::NextCharacter + , QTextCursor::NextWord + , QTextCursor::Right + , QTextCursor::WordRight + }; + + for (int i = 0; i < 5; ++i) { + QTextCursor::MoveOperation left = leftMovements[i]; + QTextCursor::MoveOperation right = rightMovements[i]; + + // Lets walk circle around anchor placed at 1,1 using up, down, left and right + cursor = table->cellAt(1, 1).firstCursorPosition(); + QCOMPARE(cursor.position(), 17); + QVERIFY(cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 18); // First right should not jump more than one char + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 21); // Lets jump to the next cell + QVERIFY(cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 33); + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 29); + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 25); + QVERIFY(cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 13); + QVERIFY(cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 1); + QVERIFY(cursor.movePosition(right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); + QVERIFY(cursor.movePosition(right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 9); + QVERIFY(cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 21); + + // Lets walk to the side 2 cells and back, first right + cursor = table->cellAt(0, 0).firstCursorPosition(); + QVERIFY(cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); // Lets jump to the next cell + QVERIFY(cursor.movePosition(right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 9); + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QVERIFY(cursor.position() < 5); + + // Then left + cursor = table->cellAt(0, 2).firstCursorPosition(); + QCOMPARE(cursor.position(), 9); + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); // A single left should do + QVERIFY(cursor.movePosition(left, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 1); + QVERIFY(cursor.movePosition(right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 5); + QVERIFY(cursor.movePosition(right, QTextCursor::KeepAnchor)); + QCOMPARE(cursor.position(), 9); + } } void tst_QTextCursor::selectedText()