Newer
Older
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** This file is part of the QtQuick module of the Qt Toolkit.
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qquicktextedit_p.h"
#include "qquicktextedit_p_p.h"
#include "qquicktextcontrol_p.h"
#include "qquicktext_p_p.h"
#include "qquicktextnodeengine_p.h"
#include "qquicktextutil_p.h"
#include <QtQml/qqmlinfo.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qevent.h>
#include <QtGui/qpainter.h>
#include <QtGui/qtextobject.h>
#include <QtGui/qtexttable.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlproperty_p.h>
#include <private/qsgadaptationlayer_p.h>
\qmltype TextEdit
\instantiates QQuickTextEdit
\ingroup qtquick-visual
\ingroup qtquick-input
\brief Displays multiple lines of editable formatted text
The TextEdit item displays a block of editable, formatted text.
It can display both plain and rich text. For example:
\qml
TextEdit {
width: 240
text: "<b>Hello</b> <i>World!</i>"
font.family: "Helvetica"
font.pointSize: 20
color: "blue"
focus: true
}
\endqml
\image declarative-textedit.gif
Setting \l {Item::focus}{focus} to \c true enables the TextEdit item to receive keyboard focus.
Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific
to a look-and-feel. For example, to add flickable scrolling that follows the cursor:
A particular look-and-feel might use smooth scrolling (eg. using SmoothedAnimation), might have a visible
scrollbar, or a scrollbar that fades in to show location, etc.
Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can
be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely
from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().
You can translate between cursor positions (characters from the start of the document) and pixel
points using positionAt() and positionToRectangle().
\sa Text, TextInput
\qmlsignal QtQuick::TextEdit::linkActivated(string link)
This signal is emitted when the user clicks on a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
The corresponding handler is \c onLinkActivated.
// This is a pretty arbitrary figure. The idea is that we don't want to break down the document
// into text nodes corresponding to a text block each so that the glyph node grouping doesn't become pointless.
static const int nodeBreakingSize = 300;
namespace {
class ProtectedLayoutAccessor: public QAbstractTextDocumentLayout
{
public:
inline QTextCharFormat formatAccessor(int pos)
{
return format(pos);
}
};
class RootNode : public QSGTransformNode
{
public:
RootNode() : cursorNode(0), frameDecorationsNode(0)
{ }
void resetFrameDecorations(QQuickTextNode* newNode)
{
if (frameDecorationsNode) {
removeChildNode(frameDecorationsNode);
delete frameDecorationsNode;
}
frameDecorationsNode = newNode;
newNode->setFlag(QSGNode::OwnedByParent);
}
void resetCursorNode(QSGRectangleNode* newNode)
{
if (cursorNode)
removeChildNode(cursorNode);
delete cursorNode;
cursorNode = newNode;
if (cursorNode) {
appendChildNode(cursorNode);
cursorNode->setFlag(QSGNode::OwnedByParent);
}
QSGRectangleNode *cursorNode;
QQuickTextNode* frameDecorationsNode;
};
QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickTextEditPrivate), parent)
QString QQuickTextEdit::text() const
if (!d->textCached) {
QQuickTextEditPrivate *d = const_cast<QQuickTextEditPrivate *>(d_func());
if (d->richText)
d->text = d->control->toHtml();
else
d->text = d->control->toPlainText();
d->textCached = true;
}
return d->text;
\qmlproperty string QtQuick::TextEdit::font.family
Sets the family name of the font.
The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
If the family isn't available a family will be set using the font matching algorithm.
*/
/*!
\qmlproperty bool QtQuick::TextEdit::font.bold
Sets whether the font weight is bold.
*/
/*!
\qmlproperty enumeration QtQuick::TextEdit::font.weight
Sets the font's weight.
The weight can be one of:
\list
\li Font.Light
\li Font.Normal - the default
\li Font.DemiBold
\li Font.Bold
\li Font.Black
\endlist
\qml
TextEdit { text: "Hello"; font.weight: Font.DemiBold }
\endqml
*/
/*!
\qmlproperty bool QtQuick::TextEdit::font.italic
Sets whether the font has an italic style.
*/
/*!
\qmlproperty bool QtQuick::TextEdit::font.underline
Sets whether the text is underlined.
*/
/*!
\qmlproperty bool QtQuick::TextEdit::font.strikeout
Sets whether the font has a strikeout style.
*/
/*!
\qmlproperty real QtQuick::TextEdit::font.pointSize
Sets the font size in points. The point size must be greater than zero.
*/
/*!
\qmlproperty int QtQuick::TextEdit::font.pixelSize
Sets the font size in pixels.
Using this function makes the font device dependent. Use
\l{TextEdit::font.pointSize} to set the size of the font in a
device independent manner.
*/
/*!
\qmlproperty real QtQuick::TextEdit::font.letterSpacing
Sets the letter spacing for the font.
Letter spacing changes the default spacing between individual letters in the font.
A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
*/
/*!
\qmlproperty real QtQuick::TextEdit::font.wordSpacing
Sets the word spacing for the font.
Word spacing changes the default spacing between individual words.
A positive value increases the word spacing by a corresponding amount of pixels,
while a negative value decreases the inter-word spacing accordingly.
*/
/*!
\qmlproperty enumeration QtQuick::TextEdit::font.capitalization
\li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
\li Font.AllUppercase - This alters the text to be rendered in all uppercase type.
\li Font.AllLowercase - This alters the text to be rendered in all lowercase type.
\li Font.SmallCaps - This alters the text to be rendered in small-caps type.
\li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
\endlist
\qml
TextEdit { text: "Hello"; font.capitalization: Font.AllLowercase }
\endqml
*/
/*!
\qmlproperty string QtQuick::TextEdit::text
The text to display. If the text format is AutoText the text edit will
automatically determine whether the text should be treated as
rich text. This determination is made using Qt::mightBeRichText().
The text-property is mostly suitable for setting the initial content and
handling modifications to relatively small text content. The append(),
insert() and remove() methods provide more fine-grained control and
remarkably better performance for modifying especially large rich text
content.
void QQuickTextEdit::setText(const QString &text)
Q_D(QQuickTextEdit);
if (QQuickTextEdit::text() == text)
d->document->clearResources();
d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text));
if (!isComponentComplete()) {
d->text = text;
} else if (d->richText) {
#ifndef QT_NO_TEXTHTMLPARSER
d->control->setHtml(text);
#else
d->control->setPlainText(text);
#endif
} else {
d->control->setPlainText(text);
}
}
\qmlproperty enumeration QtQuick::TextEdit::textFormat
The way the text property should be displayed.
\list
\li TextEdit.AutoText
\li TextEdit.PlainText
\li TextEdit.RichText
The default is TextEdit.PlainText. If the text format is TextEdit.AutoText the text edit
will automatically determine whether the text should be treated as
rich text. This determination is made using Qt::mightBeRichText().
\table
\row
\qml
Column {
TextEdit {
font.pointSize: 24
text: "<b>Hello</b> <i>World!</i>"
}
TextEdit {
font.pointSize: 24
textFormat: TextEdit.RichText
text: "<b>Hello</b> <i>World!</i>"
}
TextEdit {
font.pointSize: 24
textFormat: TextEdit.PlainText
text: "<b>Hello</b> <i>World!</i>"
}
}
\endqml
\li \image declarative-textformat.png
QQuickTextEdit::TextFormat QQuickTextEdit::textFormat() const
void QQuickTextEdit::setTextFormat(TextFormat format)
d->richText = format == RichText || (format == AutoText && (wasRich || Qt::mightBeRichText(text())));
#ifndef QT_NO_TEXTHTMLPARSER
if (isComponentComplete()) {
if (wasRich && !d->richText) {
d->control->setPlainText(!d->textCached ? d->control->toHtml() : d->text);
updateSize();
} else if (!wasRich && d->richText) {
d->control->setHtml(!d->textCached ? d->control->toPlainText() : d->text);
updateSize();
}
#endif
d->format = format;
d->control->setAcceptRichText(d->format != PlainText);
emit textFormatChanged(d->format);
}
/*!
\qmlproperty enumeration QtQuick::TextEdit::renderType
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
Override the default rendering type for this component.
Supported render types are:
\list
\li Text.QtRendering - the default
\li Text.NativeRendering
\endlist
Select Text.NativeRendering if you prefer text to look native on the target platform and do
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
*/
QQuickTextEdit::RenderType QQuickTextEdit::renderType() const
{
Q_D(const QQuickTextEdit);
return d->renderType;
}
void QQuickTextEdit::setRenderType(QQuickTextEdit::RenderType renderType)
{
Q_D(QQuickTextEdit);
if (d->renderType == renderType)
return;
d->renderType = renderType;
emit renderTypeChanged();
d->updateDefaultTextOption();
if (isComponentComplete())
updateSize();
}
QFont QQuickTextEdit::font() const
void QQuickTextEdit::setFont(const QFont &font)
if (d->sourceFont == font)
return;
d->sourceFont = font;
QFont oldFont = d->font;
d->font = font;
if (d->font.pointSizeF() != -1) {
// 0.5pt resolution
qreal size = qRound(d->font.pointSizeF()*2.0);
d->font.setPointSizeF(size/2.0);
}
if (oldFont != d->font) {
d->document->setDefaultFont(d->font);
if (d->cursorItem) {
d->cursorItem->setHeight(QFontMetrics(d->font).height());
moveCursorDelegate();
}
updateSize();
updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont);
}
emit fontChanged(d->sourceFont);
}
\qmlproperty color QtQuick::TextEdit::color
The text color.
\qml
// green text using hexadecimal notation
TextEdit { color: "#00FF00" }
\endqml
\qml
// steelblue text using SVG color name
TextEdit { color: "steelblue" }
\endqml
*/
QColor QQuickTextEdit::color() const
void QQuickTextEdit::setColor(const QColor &color)
if (d->color == color)
return;
d->color = color;
\qmlproperty color QtQuick::TextEdit::selectionColor
The text highlight color, used behind selections.
*/
QColor QQuickTextEdit::selectionColor() const
void QQuickTextEdit::setSelectionColor(const QColor &color)
if (d->selectionColor == color)
return;
d->selectionColor = color;
emit selectionColorChanged(d->selectionColor);
}
\qmlproperty color QtQuick::TextEdit::selectedTextColor
QColor QQuickTextEdit::selectedTextColor() const
void QQuickTextEdit::setSelectedTextColor(const QColor &color)
if (d->selectedTextColor == color)
return;
d->selectedTextColor = color;
emit selectedTextColorChanged(d->selectedTextColor);
}
\qmlproperty enumeration QtQuick::TextEdit::horizontalAlignment
\qmlproperty enumeration QtQuick::TextEdit::verticalAlignment
\qmlproperty enumeration QtQuick::TextEdit::effectiveHorizontalAlignment
Sets the horizontal and vertical alignment of the text within the TextEdit item's
width and height. By default, the text alignment follows the natural alignment
of the text, for example text that is read from left to right will be aligned to
the left.
Valid values for \c horizontalAlignment are:
\list
\li TextEdit.AlignLeft (default)
\li TextEdit.AlignRight
\li TextEdit.AlignHCenter
\li TextEdit.AlignJustify
\endlist
Valid values for \c verticalAlignment are:
\list
\li TextEdit.AlignTop (default)
\li TextEdit.AlignBottom
\li TextEdit.AlignVCenter
\endlist
When using the attached property LayoutMirroring::enabled to mirror application
layouts, the horizontal alignment of text will also be mirrored. However, the property
\c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
of TextEdit, use the read-only property \c effectiveHorizontalAlignment.
*/
QQuickTextEdit::HAlignment QQuickTextEdit::hAlign() const
void QQuickTextEdit::setHAlign(HAlignment align)
bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
d->hAlignImplicit = false;
if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
d->updateDefaultTextOption();
updateSize();
}
}
void QQuickTextEdit::resetHAlign()
d->hAlignImplicit = true;
if (d->determineHorizontalAlignment() && isComponentComplete()) {
d->updateDefaultTextOption();
updateSize();
}
}
QQuickTextEdit::HAlignment QQuickTextEdit::effectiveHAlign() const
Q_D(const QQuickTextEdit);
QQuickTextEdit::HAlignment effectiveAlignment = d->hAlign;
if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
switch (d->hAlign) {
case QQuickTextEdit::AlignLeft:
effectiveAlignment = QQuickTextEdit::AlignRight;
case QQuickTextEdit::AlignRight:
effectiveAlignment = QQuickTextEdit::AlignLeft;
break;
default:
break;
}
}
return effectiveAlignment;
}
bool QQuickTextEditPrivate::setHAlign(QQuickTextEdit::HAlignment alignment, bool forceAlign)
QQuickTextEdit::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
hAlign = alignment;
emit q->horizontalAlignmentChanged(alignment);
if (oldEffectiveHAlign != q->effectiveHAlign())
emit q->effectiveHorizontalAlignmentChanged();
return true;
}
return false;
}
Qt::LayoutDirection QQuickTextEditPrivate::textDirection(const QString &text) const
{
const QChar *character = text.constData();
while (!character->isNull()) {
switch (character->direction()) {
case QChar::DirL:
return Qt::LeftToRight;
case QChar::DirR:
case QChar::DirAL:
case QChar::DirAN:
return Qt::RightToLeft;
default:
break;
}
character++;
}
return Qt::LayoutDirectionAuto;
}
bool QQuickTextEditPrivate::determineHorizontalAlignment()
if (hAlignImplicit && q->isComponentComplete()) {
Qt::LayoutDirection direction = contentDirection;
if (direction == Qt::LayoutDirectionAuto) {
const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
direction = textDirection(preeditText);
if (direction == Qt::LayoutDirectionAuto)
direction = qGuiApp->inputMethod()->inputDirection();
return setHAlign(direction == Qt::RightToLeft ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft);
void QQuickTextEditPrivate::mirrorChange()
if (!hAlignImplicit && (hAlign == QQuickTextEdit::AlignRight || hAlign == QQuickTextEdit::AlignLeft)) {
updateDefaultTextOption();
q->updateSize();
emit q->effectiveHorizontalAlignmentChanged();
}
}
}
#ifndef QT_NO_IM
Qt::InputMethodHints QQuickTextEditPrivate::effectiveInputMethodHints() const
{
return inputMethodHints | Qt::ImhMultiLine;
}
#endif
QQuickTextEdit::VAlignment QQuickTextEdit::vAlign() const
void QQuickTextEdit::setVAlign(QQuickTextEdit::VAlignment alignment)
if (alignment == d->vAlign)
return;
d->vAlign = alignment;
d->updateDefaultTextOption();
updateSize();
emit verticalAlignmentChanged(d->vAlign);
}
\qmlproperty enumeration QtQuick::TextEdit::wrapMode
Set this property to wrap the text to the TextEdit item's width.
The text will only wrap if an explicit width has been set.
\list
\li TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width.
\li TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width.
\li TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
\li TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
The default is TextEdit.NoWrap. If you set a width, consider using TextEdit.Wrap.
*/
QQuickTextEdit::WrapMode QQuickTextEdit::wrapMode() const
void QQuickTextEdit::setWrapMode(WrapMode mode)
if (mode == d->wrapMode)
return;
d->wrapMode = mode;
d->updateDefaultTextOption();
updateSize();
emit wrapModeChanged();
}
\qmlproperty int QtQuick::TextEdit::lineCount
Returns the total number of lines in the textEdit item.
*/
int QQuickTextEdit::lineCount() const
\qmlproperty int QtQuick::TextEdit::length
Returns the total number of plain text characters in the TextEdit item.
As this number doesn't include any formatting markup it may not be the same as the
length of the string returned by the \l text property.
This property can be faster than querying the length the \l text property as it doesn't
require any copying or conversion of the TextEdit's internal string data.
*/
int QQuickTextEdit::length() const
{
Q_D(const QQuickTextEdit);
// QTextDocument::characterCount() includes the terminating null character.
return qMax(0, d->document->characterCount() - 1);
}
\qmlproperty real QtQuick::TextEdit::contentWidth
Returns the width of the text, including the width past the width
which is covered due to insufficient wrapping if \l wrapMode is set.
*/
qreal QQuickTextEdit::contentWidth() const
return d->contentSize.width();
\qmlproperty real QtQuick::TextEdit::contentHeight
Returns the height of the text, including the height past the height
that is covered if the text does not fit within the set height.
*/
qreal QQuickTextEdit::contentHeight() const
return d->contentSize.height();
\qmlproperty url QtQuick::TextEdit::baseUrl
This property specifies a base URL which is used to resolve relative URLs
within the text.
The default value is the url of the QML file instantiating the TextEdit item.
*/
QUrl QQuickTextEdit::baseUrl() const
{
Q_D(const QQuickTextEdit);
if (d->baseUrl.isEmpty()) {
if (QQmlContext *context = qmlContext(this))
const_cast<QQuickTextEditPrivate *>(d)->baseUrl = context->baseUrl();
}
return d->baseUrl;
}
void QQuickTextEdit::setBaseUrl(const QUrl &url)
{
Q_D(QQuickTextEdit);
if (baseUrl() != url) {
d->baseUrl = url;
d->document->setBaseUrl(url);
emit baseUrlChanged();
}
}
void QQuickTextEdit::resetBaseUrl()
{
if (QQmlContext *context = qmlContext(this))
setBaseUrl(context->baseUrl());
else
setBaseUrl(QUrl());
}
\qmlmethod rectangle QtQuick::TextEdit::positionToRectangle(position)
Returns the rectangle at the given \a position in the text. The x, y,
and height properties correspond to the cursor that would describe
that position.
*/
QRectF QQuickTextEdit::positionToRectangle(int pos) const
QTextCursor c(d->document);
c.setPosition(pos);
return d->control->cursorRect(c).translated(d->xoff, d->yoff);
\qmlmethod int QtQuick::TextEdit::positionAt(int x, int y)
Returns the text position closest to pixel position (\a x, \a y).
Position 0 is before the first character, position 1 is after the first character
but before the second, and so on until position \l {text}.length, which is after all characters.
*/
int QQuickTextEdit::positionAt(qreal x, qreal y) const
x -= d->xoff;
y -= d->yoff;
int r = d->document->documentLayout()->hitTest(QPointF(x, y), Qt::FuzzyHit);
QTextCursor cursor = d->control->textCursor();
if (r > cursor.position()) {
// The cursor position includes positions within the preedit text, but only positions in the
// same text block are offset so it is possible to get a position that is either part of the
// preedit or the next text block.
QTextLayout *layout = cursor.block().layout();
const int preeditLength = layout
? layout->preeditAreaText().length()
: 0;
if (preeditLength > 0
&& d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x, y)) {
r = r > cursor.position() + preeditLength
? r - preeditLength
: cursor.position();
}
}
\qmlmethod QtQuick::TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
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
\li TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
the previous cursor position) to the specified position.
\li TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
words between the specified position 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, 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 on or past position 9.
*/
void QQuickTextEdit::moveCursorSelection(int pos)
{
//Note that this is the same as setCursorPosition but with the KeepAnchor flag set
QTextCursor cursor = d->control->textCursor();
if (cursor.position() == pos)
return;
cursor.setPosition(pos, QTextCursor::KeepAnchor);
d->control->setTextCursor(cursor);
}
void QQuickTextEdit::moveCursorSelection(int pos, SelectionMode mode)
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
QTextCursor cursor = d->control->textCursor();
if (cursor.position() == pos)
return;
if (mode == SelectCharacters) {
cursor.setPosition(pos, QTextCursor::KeepAnchor);
} 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.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::EndOfWord, QTextCursor::KeepAnchor);
} 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.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::PreviousCharacter, QTextCursor::KeepAnchor);
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
}
}
d->control->setTextCursor(cursor);
}
\qmlproperty bool QtQuick::TextEdit::cursorVisible
If true the text edit shows a cursor.
This property is set and unset when the text edit gets active focus, but it can also
be set directly (useful, for example, if a KeyProxy might forward keys to it).
*/
bool QQuickTextEdit::isCursorVisible() const