Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qquicktextselection.cpp
Go to the documentation of this file.
1
// Copyright (C) 2023 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qquicktextselection_p.h"
6
7
#
include
<
QFont
>
8
#
include
<
QTextOption
>
9
#
include
<
QtQuick
/
private
/
qquicktextcontrol_p
.
h
>
10
#
include
<
QtQuick
/
private
/
qquicktextcontrol_p_p
.
h
>
11
#
include
<
QtQuick
/
private
/
qquicktextedit_p_p
.
h
>
12
13
QT_BEGIN_NAMESPACE
14
15
/*!
16
\qmltype TextSelection
17
\nativetype QQuickTextSelection
18
\inqmlmodule QtQuick
19
\ingroup qtquick-visual
20
\ingroup qtquick-input
21
\brief Represents a contiguous selection of text and its properties.
22
\since 6.7
23
24
\l {QtQuick::TextEdit::cursorSelection}{TextEdit.cursorSelection}
25
represents the range of text that is currently selected (for example by
26
dragging the mouse). It can be used to query and modify the selected text,
27
as well as properties in the \l {QTextCharFormat}{character} and
28
\l {QTextBlockFormat}{block} formats.
29
30
Additionally, since 6.11 it's possible to create explicit non-visual instances:
31
32
\qml
33
TextEdit {
34
id: textEdit
35
36
TextSelection {
37
id: sel1
38
}
39
}
40
\endqml
41
42
\c TextEdit.cursorSelection and any explicit TextSelection instances can be
43
used to query and modify the specified ranges of text, as well as properties in
44
the \l {QTextCharFormat}{character} and \l {QTextBlockFormat}{block} formats.
45
46
\note This API is considered tech preview and may change or be removed in
47
future versions of Qt.
48
49
\sa TextEdit, QTextCursor
50
*/
51
52
/*! \internal
53
QQuickTextSelection provides QML API using QTextCursor.
54
QQuickTextControl owns a text cursor, and one instance of
55
QQuickTextSelection represents it and delegates all operations to it.
56
But since 6.11, the user can also create other instances of TextSelection
57
in QML for the purpose of programmatic editing; in that case
58
m_control remains null, m_doc is set, QQuickTextSelection owns the
59
QTextCursor, and delegates all operations to it.
60
*/
61
QQuickTextSelection::QQuickTextSelection(QObject *parent)
62
: QObject(parent)
63
{
64
// When QQuickTextEdit creates its cursorSelection, it passes itself as the parent
65
if
(
auto
*textEdit = qmlobject_cast<QQuickTextEdit *>(parent)) {
66
m_doc = textEdit->textDocument();
67
m_control = QQuickTextEditPrivate::get(textEdit)->control;
68
connect(m_control, &QQuickTextControl::currentCharFormatChanged,
69
this
, &QQuickTextSelection::updateFromCharFormat);
70
connect(m_control, &QQuickTextControl::cursorPositionChanged,
71
this
, &QQuickTextSelection::updateFromBlockFormat);
72
}
73
}
74
75
void
QQuickTextSelection::componentComplete()
76
{
77
// If TextSelection is declared inside a TextEdit,
78
// the user doesn't need to set its document property;
79
// but we don't set m_control because this is an independent non-visual selection
80
if
(!m_doc) {
81
if
(
auto
*textEdit = qmlobject_cast<QQuickTextEdit *>(parent())) {
82
m_doc = textEdit->textDocument();
83
m_cursor = QTextCursor(m_doc->textDocument());
84
}
85
}
86
}
87
88
/*!
89
\since 6.11
90
\qmlproperty TextDocument QtQuick::TextSelection::document
91
92
The QQuickTextDocument that contains the selected text.
93
94
\sa QtQuick::TextEdit::textDocument
95
*/
96
QQuickTextDocument *QQuickTextSelection::document()
const
97
{
98
return
m_doc;
99
}
100
101
void
QQuickTextSelection::setDocument(QQuickTextDocument *doc)
102
{
103
if
(m_doc == doc)
104
return
;
105
106
m_doc = doc;
107
m_cursor = QTextCursor(m_doc->textDocument());
108
emit documentChanged();
109
}
110
111
/*!
112
\since 6.11
113
\qmlproperty int QtQuick::TextSelection::selectionStart
114
115
The position before the first character in the selection.
116
117
\sa QtQuick::TextEdit::selectionStart
118
*/
119
int
QQuickTextSelection::selectionStart()
const
120
{
121
return
cursor().selectionStart();
122
}
123
124
void
QQuickTextSelection::setSelectionStart(
int
start)
125
{
126
auto
cur = cursor();
// copy
127
if
(start == cur.selectionStart())
128
return
;
129
130
if
(m_control) {
131
cur.setPosition(start, QTextCursor::MoveAnchor);
132
m_control->setTextCursor(cur);
133
}
else
{
134
m_cursor.setPosition(start, QTextCursor::MoveAnchor);
135
}
136
emit selectionStartChanged();
137
}
138
139
/*!
140
\since 6.11
141
\qmlproperty int QtQuick::TextSelection::selectionEnd
142
143
The position after the last character in the selection.
144
145
\sa QtQuick::TextEdit::selectionEnd
146
*/
147
int
QQuickTextSelection::selectionEnd()
const
148
{
149
return
cursor().selectionEnd();
150
}
151
152
void
QQuickTextSelection::setSelectionEnd(
int
end)
153
{
154
auto
cur = cursor();
// copy
155
if
(end == cur.selectionEnd())
156
return
;
157
158
if
(m_control) {
159
cur.setPosition(end, QTextCursor::KeepAnchor);
160
m_control->setTextCursor(cur);
161
}
else
{
162
m_cursor.setPosition(end, QTextCursor::KeepAnchor);
163
}
164
emit selectionEndChanged();
165
}
166
167
/*!
168
\qmlproperty string QtQuick::TextSelection::text
169
170
The selected text, without any rich text markup.
171
172
Setting this property replaces the selected text with the given string.
173
*/
174
QString QQuickTextSelection::text()
const
175
{
176
return
cursor().selectedText();
177
}
178
179
void
QQuickTextSelection::setText(
const
QString &text)
180
{
181
auto
cur = cursor();
182
if
(cur.selectedText() == text)
183
return
;
184
185
cur.insertText(text);
186
emit textChanged();
187
}
188
189
/*!
190
\qmlproperty font QtQuick::TextSelection::font
191
192
The font of the selected text.
193
194
\sa QTextCharFormat::font()
195
*/
196
QFont QQuickTextSelection::font()
const
197
{
198
return
cursor().charFormat().font();
199
}
200
201
void
QQuickTextSelection::setFont(
const
QFont &font)
202
{
203
auto
cur = cursor();
204
if
(cur.selection().isEmpty())
205
cur.select(QTextCursor::WordUnderCursor);
206
207
if
(font == cur.charFormat().font())
208
return
;
209
210
QTextCharFormat fmt;
211
fmt.setFont(font);
212
cur.mergeCharFormat(fmt);
213
emit fontChanged();
214
}
215
216
/*!
217
\qmlproperty color QtQuick::TextSelection::color
218
219
The foreground color of the selected text.
220
221
\sa QTextCharFormat::foreground()
222
*/
223
QColor QQuickTextSelection::color()
const
224
{
225
return
cursor().charFormat().foreground().color();
226
}
227
228
void
QQuickTextSelection::setColor(QColor color)
229
{
230
auto
cur = cursor();
231
if
(cur.selection().isEmpty())
232
cur.select(QTextCursor::WordUnderCursor);
233
234
if
(color == cur.charFormat().foreground().color())
235
return
;
236
237
QTextCharFormat fmt;
238
fmt.setForeground(color);
239
cur.mergeCharFormat(fmt);
240
emit colorChanged();
241
}
242
243
/*!
244
\qmlproperty enumeration QtQuick::TextSelection::alignment
245
246
The alignment of the block containing the selected text.
247
248
\sa QTextBlockFormat::alignment()
249
*/
250
Qt::Alignment QQuickTextSelection::alignment()
const
251
{
252
return
cursor().blockFormat().alignment();
253
}
254
255
void
QQuickTextSelection::setAlignment(Qt::Alignment align)
256
{
257
if
(align == alignment())
258
return
;
259
260
QTextBlockFormat format;
261
format.setAlignment(align);
262
cursor().mergeBlockFormat(format);
263
emit alignmentChanged();
264
}
265
266
/*!
267
\since 6.11
268
\qmlmethod bool QtQuick::TextSelection::moveSelectionStart(MoveOperation op, int n)
269
270
Deselect text and move \l selectionStart \a n times according to \a op,
271
which is one of the following enum values:
272
273
\value TextSelection.NoMove Keep the cursor where it is
274
275
\value TextSelection.Start Move to the start of the document.
276
\value TextSelection.StartOfLine Move to the start of the current line.
277
\value TextSelection.StartOfBlock Move to the start of the current block.
278
\value TextSelection.StartOfWord Move to the start of the current word.
279
\value TextSelection.PreviousBlock Move to the start of the previous block.
280
\value TextSelection.PreviousCharacter Move to the previous character.
281
\value TextSelection.PreviousWord Move to the beginning of the previous word.
282
\value TextSelection.Up Move up one line.
283
\value TextSelection.Left Move left one character.
284
\value TextSelection.WordLeft Move left one word.
285
286
\value TextSelection.End Move to the end of the document.
287
\value TextSelection.EndOfLine Move to the end of the current line.
288
\value TextSelection.EndOfWord Move to the end of the current word.
289
\value TextSelection.EndOfBlock Move to the end of the current block.
290
\value TextSelection.NextBlock Move to the beginning of the next block.
291
\value TextSelection.NextCharacter Move to the next character.
292
\value TextSelection.NextWord Move to the next word.
293
\value TextSelection.Down Move down one line.
294
\value TextSelection.Right Move right one character.
295
\value TextSelection.WordRight Move right one word.
296
297
\value TextSelection.NextCell Move to the beginning of the next table cell inside the
298
current table. If the current cell is the last cell in the row, the
299
cursor will move to the first cell in the next row.
300
\value TextSelection.PreviousCell Move to the beginning of the previous table cell
301
inside the current table. If the current cell is the first cell in
302
the row, the cursor will move to the last cell in the previous row.
303
\value TextSelection.NextRow Move to the first new cell of the next row in the current table.
304
\value TextSelection.PreviousRow Move to the last cell of the previous row in the current table.
305
306
Returns \c true if all operations were completed successfully; otherwise
307
returns \c false.
308
309
\sa QTextCursor::movePosition, QTextCursor::MoveAnchor, QTextCursor::MoveOperation
310
*/
311
bool
QQuickTextSelection::moveSelectionStart(MoveOperation op,
int
n)
312
{
313
const
QTextCursor::MoveOperation qop =
static_cast
<QTextCursor::MoveOperation>(op);
314
if
(m_control) {
315
auto
cur = cursor();
316
if
(cur.movePosition(qop, QTextCursor::MoveAnchor, n)) {
317
m_control->setTextCursor(cur);
318
return
true
;
319
}
320
}
else
{
321
return
m_cursor.movePosition(qop, QTextCursor::MoveAnchor, n);
322
}
323
324
return
false
;
325
}
326
327
/*!
328
\since 6.11
329
\qmlmethod void QtQuick::TextSelection::moveSelectionEnd(MoveOperation op, int n)
330
331
Move \l selectionEnd \a n times according to \a op, which is
332
one of the enum values as used in moveSelectionStart().
333
334
If moveSelectionStart() was called immediately before,
335
\c {selectionEnd == selectionStart}, and this function moves it from there
336
so that a range of text becomes selected.
337
338
\sa QTextCursor::movePosition, QTextCursor::KeepAnchor, moveSelectionStart(), QTextCursor::MoveOperation
339
*/
340
bool
QQuickTextSelection::moveSelectionEnd(MoveOperation op,
int
n)
341
{
342
const
QTextCursor::MoveOperation qop =
static_cast
<QTextCursor::MoveOperation>(op);
343
if
(m_control) {
344
auto
cur = cursor();
345
if
(cur.movePosition(qop, QTextCursor::KeepAnchor, n)) {
346
m_control->setTextCursor(cur);
347
return
true
;
348
}
349
}
else
{
350
return
m_cursor.movePosition(qop, QTextCursor::KeepAnchor, n);
351
}
352
353
return
false
;
354
}
355
356
/*!
357
\since 6.11
358
\qmlmethod void QtQuick::TextSelection::duplicate()
359
360
Copy the selected text forward, keeping all formatting intact
361
in the copy, and end with the copy as the selection.
362
363
For example if an entire line is selected, this function inserts a copy
364
of that line immediately below, and selects the copy. If a word is
365
is selected, this function copies it to the right and selects it.
366
*/
367
void
QQuickTextSelection::duplicate()
368
{
369
auto
sel = cursor().selection();
370
const
auto
start = selectionEnd();
371
setSelectionStart(start);
372
cursor().insertFragment(sel);
373
374
// the fragment is inserted at the right place; now select it
375
const
auto
end = selectionEnd();
376
setSelectionStart(start);
377
setSelectionEnd(end);
378
}
379
380
/*!
381
\since 6.11
382
\qmlmethod void QtQuick::TextSelection::linkTo(url destination)
383
384
Create a hyperlink from the selected text to \a destination.
385
386
\sa QTextCharFormat::setAnchorHref()
387
*/
388
void
QQuickTextSelection::linkTo(
const
QUrl &destination)
389
{
390
auto
cur = cursor();
391
if
(cur.selection().isEmpty())
392
cur.select(QTextCursor::WordUnderCursor);
393
cur.beginEditBlock();
394
QTextCharFormat fmt = cur.charFormat();
395
fmt.setForeground(QPalette().link());
396
fmt.setAnchor(
true
);
397
fmt.setAnchorHref(destination.toString());
398
cur.setCharFormat(fmt);
399
cur.endEditBlock();
400
}
401
402
/*! \internal
403
Return the cursor, which is either the graphically-manipulable cursor from
404
QQuickTextControl if that is set, or else the internally-stored cursor
405
with which the user is trying to mutate and/or monitor the underlying document,
406
in the case that TextSelection is declared in QML.
407
*/
408
QTextCursor QQuickTextSelection::cursor()
const
409
{
410
if
(m_control)
411
return
m_control->textCursor();
412
return
m_cursor;
413
}
414
415
inline
void
QQuickTextSelection::updateFromCharFormat(
const
QTextCharFormat &fmt)
416
{
417
if
(fmt.font() != m_charFormat.font())
418
emit fontChanged();
419
if
(fmt.foreground().color() != m_charFormat.foreground().color())
420
emit colorChanged();
421
422
m_charFormat = fmt;
423
}
424
425
inline
void
QQuickTextSelection::updateFromBlockFormat()
426
{
427
QTextBlockFormat fmt = cursor().blockFormat();
428
429
if
(fmt.alignment() != m_blockFormat.alignment())
430
emit alignmentChanged();
431
432
m_blockFormat = fmt;
433
}
434
435
QT_END_NAMESPACE
436
437
#
include
"moc_qquicktextselection_p.cpp"
qtdeclarative
src
quick
util
qquicktextselection.cpp
Generated on
for Qt by
1.18.0