From ba63becc13221ca6538fb40c790275465dd47703 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Fri, 28 Jan 2011 15:58:37 +1000 Subject: Add a mouseSelectionMode property to TextEdit and TextInput. Adds an option to do per word selection when selectByMouse is true. Also changes the selection behavior so that the first word selected remains selected when the direction of the selection changes which is more consistent with other implementations including the existing per word selection in QTextEdit. Task-number: QTBUG-16283 Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativetextedit.cpp | 84 +++-- .../graphicsitems/qdeclarativetextedit_p.h | 5 + .../graphicsitems/qdeclarativetextedit_p_p.h | 3 +- .../graphicsitems/qdeclarativetextinput.cpp | 90 +++--- .../graphicsitems/qdeclarativetextinput_p.h | 5 + .../graphicsitems/qdeclarativetextinput_p_p.h | 2 + src/gui/text/qtextcontrol.cpp | 27 +- src/gui/text/qtextcontrol_p.h | 5 +- src/gui/text/qtextcontrol_p_p.h | 2 + .../data/mouseselectionmode_characters.qml | 8 + .../data/mouseselectionmode_default.qml | 7 + .../data/mouseselectionmode_words.qml | 8 + .../tst_qdeclarativetextedit.cpp | 349 ++++++++++++++++---- .../data/mouseselectionmode_characters.qml | 8 + .../data/mouseselectionmode_default.qml | 7 + .../data/mouseselectionmode_words.qml | 8 + .../tst_qdeclarativetextinput.cpp | 352 +++++++++++++++++---- 17 files changed, 778 insertions(+), 192 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml create mode 100644 tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml create mode 100644 tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml create mode 100644 tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 959d655..f63e4cb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -653,9 +653,7 @@ void QDeclarativeTextEdit::moveCursorSelection(int pos) selected (the 6th and 7th characters). The same sequence with TextEdit.SelectWords will extend the selection start to a word boundary - before or on position 5 and extend the selection end to a word boundary past position 9, and - then if there is a word boundary between position 7 and 8 retract the selection end to that - boundary. If there is whitespace at position 7 the selection will be retracted further. + before or on position 5 and extend the selection end to a word boundary on or past position 9. */ void QDeclarativeTextEdit::moveCursorSelection(int pos, SelectionMode mode) { @@ -665,48 +663,43 @@ void QDeclarativeTextEdit::moveCursorSelection(int pos, SelectionMode mode) return; if (mode == SelectCharacters) { cursor.setPosition(pos, QTextCursor::KeepAnchor); - } else if (cursor.anchor() < pos) { - cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); - if (cursor.position() == cursor.anchor()) { - cursor.movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor); + } else if (cursor.anchor() < pos || (cursor.anchor() == pos && cursor.position() < pos)) { + if (cursor.anchor() > cursor.position()) { + cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); + if (cursor.position() == cursor.anchor()) + cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); + else + cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor); } else { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor); + cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor); } + cursor.setPosition(pos, QTextCursor::KeepAnchor); cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); - if (cursor.position() == pos) { - cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + if (cursor.position() != pos) cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); - - if (cursor.anchor() > cursor.position()) - cursor.setPosition(pos, QTextCursor::MoveAnchor); - } else { - cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); - } - } else if (cursor.anchor() > pos) { - cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); - if (cursor.position() == cursor.anchor()) { - cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); + } else if (cursor.anchor() > pos || (cursor.anchor() == pos && cursor.position() > pos)) { + if (cursor.anchor() < cursor.position()) { + cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor); } else { - cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor); + cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); + if (cursor.position() != cursor.anchor()) { + cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor); + } } + cursor.setPosition(pos, QTextCursor::KeepAnchor); cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); - if (cursor.position() == pos) { - cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); - - if (cursor.anchor() < cursor.position()) - cursor.setPosition(pos, QTextCursor::MoveAnchor); - } else { + if (cursor.position() != pos) { cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); } - } else { - cursor.setPosition(pos, QTextCursor::MoveAnchor); } d->control->setTextCursor(cursor); } @@ -986,6 +979,35 @@ void QDeclarativeTextEdit::setSelectByMouse(bool on) } +/*! + \qmlproperty enum TextEdit::mouseSelectionMode + \since Quick 1.1 + + Specifies how text should be selected using a mouse. + + \list + \o TextEdit.SelectCharacters - The selection is updated with individual characters. (Default) + \o TextEdit.SelectWords - The selection is updated with whole words. + \endlist + + This property only applies when \l selectByMouse is true. +*/ + +QDeclarativeTextEdit::SelectionMode QDeclarativeTextEdit::mouseSelectionMode() const +{ + Q_D(const QDeclarativeTextEdit); + return d->mouseSelectionMode; +} + +void QDeclarativeTextEdit::setMouseSelectionMode(SelectionMode mode) +{ + Q_D(QDeclarativeTextEdit); + if (d->mouseSelectionMode != mode) { + d->mouseSelectionMode = mode; + d->control->setWordSelectionEnabled(mode == SelectWords); + emit mouseSelectionModeChanged(mode); + } +} /*! \qmlproperty bool TextEdit::readOnly diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index db3cb2d..7785a7a 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -92,6 +92,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextEdit : public QDeclarativeImplicitSizePa Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged) Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged) + Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1) Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1) public: @@ -186,6 +187,9 @@ public: bool selectByMouse() const; void setSelectByMouse(bool); + SelectionMode mouseSelectionMode() const; + void setMouseSelectionMode(SelectionMode mode); + bool canPaste() const; virtual void componentComplete(); @@ -235,6 +239,7 @@ Q_SIGNALS: void persistentSelectionChanged(bool isPersistentSelection); void textMarginChanged(qreal textMargin); void selectByMouseChanged(bool selectByMouse); + Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode); Q_REVISION(1) void linkActivated(const QString &link); Q_REVISION(1) void canPasteChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h index 98b3c6d..111cc02 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h @@ -73,7 +73,7 @@ public: showInputPanelOnFocus(true), clickCausedFocus(false), persistentSelection(true), requireImplicitWidth(false), textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0), format(QDeclarativeTextEdit::AutoText), document(0), wrapMode(QDeclarativeTextEdit::NoWrap), - selectByMouse(false), canPaste(false), + mouseSelectionMode(QDeclarativeTextEdit::SelectCharacters), selectByMouse(false), canPaste(false), yoff(0) { #ifdef Q_OS_SYMBIAN @@ -121,6 +121,7 @@ public: QTextDocument *document; QTextControl *control; QDeclarativeTextEdit::WrapMode wrapMode; + QDeclarativeTextEdit::SelectionMode mouseSelectionMode; int lineCount; bool selectByMouse; bool canPaste; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 3d2466d..9e62291 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1022,7 +1022,7 @@ void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); if (d->selectByMouse) { - d->control->moveCursor(d->xToPos(event->pos().x()), true); + moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode); event->setAccepted(true); } else { QDeclarativePaintedItem::mouseMoveEvent(event); @@ -1348,6 +1348,35 @@ void QDeclarativeTextInput::setSelectByMouse(bool on) } } +/*! + \qmlproperty enum TextInput::mouseSelectionMode + \since Quick 1.1 + + Specifies how text should be selected using a mouse. + + \list + \o TextInput.SelectCharacters - The selection is updated with individual characters. (Default) + \o TextInput.SelectWords - The selection is updated with whole words. + \endlist + + This property only applies when \l selectByMouse is true. +*/ + +QDeclarativeTextInput::SelectionMode QDeclarativeTextInput::mouseSelectionMode() const +{ + Q_D(const QDeclarativeTextInput); + return d->mouseSelectionMode; +} + +void QDeclarativeTextInput::setMouseSelectionMode(SelectionMode mode) +{ + Q_D(QDeclarativeTextInput); + if (d->mouseSelectionMode != mode) { + d->mouseSelectionMode = mode; + emit mouseSelectionModeChanged(mode); + } +} + bool QDeclarativeTextInput::canPaste() const { Q_D(const QDeclarativeTextInput); @@ -1397,9 +1426,7 @@ void QDeclarativeTextInput::moveCursorSelection(int position) selected (the 6th and 7th characters). The same sequence with TextInput.SelectWords will extend the selection start to a word boundary - before or on position 5 and extend the selection end to a word boundary past position 9, and - then if there is a word boundary between position 7 and 8 retract the selection end to that - boundary. If there is whitespace at position 7 the selection will be retracted further. + before or on position 5 and extend the selection end to a word boundary on or past position 9. */ void QDeclarativeTextInput::moveCursorSelection(int pos, SelectionMode mode) { @@ -1408,6 +1435,7 @@ void QDeclarativeTextInput::moveCursorSelection(int pos, SelectionMode mode) if (mode == SelectCharacters) { d->control->moveCursor(pos, true); } else if (pos != d->control->cursor()){ + const int cursor = d->control->cursor(); int anchor; if (!d->control->hasSelectedText()) anchor = d->control->cursor(); @@ -1416,55 +1444,39 @@ void QDeclarativeTextInput::moveCursorSelection(int pos, SelectionMode mode) else anchor = d->control->selectionStart(); - if (anchor < pos) { + if (anchor < pos || (anchor == pos && cursor < pos)) { QTextBoundaryFinder finder(QTextBoundaryFinder::Word, d->control->text()); finder.setPosition(anchor); - if (!(finder.boundaryReasons() & QTextBoundaryFinder::StartWord)) { - finder.toNextBoundary(); - if (finder.boundaryReasons() != QTextBoundaryFinder::StartWord) - finder.toPreviousBoundary(); + const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons(); + if (!(reasons & QTextBoundaryFinder::StartWord) + || ((reasons & QTextBoundaryFinder::EndWord) && anchor > cursor)) { + finder.toPreviousBoundary(); } anchor = finder.position(); finder.setPosition(pos); - if (!(finder.boundaryReasons() & QTextBoundaryFinder::EndWord)) { - finder.toPreviousBoundary(); - if (finder.boundaryReasons() != QTextBoundaryFinder::EndWord) - finder.toNextBoundary(); - } - int cursor = finder.position(); + if (!finder.isAtBoundary()) + finder.toNextBoundary(); - if (anchor < cursor) - d->control->setSelection(anchor, cursor - anchor); - else - d->control->moveCursor(pos, false); - - } else if (anchor > pos) { + d->control->setSelection(anchor, finder.position() - anchor); + } else if (anchor > pos || (anchor == pos && cursor > pos)) { QTextBoundaryFinder finder(QTextBoundaryFinder::Word, d->control->text()); - finder.setPosition(anchor); - if (!(finder.boundaryReasons() & QTextBoundaryFinder::EndWord)) { - finder.toPreviousBoundary(); - if (finder.boundaryReasons() != QTextBoundaryFinder::EndWord) - finder.toNextBoundary(); + + const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons(); + if (!(reasons & QTextBoundaryFinder::EndWord) + || ((reasons & QTextBoundaryFinder::StartWord) && anchor < cursor)) { + finder.toNextBoundary(); } + anchor = finder.position(); finder.setPosition(pos); - if (!(finder.boundaryReasons() & QTextBoundaryFinder::StartWord)) { - finder.toNextBoundary(); - if (finder.boundaryReasons() != QTextBoundaryFinder::StartWord) - finder.toPreviousBoundary(); - } - int cursor = finder.position(); - - if (anchor > cursor) - d->control->setSelection(anchor, cursor - anchor); - else - d->control->moveCursor(pos, false); - } else { - d->control->moveCursor(pos, false); + if (!finder.isAtBoundary()) + finder.toPreviousBoundary(); + + d->control->setSelection(anchor, finder.position() - anchor); } } } diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index 543f7a8..63d0e53 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -95,6 +95,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativeImplicitSizeP Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged) Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged) Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged) + Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1) Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1) public: @@ -192,6 +193,9 @@ public: bool selectByMouse() const; void setSelectByMouse(bool); + SelectionMode mouseSelectionMode() const; + void setMouseSelectionMode(SelectionMode mode); + bool hasAcceptableInput() const; void drawContents(QPainter *p,const QRect &r); @@ -225,6 +229,7 @@ Q_SIGNALS: void activeFocusOnPressChanged(bool activeFocusOnPress); void autoScrollChanged(bool autoScroll); void selectByMouseChanged(bool selectByMouse); + Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode); Q_REVISION(1) void canPasteChanged(); protected: diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index 1f45c11..7a0086e 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -73,6 +73,7 @@ public: QDeclarativeTextInputPrivate() : control(new QLineControl(QString())), color((QRgb)0), style(QDeclarativeText::Normal), styleColor((QRgb)0), hAlign(QDeclarativeTextInput::AlignLeft), + mouseSelectionMode(QDeclarativeTextInput::SelectCharacters), hscroll(0), oldScroll(0), focused(false), focusOnPress(true), showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false), autoScroll(true), selectByMouse(false), canPaste(false) @@ -114,6 +115,7 @@ public: QDeclarativeText::TextStyle style; QColor styleColor; QDeclarativeTextInput::HAlignment hAlign; + QDeclarativeTextInput::SelectionMode mouseSelectionMode; QPointer cursorComponent; QPointer cursorItem; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 030e196..e380b37 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -129,7 +129,8 @@ QTextControlPrivate::QTextControlPrivate() isEnabled(true), hadSelectionOnMousePress(false), ignoreUnusedNavigationEvents(false), - openExternalLinks(false) + openExternalLinks(false), + wordSelectionEnabled(false) {} bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e) @@ -1544,11 +1545,16 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con } #endif if (modifiers == Qt::ShiftModifier) { + if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { + selectedWordOnDoubleClick = cursor; + selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); + } + if (selectedBlockOnTrippleClick.hasSelection()) extendBlockwiseSelection(cursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(cursorPos, pos.x()); - else + else if (wordSelectionEnabled) setCursorPosition(cursorPos, QTextCursor::KeepAnchor); } else { @@ -1626,6 +1632,11 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF if (newCursorPos == -1) return; + if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { + selectedWordOnDoubleClick = cursor; + selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); + } + if (selectedBlockOnTrippleClick.hasSelection()) extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) @@ -2343,6 +2354,18 @@ bool QTextControl::isDragEnabled() const return d->dragEnabled; } +void QTextControl::setWordSelectionEnabled(bool enabled) +{ + Q_D(QTextControl); + d->wordSelectionEnabled = enabled; +} + +bool QTextControl::isWordSelectionEnabled() const +{ + Q_D(const QTextControl); + return d->wordSelectionEnabled; +} + #ifndef QT_NO_PRINTER void QTextControl::print(QPrinter *printer) const { diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h index 9277b68..31fa843 100644 --- a/src/gui/text/qtextcontrol_p.h +++ b/src/gui/text/qtextcontrol_p.h @@ -178,6 +178,9 @@ public: void setDragEnabled(bool enabled); bool isDragEnabled() const; + bool isWordSelectionEnabled() const; + void setWordSelectionEnabled(bool enabled); + #ifndef QT_NO_PRINTER void print(QPrinter *printer) const; #endif @@ -186,8 +189,6 @@ public: virtual QRectF blockBoundingRect(const QTextBlock &block) const; QAbstractTextDocumentLayout::PaintContext getPaintContext(QWidget *widget) const; - - public Q_SLOTS: void setPlainText(const QString &text); void setHtml(const QString &text); diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h index d7463ca..ecd13ea 100644 --- a/src/gui/text/qtextcontrol_p_p.h +++ b/src/gui/text/qtextcontrol_p_p.h @@ -211,6 +211,8 @@ public: bool ignoreUnusedNavigationEvents; bool openExternalLinks; + bool wordSelectionEnabled; + QString linkToCopy; void _q_copyLink(); void _q_updateBlock(const QTextBlock &); diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000..5784e19 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectCharacters +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml new file mode 100644 index 0000000..1e5f4aa --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml new file mode 100644 index 0000000..4b25f2f --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 1364337..b82aca8 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -112,8 +112,12 @@ private slots: void selection(); void moveCursorSelection_data(); void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); void dragMouseSelection(); void inputMethodHints(); @@ -786,91 +790,113 @@ void tst_qdeclarativetextedit::moveCursorSelection_data() QTest::newRow("jum()ped|characters") << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectCharacters << 23 << 23 << true; - QTest::newRow("(t)he|words") + QTest::newRow("<(t)he>|words") << standard[0] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 3 << true; - QTest::newRow("do(g)|words") + QTest::newRow("|words") << standard[0] << 43 << 44 << QDeclarativeTextEdit::SelectWords << 41 << 44 << true; - QTest::newRow("jum(p)ed|words") + QTest::newRow("|words") << standard[0] << 23 << 24 << QDeclarativeTextEdit::SelectWords << 20 << 26 << true; - QTest::newRow("jumped( )over|words") - << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectWords << 27 << 27 << false; - QTest::newRow("jumped( )over|words,reversed") - << standard[0] << 27 << 26 << QDeclarativeTextEdit::SelectWords << 26 << 26 << false; - QTest::newRow("(the )|words") - << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectWords << 0 << 3 << true; - QTest::newRow("( dog)|words") - << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectWords << 41 << 44 << true; - QTest::newRow("( jumped )|words") - << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectWords << 20 << 26 << true; - QTest::newRow("th(e qu)ick|words") + QTest::newRow("over|words") + << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,reversed") + << standard[0] << 27 << 26 << QDeclarativeTextEdit::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words") + << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,reversed") + << standard[0] << 4 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 9 << false; + QTest::newRow("|words") + << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,reversed") + << standard[0] << 44 << 40 << QDeclarativeTextEdit::SelectWords << 40 << 44 << false; + QTest::newRow("over|words") + << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,reversed") + << standard[0] << 27 << 19 << QDeclarativeTextEdit::SelectWords << 19 << 31 << false; + QTest::newRow("|words") << standard[0] << 2 << 6 << QDeclarativeTextEdit::SelectWords << 0 << 9 << true; - QTest::newRow("la(zy d)og|words") + QTest::newRow("") << standard[0] << 38 << 42 << QDeclarativeTextEdit::SelectWords << 36 << 44 << true; - QTest::newRow("jum(ped ov)er|words") + QTest::newRow("|words") << standard[0] << 23 << 29 << QDeclarativeTextEdit::SelectWords << 20 << 31 << true; - QTest::newRow("()the|words") + QTest::newRow("<()>the|words") << standard[0] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; - QTest::newRow("dog()|words") + QTest::newRow("dog<()>|words") << standard[0] << 44 << 44 << QDeclarativeTextEdit::SelectWords << 44 << 44 << true; - QTest::newRow("jum()ped|words") + QTest::newRow("jum<()>ped|words") << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectWords << 23 << 23 << true; - QTest::newRow("Hello(,) |words") + QTest::newRow("Hello<(,)> |words") << standard[2] << 5 << 6 << QDeclarativeTextEdit::SelectWords << 5 << 6 << true; - QTest::newRow("Hello(, )|words") - << standard[2] << 5 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 6 << true; - QTest::newRow("Hel(lo, )|words") - << standard[2] << 3 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 6 << true; - QTest::newRow("Hel(lo),|words") + QTest::newRow("Hello<(, )>world|words") + << standard[2] << 5 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,reversed") + << standard[2] << 7 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("world|words") + << standard[2] << 3 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("|words,reversed") + << standard[2] << 7 << 3 << QDeclarativeTextEdit::SelectWords << 0 << 12 << false; + QTest::newRow(",|words") << standard[2] << 3 << 5 << QDeclarativeTextEdit::SelectWords << 0 << 5 << true; - QTest::newRow("Hello(),|words") + QTest::newRow("Hello<()>,|words") << standard[2] << 5 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 5 << true; - QTest::newRow("Hello,()|words") + QTest::newRow("Hello,<()>|words") << standard[2] << 6 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 6 << true; - QTest::newRow("Hello,( )|words") - << standard[2] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 7 << 7 << false; - QTest::newRow("Hello,( )|words") - << standard[2] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 6 << false; - QTest::newRow("Hello,( world)|words") - << standard[2] << 6 << 12 << QDeclarativeTextEdit::SelectWords << 7 << 12 << true; - QTest::newRow("Hello,( world!)|words") - << standard[2] << 6 << 13 << QDeclarativeTextEdit::SelectWords << 7 << 13 << true; - QTest::newRow("Hello(, world!)|words") + QTest::newRow("Hello<,( )>world|words") + << standard[2] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,reversed") + << standard[2] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words") + << standard[2] << 6 << 12 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,reversed") + << standard[2] << 12 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words") + << standard[2] << 6 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,reversed") + << standard[2] << 13 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") << standard[2] << 5 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << true; - QTest::newRow("world(!)|words") + QTest::newRow("world<(!)>|words") << standard[2] << 12 << 13 << QDeclarativeTextEdit::SelectWords << 12 << 13 << true; - QTest::newRow("world!())|words") + QTest::newRow("world!<()>)|words") << standard[2] << 13 << 13 << QDeclarativeTextEdit::SelectWords << 13 << 13 << true; - QTest::newRow("world()!)|words") + QTest::newRow("world<()>!)|words") << standard[2] << 12 << 12 << QDeclarativeTextEdit::SelectWords << 12 << 12 << true; - QTest::newRow("(,)olleH |words") + QTest::newRow("<(,)>olleH |words") << standard[3] << 7 << 8 << QDeclarativeTextEdit::SelectWords << 7 << 8 << true; - QTest::newRow("( ,)olleH|words") - << standard[3] << 6 << 8 << QDeclarativeTextEdit::SelectWords << 7 << 8 << true; - QTest::newRow("( ,ol)leH|words") - << standard[3] << 6 << 10 << QDeclarativeTextEdit::SelectWords << 7 << 13 << true; - QTest::newRow(",(ol)leH,|words") + QTest::newRow("olleH|words") + << standard[3] << 6 << 8 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,reversed") + << standard[3] << 8 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("|words") + << standard[3] << 6 << 10 << QDeclarativeTextEdit::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,reversed") + << standard[3] << 10 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") << standard[3] << 8 << 10 << QDeclarativeTextEdit::SelectWords << 8 << 13 << true; - QTest::newRow(",()olleH|words") + QTest::newRow(",<()>olleH|words") << standard[3] << 8 << 8 << QDeclarativeTextEdit::SelectWords << 8 << 8 << true; - QTest::newRow("(),olleH|words") + QTest::newRow("<()>,olleH|words") << standard[3] << 7 << 7 << QDeclarativeTextEdit::SelectWords << 7 << 7 << true; - QTest::newRow("( ),olleH|words") - << standard[3] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 7 << 7 << false; - QTest::newRow("( ),olleH|words,reversed") - << standard[3] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 6 << false; - QTest::newRow("(dlrow ),olleH|words") - << standard[3] << 1 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 6 << true; - QTest::newRow("(!dlrow ),olleH|words") - << standard[3] << 0 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 6 << true; + QTest::newRow(",olleH|words") + << standard[3] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,reversed") + << standard[3] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words") + << standard[3] << 1 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words") + << standard[3] << 0 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 8 << false; QTest::newRow("(!dlrow ,)olleH|words") << standard[3] << 0 << 8 << QDeclarativeTextEdit::SelectWords << 0 << 8 << true; - QTest::newRow("(!)dlrow|words") + QTest::newRow("<(!)>dlrow|words") << standard[3] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 1 << true; - QTest::newRow("()!dlrow|words") + QTest::newRow("<()>!dlrow|words") << standard[3] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; - QTest::newRow("!()dlrow|words") + QTest::newRow("!<()>dlrow|words") << standard[3] << 1 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 1 << true; } @@ -893,6 +919,7 @@ void tst_qdeclarativetextedit::moveCursorSelection() texteditObject->setCursorPosition(cursorPosition); texteditObject->moveCursorSelection(movePosition, mode); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); QCOMPARE(texteditObject->selectionStart(), selectionStart); QCOMPARE(texteditObject->selectionEnd(), selectionEnd); @@ -900,11 +927,168 @@ void tst_qdeclarativetextedit::moveCursorSelection() texteditObject->setCursorPosition(movePosition); texteditObject->moveCursorSelection(cursorPosition, mode); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); QCOMPARE(texteditObject->selectionStart(), selectionStart); QCOMPARE(texteditObject->selectionEnd(), selectionEnd); } } +void tst_qdeclarativetextedit::moveCursorSelectionSequence_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition1"); + QTest::addColumn("movePosition2"); + QTest::addColumn("selection1Start"); + QTest::addColumn("selection1End"); + QTest::addColumn("selection2Start"); + QTest::addColumn("selection2End"); + + QTest::newRow("the { f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the { ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the { fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; +} + +void tst_qdeclarativetextedit::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextEdit *texteditObject = qobject_cast(texteditComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + + texteditObject->moveCursorSelection(movePosition1, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(texteditObject->selectionStart(), selection1Start); + QCOMPARE(texteditObject->selectionEnd(), selection1End); + + texteditObject->moveCursorSelection(movePosition2, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(texteditObject->selectionStart(), selection2Start); + QCOMPARE(texteditObject->selectionEnd(), selection2End); +} + + void tst_qdeclarativetextedit::mouseSelection_data() { QTest::addColumn("qmlfile"); @@ -995,6 +1179,55 @@ void tst_qdeclarativetextedit::dragMouseSelection() QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved. } +void tst_qdeclarativetextedit::mouseSelectionMode_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("selectWords"); + + // import installed + QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true; + QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false; +} + +void tst_qdeclarativetextedit::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textEditObject->selectedText(); + if (selectWords) { + QCOMPARE(str, text); + } else { + QVERIFY(str.length() > 3); + QVERIFY(str != text); + } + + delete canvas; +} + void tst_qdeclarativetextedit::inputMethodHints() { QDeclarativeView *canvas = createView(SRCDIR "/data/inputmethodhints.qml"); diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000..0ffc6ff --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectCharacters +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml new file mode 100644 index 0000000..87c174b --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml new file mode 100644 index 0000000..df69a7d --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 7cdec27..675367c 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -91,7 +91,11 @@ private slots: void selection(); void moveCursorSelection_data(); void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); void dragMouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); void horizontalAlignment_data(); void horizontalAlignment(); @@ -462,91 +466,115 @@ void tst_qdeclarativetextinput::moveCursorSelection_data() QTest::newRow("jum()ped|characters") << standard[0] << 23 << 23 << QDeclarativeTextInput::SelectCharacters << 23 << 23 << true; - QTest::newRow("(t)he|words") + QTest::newRow("<(t)he>|words") << standard[0] << 0 << 1 << QDeclarativeTextInput::SelectWords << 0 << 3 << true; - QTest::newRow("do(g)|words") + QTest::newRow("|words") << standard[0] << 43 << 44 << QDeclarativeTextInput::SelectWords << 41 << 44 << true; - QTest::newRow("jum(p)ed|words") + QTest::newRow("|words") << standard[0] << 23 << 24 << QDeclarativeTextInput::SelectWords << 20 << 26 << true; - QTest::newRow("jumped( )over|words") - << standard[0] << 26 << 27 << QDeclarativeTextInput::SelectWords << 27 << 27 << false; - QTest::newRow("jumped( )over|words,reversed") - << standard[0] << 27 << 26 << QDeclarativeTextInput::SelectWords << 26 << 26 << false; - QTest::newRow("(the )|words") - << standard[0] << 0 << 4 << QDeclarativeTextInput::SelectWords << 0 << 3 << true; - QTest::newRow("( dog)|words") - << standard[0] << 40 << 44 << QDeclarativeTextInput::SelectWords << 41 << 44 << true; - QTest::newRow("( jumped )|words") - << standard[0] << 19 << 27 << QDeclarativeTextInput::SelectWords << 20 << 26 << true; - QTest::newRow("th(e qu)ick|words") + QTest::newRow("over|words,ltr") + << standard[0] << 26 << 27 << QDeclarativeTextInput::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,rtl") + << standard[0] << 27 << 26 << QDeclarativeTextInput::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words,ltr") + << standard[0] << 0 << 4 << QDeclarativeTextInput::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,rtl") + << standard[0] << 4 << 0 << QDeclarativeTextInput::SelectWords << 0 << 9 << false; + QTest::newRow("|words,ltr") + << standard[0] << 40 << 44 << QDeclarativeTextInput::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,rtl") + << standard[0] << 44 << 40 << QDeclarativeTextInput::SelectWords << 40 << 44 << false; + QTest::newRow("over|words,ltr") + << standard[0] << 19 << 27 << QDeclarativeTextInput::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,rtl") + << standard[0] << 27 << 19 << QDeclarativeTextInput::SelectWords << 19 << 31 << false; + QTest::newRow("|words") << standard[0] << 2 << 6 << QDeclarativeTextInput::SelectWords << 0 << 9 << true; - QTest::newRow("la(zy d)og|words") + QTest::newRow("") << standard[0] << 38 << 42 << QDeclarativeTextInput::SelectWords << 36 << 44 << true; - QTest::newRow("jum(ped ov)er|words") + QTest::newRow("|words") << standard[0] << 23 << 29 << QDeclarativeTextInput::SelectWords << 20 << 31 << true; - QTest::newRow("()the|words") + QTest::newRow("<()>the|words") << standard[0] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << true; - QTest::newRow("dog()|words") + QTest::newRow("dog<()>|words") << standard[0] << 44 << 44 << QDeclarativeTextInput::SelectWords << 44 << 44 << true; - QTest::newRow("jum()ped|words") + QTest::newRow("jum<()>ped|words") << standard[0] << 23 << 23 << QDeclarativeTextInput::SelectWords << 23 << 23 << true; - QTest::newRow("Hello(,) |words") + QTest::newRow("Hello<(,)> |words") << standard[2] << 5 << 6 << QDeclarativeTextInput::SelectWords << 5 << 6 << true; - QTest::newRow("Hello(, )|words") - << standard[2] << 5 << 7 << QDeclarativeTextInput::SelectWords << 5 << 6 << true; - QTest::newRow("Hel(lo, )|words") - << standard[2] << 3 << 7 << QDeclarativeTextInput::SelectWords << 0 << 6 << true; - QTest::newRow("Hel(lo),|words") + QTest::newRow("Hello<(, )>world|words,ltr") + << standard[2] << 5 << 7 << QDeclarativeTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,rtl") + << standard[2] << 7 << 5 << QDeclarativeTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("world|words,ltr") + << standard[2] << 3 << 7 << QDeclarativeTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("|words,rtl") + << standard[2] << 7 << 3 << QDeclarativeTextInput::SelectWords << 0 << 12 << false; + QTest::newRow(",|words") << standard[2] << 3 << 5 << QDeclarativeTextInput::SelectWords << 0 << 5 << true; - QTest::newRow("Hello(),|words") + QTest::newRow("Hello<()>,|words") << standard[2] << 5 << 5 << QDeclarativeTextInput::SelectWords << 5 << 5 << true; - QTest::newRow("Hello,()|words") + QTest::newRow("Hello,<()>|words") << standard[2] << 6 << 6 << QDeclarativeTextInput::SelectWords << 6 << 6 << true; - QTest::newRow("Hello,( )|words") - << standard[2] << 6 << 7 << QDeclarativeTextInput::SelectWords << 7 << 7 << false; - QTest::newRow("Hello,( )|words,reversed") - << standard[2] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 6 << false; - QTest::newRow("Hello,( world)|words") - << standard[2] << 6 << 12 << QDeclarativeTextInput::SelectWords << 7 << 12 << true; - QTest::newRow("Hello,( world!)|words") - << standard[2] << 6 << 13 << QDeclarativeTextInput::SelectWords << 7 << 13 << true; - QTest::newRow("Hello(, world!)|words") + QTest::newRow("Hello<,( )>world|words,ltr") + << standard[2] << 6 << 7 << QDeclarativeTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,rtl") + << standard[2] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words,ltr") + << standard[2] << 6 << 12 << QDeclarativeTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,rtl") + << standard[2] << 12 << 6 << QDeclarativeTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words,ltr") + << standard[2] << 6 << 13 << QDeclarativeTextInput::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,rtl") + << standard[2] << 13 << 6 << QDeclarativeTextInput::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") << standard[2] << 5 << 13 << QDeclarativeTextInput::SelectWords << 5 << 13 << true; - QTest::newRow("world(!)|words") - << standard[2] << 12 << 13 << QDeclarativeTextInput::SelectWords << 12 << 13 << true; - QTest::newRow("world!())|words") + // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings. + // QTBUG-11365 + // QTest::newRow("world<(!)>|words") + // << standard[2] << 12 << 13 << QDeclarativeTextInput::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") << standard[2] << 13 << 13 << QDeclarativeTextInput::SelectWords << 13 << 13 << true; - QTest::newRow("world()!)|words") + QTest::newRow("world<()>!)|words") << standard[2] << 12 << 12 << QDeclarativeTextInput::SelectWords << 12 << 12 << true; - QTest::newRow("(,)olleH |words") + QTest::newRow("<(,)>olleH |words") << standard[3] << 7 << 8 << QDeclarativeTextInput::SelectWords << 7 << 8 << true; - QTest::newRow("( ,)olleH|words") - << standard[3] << 6 << 8 << QDeclarativeTextInput::SelectWords << 7 << 8 << true; - QTest::newRow("( ,ol)leH|words") - << standard[3] << 6 << 10 << QDeclarativeTextInput::SelectWords << 7 << 13 << true; - QTest::newRow(",(ol)leH,|words") + QTest::newRow("olleH|words,ltr") + << standard[3] << 6 << 8 << QDeclarativeTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,rtl") + << standard[3] << 8 << 6 << QDeclarativeTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("|words,ltr") + << standard[3] << 6 << 10 << QDeclarativeTextInput::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,rtl") + << standard[3] << 10 << 6 << QDeclarativeTextInput::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") << standard[3] << 8 << 10 << QDeclarativeTextInput::SelectWords << 8 << 13 << true; - QTest::newRow(",()olleH|words") + QTest::newRow(",<()>olleH|words") << standard[3] << 8 << 8 << QDeclarativeTextInput::SelectWords << 8 << 8 << true; - QTest::newRow("(),olleH|words") + QTest::newRow("<()>,olleH|words") << standard[3] << 7 << 7 << QDeclarativeTextInput::SelectWords << 7 << 7 << true; - QTest::newRow("( ),olleH|words") - << standard[3] << 6 << 7 << QDeclarativeTextInput::SelectWords << 7 << 7 << false; - QTest::newRow("( ),olleH|words,reversed") - << standard[3] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 6 << false; - QTest::newRow("(dlrow ),olleH|words") - << standard[3] << 1 << 7 << QDeclarativeTextInput::SelectWords << 1 << 6 << true; - QTest::newRow("(!dlrow ),olleH|words") - << standard[3] << 0 << 7 << QDeclarativeTextInput::SelectWords << 0 << 6 << true; + QTest::newRow(",olleH|words,ltr") + << standard[3] << 6 << 7 << QDeclarativeTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,rtl") + << standard[3] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words,ltr") + << standard[3] << 1 << 7 << QDeclarativeTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 1 << QDeclarativeTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words,ltr") + << standard[3] << 0 << 7 << QDeclarativeTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 0 << QDeclarativeTextInput::SelectWords << 0 << 8 << false; QTest::newRow("(!dlrow ,)olleH|words") << standard[3] << 0 << 8 << QDeclarativeTextInput::SelectWords << 0 << 8 << true; - QTest::newRow("(!)dlrow|words") + QTest::newRow("<(!)>dlrow|words") << standard[3] << 0 << 1 << QDeclarativeTextInput::SelectWords << 0 << 1 << true; - QTest::newRow("()!dlrow|words") + QTest::newRow("<()>!dlrow|words") << standard[3] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << true; - QTest::newRow("!()dlrow|words") + QTest::newRow("!<()>dlrow|words") << standard[3] << 1 << 1 << QDeclarativeTextInput::SelectWords << 1 << 1 << true; } @@ -569,6 +597,7 @@ void tst_qdeclarativetextinput::moveCursorSelection() textinputObject->setCursorPosition(cursorPosition); textinputObject->moveCursorSelection(movePosition, mode); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); QCOMPARE(textinputObject->selectionStart(), selectionStart); QCOMPARE(textinputObject->selectionEnd(), selectionEnd); @@ -576,11 +605,167 @@ void tst_qdeclarativetextinput::moveCursorSelection() textinputObject->setCursorPosition(movePosition); textinputObject->moveCursorSelection(cursorPosition, mode); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); QCOMPARE(textinputObject->selectionStart(), selectionStart); QCOMPARE(textinputObject->selectionEnd(), selectionEnd); } } +void tst_qdeclarativetextinput::moveCursorSelectionSequence_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition1"); + QTest::addColumn("movePosition2"); + QTest::addColumn("selection1Start"); + QTest::addColumn("selection1End"); + QTest::addColumn("selection2Start"); + QTest::addColumn("selection2End"); + + QTest::newRow("the { f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the { ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<( {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the { fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; +} + +void tst_qdeclarativetextinput::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 1.1\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + textinputObject->setCursorPosition(cursorPosition); + + textinputObject->moveCursorSelection(movePosition1, QDeclarativeTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(textinputObject->selectionStart(), selection1Start); + QCOMPARE(textinputObject->selectionEnd(), selection1End); + + textinputObject->moveCursorSelection(movePosition2, QDeclarativeTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(textinputObject->selectionStart(), selection2Start); + QCOMPARE(textinputObject->selectionEnd(), selection2End); +} + void tst_qdeclarativetextinput::dragMouseSelection() { QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; @@ -626,6 +811,55 @@ void tst_qdeclarativetextinput::dragMouseSelection() delete canvas; } +void tst_qdeclarativetextinput::mouseSelectionMode_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("selectWords"); + + // import installed + QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true; + QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false; +} + +void tst_qdeclarativetextinput::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textInputObject->selectedText(); + if (selectWords) { + QCOMPARE(str, text); + } else { + QVERIFY(str.length() > 3); + QVERIFY(str != text); + } + + delete canvas; +} + void tst_qdeclarativetextinput::horizontalAlignment_data() { QTest::addColumn("hAlign"); -- cgit v0.12