Make sure cursor navigation in qtexttable works like user expects

Before the selection of cells NW of anchor showed some defects where
cells would not be selected as the user expects

Change-Id: Ia2b63f11b8d534e918ffb97b76339d60f1ca0389
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
This commit is contained in:
C. Boemann 2011-12-10 05:15:38 +01:00 committed by Qt by Nokia
parent 1ee9c0925b
commit 1222da803a
2 changed files with 139 additions and 26 deletions

View File

@ -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<QTextTable *>(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();

View File

@ -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()