Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/text/qtextobject.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||
2 | ** | - | ||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||
5 | ** | - | ||||||||||||
6 | ** This file is part of the QtGui module of the Qt Toolkit. | - | ||||||||||||
7 | ** | - | ||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||
16 | ** | - | ||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||
24 | ** | - | ||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||
35 | ** | - | ||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||
37 | ** | - | ||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||
39 | - | |||||||||||||
40 | #include "qtextobject.h" | - | ||||||||||||
41 | #include "qtextobject_p.h" | - | ||||||||||||
42 | #include "qtextcursor_p.h" | - | ||||||||||||
43 | #include "qtextdocument.h" | - | ||||||||||||
44 | #include "qtextformat_p.h" | - | ||||||||||||
45 | #include "qtextdocument_p.h" | - | ||||||||||||
46 | #include "qtextcursor.h" | - | ||||||||||||
47 | #include "qtextlist.h" | - | ||||||||||||
48 | #include "qabstracttextdocumentlayout.h" | - | ||||||||||||
49 | #include "qtextengine_p.h" | - | ||||||||||||
50 | #include "qdebug.h" | - | ||||||||||||
51 | - | |||||||||||||
52 | #include <algorithm> | - | ||||||||||||
53 | - | |||||||||||||
54 | QT_BEGIN_NAMESPACE | - | ||||||||||||
55 | - | |||||||||||||
56 | // ### DOC: We ought to explain the CONCEPT of objectIndexes if | - | ||||||||||||
57 | // relevant to the public API | - | ||||||||||||
58 | /*! | - | ||||||||||||
59 | \class QTextObject | - | ||||||||||||
60 | \reentrant | - | ||||||||||||
61 | - | |||||||||||||
62 | \brief The QTextObject class is a base class for different kinds | - | ||||||||||||
63 | of objects that can group parts of a QTextDocument together. | - | ||||||||||||
64 | \inmodule QtGui | - | ||||||||||||
65 | - | |||||||||||||
66 | \ingroup richtext-processing | - | ||||||||||||
67 | - | |||||||||||||
68 | The common grouping text objects are lists (QTextList), frames | - | ||||||||||||
69 | (QTextFrame), and tables (QTextTable). A text object has an | - | ||||||||||||
70 | associated format() and document(). | - | ||||||||||||
71 | - | |||||||||||||
72 | There are essentially two kinds of text objects: those that are used | - | ||||||||||||
73 | with blocks (block formats), and those that are used with characters | - | ||||||||||||
74 | (character formats). The first kind are derived from QTextBlockGroup, | - | ||||||||||||
75 | and the second kind from QTextFrame. | - | ||||||||||||
76 | - | |||||||||||||
77 | You rarely need to use this class directly. When creating custom text | - | ||||||||||||
78 | objects, you will also need to reimplement QTextDocument::createObject() | - | ||||||||||||
79 | which acts as a factory method for creating text objects. | - | ||||||||||||
80 | - | |||||||||||||
81 | \sa QTextDocument, {Text Object Example} | - | ||||||||||||
82 | */ | - | ||||||||||||
83 | - | |||||||||||||
84 | /*! | - | ||||||||||||
85 | \fn QTextObject::QTextObject(QTextDocument *document) | - | ||||||||||||
86 | - | |||||||||||||
87 | Creates a new QTextObject for the given \a document. | - | ||||||||||||
88 | - | |||||||||||||
89 | \warning This function should never be called directly, but only | - | ||||||||||||
90 | from QTextDocument::createObject(). | - | ||||||||||||
91 | */ | - | ||||||||||||
92 | QTextObject::QTextObject(QTextDocument *doc) | - | ||||||||||||
93 | : QObject(*new QTextObjectPrivate(doc), doc) | - | ||||||||||||
94 | { | - | ||||||||||||
95 | } never executed: end of block | 0 | ||||||||||||
96 | - | |||||||||||||
97 | /*! | - | ||||||||||||
98 | \fn QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *document) | - | ||||||||||||
99 | - | |||||||||||||
100 | \internal | - | ||||||||||||
101 | */ | - | ||||||||||||
102 | QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc) | - | ||||||||||||
103 | : QObject(p, doc) | - | ||||||||||||
104 | { | - | ||||||||||||
105 | } never executed: end of block | 0 | ||||||||||||
106 | - | |||||||||||||
107 | /*! | - | ||||||||||||
108 | Destroys the text object. | - | ||||||||||||
109 | - | |||||||||||||
110 | \warning Text objects are owned by the document, so you should | - | ||||||||||||
111 | never destroy them yourself. | - | ||||||||||||
112 | */ | - | ||||||||||||
113 | QTextObject::~QTextObject() | - | ||||||||||||
114 | { | - | ||||||||||||
115 | } | - | ||||||||||||
116 | - | |||||||||||||
117 | /*! | - | ||||||||||||
118 | Returns the text object's format. | - | ||||||||||||
119 | - | |||||||||||||
120 | \sa setFormat(), document() | - | ||||||||||||
121 | */ | - | ||||||||||||
122 | QTextFormat QTextObject::format() const | - | ||||||||||||
123 | { | - | ||||||||||||
124 | Q_D(const QTextObject); | - | ||||||||||||
125 | return d->pieceTable->formatCollection()->objectFormat(d->objectIndex); never executed: return d->pieceTable->formatCollection()->objectFormat(d->objectIndex); | 0 | ||||||||||||
126 | } | - | ||||||||||||
127 | - | |||||||||||||
128 | /*! | - | ||||||||||||
129 | Returns the index of the object's format in the document's internal | - | ||||||||||||
130 | list of formats. | - | ||||||||||||
131 | - | |||||||||||||
132 | \sa QTextDocument::allFormats() | - | ||||||||||||
133 | */ | - | ||||||||||||
134 | int QTextObject::formatIndex() const | - | ||||||||||||
135 | { | - | ||||||||||||
136 | Q_D(const QTextObject); | - | ||||||||||||
137 | return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex); never executed: return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex); | 0 | ||||||||||||
138 | } | - | ||||||||||||
139 | - | |||||||||||||
140 | - | |||||||||||||
141 | /*! | - | ||||||||||||
142 | Sets the text object's \a format. | - | ||||||||||||
143 | - | |||||||||||||
144 | \sa format() | - | ||||||||||||
145 | */ | - | ||||||||||||
146 | void QTextObject::setFormat(const QTextFormat &format) | - | ||||||||||||
147 | { | - | ||||||||||||
148 | Q_D(QTextObject); | - | ||||||||||||
149 | int idx = d->pieceTable->formatCollection()->indexForFormat(format); | - | ||||||||||||
150 | d->pieceTable->changeObjectFormat(this, idx); | - | ||||||||||||
151 | } never executed: end of block | 0 | ||||||||||||
152 | - | |||||||||||||
153 | /*! | - | ||||||||||||
154 | Returns the object index of this object. This can be used together with | - | ||||||||||||
155 | QTextFormat::setObjectIndex(). | - | ||||||||||||
156 | */ | - | ||||||||||||
157 | int QTextObject::objectIndex() const | - | ||||||||||||
158 | { | - | ||||||||||||
159 | Q_D(const QTextObject); | - | ||||||||||||
160 | return d->objectIndex; never executed: return d->objectIndex; | 0 | ||||||||||||
161 | } | - | ||||||||||||
162 | - | |||||||||||||
163 | /*! | - | ||||||||||||
164 | Returns the document this object belongs to. | - | ||||||||||||
165 | - | |||||||||||||
166 | \sa format() | - | ||||||||||||
167 | */ | - | ||||||||||||
168 | QTextDocument *QTextObject::document() const | - | ||||||||||||
169 | { | - | ||||||||||||
170 | return static_cast<QTextDocument *>(parent()); never executed: return static_cast<QTextDocument *>(parent()); | 0 | ||||||||||||
171 | } | - | ||||||||||||
172 | - | |||||||||||||
173 | /*! | - | ||||||||||||
174 | \internal | - | ||||||||||||
175 | */ | - | ||||||||||||
176 | QTextDocumentPrivate *QTextObject::docHandle() const | - | ||||||||||||
177 | { | - | ||||||||||||
178 | return static_cast<const QTextDocument *>(parent())->docHandle(); never executed: return static_cast<const QTextDocument *>(parent())->docHandle(); | 0 | ||||||||||||
179 | } | - | ||||||||||||
180 | - | |||||||||||||
181 | /*! | - | ||||||||||||
182 | \class QTextBlockGroup | - | ||||||||||||
183 | \reentrant | - | ||||||||||||
184 | - | |||||||||||||
185 | \brief The QTextBlockGroup class provides a container for text blocks within | - | ||||||||||||
186 | a QTextDocument. | - | ||||||||||||
187 | \inmodule QtGui | - | ||||||||||||
188 | - | |||||||||||||
189 | \ingroup richtext-processing | - | ||||||||||||
190 | - | |||||||||||||
191 | Block groups can be used to organize blocks of text within a document. | - | ||||||||||||
192 | They maintain an up-to-date list of the text blocks that belong to | - | ||||||||||||
193 | them, even when text blocks are being edited. | - | ||||||||||||
194 | - | |||||||||||||
195 | Each group has a parent document which is specified when the group is | - | ||||||||||||
196 | constructed. | - | ||||||||||||
197 | - | |||||||||||||
198 | Text blocks can be inserted into a group with blockInserted(), and removed | - | ||||||||||||
199 | with blockRemoved(). If a block's format is changed, blockFormatChanged() | - | ||||||||||||
200 | is called. | - | ||||||||||||
201 | - | |||||||||||||
202 | The list of blocks in the group is returned by blockList(). Note that the | - | ||||||||||||
203 | blocks in the list are not necessarily adjacent elements in the document; | - | ||||||||||||
204 | for example, the top-level items in a multi-level list will be separated | - | ||||||||||||
205 | by the items in lower levels of the list. | - | ||||||||||||
206 | - | |||||||||||||
207 | \sa QTextBlock, QTextDocument | - | ||||||||||||
208 | */ | - | ||||||||||||
209 | - | |||||||||||||
210 | void QTextBlockGroupPrivate::markBlocksDirty() | - | ||||||||||||
211 | { | - | ||||||||||||
212 | for (int i = 0; i < blocks.count(); ++i) {
| 0 | ||||||||||||
213 | const QTextBlock &block = blocks.at(i); | - | ||||||||||||
214 | pieceTable->documentChange(block.position(), block.length()); | - | ||||||||||||
215 | } never executed: end of block | 0 | ||||||||||||
216 | } never executed: end of block | 0 | ||||||||||||
217 | - | |||||||||||||
218 | /*! | - | ||||||||||||
219 | \fn QTextBlockGroup::QTextBlockGroup(QTextDocument *document) | - | ||||||||||||
220 | - | |||||||||||||
221 | Creates a new new block group for the given \a document. | - | ||||||||||||
222 | - | |||||||||||||
223 | \warning This function should only be called from | - | ||||||||||||
224 | QTextDocument::createObject(). | - | ||||||||||||
225 | */ | - | ||||||||||||
226 | QTextBlockGroup::QTextBlockGroup(QTextDocument *doc) | - | ||||||||||||
227 | : QTextObject(*new QTextBlockGroupPrivate(doc), doc) | - | ||||||||||||
228 | { | - | ||||||||||||
229 | } never executed: end of block | 0 | ||||||||||||
230 | - | |||||||||||||
231 | /*! | - | ||||||||||||
232 | \internal | - | ||||||||||||
233 | */ | - | ||||||||||||
234 | QTextBlockGroup::QTextBlockGroup(QTextBlockGroupPrivate &p, QTextDocument *doc) | - | ||||||||||||
235 | : QTextObject(p, doc) | - | ||||||||||||
236 | { | - | ||||||||||||
237 | } never executed: end of block | 0 | ||||||||||||
238 | - | |||||||||||||
239 | /*! | - | ||||||||||||
240 | Destroys this block group; the blocks are not deleted, they simply | - | ||||||||||||
241 | don't belong to this block anymore. | - | ||||||||||||
242 | */ | - | ||||||||||||
243 | QTextBlockGroup::~QTextBlockGroup() | - | ||||||||||||
244 | { | - | ||||||||||||
245 | } | - | ||||||||||||
246 | - | |||||||||||||
247 | // ### DOC: Shouldn't this be insertBlock()? | - | ||||||||||||
248 | /*! | - | ||||||||||||
249 | Appends the given \a block to the end of the group. | - | ||||||||||||
250 | - | |||||||||||||
251 | \warning If you reimplement this function you must call the base | - | ||||||||||||
252 | class implementation. | - | ||||||||||||
253 | */ | - | ||||||||||||
254 | void QTextBlockGroup::blockInserted(const QTextBlock &block) | - | ||||||||||||
255 | { | - | ||||||||||||
256 | Q_D(QTextBlockGroup); | - | ||||||||||||
257 | QTextBlockGroupPrivate::BlockList::Iterator it = std::lower_bound(d->blocks.begin(), d->blocks.end(), block); | - | ||||||||||||
258 | d->blocks.insert(it, block); | - | ||||||||||||
259 | d->markBlocksDirty(); | - | ||||||||||||
260 | } never executed: end of block | 0 | ||||||||||||
261 | - | |||||||||||||
262 | // ### DOC: Shouldn't this be removeBlock()? | - | ||||||||||||
263 | /*! | - | ||||||||||||
264 | Removes the given \a block from the group; the block itself is not | - | ||||||||||||
265 | deleted, it simply isn't a member of this group anymore. | - | ||||||||||||
266 | */ | - | ||||||||||||
267 | void QTextBlockGroup::blockRemoved(const QTextBlock &block) | - | ||||||||||||
268 | { | - | ||||||||||||
269 | Q_D(QTextBlockGroup); | - | ||||||||||||
270 | d->blocks.removeAll(block); | - | ||||||||||||
271 | d->markBlocksDirty(); | - | ||||||||||||
272 | if (d->blocks.isEmpty()) {
| 0 | ||||||||||||
273 | document()->docHandle()->deleteObject(this); | - | ||||||||||||
274 | return; never executed: return; | 0 | ||||||||||||
275 | } | - | ||||||||||||
276 | } never executed: end of block | 0 | ||||||||||||
277 | - | |||||||||||||
278 | /*! | - | ||||||||||||
279 | This function is called whenever the specified \a block of text is changed. | - | ||||||||||||
280 | The text block is a member of this group. | - | ||||||||||||
281 | - | |||||||||||||
282 | The base class implementation does nothing. | - | ||||||||||||
283 | */ | - | ||||||||||||
284 | void QTextBlockGroup::blockFormatChanged(const QTextBlock &) | - | ||||||||||||
285 | { | - | ||||||||||||
286 | } | - | ||||||||||||
287 | - | |||||||||||||
288 | /*! | - | ||||||||||||
289 | Returns a (possibly empty) list of all the blocks that are part of | - | ||||||||||||
290 | the block group. | - | ||||||||||||
291 | */ | - | ||||||||||||
292 | QList<QTextBlock> QTextBlockGroup::blockList() const | - | ||||||||||||
293 | { | - | ||||||||||||
294 | Q_D(const QTextBlockGroup); | - | ||||||||||||
295 | return d->blocks; never executed: return d->blocks; | 0 | ||||||||||||
296 | } | - | ||||||||||||
297 | - | |||||||||||||
298 | - | |||||||||||||
299 | - | |||||||||||||
300 | QTextFrameLayoutData::~QTextFrameLayoutData() | - | ||||||||||||
301 | { | - | ||||||||||||
302 | } | - | ||||||||||||
303 | - | |||||||||||||
304 | - | |||||||||||||
305 | /*! | - | ||||||||||||
306 | \class QTextFrame | - | ||||||||||||
307 | \reentrant | - | ||||||||||||
308 | - | |||||||||||||
309 | \brief The QTextFrame class represents a frame in a QTextDocument. | - | ||||||||||||
310 | \inmodule QtGui | - | ||||||||||||
311 | - | |||||||||||||
312 | \ingroup richtext-processing | - | ||||||||||||
313 | - | |||||||||||||
314 | Text frames provide structure for the text in a document. They are used | - | ||||||||||||
315 | as generic containers for other document elements. | - | ||||||||||||
316 | Frames are usually created by using QTextCursor::insertFrame(). | - | ||||||||||||
317 | - | |||||||||||||
318 | \omit | - | ||||||||||||
319 | Each frame in a document consists of a frame start character, | - | ||||||||||||
320 | QChar(0xFDD0), followed by the frame's contents, followed by a | - | ||||||||||||
321 | frame end character, QChar(0xFDD1). The character formats of the | - | ||||||||||||
322 | start and end character contain a reference to the frame object's | - | ||||||||||||
323 | objectIndex. | - | ||||||||||||
324 | \endomit | - | ||||||||||||
325 | - | |||||||||||||
326 | Frames can be used to create hierarchical structures in rich text documents. | - | ||||||||||||
327 | Each document has a root frame (QTextDocument::rootFrame()), and each frame | - | ||||||||||||
328 | beneath the root frame has a parent frame and a (possibly empty) list of | - | ||||||||||||
329 | child frames. The parent frame can be found with parentFrame(), and the | - | ||||||||||||
330 | childFrames() function provides a list of child frames. | - | ||||||||||||
331 | - | |||||||||||||
332 | Each frame contains at least one text block to enable text cursors to | - | ||||||||||||
333 | insert new document elements within. As a result, the QTextFrame::iterator | - | ||||||||||||
334 | class is used to traverse both the blocks and child frames within a given | - | ||||||||||||
335 | frame. The first and last child elements in the frame can be found with | - | ||||||||||||
336 | begin() and end(). | - | ||||||||||||
337 | - | |||||||||||||
338 | A frame also has a format (specified using QTextFrameFormat) which can be set | - | ||||||||||||
339 | with setFormat() and read with format(). | - | ||||||||||||
340 | - | |||||||||||||
341 | Text cursors can be obtained that point to the first and last valid cursor | - | ||||||||||||
342 | positions within a frame; use the firstCursorPosition() and | - | ||||||||||||
343 | lastCursorPosition() functions for this. The frame's extent in the | - | ||||||||||||
344 | document can be found with firstPosition() and lastPosition(). | - | ||||||||||||
345 | - | |||||||||||||
346 | You can iterate over a frame's contents using the | - | ||||||||||||
347 | QTextFrame::iterator class: this provides read-only access to its | - | ||||||||||||
348 | internal list of text blocks and child frames. | - | ||||||||||||
349 | - | |||||||||||||
350 | \sa QTextCursor, QTextDocument | - | ||||||||||||
351 | */ | - | ||||||||||||
352 | - | |||||||||||||
353 | /*! | - | ||||||||||||
354 | \typedef QTextFrame::Iterator | - | ||||||||||||
355 | - | |||||||||||||
356 | Qt-style synonym for QTextFrame::iterator. | - | ||||||||||||
357 | */ | - | ||||||||||||
358 | - | |||||||||||||
359 | /*! | - | ||||||||||||
360 | \fn QTextFrame *QTextFrame::iterator::parentFrame() const | - | ||||||||||||
361 | - | |||||||||||||
362 | Returns the parent frame of the current frame. | - | ||||||||||||
363 | - | |||||||||||||
364 | \sa currentFrame(), QTextFrame::parentFrame() | - | ||||||||||||
365 | */ | - | ||||||||||||
366 | - | |||||||||||||
367 | /*! | - | ||||||||||||
368 | \fn bool QTextFrame::iterator::operator==(const iterator &other) const | - | ||||||||||||
369 | - | |||||||||||||
370 | Retuns true if the iterator is the same as the \a other iterator; | - | ||||||||||||
371 | otherwise returns \c false. | - | ||||||||||||
372 | */ | - | ||||||||||||
373 | - | |||||||||||||
374 | /*! | - | ||||||||||||
375 | \fn bool QTextFrame::iterator::operator!=(const iterator &other) const | - | ||||||||||||
376 | - | |||||||||||||
377 | Retuns true if the iterator is different from the \a other iterator; | - | ||||||||||||
378 | otherwise returns \c false. | - | ||||||||||||
379 | */ | - | ||||||||||||
380 | - | |||||||||||||
381 | /*! | - | ||||||||||||
382 | \fn QTextFrame::iterator QTextFrame::iterator::operator++(int) | - | ||||||||||||
383 | - | |||||||||||||
384 | The postfix ++ operator (\c{i++}) advances the iterator to the | - | ||||||||||||
385 | next item in the text frame, and returns an iterator to the old item. | - | ||||||||||||
386 | */ | - | ||||||||||||
387 | - | |||||||||||||
388 | /*! | - | ||||||||||||
389 | \fn QTextFrame::iterator QTextFrame::iterator::operator--(int) | - | ||||||||||||
390 | - | |||||||||||||
391 | The postfix -- operator (\c{i--}) makes the preceding item in the | - | ||||||||||||
392 | current frame, and returns an iterator to the old item. | - | ||||||||||||
393 | */ | - | ||||||||||||
394 | - | |||||||||||||
395 | /*! | - | ||||||||||||
396 | \fn void QTextFrame::setFrameFormat(const QTextFrameFormat &format) | - | ||||||||||||
397 | - | |||||||||||||
398 | Sets the frame's \a format. | - | ||||||||||||
399 | - | |||||||||||||
400 | \sa frameFormat() | - | ||||||||||||
401 | */ | - | ||||||||||||
402 | - | |||||||||||||
403 | /*! | - | ||||||||||||
404 | \fn QTextFrameFormat QTextFrame::frameFormat() const | - | ||||||||||||
405 | - | |||||||||||||
406 | Returns the frame's format. | - | ||||||||||||
407 | - | |||||||||||||
408 | \sa setFrameFormat() | - | ||||||||||||
409 | */ | - | ||||||||||||
410 | - | |||||||||||||
411 | /*! | - | ||||||||||||
412 | \fn QTextFrame::QTextFrame(QTextDocument *document) | - | ||||||||||||
413 | - | |||||||||||||
414 | Creates a new empty frame for the text \a document. | - | ||||||||||||
415 | */ | - | ||||||||||||
416 | QTextFrame::QTextFrame(QTextDocument *doc) | - | ||||||||||||
417 | : QTextObject(*new QTextFramePrivate(doc), doc) | - | ||||||||||||
418 | { | - | ||||||||||||
419 | } never executed: end of block | 0 | ||||||||||||
420 | - | |||||||||||||
421 | /*! | - | ||||||||||||
422 | Destroys the text frame. | - | ||||||||||||
423 | - | |||||||||||||
424 | \warning Text frames are owned by the document, so you should | - | ||||||||||||
425 | never destroy them yourself. In order to remove a frame from | - | ||||||||||||
426 | its document, remove its contents using a \c QTextCursor. | - | ||||||||||||
427 | */ | - | ||||||||||||
428 | QTextFrame::~QTextFrame() | - | ||||||||||||
429 | { | - | ||||||||||||
430 | Q_D(QTextFrame); | - | ||||||||||||
431 | delete d->layoutData; | - | ||||||||||||
432 | } never executed: end of block | 0 | ||||||||||||
433 | - | |||||||||||||
434 | /*! | - | ||||||||||||
435 | \internal | - | ||||||||||||
436 | */ | - | ||||||||||||
437 | QTextFrame::QTextFrame(QTextFramePrivate &p, QTextDocument *doc) | - | ||||||||||||
438 | : QTextObject(p, doc) | - | ||||||||||||
439 | { | - | ||||||||||||
440 | } never executed: end of block | 0 | ||||||||||||
441 | - | |||||||||||||
442 | /*! | - | ||||||||||||
443 | Returns a (possibly empty) list of the frame's child frames. | - | ||||||||||||
444 | - | |||||||||||||
445 | \sa parentFrame() | - | ||||||||||||
446 | */ | - | ||||||||||||
447 | QList<QTextFrame *> QTextFrame::childFrames() const | - | ||||||||||||
448 | { | - | ||||||||||||
449 | Q_D(const QTextFrame); | - | ||||||||||||
450 | return d->childFrames; never executed: return d->childFrames; | 0 | ||||||||||||
451 | } | - | ||||||||||||
452 | - | |||||||||||||
453 | /*! | - | ||||||||||||
454 | Returns the frame's parent frame. If the frame is the root frame of a | - | ||||||||||||
455 | document, this will return 0. | - | ||||||||||||
456 | - | |||||||||||||
457 | \sa childFrames(), QTextDocument::rootFrame() | - | ||||||||||||
458 | */ | - | ||||||||||||
459 | QTextFrame *QTextFrame::parentFrame() const | - | ||||||||||||
460 | { | - | ||||||||||||
461 | Q_D(const QTextFrame); | - | ||||||||||||
462 | return d->parentFrame; never executed: return d->parentFrame; | 0 | ||||||||||||
463 | } | - | ||||||||||||
464 | - | |||||||||||||
465 | - | |||||||||||||
466 | /*! | - | ||||||||||||
467 | Returns the first cursor position inside the frame. | - | ||||||||||||
468 | - | |||||||||||||
469 | \sa lastCursorPosition(), firstPosition(), lastPosition() | - | ||||||||||||
470 | */ | - | ||||||||||||
471 | QTextCursor QTextFrame::firstCursorPosition() const | - | ||||||||||||
472 | { | - | ||||||||||||
473 | Q_D(const QTextFrame); | - | ||||||||||||
474 | return QTextCursorPrivate::fromPosition(d->pieceTable, firstPosition()); never executed: return QTextCursorPrivate::fromPosition(d->pieceTable, firstPosition()); | 0 | ||||||||||||
475 | } | - | ||||||||||||
476 | - | |||||||||||||
477 | /*! | - | ||||||||||||
478 | Returns the last cursor position inside the frame. | - | ||||||||||||
479 | - | |||||||||||||
480 | \sa firstCursorPosition(), firstPosition(), lastPosition() | - | ||||||||||||
481 | */ | - | ||||||||||||
482 | QTextCursor QTextFrame::lastCursorPosition() const | - | ||||||||||||
483 | { | - | ||||||||||||
484 | Q_D(const QTextFrame); | - | ||||||||||||
485 | return QTextCursorPrivate::fromPosition(d->pieceTable, lastPosition()); never executed: return QTextCursorPrivate::fromPosition(d->pieceTable, lastPosition()); | 0 | ||||||||||||
486 | } | - | ||||||||||||
487 | - | |||||||||||||
488 | /*! | - | ||||||||||||
489 | Returns the first document position inside the frame. | - | ||||||||||||
490 | - | |||||||||||||
491 | \sa lastPosition(), firstCursorPosition(), lastCursorPosition() | - | ||||||||||||
492 | */ | - | ||||||||||||
493 | int QTextFrame::firstPosition() const | - | ||||||||||||
494 | { | - | ||||||||||||
495 | Q_D(const QTextFrame); | - | ||||||||||||
496 | if (!d->fragment_start)
| 0 | ||||||||||||
497 | return 0; never executed: return 0; | 0 | ||||||||||||
498 | return d->pieceTable->fragmentMap().position(d->fragment_start) + 1; never executed: return d->pieceTable->fragmentMap().position(d->fragment_start) + 1; | 0 | ||||||||||||
499 | } | - | ||||||||||||
500 | - | |||||||||||||
501 | /*! | - | ||||||||||||
502 | Returns the last document position inside the frame. | - | ||||||||||||
503 | - | |||||||||||||
504 | \sa firstPosition(), firstCursorPosition(), lastCursorPosition() | - | ||||||||||||
505 | */ | - | ||||||||||||
506 | int QTextFrame::lastPosition() const | - | ||||||||||||
507 | { | - | ||||||||||||
508 | Q_D(const QTextFrame); | - | ||||||||||||
509 | if (!d->fragment_end)
| 0 | ||||||||||||
510 | return d->pieceTable->length() - 1; never executed: return d->pieceTable->length() - 1; | 0 | ||||||||||||
511 | return d->pieceTable->fragmentMap().position(d->fragment_end); never executed: return d->pieceTable->fragmentMap().position(d->fragment_end); | 0 | ||||||||||||
512 | } | - | ||||||||||||
513 | - | |||||||||||||
514 | /*! | - | ||||||||||||
515 | \internal | - | ||||||||||||
516 | */ | - | ||||||||||||
517 | QTextFrameLayoutData *QTextFrame::layoutData() const | - | ||||||||||||
518 | { | - | ||||||||||||
519 | Q_D(const QTextFrame); | - | ||||||||||||
520 | return d->layoutData; never executed: return d->layoutData; | 0 | ||||||||||||
521 | } | - | ||||||||||||
522 | - | |||||||||||||
523 | /*! | - | ||||||||||||
524 | \internal | - | ||||||||||||
525 | */ | - | ||||||||||||
526 | void QTextFrame::setLayoutData(QTextFrameLayoutData *data) | - | ||||||||||||
527 | { | - | ||||||||||||
528 | Q_D(QTextFrame); | - | ||||||||||||
529 | delete d->layoutData; | - | ||||||||||||
530 | d->layoutData = data; | - | ||||||||||||
531 | } never executed: end of block | 0 | ||||||||||||
532 | - | |||||||||||||
533 | - | |||||||||||||
534 | - | |||||||||||||
535 | void QTextFramePrivate::fragmentAdded(QChar type, uint fragment) | - | ||||||||||||
536 | { | - | ||||||||||||
537 | if (type == QTextBeginningOfFrame) {
| 0 | ||||||||||||
538 | Q_ASSERT(!fragment_start); | - | ||||||||||||
539 | fragment_start = fragment; | - | ||||||||||||
540 | } else if (type == QTextEndOfFrame) { never executed: end of block
| 0 | ||||||||||||
541 | Q_ASSERT(!fragment_end); | - | ||||||||||||
542 | fragment_end = fragment; | - | ||||||||||||
543 | } else if (type == QChar::ObjectReplacementCharacter) { never executed: end of block
| 0 | ||||||||||||
544 | Q_ASSERT(!fragment_start); | - | ||||||||||||
545 | Q_ASSERT(!fragment_end); | - | ||||||||||||
546 | fragment_start = fragment; | - | ||||||||||||
547 | fragment_end = fragment; | - | ||||||||||||
548 | } else { never executed: end of block | 0 | ||||||||||||
549 | Q_ASSERT(false); | - | ||||||||||||
550 | } never executed: end of block | 0 | ||||||||||||
551 | } | - | ||||||||||||
552 | - | |||||||||||||
553 | void QTextFramePrivate::fragmentRemoved(QChar type, uint fragment) | - | ||||||||||||
554 | { | - | ||||||||||||
555 | Q_UNUSED(fragment); // --release warning | - | ||||||||||||
556 | if (type == QTextBeginningOfFrame) {
| 0 | ||||||||||||
557 | Q_ASSERT(fragment_start == fragment); | - | ||||||||||||
558 | fragment_start = 0; | - | ||||||||||||
559 | } else if (type == QTextEndOfFrame) { never executed: end of block
| 0 | ||||||||||||
560 | Q_ASSERT(fragment_end == fragment); | - | ||||||||||||
561 | fragment_end = 0; | - | ||||||||||||
562 | } else if (type == QChar::ObjectReplacementCharacter) { never executed: end of block
| 0 | ||||||||||||
563 | Q_ASSERT(fragment_start == fragment); | - | ||||||||||||
564 | Q_ASSERT(fragment_end == fragment); | - | ||||||||||||
565 | fragment_start = 0; | - | ||||||||||||
566 | fragment_end = 0; | - | ||||||||||||
567 | } else { never executed: end of block | 0 | ||||||||||||
568 | Q_ASSERT(false); | - | ||||||||||||
569 | } never executed: end of block | 0 | ||||||||||||
570 | remove_me(); | - | ||||||||||||
571 | } never executed: end of block | 0 | ||||||||||||
572 | - | |||||||||||||
573 | - | |||||||||||||
574 | void QTextFramePrivate::remove_me() | - | ||||||||||||
575 | { | - | ||||||||||||
576 | Q_Q(QTextFrame); | - | ||||||||||||
577 | if (fragment_start == 0 && fragment_end == 0
| 0 | ||||||||||||
578 | && !parentFrame) {
| 0 | ||||||||||||
579 | q->document()->docHandle()->deleteObject(q); | - | ||||||||||||
580 | return; never executed: return; | 0 | ||||||||||||
581 | } | - | ||||||||||||
582 | - | |||||||||||||
583 | if (!parentFrame)
| 0 | ||||||||||||
584 | return; never executed: return; | 0 | ||||||||||||
585 | - | |||||||||||||
586 | int index = parentFrame->d_func()->childFrames.indexOf(q); | - | ||||||||||||
587 | - | |||||||||||||
588 | // iterator over all children and move them to the parent | - | ||||||||||||
589 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||
590 | QTextFrame *c = childFrames.at(i); | - | ||||||||||||
591 | parentFrame->d_func()->childFrames.insert(index, c); | - | ||||||||||||
592 | c->d_func()->parentFrame = parentFrame; | - | ||||||||||||
593 | ++index; | - | ||||||||||||
594 | } never executed: end of block | 0 | ||||||||||||
595 | Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q); | - | ||||||||||||
596 | parentFrame->d_func()->childFrames.removeAt(index); | - | ||||||||||||
597 | - | |||||||||||||
598 | childFrames.clear(); | - | ||||||||||||
599 | parentFrame = 0; | - | ||||||||||||
600 | } never executed: end of block | 0 | ||||||||||||
601 | - | |||||||||||||
602 | /*! | - | ||||||||||||
603 | \class QTextFrame::iterator | - | ||||||||||||
604 | \reentrant | - | ||||||||||||
605 | - | |||||||||||||
606 | \brief The iterator class provides an iterator for reading | - | ||||||||||||
607 | the contents of a QTextFrame. | - | ||||||||||||
608 | - | |||||||||||||
609 | \inmodule QtGui | - | ||||||||||||
610 | \ingroup richtext-processing | - | ||||||||||||
611 | - | |||||||||||||
612 | A frame consists of an arbitrary sequence of \l{QTextBlock}s and | - | ||||||||||||
613 | child \l{QTextFrame}s. This class provides a way to iterate over the | - | ||||||||||||
614 | child objects of a frame, and read their contents. It does not provide | - | ||||||||||||
615 | a way to modify the contents of the frame. | - | ||||||||||||
616 | - | |||||||||||||
617 | */ | - | ||||||||||||
618 | - | |||||||||||||
619 | /*! | - | ||||||||||||
620 | \fn bool QTextFrame::iterator::atEnd() const | - | ||||||||||||
621 | - | |||||||||||||
622 | Returns \c true if the current item is the last item in the text frame. | - | ||||||||||||
623 | */ | - | ||||||||||||
624 | - | |||||||||||||
625 | /*! | - | ||||||||||||
626 | Returns an iterator pointing to the first document element inside the frame. | - | ||||||||||||
627 | Please see the document \l{STL-style-Iterators} for more information. | - | ||||||||||||
628 | - | |||||||||||||
629 | \sa end() | - | ||||||||||||
630 | */ | - | ||||||||||||
631 | QTextFrame::iterator QTextFrame::begin() const | - | ||||||||||||
632 | { | - | ||||||||||||
633 | const QTextDocumentPrivate *priv = docHandle(); | - | ||||||||||||
634 | int b = priv->blockMap().findNode(firstPosition()); | - | ||||||||||||
635 | int e = priv->blockMap().findNode(lastPosition()+1); | - | ||||||||||||
636 | return iterator(const_cast<QTextFrame *>(this), b, b, e); never executed: return iterator(const_cast<QTextFrame *>(this), b, b, e); | 0 | ||||||||||||
637 | } | - | ||||||||||||
638 | - | |||||||||||||
639 | /*! | - | ||||||||||||
640 | Returns an iterator pointing to the position past the last document element inside the frame. | - | ||||||||||||
641 | Please see the document \l{STL-Style Iterators} for more information. | - | ||||||||||||
642 | \sa begin() | - | ||||||||||||
643 | */ | - | ||||||||||||
644 | QTextFrame::iterator QTextFrame::end() const | - | ||||||||||||
645 | { | - | ||||||||||||
646 | const QTextDocumentPrivate *priv = docHandle(); | - | ||||||||||||
647 | int b = priv->blockMap().findNode(firstPosition()); | - | ||||||||||||
648 | int e = priv->blockMap().findNode(lastPosition()+1); | - | ||||||||||||
649 | return iterator(const_cast<QTextFrame *>(this), e, b, e); never executed: return iterator(const_cast<QTextFrame *>(this), e, b, e); | 0 | ||||||||||||
650 | } | - | ||||||||||||
651 | - | |||||||||||||
652 | /*! | - | ||||||||||||
653 | Constructs an invalid iterator. | - | ||||||||||||
654 | */ | - | ||||||||||||
655 | QTextFrame::iterator::iterator() | - | ||||||||||||
656 | { | - | ||||||||||||
657 | f = 0; | - | ||||||||||||
658 | b = 0; | - | ||||||||||||
659 | e = 0; | - | ||||||||||||
660 | cf = 0; | - | ||||||||||||
661 | cb = 0; | - | ||||||||||||
662 | } never executed: end of block | 0 | ||||||||||||
663 | - | |||||||||||||
664 | /*! | - | ||||||||||||
665 | \internal | - | ||||||||||||
666 | */ | - | ||||||||||||
667 | QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end) | - | ||||||||||||
668 | { | - | ||||||||||||
669 | f = frame; | - | ||||||||||||
670 | b = begin; | - | ||||||||||||
671 | e = end; | - | ||||||||||||
672 | cf = 0; | - | ||||||||||||
673 | cb = block; | - | ||||||||||||
674 | } never executed: end of block | 0 | ||||||||||||
675 | - | |||||||||||||
676 | #if QT_VERSION < QT_VERSION_CHECK(6,0,0) | - | ||||||||||||
677 | - | |||||||||||||
678 | /*! | - | ||||||||||||
679 | Copy constructor. Constructs a copy of the \a other iterator. | - | ||||||||||||
680 | */ | - | ||||||||||||
681 | QTextFrame::iterator::iterator(const iterator &other) Q_DECL_NOTHROW | - | ||||||||||||
682 | { | - | ||||||||||||
683 | f = other.f; | - | ||||||||||||
684 | b = other.b; | - | ||||||||||||
685 | e = other.e; | - | ||||||||||||
686 | cf = other.cf; | - | ||||||||||||
687 | cb = other.cb; | - | ||||||||||||
688 | } never executed: end of block | 0 | ||||||||||||
689 | - | |||||||||||||
690 | /*! | - | ||||||||||||
691 | Assigns \a other to this iterator and returns a reference to | - | ||||||||||||
692 | this iterator. | - | ||||||||||||
693 | */ | - | ||||||||||||
694 | QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) Q_DECL_NOTHROW | - | ||||||||||||
695 | { | - | ||||||||||||
696 | f = other.f; | - | ||||||||||||
697 | b = other.b; | - | ||||||||||||
698 | e = other.e; | - | ||||||||||||
699 | cf = other.cf; | - | ||||||||||||
700 | cb = other.cb; | - | ||||||||||||
701 | return *this; never executed: return *this; | 0 | ||||||||||||
702 | } | - | ||||||||||||
703 | - | |||||||||||||
704 | #endif | - | ||||||||||||
705 | - | |||||||||||||
706 | /*! | - | ||||||||||||
707 | Returns the current frame pointed to by the iterator, or 0 if the | - | ||||||||||||
708 | iterator currently points to a block. | - | ||||||||||||
709 | - | |||||||||||||
710 | \sa currentBlock() | - | ||||||||||||
711 | */ | - | ||||||||||||
712 | QTextFrame *QTextFrame::iterator::currentFrame() const | - | ||||||||||||
713 | { | - | ||||||||||||
714 | return cf; never executed: return cf; | 0 | ||||||||||||
715 | } | - | ||||||||||||
716 | - | |||||||||||||
717 | /*! | - | ||||||||||||
718 | Returns the current block the iterator points to. If the iterator | - | ||||||||||||
719 | points to a child frame, the returned block is invalid. | - | ||||||||||||
720 | - | |||||||||||||
721 | \sa currentFrame() | - | ||||||||||||
722 | */ | - | ||||||||||||
723 | QTextBlock QTextFrame::iterator::currentBlock() const | - | ||||||||||||
724 | { | - | ||||||||||||
725 | if (!f)
| 0 | ||||||||||||
726 | return QTextBlock(); never executed: return QTextBlock(); | 0 | ||||||||||||
727 | return QTextBlock(f->docHandle(), cb); never executed: return QTextBlock(f->docHandle(), cb); | 0 | ||||||||||||
728 | } | - | ||||||||||||
729 | - | |||||||||||||
730 | /*! | - | ||||||||||||
731 | Moves the iterator to the next frame or block. | - | ||||||||||||
732 | - | |||||||||||||
733 | \sa currentBlock(), currentFrame() | - | ||||||||||||
734 | */ | - | ||||||||||||
735 | QTextFrame::iterator &QTextFrame::iterator::operator++() | - | ||||||||||||
736 | { | - | ||||||||||||
737 | const QTextDocumentPrivate *priv = f->docHandle(); | - | ||||||||||||
738 | const QTextDocumentPrivate::BlockMap &map = priv->blockMap(); | - | ||||||||||||
739 | if (cf) {
| 0 | ||||||||||||
740 | int end = cf->lastPosition() + 1; | - | ||||||||||||
741 | cb = map.findNode(end); | - | ||||||||||||
742 | cf = 0; | - | ||||||||||||
743 | } else if (cb) { never executed: end of block
| 0 | ||||||||||||
744 | cb = map.next(cb); | - | ||||||||||||
745 | if (cb == e)
| 0 | ||||||||||||
746 | return *this; never executed: return *this; | 0 | ||||||||||||
747 | - | |||||||||||||
748 | if (!f->d_func()->childFrames.isEmpty()) {
| 0 | ||||||||||||
749 | int pos = map.position(cb); | - | ||||||||||||
750 | // check if we entered a frame | - | ||||||||||||
751 | QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1); | - | ||||||||||||
752 | if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
| 0 | ||||||||||||
753 | QTextFrame *nf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format)); | - | ||||||||||||
754 | if (nf) {
| 0 | ||||||||||||
755 | if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame && nf != f) {
| 0 | ||||||||||||
756 | cf = nf; | - | ||||||||||||
757 | cb = 0; | - | ||||||||||||
758 | } else { never executed: end of block | 0 | ||||||||||||
759 | Q_ASSERT(priv->buffer().at(frag->stringPosition) != QTextEndOfFrame); | - | ||||||||||||
760 | } never executed: end of block | 0 | ||||||||||||
761 | } | - | ||||||||||||
762 | } never executed: end of block | 0 | ||||||||||||
763 | } never executed: end of block | 0 | ||||||||||||
764 | } never executed: end of block | 0 | ||||||||||||
765 | return *this; never executed: return *this; | 0 | ||||||||||||
766 | } | - | ||||||||||||
767 | - | |||||||||||||
768 | /*! | - | ||||||||||||
769 | Moves the iterator to the previous frame or block. | - | ||||||||||||
770 | - | |||||||||||||
771 | \sa currentBlock(), currentFrame() | - | ||||||||||||
772 | */ | - | ||||||||||||
773 | QTextFrame::iterator &QTextFrame::iterator::operator--() | - | ||||||||||||
774 | { | - | ||||||||||||
775 | const QTextDocumentPrivate *priv = f->docHandle(); | - | ||||||||||||
776 | const QTextDocumentPrivate::BlockMap &map = priv->blockMap(); | - | ||||||||||||
777 | if (cf) {
| 0 | ||||||||||||
778 | int start = cf->firstPosition() - 1; | - | ||||||||||||
779 | cb = map.findNode(start); | - | ||||||||||||
780 | cf = 0; | - | ||||||||||||
781 | } else { never executed: end of block | 0 | ||||||||||||
782 | if (cb == b)
| 0 | ||||||||||||
783 | goto end; never executed: goto end; | 0 | ||||||||||||
784 | if (cb != e) {
| 0 | ||||||||||||
785 | int pos = map.position(cb); | - | ||||||||||||
786 | // check if we have to enter a frame | - | ||||||||||||
787 | QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1); | - | ||||||||||||
788 | if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
| 0 | ||||||||||||
789 | QTextFrame *pf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format)); | - | ||||||||||||
790 | if (pf) {
| 0 | ||||||||||||
791 | if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame) {
| 0 | ||||||||||||
792 | Q_ASSERT(pf == f); | - | ||||||||||||
793 | } else if (priv->buffer().at(frag->stringPosition) == QTextEndOfFrame) { never executed: end of block
| 0 | ||||||||||||
794 | Q_ASSERT(pf != f); | - | ||||||||||||
795 | cf = pf; | - | ||||||||||||
796 | cb = 0; | - | ||||||||||||
797 | goto end; never executed: goto end; | 0 | ||||||||||||
798 | } | - | ||||||||||||
799 | } never executed: end of block | 0 | ||||||||||||
800 | } never executed: end of block | 0 | ||||||||||||
801 | } never executed: end of block | 0 | ||||||||||||
802 | cb = map.previous(cb); | - | ||||||||||||
803 | } never executed: end of block | 0 | ||||||||||||
804 | end: code before this statement never executed: end: | 0 | ||||||||||||
805 | return *this; never executed: return *this; | 0 | ||||||||||||
806 | } | - | ||||||||||||
807 | - | |||||||||||||
808 | /*! | - | ||||||||||||
809 | \class QTextBlockUserData | - | ||||||||||||
810 | \reentrant | - | ||||||||||||
811 | - | |||||||||||||
812 | \brief The QTextBlockUserData class is used to associate custom data with blocks of text. | - | ||||||||||||
813 | \inmodule QtGui | - | ||||||||||||
814 | \since 4.1 | - | ||||||||||||
815 | - | |||||||||||||
816 | \ingroup richtext-processing | - | ||||||||||||
817 | - | |||||||||||||
818 | QTextBlockUserData provides an abstract interface for container classes that are used | - | ||||||||||||
819 | to associate application-specific user data with text blocks in a QTextDocument. | - | ||||||||||||
820 | - | |||||||||||||
821 | Generally, subclasses of this class provide functions to allow data to be stored | - | ||||||||||||
822 | and retrieved, and instances are attached to blocks of text using | - | ||||||||||||
823 | QTextBlock::setUserData(). This makes it possible to store additional data per text | - | ||||||||||||
824 | block in a way that can be retrieved safely by the application. | - | ||||||||||||
825 | - | |||||||||||||
826 | Each subclass should provide a reimplementation of the destructor to ensure that any | - | ||||||||||||
827 | private data is automatically cleaned up when user data objects are deleted. | - | ||||||||||||
828 | - | |||||||||||||
829 | \sa QTextBlock | - | ||||||||||||
830 | */ | - | ||||||||||||
831 | - | |||||||||||||
832 | /*! | - | ||||||||||||
833 | Destroys the user data. | - | ||||||||||||
834 | */ | - | ||||||||||||
835 | QTextBlockUserData::~QTextBlockUserData() | - | ||||||||||||
836 | { | - | ||||||||||||
837 | } | - | ||||||||||||
838 | - | |||||||||||||
839 | /*! | - | ||||||||||||
840 | \class QTextBlock | - | ||||||||||||
841 | \reentrant | - | ||||||||||||
842 | - | |||||||||||||
843 | \brief The QTextBlock class provides a container for text fragments in a | - | ||||||||||||
844 | QTextDocument. | - | ||||||||||||
845 | \inmodule QtGui | - | ||||||||||||
846 | - | |||||||||||||
847 | \ingroup richtext-processing | - | ||||||||||||
848 | - | |||||||||||||
849 | A text block encapsulates a block or paragraph of text in a QTextDocument. | - | ||||||||||||
850 | QTextBlock provides read-only access to the block/paragraph structure of | - | ||||||||||||
851 | QTextDocuments. It is mainly of use if you want to implement your own | - | ||||||||||||
852 | layouts for the visual representation of a QTextDocument, or if you want to | - | ||||||||||||
853 | iterate over a document and write out the contents in your own custom | - | ||||||||||||
854 | format. | - | ||||||||||||
855 | - | |||||||||||||
856 | Text blocks are created by their parent documents. If you need to create | - | ||||||||||||
857 | a new text block, or modify the contents of a document while examining its | - | ||||||||||||
858 | contents, use the cursor-based interface provided by QTextCursor instead. | - | ||||||||||||
859 | - | |||||||||||||
860 | Each text block is located at a specific position() in a document(). | - | ||||||||||||
861 | The contents of the block can be obtained by using the text() function. | - | ||||||||||||
862 | The length() function determines the block's size within the document | - | ||||||||||||
863 | (including formatting characters). | - | ||||||||||||
864 | The visual properties of the block are determined by its text layout(), | - | ||||||||||||
865 | its charFormat(), and its blockFormat(). | - | ||||||||||||
866 | - | |||||||||||||
867 | The next() and previous() functions enable iteration over consecutive | - | ||||||||||||
868 | valid blocks in a document under the condition that the document is not | - | ||||||||||||
869 | modified by other means during the iteration process. Note that, although | - | ||||||||||||
870 | blocks are returned in sequence, adjacent blocks may come from different | - | ||||||||||||
871 | places in the document structure. The validity of a block can be determined | - | ||||||||||||
872 | by calling isValid(). | - | ||||||||||||
873 | - | |||||||||||||
874 | QTextBlock provides comparison operators to make it easier to work with | - | ||||||||||||
875 | blocks: \l operator==() compares two block for equality, \l operator!=() | - | ||||||||||||
876 | compares two blocks for inequality, and \l operator<() determines whether | - | ||||||||||||
877 | a block precedes another in the same document. | - | ||||||||||||
878 | - | |||||||||||||
879 | \image qtextblock-sequence.png | - | ||||||||||||
880 | - | |||||||||||||
881 | \sa QTextBlockFormat, QTextCharFormat, QTextFragment | - | ||||||||||||
882 | */ | - | ||||||||||||
883 | - | |||||||||||||
884 | /*! | - | ||||||||||||
885 | \fn QTextBlock::QTextBlock(QTextDocumentPrivate *priv, int b) | - | ||||||||||||
886 | - | |||||||||||||
887 | \internal | - | ||||||||||||
888 | */ | - | ||||||||||||
889 | - | |||||||||||||
890 | /*! | - | ||||||||||||
891 | \fn QTextBlock::QTextBlock() | - | ||||||||||||
892 | - | |||||||||||||
893 | \internal | - | ||||||||||||
894 | */ | - | ||||||||||||
895 | - | |||||||||||||
896 | /*! | - | ||||||||||||
897 | \fn QTextBlock::QTextBlock(const QTextBlock &other) | - | ||||||||||||
898 | - | |||||||||||||
899 | Copies the \a other text block's attributes to this text block. | - | ||||||||||||
900 | */ | - | ||||||||||||
901 | - | |||||||||||||
902 | /*! | - | ||||||||||||
903 | \fn bool QTextBlock::isValid() const | - | ||||||||||||
904 | - | |||||||||||||
905 | Returns \c true if this text block is valid; otherwise returns \c false. | - | ||||||||||||
906 | */ | - | ||||||||||||
907 | - | |||||||||||||
908 | bool QTextBlock::isValid() const | - | ||||||||||||
909 | { | - | ||||||||||||
910 | return p != 0 && p->blockMap().isValid(n); never executed: return p != 0 && p->blockMap().isValid(n); | 0 | ||||||||||||
911 | } | - | ||||||||||||
912 | - | |||||||||||||
913 | /*! | - | ||||||||||||
914 | \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other) | - | ||||||||||||
915 | - | |||||||||||||
916 | Assigns the \a other text block to this text block. | - | ||||||||||||
917 | */ | - | ||||||||||||
918 | - | |||||||||||||
919 | /*! | - | ||||||||||||
920 | \fn bool QTextBlock::operator==(const QTextBlock &other) const | - | ||||||||||||
921 | - | |||||||||||||
922 | Returns \c true if this text block is the same as the \a other text | - | ||||||||||||
923 | block. | - | ||||||||||||
924 | */ | - | ||||||||||||
925 | - | |||||||||||||
926 | /*! | - | ||||||||||||
927 | \fn bool QTextBlock::operator!=(const QTextBlock &other) const | - | ||||||||||||
928 | - | |||||||||||||
929 | Returns \c true if this text block is different from the \a other | - | ||||||||||||
930 | text block. | - | ||||||||||||
931 | */ | - | ||||||||||||
932 | - | |||||||||||||
933 | /*! | - | ||||||||||||
934 | \fn bool QTextBlock::operator<(const QTextBlock &other) const | - | ||||||||||||
935 | - | |||||||||||||
936 | Returns \c true if this text block occurs before the \a other text | - | ||||||||||||
937 | block in the document. | - | ||||||||||||
938 | */ | - | ||||||||||||
939 | - | |||||||||||||
940 | /*! | - | ||||||||||||
941 | \class QTextBlock::iterator | - | ||||||||||||
942 | \reentrant | - | ||||||||||||
943 | - | |||||||||||||
944 | \brief The QTextBlock::iterator class provides an iterator for reading | - | ||||||||||||
945 | the contents of a QTextBlock. | - | ||||||||||||
946 | \inmodule QtGui | - | ||||||||||||
947 | - | |||||||||||||
948 | \ingroup richtext-processing | - | ||||||||||||
949 | - | |||||||||||||
950 | A block consists of a sequence of text fragments. This class provides | - | ||||||||||||
951 | a way to iterate over these, and read their contents. It does not provide | - | ||||||||||||
952 | a way to modify the internal structure or contents of the block. | - | ||||||||||||
953 | - | |||||||||||||
954 | An iterator can be constructed and used to access the fragments within | - | ||||||||||||
955 | a text block in the following way: | - | ||||||||||||
956 | - | |||||||||||||
957 | \snippet textblock-fragments/xmlwriter.cpp 4 | - | ||||||||||||
958 | \snippet textblock-fragments/xmlwriter.cpp 7 | - | ||||||||||||
959 | - | |||||||||||||
960 | \sa QTextFragment | - | ||||||||||||
961 | */ | - | ||||||||||||
962 | - | |||||||||||||
963 | /*! | - | ||||||||||||
964 | \typedef QTextBlock::Iterator | - | ||||||||||||
965 | - | |||||||||||||
966 | Qt-style synonym for QTextBlock::iterator. | - | ||||||||||||
967 | */ | - | ||||||||||||
968 | - | |||||||||||||
969 | /*! | - | ||||||||||||
970 | \fn QTextBlock::iterator::iterator() | - | ||||||||||||
971 | - | |||||||||||||
972 | Constructs an iterator for this text block. | - | ||||||||||||
973 | */ | - | ||||||||||||
974 | - | |||||||||||||
975 | /*! | - | ||||||||||||
976 | \fn QTextBlock::iterator::iterator(const iterator &other) | - | ||||||||||||
977 | - | |||||||||||||
978 | Copy constructor. Constructs a copy of the \a other iterator. | - | ||||||||||||
979 | */ | - | ||||||||||||
980 | - | |||||||||||||
981 | /*! | - | ||||||||||||
982 | \fn bool QTextBlock::iterator::atEnd() const | - | ||||||||||||
983 | - | |||||||||||||
984 | Returns \c true if the current item is the last item in the text block. | - | ||||||||||||
985 | */ | - | ||||||||||||
986 | - | |||||||||||||
987 | /*! | - | ||||||||||||
988 | \fn bool QTextBlock::iterator::operator==(const iterator &other) const | - | ||||||||||||
989 | - | |||||||||||||
990 | Retuns true if this iterator is the same as the \a other iterator; | - | ||||||||||||
991 | otherwise returns \c false. | - | ||||||||||||
992 | */ | - | ||||||||||||
993 | - | |||||||||||||
994 | /*! | - | ||||||||||||
995 | \fn bool QTextBlock::iterator::operator!=(const iterator &other) const | - | ||||||||||||
996 | - | |||||||||||||
997 | Retuns true if this iterator is different from the \a other iterator; | - | ||||||||||||
998 | otherwise returns \c false. | - | ||||||||||||
999 | */ | - | ||||||||||||
1000 | - | |||||||||||||
1001 | /*! | - | ||||||||||||
1002 | \fn QTextBlock::iterator QTextBlock::iterator::operator++(int) | - | ||||||||||||
1003 | - | |||||||||||||
1004 | The postfix ++ operator (\c{i++}) advances the iterator to the | - | ||||||||||||
1005 | next item in the text block and returns an iterator to the old current | - | ||||||||||||
1006 | item. | - | ||||||||||||
1007 | */ | - | ||||||||||||
1008 | - | |||||||||||||
1009 | /*! | - | ||||||||||||
1010 | \fn QTextBlock::iterator QTextBlock::iterator::operator--(int) | - | ||||||||||||
1011 | - | |||||||||||||
1012 | The postfix -- operator (\c{i--}) makes the preceding item current and | - | ||||||||||||
1013 | returns an iterator to the old current item. | - | ||||||||||||
1014 | */ | - | ||||||||||||
1015 | - | |||||||||||||
1016 | /*! | - | ||||||||||||
1017 | \fn QTextDocumentPrivate *QTextBlock::docHandle() const | - | ||||||||||||
1018 | - | |||||||||||||
1019 | \internal | - | ||||||||||||
1020 | */ | - | ||||||||||||
1021 | - | |||||||||||||
1022 | /*! | - | ||||||||||||
1023 | \fn int QTextBlock::fragmentIndex() const | - | ||||||||||||
1024 | - | |||||||||||||
1025 | \internal | - | ||||||||||||
1026 | */ | - | ||||||||||||
1027 | - | |||||||||||||
1028 | /*! | - | ||||||||||||
1029 | Returns the index of the block's first character within the document. | - | ||||||||||||
1030 | */ | - | ||||||||||||
1031 | int QTextBlock::position() const | - | ||||||||||||
1032 | { | - | ||||||||||||
1033 | if (!p || !n)
| 0 | ||||||||||||
1034 | return 0; never executed: return 0; | 0 | ||||||||||||
1035 | - | |||||||||||||
1036 | return p->blockMap().position(n); never executed: return p->blockMap().position(n); | 0 | ||||||||||||
1037 | } | - | ||||||||||||
1038 | - | |||||||||||||
1039 | /*! | - | ||||||||||||
1040 | Returns the length of the block in characters. | - | ||||||||||||
1041 | - | |||||||||||||
1042 | \note The length returned includes all formatting characters, | - | ||||||||||||
1043 | for example, newline. | - | ||||||||||||
1044 | - | |||||||||||||
1045 | \sa text(), charFormat(), blockFormat() | - | ||||||||||||
1046 | */ | - | ||||||||||||
1047 | int QTextBlock::length() const | - | ||||||||||||
1048 | { | - | ||||||||||||
1049 | if (!p || !n)
| 0 | ||||||||||||
1050 | return 0; never executed: return 0; | 0 | ||||||||||||
1051 | - | |||||||||||||
1052 | return p->blockMap().size(n); never executed: return p->blockMap().size(n); | 0 | ||||||||||||
1053 | } | - | ||||||||||||
1054 | - | |||||||||||||
1055 | /*! | - | ||||||||||||
1056 | Returns \c true if the given \a position is located within the text | - | ||||||||||||
1057 | block; otherwise returns \c false. | - | ||||||||||||
1058 | */ | - | ||||||||||||
1059 | bool QTextBlock::contains(int position) const | - | ||||||||||||
1060 | { | - | ||||||||||||
1061 | if (!p || !n)
| 0 | ||||||||||||
1062 | return false; never executed: return false; | 0 | ||||||||||||
1063 | - | |||||||||||||
1064 | int pos = p->blockMap().position(n); | - | ||||||||||||
1065 | int len = p->blockMap().size(n); | - | ||||||||||||
1066 | return position >= pos && position < pos + len; never executed: return position >= pos && position < pos + len; | 0 | ||||||||||||
1067 | } | - | ||||||||||||
1068 | - | |||||||||||||
1069 | /*! | - | ||||||||||||
1070 | Returns the QTextLayout that is used to lay out and display the | - | ||||||||||||
1071 | block's contents. | - | ||||||||||||
1072 | - | |||||||||||||
1073 | Note that the returned QTextLayout object can only be modified from the | - | ||||||||||||
1074 | documentChanged implementation of a QAbstractTextDocumentLayout subclass. | - | ||||||||||||
1075 | Any changes applied from the outside cause undefined behavior. | - | ||||||||||||
1076 | - | |||||||||||||
1077 | \sa clearLayout() | - | ||||||||||||
1078 | */ | - | ||||||||||||
1079 | QTextLayout *QTextBlock::layout() const | - | ||||||||||||
1080 | { | - | ||||||||||||
1081 | if (!p || !n)
| 0 | ||||||||||||
1082 | return 0; never executed: return 0; | 0 | ||||||||||||
1083 | - | |||||||||||||
1084 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1085 | if (!b->layout)
| 0 | ||||||||||||
1086 | b->layout = new QTextLayout(*this); never executed: b->layout = new QTextLayout(*this); | 0 | ||||||||||||
1087 | return b->layout; never executed: return b->layout; | 0 | ||||||||||||
1088 | } | - | ||||||||||||
1089 | - | |||||||||||||
1090 | /*! | - | ||||||||||||
1091 | \since 4.4 | - | ||||||||||||
1092 | Clears the QTextLayout that is used to lay out and display the | - | ||||||||||||
1093 | block's contents. | - | ||||||||||||
1094 | - | |||||||||||||
1095 | \sa layout() | - | ||||||||||||
1096 | */ | - | ||||||||||||
1097 | void QTextBlock::clearLayout() | - | ||||||||||||
1098 | { | - | ||||||||||||
1099 | if (!p || !n)
| 0 | ||||||||||||
1100 | return; never executed: return; | 0 | ||||||||||||
1101 | - | |||||||||||||
1102 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1103 | if (b->layout)
| 0 | ||||||||||||
1104 | b->layout->clearLayout(); never executed: b->layout->clearLayout(); | 0 | ||||||||||||
1105 | } never executed: end of block | 0 | ||||||||||||
1106 | - | |||||||||||||
1107 | /*! | - | ||||||||||||
1108 | Returns the QTextBlockFormat that describes block-specific properties. | - | ||||||||||||
1109 | - | |||||||||||||
1110 | \sa charFormat() | - | ||||||||||||
1111 | */ | - | ||||||||||||
1112 | QTextBlockFormat QTextBlock::blockFormat() const | - | ||||||||||||
1113 | { | - | ||||||||||||
1114 | if (!p || !n)
| 0 | ||||||||||||
1115 | return QTextFormat().toBlockFormat(); never executed: return QTextFormat().toBlockFormat(); | 0 | ||||||||||||
1116 | - | |||||||||||||
1117 | return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format); never executed: return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format); | 0 | ||||||||||||
1118 | } | - | ||||||||||||
1119 | - | |||||||||||||
1120 | /*! | - | ||||||||||||
1121 | Returns an index into the document's internal list of block formats | - | ||||||||||||
1122 | for the text block's format. | - | ||||||||||||
1123 | - | |||||||||||||
1124 | \sa QTextDocument::allFormats() | - | ||||||||||||
1125 | */ | - | ||||||||||||
1126 | int QTextBlock::blockFormatIndex() const | - | ||||||||||||
1127 | { | - | ||||||||||||
1128 | if (!p || !n)
| 0 | ||||||||||||
1129 | return -1; never executed: return -1; | 0 | ||||||||||||
1130 | - | |||||||||||||
1131 | return p->blockMap().fragment(n)->format; never executed: return p->blockMap().fragment(n)->format; | 0 | ||||||||||||
1132 | } | - | ||||||||||||
1133 | - | |||||||||||||
1134 | /*! | - | ||||||||||||
1135 | Returns the QTextCharFormat that describes the block's character | - | ||||||||||||
1136 | format. The block's character format is used when inserting text into | - | ||||||||||||
1137 | an empty block. | - | ||||||||||||
1138 | - | |||||||||||||
1139 | \sa blockFormat() | - | ||||||||||||
1140 | */ | - | ||||||||||||
1141 | QTextCharFormat QTextBlock::charFormat() const | - | ||||||||||||
1142 | { | - | ||||||||||||
1143 | if (!p || !n)
| 0 | ||||||||||||
1144 | return QTextFormat().toCharFormat(); never executed: return QTextFormat().toCharFormat(); | 0 | ||||||||||||
1145 | - | |||||||||||||
1146 | return p->formatCollection()->charFormat(charFormatIndex()); never executed: return p->formatCollection()->charFormat(charFormatIndex()); | 0 | ||||||||||||
1147 | } | - | ||||||||||||
1148 | - | |||||||||||||
1149 | /*! | - | ||||||||||||
1150 | Returns an index into the document's internal list of character formats | - | ||||||||||||
1151 | for the text block's character format. | - | ||||||||||||
1152 | - | |||||||||||||
1153 | \sa QTextDocument::allFormats() | - | ||||||||||||
1154 | */ | - | ||||||||||||
1155 | int QTextBlock::charFormatIndex() const | - | ||||||||||||
1156 | { | - | ||||||||||||
1157 | if (!p || !n)
| 0 | ||||||||||||
1158 | return -1; never executed: return -1; | 0 | ||||||||||||
1159 | - | |||||||||||||
1160 | return p->blockCharFormatIndex(n); never executed: return p->blockCharFormatIndex(n); | 0 | ||||||||||||
1161 | } | - | ||||||||||||
1162 | - | |||||||||||||
1163 | /*! | - | ||||||||||||
1164 | \since 4.7 | - | ||||||||||||
1165 | - | |||||||||||||
1166 | Returns the resolved text direction. | - | ||||||||||||
1167 | - | |||||||||||||
1168 | If the block has no explicit direction set, it will resolve the | - | ||||||||||||
1169 | direction from the blocks content. Returns either Qt::LeftToRight | - | ||||||||||||
1170 | or Qt::RightToLeft. | - | ||||||||||||
1171 | - | |||||||||||||
1172 | \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection | - | ||||||||||||
1173 | */ | - | ||||||||||||
1174 | Qt::LayoutDirection QTextBlock::textDirection() const | - | ||||||||||||
1175 | { | - | ||||||||||||
1176 | Qt::LayoutDirection dir = blockFormat().layoutDirection(); | - | ||||||||||||
1177 | if (dir != Qt::LayoutDirectionAuto)
| 0 | ||||||||||||
1178 | return dir; never executed: return dir; | 0 | ||||||||||||
1179 | - | |||||||||||||
1180 | dir = p->defaultTextOption.textDirection(); | - | ||||||||||||
1181 | if (dir != Qt::LayoutDirectionAuto)
| 0 | ||||||||||||
1182 | return dir; never executed: return dir; | 0 | ||||||||||||
1183 | - | |||||||||||||
1184 | const QString buffer = p->buffer(); | - | ||||||||||||
1185 | - | |||||||||||||
1186 | const int pos = position(); | - | ||||||||||||
1187 | QTextDocumentPrivate::FragmentIterator it = p->find(pos); | - | ||||||||||||
1188 | QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char | - | ||||||||||||
1189 | for (; it != end; ++it) {
| 0 | ||||||||||||
1190 | const QTextFragmentData * const frag = it.value(); | - | ||||||||||||
1191 | const QChar *p = buffer.constData() + frag->stringPosition; | - | ||||||||||||
1192 | const QChar * const end = p + frag->size_array[0]; | - | ||||||||||||
1193 | while (p < end) {
| 0 | ||||||||||||
1194 | uint ucs4 = p->unicode(); | - | ||||||||||||
1195 | if (QChar::isHighSurrogate(ucs4) && p + 1 < end) {
| 0 | ||||||||||||
1196 | ushort low = p[1].unicode(); | - | ||||||||||||
1197 | if (QChar::isLowSurrogate(low)) {
| 0 | ||||||||||||
1198 | ucs4 = QChar::surrogateToUcs4(ucs4, low); | - | ||||||||||||
1199 | ++p; | - | ||||||||||||
1200 | } never executed: end of block | 0 | ||||||||||||
1201 | } never executed: end of block | 0 | ||||||||||||
1202 | switch (QChar::direction(ucs4)) { | - | ||||||||||||
1203 | case QChar::DirL: never executed: case QChar::DirL: | 0 | ||||||||||||
1204 | return Qt::LeftToRight; never executed: return Qt::LeftToRight; | 0 | ||||||||||||
1205 | case QChar::DirR: never executed: case QChar::DirR: | 0 | ||||||||||||
1206 | case QChar::DirAL: never executed: case QChar::DirAL: | 0 | ||||||||||||
1207 | return Qt::RightToLeft; never executed: return Qt::RightToLeft; | 0 | ||||||||||||
1208 | default: never executed: default: | 0 | ||||||||||||
1209 | break; never executed: break; | 0 | ||||||||||||
1210 | } | - | ||||||||||||
1211 | ++p; | - | ||||||||||||
1212 | } never executed: end of block | 0 | ||||||||||||
1213 | } never executed: end of block | 0 | ||||||||||||
1214 | return Qt::LeftToRight; never executed: return Qt::LeftToRight; | 0 | ||||||||||||
1215 | } | - | ||||||||||||
1216 | - | |||||||||||||
1217 | /*! | - | ||||||||||||
1218 | Returns the block's contents as plain text. | - | ||||||||||||
1219 | - | |||||||||||||
1220 | \sa length(), charFormat(), blockFormat() | - | ||||||||||||
1221 | */ | - | ||||||||||||
1222 | QString QTextBlock::text() const | - | ||||||||||||
1223 | { | - | ||||||||||||
1224 | if (!p || !n)
| 0 | ||||||||||||
1225 | return QString(); never executed: return QString(); | 0 | ||||||||||||
1226 | - | |||||||||||||
1227 | const QString buffer = p->buffer(); | - | ||||||||||||
1228 | QString text; | - | ||||||||||||
1229 | text.reserve(length()); | - | ||||||||||||
1230 | - | |||||||||||||
1231 | const int pos = position(); | - | ||||||||||||
1232 | QTextDocumentPrivate::FragmentIterator it = p->find(pos); | - | ||||||||||||
1233 | QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char | - | ||||||||||||
1234 | for (; it != end; ++it) {
| 0 | ||||||||||||
1235 | const QTextFragmentData * const frag = it.value(); | - | ||||||||||||
1236 | text += QString::fromRawData(buffer.constData() + frag->stringPosition, frag->size_array[0]); | - | ||||||||||||
1237 | } never executed: end of block | 0 | ||||||||||||
1238 | - | |||||||||||||
1239 | return text; never executed: return text; | 0 | ||||||||||||
1240 | } | - | ||||||||||||
1241 | - | |||||||||||||
1242 | /*! | - | ||||||||||||
1243 | \since 5.3 | - | ||||||||||||
1244 | - | |||||||||||||
1245 | Returns the block's text format options as a list of continuous ranges | - | ||||||||||||
1246 | of QTextCharFormat. The range's character format is used when inserting text | - | ||||||||||||
1247 | within the range boundaries. | - | ||||||||||||
1248 | - | |||||||||||||
1249 | \sa charFormat(), blockFormat() | - | ||||||||||||
1250 | */ | - | ||||||||||||
1251 | QVector<QTextLayout::FormatRange> QTextBlock::textFormats() const | - | ||||||||||||
1252 | { | - | ||||||||||||
1253 | QVector<QTextLayout::FormatRange> formats; | - | ||||||||||||
1254 | if (!p || !n)
| 0 | ||||||||||||
1255 | return formats; never executed: return formats; | 0 | ||||||||||||
1256 | - | |||||||||||||
1257 | const QTextFormatCollection *formatCollection = p->formatCollection(); | - | ||||||||||||
1258 | - | |||||||||||||
1259 | int start = 0; | - | ||||||||||||
1260 | int cur = start; | - | ||||||||||||
1261 | int format = -1; | - | ||||||||||||
1262 | - | |||||||||||||
1263 | const int pos = position(); | - | ||||||||||||
1264 | QTextDocumentPrivate::FragmentIterator it = p->find(pos); | - | ||||||||||||
1265 | QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char | - | ||||||||||||
1266 | for (; it != end; ++it) {
| 0 | ||||||||||||
1267 | const QTextFragmentData * const frag = it.value(); | - | ||||||||||||
1268 | if (format != it.value()->format) {
| 0 | ||||||||||||
1269 | if (cur - start > 0) {
| 0 | ||||||||||||
1270 | QTextLayout::FormatRange range; | - | ||||||||||||
1271 | range.start = start; | - | ||||||||||||
1272 | range.length = cur - start; | - | ||||||||||||
1273 | range.format = formatCollection->charFormat(format); | - | ||||||||||||
1274 | formats.append(range); | - | ||||||||||||
1275 | } never executed: end of block | 0 | ||||||||||||
1276 | - | |||||||||||||
1277 | format = frag->format; | - | ||||||||||||
1278 | start = cur; | - | ||||||||||||
1279 | } never executed: end of block | 0 | ||||||||||||
1280 | cur += frag->size_array[0]; | - | ||||||||||||
1281 | } never executed: end of block | 0 | ||||||||||||
1282 | if (cur - start > 0) {
| 0 | ||||||||||||
1283 | QTextLayout::FormatRange range; | - | ||||||||||||
1284 | range.start = start; | - | ||||||||||||
1285 | range.length = cur - start; | - | ||||||||||||
1286 | range.format = formatCollection->charFormat(format); | - | ||||||||||||
1287 | formats.append(range); | - | ||||||||||||
1288 | } never executed: end of block | 0 | ||||||||||||
1289 | - | |||||||||||||
1290 | return formats; never executed: return formats; | 0 | ||||||||||||
1291 | } | - | ||||||||||||
1292 | - | |||||||||||||
1293 | /*! | - | ||||||||||||
1294 | Returns the text document this text block belongs to, or 0 if the | - | ||||||||||||
1295 | text block does not belong to any document. | - | ||||||||||||
1296 | */ | - | ||||||||||||
1297 | const QTextDocument *QTextBlock::document() const | - | ||||||||||||
1298 | { | - | ||||||||||||
1299 | return p ? p->document() : 0; never executed: return p ? p->document() : 0; | 0 | ||||||||||||
1300 | } | - | ||||||||||||
1301 | - | |||||||||||||
1302 | /*! | - | ||||||||||||
1303 | If the block represents a list item, returns the list that the item belongs | - | ||||||||||||
1304 | to; otherwise returns 0. | - | ||||||||||||
1305 | */ | - | ||||||||||||
1306 | QTextList *QTextBlock::textList() const | - | ||||||||||||
1307 | { | - | ||||||||||||
1308 | if (!isValid())
| 0 | ||||||||||||
1309 | return 0; never executed: return 0; | 0 | ||||||||||||
1310 | - | |||||||||||||
1311 | const QTextBlockFormat fmt = blockFormat(); | - | ||||||||||||
1312 | QTextObject *obj = p->document()->objectForFormat(fmt); | - | ||||||||||||
1313 | return qobject_cast<QTextList *>(obj); never executed: return qobject_cast<QTextList *>(obj); | 0 | ||||||||||||
1314 | } | - | ||||||||||||
1315 | - | |||||||||||||
1316 | /*! | - | ||||||||||||
1317 | \since 4.1 | - | ||||||||||||
1318 | - | |||||||||||||
1319 | Returns a pointer to a QTextBlockUserData object if previously set with | - | ||||||||||||
1320 | setUserData() or a null pointer. | - | ||||||||||||
1321 | */ | - | ||||||||||||
1322 | QTextBlockUserData *QTextBlock::userData() const | - | ||||||||||||
1323 | { | - | ||||||||||||
1324 | if (!p || !n)
| 0 | ||||||||||||
1325 | return 0; never executed: return 0; | 0 | ||||||||||||
1326 | - | |||||||||||||
1327 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1328 | return b->userData; never executed: return b->userData; | 0 | ||||||||||||
1329 | } | - | ||||||||||||
1330 | - | |||||||||||||
1331 | /*! | - | ||||||||||||
1332 | \since 4.1 | - | ||||||||||||
1333 | - | |||||||||||||
1334 | Attaches the given \a data object to the text block. | - | ||||||||||||
1335 | - | |||||||||||||
1336 | QTextBlockUserData can be used to store custom settings. The | - | ||||||||||||
1337 | ownership is passed to the underlying text document, i.e. the | - | ||||||||||||
1338 | provided QTextBlockUserData object will be deleted if the | - | ||||||||||||
1339 | corresponding text block gets deleted. The user data object is | - | ||||||||||||
1340 | not stored in the undo history, so it will not be available after | - | ||||||||||||
1341 | undoing the deletion of a text block. | - | ||||||||||||
1342 | - | |||||||||||||
1343 | For example, if you write a programming editor in an IDE, you may | - | ||||||||||||
1344 | want to let your user set breakpoints visually in your code for an | - | ||||||||||||
1345 | integrated debugger. In a programming editor a line of text | - | ||||||||||||
1346 | usually corresponds to one QTextBlock. The QTextBlockUserData | - | ||||||||||||
1347 | interface allows the developer to store data for each QTextBlock, | - | ||||||||||||
1348 | like for example in which lines of the source code the user has a | - | ||||||||||||
1349 | breakpoint set. Of course this could also be stored externally, | - | ||||||||||||
1350 | but by storing it inside the QTextDocument, it will for example be | - | ||||||||||||
1351 | automatically deleted when the user deletes the associated | - | ||||||||||||
1352 | line. It's really just a way to store custom information in the | - | ||||||||||||
1353 | QTextDocument without using custom properties in QTextFormat which | - | ||||||||||||
1354 | would affect the undo/redo stack. | - | ||||||||||||
1355 | */ | - | ||||||||||||
1356 | void QTextBlock::setUserData(QTextBlockUserData *data) | - | ||||||||||||
1357 | { | - | ||||||||||||
1358 | if (!p || !n)
| 0 | ||||||||||||
1359 | return; never executed: return; | 0 | ||||||||||||
1360 | - | |||||||||||||
1361 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1362 | if (data != b->userData)
| 0 | ||||||||||||
1363 | delete b->userData; never executed: delete b->userData; | 0 | ||||||||||||
1364 | b->userData = data; | - | ||||||||||||
1365 | } never executed: end of block | 0 | ||||||||||||
1366 | - | |||||||||||||
1367 | /*! | - | ||||||||||||
1368 | \since 4.1 | - | ||||||||||||
1369 | - | |||||||||||||
1370 | Returns the integer value previously set with setUserState() or -1. | - | ||||||||||||
1371 | */ | - | ||||||||||||
1372 | int QTextBlock::userState() const | - | ||||||||||||
1373 | { | - | ||||||||||||
1374 | if (!p || !n)
| 0 | ||||||||||||
1375 | return -1; never executed: return -1; | 0 | ||||||||||||
1376 | - | |||||||||||||
1377 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1378 | return b->userState; never executed: return b->userState; | 0 | ||||||||||||
1379 | } | - | ||||||||||||
1380 | - | |||||||||||||
1381 | /*! | - | ||||||||||||
1382 | \since 4.1 | - | ||||||||||||
1383 | - | |||||||||||||
1384 | Stores the specified \a state integer value in the text block. This may be | - | ||||||||||||
1385 | useful for example in a syntax highlighter to store a text parsing state. | - | ||||||||||||
1386 | */ | - | ||||||||||||
1387 | void QTextBlock::setUserState(int state) | - | ||||||||||||
1388 | { | - | ||||||||||||
1389 | if (!p || !n)
| 0 | ||||||||||||
1390 | return; never executed: return; | 0 | ||||||||||||
1391 | - | |||||||||||||
1392 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1393 | b->userState = state; | - | ||||||||||||
1394 | } never executed: end of block | 0 | ||||||||||||
1395 | - | |||||||||||||
1396 | /*! | - | ||||||||||||
1397 | \since 4.4 | - | ||||||||||||
1398 | - | |||||||||||||
1399 | Returns the blocks revision. | - | ||||||||||||
1400 | - | |||||||||||||
1401 | \sa setRevision(), QTextDocument::revision() | - | ||||||||||||
1402 | */ | - | ||||||||||||
1403 | int QTextBlock::revision() const | - | ||||||||||||
1404 | { | - | ||||||||||||
1405 | if (!p || !n)
| 0 | ||||||||||||
1406 | return -1; never executed: return -1; | 0 | ||||||||||||
1407 | - | |||||||||||||
1408 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1409 | return b->revision; never executed: return b->revision; | 0 | ||||||||||||
1410 | } | - | ||||||||||||
1411 | - | |||||||||||||
1412 | /*! | - | ||||||||||||
1413 | \since 4.4 | - | ||||||||||||
1414 | - | |||||||||||||
1415 | Sets a blocks revision to \a rev. | - | ||||||||||||
1416 | - | |||||||||||||
1417 | \sa revision(), QTextDocument::revision() | - | ||||||||||||
1418 | */ | - | ||||||||||||
1419 | void QTextBlock::setRevision(int rev) | - | ||||||||||||
1420 | { | - | ||||||||||||
1421 | if (!p || !n)
| 0 | ||||||||||||
1422 | return; never executed: return; | 0 | ||||||||||||
1423 | - | |||||||||||||
1424 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1425 | b->revision = rev; | - | ||||||||||||
1426 | } never executed: end of block | 0 | ||||||||||||
1427 | - | |||||||||||||
1428 | /*! | - | ||||||||||||
1429 | \since 4.4 | - | ||||||||||||
1430 | - | |||||||||||||
1431 | Returns \c true if the block is visible; otherwise returns \c false. | - | ||||||||||||
1432 | - | |||||||||||||
1433 | \sa setVisible() | - | ||||||||||||
1434 | */ | - | ||||||||||||
1435 | bool QTextBlock::isVisible() const | - | ||||||||||||
1436 | { | - | ||||||||||||
1437 | if (!p || !n)
| 0 | ||||||||||||
1438 | return true; never executed: return true; | 0 | ||||||||||||
1439 | - | |||||||||||||
1440 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1441 | return !b->hidden; never executed: return !b->hidden; | 0 | ||||||||||||
1442 | } | - | ||||||||||||
1443 | - | |||||||||||||
1444 | /*! | - | ||||||||||||
1445 | \since 4.4 | - | ||||||||||||
1446 | - | |||||||||||||
1447 | Sets the block's visibility to \a visible. | - | ||||||||||||
1448 | - | |||||||||||||
1449 | \sa isVisible() | - | ||||||||||||
1450 | */ | - | ||||||||||||
1451 | void QTextBlock::setVisible(bool visible) | - | ||||||||||||
1452 | { | - | ||||||||||||
1453 | if (!p || !n)
| 0 | ||||||||||||
1454 | return; never executed: return; | 0 | ||||||||||||
1455 | - | |||||||||||||
1456 | const QTextBlockData *b = p->blockMap().fragment(n); | - | ||||||||||||
1457 | b->hidden = !visible; | - | ||||||||||||
1458 | } never executed: end of block | 0 | ||||||||||||
1459 | - | |||||||||||||
1460 | - | |||||||||||||
1461 | /*! | - | ||||||||||||
1462 | \since 4.4 | - | ||||||||||||
1463 | - | |||||||||||||
1464 | Returns the number of this block, or -1 if the block is invalid. | - | ||||||||||||
1465 | - | |||||||||||||
1466 | \sa QTextCursor::blockNumber() | - | ||||||||||||
1467 | - | |||||||||||||
1468 | */ | - | ||||||||||||
1469 | int QTextBlock::blockNumber() const | - | ||||||||||||
1470 | { | - | ||||||||||||
1471 | if (!p || !n)
| 0 | ||||||||||||
1472 | return -1; never executed: return -1; | 0 | ||||||||||||
1473 | return p->blockMap().position(n, 1); never executed: return p->blockMap().position(n, 1); | 0 | ||||||||||||
1474 | } | - | ||||||||||||
1475 | - | |||||||||||||
1476 | /*! | - | ||||||||||||
1477 | \since 4.5 | - | ||||||||||||
1478 | - | |||||||||||||
1479 | Returns the first line number of this block, or -1 if the block is invalid. | - | ||||||||||||
1480 | Unless the layout supports it, the line number is identical to the block number. | - | ||||||||||||
1481 | - | |||||||||||||
1482 | \sa QTextBlock::blockNumber() | - | ||||||||||||
1483 | - | |||||||||||||
1484 | */ | - | ||||||||||||
1485 | int QTextBlock::firstLineNumber() const | - | ||||||||||||
1486 | { | - | ||||||||||||
1487 | if (!p || !n)
| 0 | ||||||||||||
1488 | return -1; never executed: return -1; | 0 | ||||||||||||
1489 | return p->blockMap().position(n, 2); never executed: return p->blockMap().position(n, 2); | 0 | ||||||||||||
1490 | } | - | ||||||||||||
1491 | - | |||||||||||||
1492 | - | |||||||||||||
1493 | /*! | - | ||||||||||||
1494 | \since 4.5 | - | ||||||||||||
1495 | - | |||||||||||||
1496 | Sets the line count to \a count. | - | ||||||||||||
1497 | - | |||||||||||||
1498 | \sa lineCount() | - | ||||||||||||
1499 | */ | - | ||||||||||||
1500 | void QTextBlock::setLineCount(int count) | - | ||||||||||||
1501 | { | - | ||||||||||||
1502 | if (!p || !n)
| 0 | ||||||||||||
1503 | return; never executed: return; | 0 | ||||||||||||
1504 | p->blockMap().setSize(n, count, 2); | - | ||||||||||||
1505 | } never executed: end of block | 0 | ||||||||||||
1506 | /*! | - | ||||||||||||
1507 | \since 4.5 | - | ||||||||||||
1508 | - | |||||||||||||
1509 | Returns the line count. Not all document layouts support this feature. | - | ||||||||||||
1510 | - | |||||||||||||
1511 | \sa setLineCount() | - | ||||||||||||
1512 | */ | - | ||||||||||||
1513 | int QTextBlock::lineCount() const | - | ||||||||||||
1514 | { | - | ||||||||||||
1515 | if (!p || !n)
| 0 | ||||||||||||
1516 | return -1; never executed: return -1; | 0 | ||||||||||||
1517 | return p->blockMap().size(n, 2); never executed: return p->blockMap().size(n, 2); | 0 | ||||||||||||
1518 | } | - | ||||||||||||
1519 | - | |||||||||||||
1520 | - | |||||||||||||
1521 | /*! | - | ||||||||||||
1522 | Returns a text block iterator pointing to the beginning of the | - | ||||||||||||
1523 | text block. | - | ||||||||||||
1524 | - | |||||||||||||
1525 | \sa end() | - | ||||||||||||
1526 | */ | - | ||||||||||||
1527 | QTextBlock::iterator QTextBlock::begin() const | - | ||||||||||||
1528 | { | - | ||||||||||||
1529 | if (!p || !n)
| 0 | ||||||||||||
1530 | return iterator(); never executed: return iterator(); | 0 | ||||||||||||
1531 | - | |||||||||||||
1532 | int pos = position(); | - | ||||||||||||
1533 | int len = length() - 1; // exclude the fragment that holds the paragraph separator | - | ||||||||||||
1534 | int b = p->fragmentMap().findNode(pos); | - | ||||||||||||
1535 | int e = p->fragmentMap().findNode(pos+len); | - | ||||||||||||
1536 | return iterator(p, b, e, b); never executed: return iterator(p, b, e, b); | 0 | ||||||||||||
1537 | } | - | ||||||||||||
1538 | - | |||||||||||||
1539 | /*! | - | ||||||||||||
1540 | Returns a text block iterator pointing to the end of the text | - | ||||||||||||
1541 | block. | - | ||||||||||||
1542 | - | |||||||||||||
1543 | \sa begin(), next(), previous() | - | ||||||||||||
1544 | */ | - | ||||||||||||
1545 | QTextBlock::iterator QTextBlock::end() const | - | ||||||||||||
1546 | { | - | ||||||||||||
1547 | if (!p || !n)
| 0 | ||||||||||||
1548 | return iterator(); never executed: return iterator(); | 0 | ||||||||||||
1549 | - | |||||||||||||
1550 | int pos = position(); | - | ||||||||||||
1551 | int len = length() - 1; // exclude the fragment that holds the paragraph separator | - | ||||||||||||
1552 | int b = p->fragmentMap().findNode(pos); | - | ||||||||||||
1553 | int e = p->fragmentMap().findNode(pos+len); | - | ||||||||||||
1554 | return iterator(p, b, e, e); never executed: return iterator(p, b, e, e); | 0 | ||||||||||||
1555 | } | - | ||||||||||||
1556 | - | |||||||||||||
1557 | - | |||||||||||||
1558 | /*! | - | ||||||||||||
1559 | Returns the text block in the document after this block, or an empty | - | ||||||||||||
1560 | text block if this is the last one. | - | ||||||||||||
1561 | - | |||||||||||||
1562 | Note that the next block may be in a different frame or table to this block. | - | ||||||||||||
1563 | - | |||||||||||||
1564 | \sa previous(), begin(), end() | - | ||||||||||||
1565 | */ | - | ||||||||||||
1566 | QTextBlock QTextBlock::next() const | - | ||||||||||||
1567 | { | - | ||||||||||||
1568 | if (!isValid())
| 0 | ||||||||||||
1569 | return QTextBlock(); never executed: return QTextBlock(); | 0 | ||||||||||||
1570 | - | |||||||||||||
1571 | return QTextBlock(p, p->blockMap().next(n)); never executed: return QTextBlock(p, p->blockMap().next(n)); | 0 | ||||||||||||
1572 | } | - | ||||||||||||
1573 | - | |||||||||||||
1574 | /*! | - | ||||||||||||
1575 | Returns the text block in the document before this block, or an empty text | - | ||||||||||||
1576 | block if this is the first one. | - | ||||||||||||
1577 | - | |||||||||||||
1578 | Note that the previous block may be in a different frame or table to this block. | - | ||||||||||||
1579 | - | |||||||||||||
1580 | \sa next(), begin(), end() | - | ||||||||||||
1581 | */ | - | ||||||||||||
1582 | QTextBlock QTextBlock::previous() const | - | ||||||||||||
1583 | { | - | ||||||||||||
1584 | if (!p)
| 0 | ||||||||||||
1585 | return QTextBlock(); never executed: return QTextBlock(); | 0 | ||||||||||||
1586 | - | |||||||||||||
1587 | return QTextBlock(p, p->blockMap().previous(n)); never executed: return QTextBlock(p, p->blockMap().previous(n)); | 0 | ||||||||||||
1588 | } | - | ||||||||||||
1589 | - | |||||||||||||
1590 | - | |||||||||||||
1591 | /*! | - | ||||||||||||
1592 | Returns the text fragment the iterator currently points to. | - | ||||||||||||
1593 | */ | - | ||||||||||||
1594 | QTextFragment QTextBlock::iterator::fragment() const | - | ||||||||||||
1595 | { | - | ||||||||||||
1596 | int ne = n; | - | ||||||||||||
1597 | int formatIndex = p->fragmentMap().fragment(n)->format; | - | ||||||||||||
1598 | do { | - | ||||||||||||
1599 | ne = p->fragmentMap().next(ne); | - | ||||||||||||
1600 | } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex); never executed: end of block
| 0 | ||||||||||||
1601 | return QTextFragment(p, n, ne); never executed: return QTextFragment(p, n, ne); | 0 | ||||||||||||
1602 | } | - | ||||||||||||
1603 | - | |||||||||||||
1604 | /*! | - | ||||||||||||
1605 | The prefix ++ operator (\c{++i}) advances the iterator to the | - | ||||||||||||
1606 | next item in the hash and returns an iterator to the new current | - | ||||||||||||
1607 | item. | - | ||||||||||||
1608 | */ | - | ||||||||||||
1609 | - | |||||||||||||
1610 | QTextBlock::iterator &QTextBlock::iterator::operator++() | - | ||||||||||||
1611 | { | - | ||||||||||||
1612 | int ne = n; | - | ||||||||||||
1613 | int formatIndex = p->fragmentMap().fragment(n)->format; | - | ||||||||||||
1614 | do { | - | ||||||||||||
1615 | ne = p->fragmentMap().next(ne); | - | ||||||||||||
1616 | } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex); never executed: end of block
| 0 | ||||||||||||
1617 | n = ne; | - | ||||||||||||
1618 | return *this; never executed: return *this; | 0 | ||||||||||||
1619 | } | - | ||||||||||||
1620 | - | |||||||||||||
1621 | /*! | - | ||||||||||||
1622 | The prefix -- operator (\c{--i}) makes the preceding item | - | ||||||||||||
1623 | current and returns an iterator pointing to the new current item. | - | ||||||||||||
1624 | */ | - | ||||||||||||
1625 | - | |||||||||||||
1626 | QTextBlock::iterator &QTextBlock::iterator::operator--() | - | ||||||||||||
1627 | { | - | ||||||||||||
1628 | n = p->fragmentMap().previous(n); | - | ||||||||||||
1629 | - | |||||||||||||
1630 | if (n == b)
| 0 | ||||||||||||
1631 | return *this; never executed: return *this; | 0 | ||||||||||||
1632 | - | |||||||||||||
1633 | int formatIndex = p->fragmentMap().fragment(n)->format; | - | ||||||||||||
1634 | int last = n; | - | ||||||||||||
1635 | - | |||||||||||||
1636 | while (n != b && p->fragmentMap().fragment(n)->format != formatIndex) {
| 0 | ||||||||||||
1637 | last = n; | - | ||||||||||||
1638 | n = p->fragmentMap().previous(n); | - | ||||||||||||
1639 | } never executed: end of block | 0 | ||||||||||||
1640 | - | |||||||||||||
1641 | n = last; | - | ||||||||||||
1642 | return *this; never executed: return *this; | 0 | ||||||||||||
1643 | } | - | ||||||||||||
1644 | - | |||||||||||||
1645 | - | |||||||||||||
1646 | /*! | - | ||||||||||||
1647 | \class QTextFragment | - | ||||||||||||
1648 | \reentrant | - | ||||||||||||
1649 | - | |||||||||||||
1650 | \brief The QTextFragment class holds a piece of text in a | - | ||||||||||||
1651 | QTextDocument with a single QTextCharFormat. | - | ||||||||||||
1652 | \inmodule QtGui | - | ||||||||||||
1653 | - | |||||||||||||
1654 | \ingroup richtext-processing | - | ||||||||||||
1655 | - | |||||||||||||
1656 | A text fragment describes a piece of text that is stored with a single | - | ||||||||||||
1657 | character format. Text in which the character format changes can be | - | ||||||||||||
1658 | represented by sequences of text fragments with different formats. | - | ||||||||||||
1659 | - | |||||||||||||
1660 | If the user edits the text in a fragment and introduces a different | - | ||||||||||||
1661 | character format, the fragment's text will be split at each point where | - | ||||||||||||
1662 | the format changes, and new fragments will be created. | - | ||||||||||||
1663 | For example, changing the style of some text in the middle of a | - | ||||||||||||
1664 | sentence will cause the fragment to be broken into three separate fragments: | - | ||||||||||||
1665 | the first and third with the same format as before, and the second with | - | ||||||||||||
1666 | the new style. The first fragment will contain the text from the beginning | - | ||||||||||||
1667 | of the sentence, the second will contain the text from the middle, and the | - | ||||||||||||
1668 | third takes the text from the end of the sentence. | - | ||||||||||||
1669 | - | |||||||||||||
1670 | \image qtextfragment-split.png | - | ||||||||||||
1671 | - | |||||||||||||
1672 | A fragment's text and character format can be obtained with the text() | - | ||||||||||||
1673 | and charFormat() functions. The length() function gives the length of | - | ||||||||||||
1674 | the text in the fragment. position() gives the position in the document | - | ||||||||||||
1675 | of the start of the fragment. To determine whether the fragment contains | - | ||||||||||||
1676 | a particular position within the document, use the contains() function. | - | ||||||||||||
1677 | - | |||||||||||||
1678 | \sa QTextDocument, {Rich Text Document Structure} | - | ||||||||||||
1679 | */ | - | ||||||||||||
1680 | - | |||||||||||||
1681 | /*! | - | ||||||||||||
1682 | \fn QTextFragment::QTextFragment(const QTextDocumentPrivate *priv, int f, int fe) | - | ||||||||||||
1683 | \internal | - | ||||||||||||
1684 | */ | - | ||||||||||||
1685 | - | |||||||||||||
1686 | /*! | - | ||||||||||||
1687 | \fn QTextFragment::QTextFragment() | - | ||||||||||||
1688 | - | |||||||||||||
1689 | Creates a new empty text fragment. | - | ||||||||||||
1690 | */ | - | ||||||||||||
1691 | - | |||||||||||||
1692 | /*! | - | ||||||||||||
1693 | \fn QTextFragment::QTextFragment(const QTextFragment &other) | - | ||||||||||||
1694 | - | |||||||||||||
1695 | Copies the content (text and format) of the \a other text fragment | - | ||||||||||||
1696 | to this text fragment. | - | ||||||||||||
1697 | */ | - | ||||||||||||
1698 | - | |||||||||||||
1699 | /*! | - | ||||||||||||
1700 | \fn QTextFragment &QTextFragment::operator=(const QTextFragment | - | ||||||||||||
1701 | &other) | - | ||||||||||||
1702 | - | |||||||||||||
1703 | Assigns the content (text and format) of the \a other text fragment | - | ||||||||||||
1704 | to this text fragment. | - | ||||||||||||
1705 | */ | - | ||||||||||||
1706 | - | |||||||||||||
1707 | /*! | - | ||||||||||||
1708 | \fn bool QTextFragment::isValid() const | - | ||||||||||||
1709 | - | |||||||||||||
1710 | Returns \c true if this is a valid text fragment (i.e. has a valid | - | ||||||||||||
1711 | position in a document); otherwise returns \c false. | - | ||||||||||||
1712 | */ | - | ||||||||||||
1713 | - | |||||||||||||
1714 | /*! | - | ||||||||||||
1715 | \fn bool QTextFragment::operator==(const QTextFragment &other) const | - | ||||||||||||
1716 | - | |||||||||||||
1717 | Returns \c true if this text fragment is the same (at the same | - | ||||||||||||
1718 | position) as the \a other text fragment; otherwise returns \c false. | - | ||||||||||||
1719 | */ | - | ||||||||||||
1720 | - | |||||||||||||
1721 | /*! | - | ||||||||||||
1722 | \fn bool QTextFragment::operator!=(const QTextFragment &other) const | - | ||||||||||||
1723 | - | |||||||||||||
1724 | Returns \c true if this text fragment is different (at a different | - | ||||||||||||
1725 | position) from the \a other text fragment; otherwise returns | - | ||||||||||||
1726 | false. | - | ||||||||||||
1727 | */ | - | ||||||||||||
1728 | - | |||||||||||||
1729 | /*! | - | ||||||||||||
1730 | \fn bool QTextFragment::operator<(const QTextFragment &other) const | - | ||||||||||||
1731 | - | |||||||||||||
1732 | Returns \c true if this text fragment appears earlier in the document | - | ||||||||||||
1733 | than the \a other text fragment; otherwise returns \c false. | - | ||||||||||||
1734 | */ | - | ||||||||||||
1735 | - | |||||||||||||
1736 | /*! | - | ||||||||||||
1737 | Returns the glyphs corresponding to \a len characters of this text fragment starting at | - | ||||||||||||
1738 | position \a pos. The positions of the glyphs are relative to the position of the QTextBlock's | - | ||||||||||||
1739 | layout. | - | ||||||||||||
1740 | - | |||||||||||||
1741 | If \a pos is less than zero, it will default to the start of the QTextFragment. If \a len | - | ||||||||||||
1742 | is less than zero, it will default to the length of the fragment. | - | ||||||||||||
1743 | - | |||||||||||||
1744 | \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun() | - | ||||||||||||
1745 | */ | - | ||||||||||||
1746 | #if !defined(QT_NO_RAWFONT) | - | ||||||||||||
1747 | QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const | - | ||||||||||||
1748 | { | - | ||||||||||||
1749 | if (!p || !n)
| 0 | ||||||||||||
1750 | return QList<QGlyphRun>(); never executed: return QList<QGlyphRun>(); | 0 | ||||||||||||
1751 | - | |||||||||||||
1752 | int blockNode = p->blockMap().findNode(position()); | - | ||||||||||||
1753 | - | |||||||||||||
1754 | const QTextBlockData *blockData = p->blockMap().fragment(blockNode); | - | ||||||||||||
1755 | QTextLayout *layout = blockData->layout; | - | ||||||||||||
1756 | - | |||||||||||||
1757 | int blockPosition = p->blockMap().position(blockNode); | - | ||||||||||||
1758 | if (pos < 0)
| 0 | ||||||||||||
1759 | pos = position() - blockPosition; never executed: pos = position() - blockPosition; | 0 | ||||||||||||
1760 | if (len < 0)
| 0 | ||||||||||||
1761 | len = length(); never executed: len = length(); | 0 | ||||||||||||
1762 | if (len == 0)
| 0 | ||||||||||||
1763 | return QList<QGlyphRun>(); never executed: return QList<QGlyphRun>(); | 0 | ||||||||||||
1764 | - | |||||||||||||
1765 | QList<QGlyphRun> ret; | - | ||||||||||||
1766 | for (int i=0; i<layout->lineCount(); ++i) {
| 0 | ||||||||||||
1767 | QTextLine textLine = layout->lineAt(i); | - | ||||||||||||
1768 | ret += textLine.glyphRuns(pos, len); | - | ||||||||||||
1769 | } never executed: end of block | 0 | ||||||||||||
1770 | - | |||||||||||||
1771 | return ret; never executed: return ret; | 0 | ||||||||||||
1772 | } | - | ||||||||||||
1773 | #endif // QT_NO_RAWFONT | - | ||||||||||||
1774 | - | |||||||||||||
1775 | /*! | - | ||||||||||||
1776 | Returns the position of this text fragment in the document. | - | ||||||||||||
1777 | */ | - | ||||||||||||
1778 | int QTextFragment::position() const | - | ||||||||||||
1779 | { | - | ||||||||||||
1780 | if (!p || !n)
| 0 | ||||||||||||
1781 | return 0; // ### -1 instead? never executed: return 0; | 0 | ||||||||||||
1782 | - | |||||||||||||
1783 | return p->fragmentMap().position(n); never executed: return p->fragmentMap().position(n); | 0 | ||||||||||||
1784 | } | - | ||||||||||||
1785 | - | |||||||||||||
1786 | /*! | - | ||||||||||||
1787 | Returns the number of characters in the text fragment. | - | ||||||||||||
1788 | - | |||||||||||||
1789 | \sa text() | - | ||||||||||||
1790 | */ | - | ||||||||||||
1791 | int QTextFragment::length() const | - | ||||||||||||
1792 | { | - | ||||||||||||
1793 | if (!p || !n)
| 0 | ||||||||||||
1794 | return 0; never executed: return 0; | 0 | ||||||||||||
1795 | - | |||||||||||||
1796 | int len = 0; | - | ||||||||||||
1797 | int f = n; | - | ||||||||||||
1798 | while (f != ne) {
| 0 | ||||||||||||
1799 | len += p->fragmentMap().size(f); | - | ||||||||||||
1800 | f = p->fragmentMap().next(f); | - | ||||||||||||
1801 | } never executed: end of block | 0 | ||||||||||||
1802 | return len; never executed: return len; | 0 | ||||||||||||
1803 | } | - | ||||||||||||
1804 | - | |||||||||||||
1805 | /*! | - | ||||||||||||
1806 | Returns \c true if the text fragment contains the text at the given | - | ||||||||||||
1807 | \a position in the document; otherwise returns \c false. | - | ||||||||||||
1808 | */ | - | ||||||||||||
1809 | bool QTextFragment::contains(int position) const | - | ||||||||||||
1810 | { | - | ||||||||||||
1811 | if (!p || !n)
| 0 | ||||||||||||
1812 | return false; never executed: return false; | 0 | ||||||||||||
1813 | int pos = this->position(); | - | ||||||||||||
1814 | return position >= pos && position < pos + length(); never executed: return position >= pos && position < pos + length(); | 0 | ||||||||||||
1815 | } | - | ||||||||||||
1816 | - | |||||||||||||
1817 | /*! | - | ||||||||||||
1818 | Returns the text fragment's character format. | - | ||||||||||||
1819 | - | |||||||||||||
1820 | \sa text() | - | ||||||||||||
1821 | */ | - | ||||||||||||
1822 | QTextCharFormat QTextFragment::charFormat() const | - | ||||||||||||
1823 | { | - | ||||||||||||
1824 | if (!p || !n)
| 0 | ||||||||||||
1825 | return QTextCharFormat(); never executed: return QTextCharFormat(); | 0 | ||||||||||||
1826 | const QTextFragmentData *data = p->fragmentMap().fragment(n); | - | ||||||||||||
1827 | return p->formatCollection()->charFormat(data->format); never executed: return p->formatCollection()->charFormat(data->format); | 0 | ||||||||||||
1828 | } | - | ||||||||||||
1829 | - | |||||||||||||
1830 | /*! | - | ||||||||||||
1831 | Returns an index into the document's internal list of character formats | - | ||||||||||||
1832 | for the text fragment's character format. | - | ||||||||||||
1833 | - | |||||||||||||
1834 | \sa QTextDocument::allFormats() | - | ||||||||||||
1835 | */ | - | ||||||||||||
1836 | int QTextFragment::charFormatIndex() const | - | ||||||||||||
1837 | { | - | ||||||||||||
1838 | if (!p || !n)
| 0 | ||||||||||||
1839 | return -1; never executed: return -1; | 0 | ||||||||||||
1840 | const QTextFragmentData *data = p->fragmentMap().fragment(n); | - | ||||||||||||
1841 | return data->format; never executed: return data->format; | 0 | ||||||||||||
1842 | } | - | ||||||||||||
1843 | - | |||||||||||||
1844 | /*! | - | ||||||||||||
1845 | Returns the text fragment's as plain text. | - | ||||||||||||
1846 | - | |||||||||||||
1847 | \sa length(), charFormat() | - | ||||||||||||
1848 | */ | - | ||||||||||||
1849 | QString QTextFragment::text() const | - | ||||||||||||
1850 | { | - | ||||||||||||
1851 | if (!p || !n)
| 0 | ||||||||||||
1852 | return QString(); never executed: return QString(); | 0 | ||||||||||||
1853 | - | |||||||||||||
1854 | QString result; | - | ||||||||||||
1855 | QString buffer = p->buffer(); | - | ||||||||||||
1856 | int f = n; | - | ||||||||||||
1857 | while (f != ne) {
| 0 | ||||||||||||
1858 | const QTextFragmentData * const frag = p->fragmentMap().fragment(f); | - | ||||||||||||
1859 | result += QString(buffer.constData() + frag->stringPosition, frag->size_array[0]); | - | ||||||||||||
1860 | f = p->fragmentMap().next(f); | - | ||||||||||||
1861 | } never executed: end of block | 0 | ||||||||||||
1862 | return result; never executed: return result; | 0 | ||||||||||||
1863 | } | - | ||||||||||||
1864 | - | |||||||||||||
1865 | QT_END_NAMESPACE | - | ||||||||||||
Source code | Switch to Preprocessed file |