summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-01-07 07:42:12 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2011-01-10 03:51:19 (GMT)
commitcbf6bfbff8c0643bc82bb2456214994931052bd6 (patch)
treec9f8510af5dfddb365e4b5f0c34ed6729332fa49 /src/declarative
parent6db61ce39aa2fefaa9e22ca84edd8d140a5c6449 (diff)
downloadQt-cbf6bfbff8c0643bc82bb2456214994931052bd6.zip
Qt-cbf6bfbff8c0643bc82bb2456214994931052bd6.tar.gz
Qt-cbf6bfbff8c0643bc82bb2456214994931052bd6.tar.bz2
Add selection modes to TextEdit and TextInput.
Add an overload for moveCursorSelection which takes a parameter specifying whether to update the selection with individual characters or whole words. Task-number: QTBUG-16283 Reviewed-by: Martin Jones
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp89
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp101
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h7
4 files changed, 187 insertions, 17 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 6a51a3c..7ea3dec 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -579,37 +579,108 @@ int QDeclarativeTextEdit::positionAt(int x, int y) const
return r;
}
+void QDeclarativeTextEdit::moveCursorSelection(int pos)
+{
+ //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
+ Q_D(QDeclarativeTextEdit);
+ QTextCursor cursor = d->control->textCursor();
+ if (cursor.position() == pos)
+ return;
+ cursor.setPosition(pos, QTextCursor::KeepAnchor);
+ d->control->setTextCursor(cursor);
+}
+
/*!
- \qmlmethod int TextEdit::moveCursorSelection(int pos)
+ \qmlmethod void TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
+ \since Quick 1.1
- Moves the cursor to \a position and updates the selection accordingly.
- (To only move the cursor, set the \l cursorPosition property.)
+ Moves the cursor to \a position and updates the selection according to the optional \a mode
+ parameter. (To only move the cursor, set the \l cursorPosition property.)
When this method is called it additionally sets either the
selectionStart or the selectionEnd (whichever was at the previous cursor position)
to the specified position. This allows you to easily extend and contract the selected
text range.
+ The selection mode specifies whether the selection is updated on a per character or a per word
+ basis. If not specified the selection mode will default to TextEdit.SelectCharacters.
+
+ \list
+ \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
+ the previous cursor position) to the specified position.
+ \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
+ words between the specified postion and the previous cursor position. Words partially in the
+ range are included.
+ \endlist
+
For example, take this sequence of calls:
\code
cursorPosition = 5
- moveCursorSelection(9)
- moveCursorSelection(7)
+ moveCursorSelection(9, TextEdit.SelectCharacters)
+ moveCursorSelection(7, TextEdit.SelectCharacters)
\endcode
This moves the cursor to position 5, extend the selection end from 5 to 9
and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
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.
*/
-void QDeclarativeTextEdit::moveCursorSelection(int pos)
+void QDeclarativeTextEdit::moveCursorSelection(int pos, SelectionMode mode)
{
- //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
Q_D(QDeclarativeTextEdit);
QTextCursor cursor = d->control->textCursor();
if (cursor.position() == pos)
return;
- cursor.setPosition(pos, QTextCursor::KeepAnchor);
+ 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 {
+ cursor.movePosition(QTextCursor::PreviousCharacter, 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);
+ 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);
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
+ } else {
+ 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 {
+ cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+ }
+ } else {
+ cursor.setPosition(pos, QTextCursor::MoveAnchor);
+ }
d->control->setTextCursor(cursor);
}
@@ -655,7 +726,7 @@ void QDeclarativeTextEdit::setCursorPosition(int pos)
if (pos < 0 || pos > d->text.length())
return;
QTextCursor cursor = d->control->textCursor();
- if (cursor.position() == pos)
+ if (cursor.position() == pos && cursor.anchor() == pos)
return;
cursor.setPosition(pos);
d->control->setTextCursor(cursor);
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 37b24f7..6a05aa8 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextEdit : public QDeclarativePaintedItem
Q_ENUMS(HAlignment)
Q_ENUMS(TextFormat)
Q_ENUMS(WrapMode)
+ Q_ENUMS(SelectionMode)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
@@ -120,6 +121,11 @@ public:
Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
};
+ enum SelectionMode {
+ SelectCharacters,
+ SelectWords
+ };
+
Q_INVOKABLE void openSoftwareInputPanel();
Q_INVOKABLE void closeSoftwareInputPanel();
@@ -195,6 +201,7 @@ public:
Q_INVOKABLE QRectF positionToRectangle(int) const;
Q_INVOKABLE int positionAt(int x, int y) const;
Q_INVOKABLE void moveCursorSelection(int pos);
+ Q_INVOKABLE Q_REVISION(1) void moveCursorSelection(int pos, SelectionMode mode);
QRectF boundingRect() const;
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index ac07d4b..491d219c4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -50,6 +50,7 @@
#include <QApplication>
#include <QFontMetrics>
#include <QPainter>
+#include <QTextBoundaryFinder>
#ifndef QT_NO_LINEEDIT
@@ -1320,35 +1321,119 @@ void QDeclarativeTextInput::setSelectByMouse(bool on)
}
}
+void QDeclarativeTextInput::moveCursorSelection(int position)
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->moveCursor(position, true);
+ d->updateHorizontalScroll();
+}
/*!
- \qmlmethod void TextInput::moveCursorSelection(int position)
+ \qmlmethod void TextInput::moveCursorSelection(int position, SelectionMode mode = TextInput.SelectCharacters)
+ \since Quick 1.1
- Moves the cursor to \a position and updates the selection accordingly.
- (To only move the cursor, set the \l cursorPosition property.)
+ Moves the cursor to \a position and updates the selection according to the optional \a mode
+ parameter. (To only move the cursor, set the \l cursorPosition property.)
When this method is called it additionally sets either the
selectionStart or the selectionEnd (whichever was at the previous cursor position)
to the specified position. This allows you to easily extend and contract the selected
text range.
+ The selection mode specifies whether the selection is updated on a per character or a per word
+ basis. If not specified the selection mode will default to TextInput.SelectCharacters.
+
+ \list
+ \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
+ the previous cursor position) to the specified position.
+ \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
+ words between the specified postion and the previous cursor position. Words partially in the
+ range are included.
+ \endlist
+
For example, take this sequence of calls:
\code
cursorPosition = 5
- moveCursorSelection(9)
- moveCursorSelection(7)
+ moveCursorSelection(9, TextInput.SelectCharacters)
+ moveCursorSelection(7, TextInput.SelectCharacters)
\endcode
This moves the cursor to position 5, extend the selection end from 5 to 9
and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
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.
*/
-void QDeclarativeTextInput::moveCursorSelection(int position)
+void QDeclarativeTextInput::moveCursorSelection(int pos, SelectionMode mode)
{
Q_D(QDeclarativeTextInput);
- d->control->moveCursor(position, true);
- d->updateHorizontalScroll();
+
+ if (mode == SelectCharacters) {
+ d->control->moveCursor(pos, true);
+ } else if (pos != d->control->cursor()){
+ int anchor;
+ if (!d->control->hasSelectedText())
+ anchor = d->control->cursor();
+ else if (d->control->selectionStart() == d->control->cursor())
+ anchor = d->control->selectionEnd();
+ else
+ anchor = d->control->selectionStart();
+
+ if (anchor < 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();
+ }
+ 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 (anchor < cursor)
+ d->control->setSelection(anchor, cursor - anchor);
+ else
+ d->control->moveCursor(pos, false);
+
+ } else if (anchor > 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();
+ }
+ 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);
+ }
+ }
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index 878f040..25b8e66 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -63,6 +63,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativePaintedItem
Q_OBJECT
Q_ENUMS(HAlignment)
Q_ENUMS(EchoMode)
+ Q_ENUMS(SelectionMode)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
@@ -112,10 +113,16 @@ public:
AlignHCenter = Qt::AlignHCenter
};
+ enum SelectionMode {
+ SelectCharacters,
+ SelectWords
+ };
+
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE int positionAt(int x) const;
Q_INVOKABLE QRectF positionToRectangle(int pos) const;
Q_INVOKABLE void moveCursorSelection(int pos);
+ Q_INVOKABLE Q_REVISION(1) void moveCursorSelection(int pos, SelectionMode mode);
Q_INVOKABLE void openSoftwareInputPanel();
Q_INVOKABLE void closeSoftwareInputPanel();