1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qtextobject.h"
43 #include "qtextobject_p.h"
44 #include "qtextdocument.h"
45 #include "qtextformat_p.h"
46 #include "qtextdocument_p.h"
47 #include "qtextcursor.h"
48 #include "qtextlist.h"
49 #include "qabstracttextdocumentlayout.h"
50 #include "qtextengine_p.h"
55 // ### DOC: We ought to explain the CONCEPT of objectIndexes if
56 // relevant to the public API
61 \brief The QTextObject class is a base class for different kinds
62 of objects that can group parts of a QTextDocument together.
65 \ingroup richtext-processing
67 The common grouping text objects are lists (QTextList), frames
68 (QTextFrame), and tables (QTextTable). A text object has an
69 associated format() and document().
71 There are essentially two kinds of text objects: those that are used
72 with blocks (block formats), and those that are used with characters
73 (character formats). The first kind are derived from QTextBlockGroup,
74 and the second kind from QTextFrame.
76 You rarely need to use this class directly. When creating custom text
77 objects, you will also need to reimplement QTextDocument::createObject()
78 which acts as a factory method for creating text objects.
80 \sa QTextDocument, {Text Object Example}
84 \fn QTextObject::QTextObject(QTextDocument *document)
86 Creates a new QTextObject for the given \a document.
88 \warning This function should never be called directly, but only
89 from QTextDocument::createObject().
91 QTextObject::QTextObject(QTextDocument *doc)
92 : QObject(*new QTextObjectPrivate(doc), doc)
97 \fn QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *document)
101 QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc)
107 Destroys the text object.
109 \warning Text objects are owned by the document, so you should
110 never destroy them yourself.
112 QTextObject::~QTextObject()
117 Returns the text object's format.
119 \sa setFormat(), document()
121 QTextFormat QTextObject::format() const
123 Q_D(const QTextObject);
124 return d->pieceTable->formatCollection()->objectFormat(d->objectIndex);
128 Returns the index of the object's format in the document's internal
131 \sa QTextDocument::allFormats()
133 int QTextObject::formatIndex() const
135 Q_D(const QTextObject);
136 return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex);
141 Sets the text object's \a format.
145 void QTextObject::setFormat(const QTextFormat &format)
148 int idx = d->pieceTable->formatCollection()->indexForFormat(format);
149 d->pieceTable->changeObjectFormat(this, idx);
153 Returns the object index of this object. This can be used together with
154 QTextFormat::setObjectIndex().
156 int QTextObject::objectIndex() const
158 Q_D(const QTextObject);
159 return d->objectIndex;
163 Returns the document this object belongs to.
167 QTextDocument *QTextObject::document() const
169 return static_cast<QTextDocument *>(parent());
175 QTextDocumentPrivate *QTextObject::docHandle() const
177 return static_cast<const QTextDocument *>(parent())->docHandle();
181 \class QTextBlockGroup
184 \brief The QTextBlockGroup class provides a container for text blocks within
188 \ingroup richtext-processing
190 Block groups can be used to organize blocks of text within a document.
191 They maintain an up-to-date list of the text blocks that belong to
192 them, even when text blocks are being edited.
194 Each group has a parent document which is specified when the group is
197 Text blocks can be inserted into a group with blockInserted(), and removed
198 with blockRemoved(). If a block's format is changed, blockFormatChanged()
201 The list of blocks in the group is returned by blockList(). Note that the
202 blocks in the list are not necessarily adjacent elements in the document;
203 for example, the top-level items in a multi-level list will be separated
204 by the items in lower levels of the list.
206 \sa QTextBlock, QTextDocument
209 void QTextBlockGroupPrivate::markBlocksDirty()
211 for (int i = 0; i < blocks.count(); ++i) {
212 const QTextBlock &block = blocks.at(i);
213 pieceTable->documentChange(block.position(), block.length());
218 \fn QTextBlockGroup::QTextBlockGroup(QTextDocument *document)
220 Creates a new new block group for the given \a document.
222 \warning This function should only be called from
223 QTextDocument::createObject().
225 QTextBlockGroup::QTextBlockGroup(QTextDocument *doc)
226 : QTextObject(*new QTextBlockGroupPrivate(doc), doc)
233 QTextBlockGroup::QTextBlockGroup(QTextBlockGroupPrivate &p, QTextDocument *doc)
234 : QTextObject(p, doc)
239 Destroys this block group; the blocks are not deleted, they simply
240 don't belong to this block anymore.
242 QTextBlockGroup::~QTextBlockGroup()
246 // ### DOC: Shouldn't this be insertBlock()?
248 Appends the given \a block to the end of the group.
250 \warning If you reimplement this function you must call the base
251 class implementation.
253 void QTextBlockGroup::blockInserted(const QTextBlock &block)
255 Q_D(QTextBlockGroup);
256 QTextBlockGroupPrivate::BlockList::Iterator it = qLowerBound(d->blocks.begin(), d->blocks.end(), block);
257 d->blocks.insert(it, block);
258 d->markBlocksDirty();
261 // ### DOC: Shouldn't this be removeBlock()?
263 Removes the given \a block from the group; the block itself is not
264 deleted, it simply isn't a member of this group anymore.
266 void QTextBlockGroup::blockRemoved(const QTextBlock &block)
268 Q_D(QTextBlockGroup);
269 d->blocks.removeAll(block);
270 d->markBlocksDirty();
271 if (d->blocks.isEmpty()) {
272 document()->docHandle()->deleteObject(this);
278 This function is called whenever the specified \a block of text is changed.
279 The text block is a member of this group.
281 The base class implementation does nothing.
283 void QTextBlockGroup::blockFormatChanged(const QTextBlock &)
288 Returns a (possibly empty) list of all the blocks that are part of
291 QList<QTextBlock> QTextBlockGroup::blockList() const
293 Q_D(const QTextBlockGroup);
299 QTextFrameLayoutData::~QTextFrameLayoutData()
308 \brief The QTextFrame class represents a frame in a QTextDocument.
311 \ingroup richtext-processing
313 Text frames provide structure for the text in a document. They are used
314 as generic containers for other document elements.
315 Frames are usually created by using QTextCursor::insertFrame().
318 Each frame in a document consists of a frame start character,
319 QChar(0xFDD0), followed by the frame's contents, followed by a
320 frame end character, QChar(0xFDD1). The character formats of the
321 start and end character contain a reference to the frame object's
325 Frames can be used to create hierarchical structures in rich text documents.
326 Each document has a root frame (QTextDocument::rootFrame()), and each frame
327 beneath the root frame has a parent frame and a (possibly empty) list of
328 child frames. The parent frame can be found with parentFrame(), and the
329 childFrames() function provides a list of child frames.
331 Each frame contains at least one text block to enable text cursors to
332 insert new document elements within. As a result, the QTextFrame::iterator
333 class is used to traverse both the blocks and child frames within a given
334 frame. The first and last child elements in the frame can be found with
337 A frame also has a format (specified using QTextFrameFormat) which can be set
338 with setFormat() and read with format().
340 Text cursors can be obtained that point to the first and last valid cursor
341 positions within a frame; use the firstCursorPosition() and
342 lastCursorPosition() functions for this. The frame's extent in the
343 document can be found with firstPosition() and lastPosition().
345 You can iterate over a frame's contents using the
346 QTextFrame::iterator class: this provides read-only access to its
347 internal list of text blocks and child frames.
349 \sa QTextCursor, QTextDocument
353 \typedef QTextFrame::Iterator
355 Qt-style synonym for QTextFrame::iterator.
359 \fn QTextFrame *QTextFrame::iterator::parentFrame() const
361 Returns the parent frame of the current frame.
363 \sa currentFrame(), QTextFrame::parentFrame()
367 \fn bool QTextFrame::iterator::operator==(const iterator &other) const
369 Retuns true if the iterator is the same as the \a other iterator;
370 otherwise returns false.
374 \fn bool QTextFrame::iterator::operator!=(const iterator &other) const
376 Retuns true if the iterator is different from the \a other iterator;
377 otherwise returns false.
381 \fn QTextFrame::iterator QTextFrame::iterator::operator++(int)
383 The postfix ++ operator (\c{i++}) advances the iterator to the
384 next item in the text frame, and returns an iterator to the old item.
388 \fn QTextFrame::iterator QTextFrame::iterator::operator--(int)
390 The postfix -- operator (\c{i--}) makes the preceding item in the
391 current frame, and returns an iterator to the old item.
395 \fn void QTextFrame::setFrameFormat(const QTextFrameFormat &format)
397 Sets the frame's \a format.
403 \fn QTextFrameFormat QTextFrame::frameFormat() const
405 Returns the frame's format.
411 \fn QTextFrame::QTextFrame(QTextDocument *document)
413 Creates a new empty frame for the text \a document.
415 QTextFrame::QTextFrame(QTextDocument *doc)
416 : QTextObject(*new QTextFramePrivate(doc), doc)
420 // ### DOC: What does this do to child frames?
422 Destroys the frame, and removes it from the document's layout.
424 QTextFrame::~QTextFrame()
427 delete d->layoutData;
433 QTextFrame::QTextFrame(QTextFramePrivate &p, QTextDocument *doc)
434 : QTextObject(p, doc)
439 Returns a (possibly empty) list of the frame's child frames.
443 QList<QTextFrame *> QTextFrame::childFrames() const
445 Q_D(const QTextFrame);
446 return d->childFrames;
450 Returns the frame's parent frame. If the frame is the root frame of a
451 document, this will return 0.
453 \sa childFrames(), QTextDocument::rootFrame()
455 QTextFrame *QTextFrame::parentFrame() const
457 Q_D(const QTextFrame);
458 return d->parentFrame;
463 Returns the first cursor position inside the frame.
465 \sa lastCursorPosition(), firstPosition(), lastPosition()
467 QTextCursor QTextFrame::firstCursorPosition() const
469 Q_D(const QTextFrame);
470 return QTextCursor(d->pieceTable, firstPosition());
474 Returns the last cursor position inside the frame.
476 \sa firstCursorPosition(), firstPosition(), lastPosition()
478 QTextCursor QTextFrame::lastCursorPosition() const
480 Q_D(const QTextFrame);
481 return QTextCursor(d->pieceTable, lastPosition());
485 Returns the first document position inside the frame.
487 \sa lastPosition(), firstCursorPosition(), lastCursorPosition()
489 int QTextFrame::firstPosition() const
491 Q_D(const QTextFrame);
492 if (!d->fragment_start)
494 return d->pieceTable->fragmentMap().position(d->fragment_start) + 1;
498 Returns the last document position inside the frame.
500 \sa firstPosition(), firstCursorPosition(), lastCursorPosition()
502 int QTextFrame::lastPosition() const
504 Q_D(const QTextFrame);
505 if (!d->fragment_end)
506 return d->pieceTable->length() - 1;
507 return d->pieceTable->fragmentMap().position(d->fragment_end);
513 QTextFrameLayoutData *QTextFrame::layoutData() const
515 Q_D(const QTextFrame);
516 return d->layoutData;
522 void QTextFrame::setLayoutData(QTextFrameLayoutData *data)
525 delete d->layoutData;
526 d->layoutData = data;
531 void QTextFramePrivate::fragmentAdded(QChar type, uint fragment)
533 if (type == QTextBeginningOfFrame) {
534 Q_ASSERT(!fragment_start);
535 fragment_start = fragment;
536 } else if (type == QTextEndOfFrame) {
537 Q_ASSERT(!fragment_end);
538 fragment_end = fragment;
539 } else if (type == QChar::ObjectReplacementCharacter) {
540 Q_ASSERT(!fragment_start);
541 Q_ASSERT(!fragment_end);
542 fragment_start = fragment;
543 fragment_end = fragment;
549 void QTextFramePrivate::fragmentRemoved(QChar type, uint fragment)
551 Q_UNUSED(fragment); // --release warning
552 if (type == QTextBeginningOfFrame) {
553 Q_ASSERT(fragment_start == fragment);
555 } else if (type == QTextEndOfFrame) {
556 Q_ASSERT(fragment_end == fragment);
558 } else if (type == QChar::ObjectReplacementCharacter) {
559 Q_ASSERT(fragment_start == fragment);
560 Q_ASSERT(fragment_end == fragment);
570 void QTextFramePrivate::remove_me()
573 if (fragment_start == 0 && fragment_end == 0
575 q->document()->docHandle()->deleteObject(q);
582 int index = parentFrame->d_func()->childFrames.indexOf(q);
584 // iterator over all children and move them to the parent
585 for (int i = 0; i < childFrames.size(); ++i) {
586 QTextFrame *c = childFrames.at(i);
587 parentFrame->d_func()->childFrames.insert(index, c);
588 c->d_func()->parentFrame = parentFrame;
591 Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q);
592 parentFrame->d_func()->childFrames.removeAt(index);
599 \class QTextFrame::iterator
602 \brief The iterator class provides an iterator for reading
603 the contents of a QTextFrame.
606 \ingroup richtext-processing
608 A frame consists of an arbitrary sequence of \l{QTextBlock}s and
609 child \l{QTextFrame}s. This class provides a way to iterate over the
610 child objects of a frame, and read their contents. It does not provide
611 a way to modify the contents of the frame.
616 \fn bool QTextFrame::iterator::atEnd() const
618 Returns true if the current item is the last item in the text frame.
622 Returns an iterator pointing to the first document element inside the frame.
623 Please see the document \l{STL-style-Iterators} for more information.
627 QTextFrame::iterator QTextFrame::begin() const
629 const QTextDocumentPrivate *priv = docHandle();
630 int b = priv->blockMap().findNode(firstPosition());
631 int e = priv->blockMap().findNode(lastPosition()+1);
632 return iterator(const_cast<QTextFrame *>(this), b, b, e);
636 Returns an iterator pointing to the position past the last document element inside the frame.
637 Please see the document \l{STL-Style Iterators} for more information.
640 QTextFrame::iterator QTextFrame::end() const
642 const QTextDocumentPrivate *priv = docHandle();
643 int b = priv->blockMap().findNode(firstPosition());
644 int e = priv->blockMap().findNode(lastPosition()+1);
645 return iterator(const_cast<QTextFrame *>(this), e, b, e);
649 Constructs an invalid iterator.
651 QTextFrame::iterator::iterator()
663 QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
673 Copy constructor. Constructs a copy of the \a other iterator.
675 QTextFrame::iterator::iterator(const iterator &other)
685 Assigns \a other to this iterator and returns a reference to
688 QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other)
699 Returns the current frame pointed to by the iterator, or 0 if the
700 iterator currently points to a block.
704 QTextFrame *QTextFrame::iterator::currentFrame() const
710 Returns the current block the iterator points to. If the iterator
711 points to a child frame, the returned block is invalid.
715 QTextBlock QTextFrame::iterator::currentBlock() const
719 return QTextBlock(f->docHandle(), cb);
723 Moves the iterator to the next frame or block.
725 \sa currentBlock(), currentFrame()
727 QTextFrame::iterator &QTextFrame::iterator::operator++()
729 const QTextDocumentPrivate *priv = f->docHandle();
730 const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
732 int end = cf->lastPosition() + 1;
733 cb = map.findNode(end);
740 if (!f->d_func()->childFrames.isEmpty()) {
741 int pos = map.position(cb);
742 // check if we entered a frame
743 QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
744 if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
745 QTextFrame *nf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
747 if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame && nf != f) {
751 Q_ASSERT(priv->buffer().at(frag->stringPosition) != QTextEndOfFrame);
761 Moves the iterator to the previous frame or block.
763 \sa currentBlock(), currentFrame()
765 QTextFrame::iterator &QTextFrame::iterator::operator--()
767 const QTextDocumentPrivate *priv = f->docHandle();
768 const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
770 int start = cf->firstPosition() - 1;
771 cb = map.findNode(start);
777 int pos = map.position(cb);
778 // check if we have to enter a frame
779 QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
780 if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
781 QTextFrame *pf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
783 if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame) {
785 } else if (priv->buffer().at(frag->stringPosition) == QTextEndOfFrame) {
794 cb = map.previous(cb);
801 \class QTextBlockUserData
804 \brief The QTextBlockUserData class is used to associate custom data with blocks of text.
808 \ingroup richtext-processing
810 QTextBlockUserData provides an abstract interface for container classes that are used
811 to associate application-specific user data with text blocks in a QTextDocument.
813 Generally, subclasses of this class provide functions to allow data to be stored
814 and retrieved, and instances are attached to blocks of text using
815 QTextBlock::setUserData(). This makes it possible to store additional data per text
816 block in a way that can be retrieved safely by the application.
818 Each subclass should provide a reimplementation of the destructor to ensure that any
819 private data is automatically cleaned up when user data objects are deleted.
825 Destroys the user data.
827 QTextBlockUserData::~QTextBlockUserData()
835 \brief The QTextBlock class provides a container for text fragments in a
839 \ingroup richtext-processing
841 A text block encapsulates a block or paragraph of text in a QTextDocument.
842 QTextBlock provides read-only access to the block/paragraph structure of
843 QTextDocuments. It is mainly of use if you want to implement your own
844 layouts for the visual representation of a QTextDocument, or if you want to
845 iterate over a document and write out the contents in your own custom
848 Text blocks are created by their parent documents. If you need to create
849 a new text block, or modify the contents of a document while examining its
850 contents, use the cursor-based interface provided by QTextCursor instead.
852 Each text block is located at a specific position() in a document().
853 The contents of the block can be obtained by using the text() function.
854 The length() function determines the block's size within the document
855 (including formatting characters).
856 The visual properties of the block are determined by its text layout(),
857 its charFormat(), and its blockFormat().
859 The next() and previous() functions enable iteration over consecutive
860 valid blocks in a document under the condition that the document is not
861 modified by other means during the iteration process. Note that, although
862 blocks are returned in sequence, adjacent blocks may come from different
863 places in the document structure. The validity of a block can be determined
864 by calling isValid().
866 QTextBlock provides comparison operators to make it easier to work with
867 blocks: \l operator==() compares two block for equality, \l operator!=()
868 compares two blocks for inequality, and \l operator<() determines whether
869 a block precedes another in the same document.
871 \img qtextblock-sequence.png
873 \sa QTextBlockFormat, QTextCharFormat, QTextFragment
877 \fn QTextBlock::QTextBlock(QTextDocumentPrivate *priv, int b)
883 \fn QTextBlock::QTextBlock()
889 \fn QTextBlock::QTextBlock(const QTextBlock &other)
891 Copies the \a other text block's attributes to this text block.
895 \fn bool QTextBlock::isValid() const
897 Returns true if this text block is valid; otherwise returns false.
900 bool QTextBlock::isValid() const
902 return p != 0 && p->blockMap().isValid(n);
906 \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)
908 Assigns the \a other text block to this text block.
912 \fn bool QTextBlock::operator==(const QTextBlock &other) const
914 Returns true if this text block is the same as the \a other text
919 \fn bool QTextBlock::operator!=(const QTextBlock &other) const
921 Returns true if this text block is different from the \a other
926 \fn bool QTextBlock::operator<(const QTextBlock &other) const
928 Returns true if this text block occurs before the \a other text
929 block in the document.
933 \class QTextBlock::iterator
936 \brief The QTextBlock::iterator class provides an iterator for reading
937 the contents of a QTextBlock.
940 \ingroup richtext-processing
942 A block consists of a sequence of text fragments. This class provides
943 a way to iterate over these, and read their contents. It does not provide
944 a way to modify the internal structure or contents of the block.
946 An iterator can be constructed and used to access the fragments within
947 a text block in the following way:
949 \snippet textblock-fragments/xmlwriter.cpp 4
950 \snippet textblock-fragments/xmlwriter.cpp 7
956 \typedef QTextBlock::Iterator
958 Qt-style synonym for QTextBlock::iterator.
962 \fn QTextBlock::iterator::iterator()
964 Constructs an iterator for this text block.
968 \fn QTextBlock::iterator::iterator(const iterator &other)
970 Copy constructor. Constructs a copy of the \a other iterator.
974 \fn bool QTextBlock::iterator::atEnd() const
976 Returns true if the current item is the last item in the text block.
980 \fn bool QTextBlock::iterator::operator==(const iterator &other) const
982 Retuns true if this iterator is the same as the \a other iterator;
983 otherwise returns false.
987 \fn bool QTextBlock::iterator::operator!=(const iterator &other) const
989 Retuns true if this iterator is different from the \a other iterator;
990 otherwise returns false.
994 \fn QTextBlock::iterator QTextBlock::iterator::operator++(int)
996 The postfix ++ operator (\c{i++}) advances the iterator to the
997 next item in the text block and returns an iterator to the old current
1002 \fn QTextBlock::iterator QTextBlock::iterator::operator--(int)
1004 The postfix -- operator (\c{i--}) makes the preceding item current and
1005 returns an iterator to the old current item.
1009 \fn QTextDocumentPrivate *QTextBlock::docHandle() const
1015 \fn int QTextBlock::fragmentIndex() const
1021 Returns the index of the block's first character within the document.
1023 int QTextBlock::position() const
1028 return p->blockMap().position(n);
1032 Returns the length of the block in characters.
1034 \note The length returned includes all formatting characters,
1035 for example, newline.
1037 \sa text(), charFormat(), blockFormat()
1039 int QTextBlock::length() const
1044 return p->blockMap().size(n);
1048 Returns true if the given \a position is located within the text
1049 block; otherwise returns false.
1051 bool QTextBlock::contains(int position) const
1056 int pos = p->blockMap().position(n);
1057 int len = p->blockMap().size(n);
1058 return position >= pos && position < pos + len;
1062 Returns the QTextLayout that is used to lay out and display the
1065 Note that the returned QTextLayout object can only be modified from the
1066 documentChanged implementation of a QAbstractTextDocumentLayout subclass.
1067 Any changes applied from the outside cause undefined behavior.
1071 QTextLayout *QTextBlock::layout() const
1076 const QTextBlockData *b = p->blockMap().fragment(n);
1078 b->layout = new QTextLayout(*this);
1084 Clears the QTextLayout that is used to lay out and display the
1089 void QTextBlock::clearLayout()
1094 const QTextBlockData *b = p->blockMap().fragment(n);
1096 b->layout->clearLayout();
1100 Returns the QTextBlockFormat that describes block-specific properties.
1104 QTextBlockFormat QTextBlock::blockFormat() const
1107 return QTextFormat().toBlockFormat();
1109 return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format);
1113 Returns an index into the document's internal list of block formats
1114 for the text block's format.
1116 \sa QTextDocument::allFormats()
1118 int QTextBlock::blockFormatIndex() const
1123 return p->blockMap().fragment(n)->format;
1127 Returns the QTextCharFormat that describes the block's character
1128 format. The block's character format is used when inserting text into
1133 QTextCharFormat QTextBlock::charFormat() const
1136 return QTextFormat().toCharFormat();
1138 return p->formatCollection()->charFormat(charFormatIndex());
1142 Returns an index into the document's internal list of character formats
1143 for the text block's character format.
1145 \sa QTextDocument::allFormats()
1147 int QTextBlock::charFormatIndex() const
1152 return p->blockCharFormatIndex(n);
1158 Returns the resolved text direction.
1160 If the block has no explicit direction set, it will resolve the
1161 direction from the blocks content. Returns either Qt::LeftToRight
1164 \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection
1166 Qt::LayoutDirection QTextBlock::textDirection() const
1168 Qt::LayoutDirection dir = blockFormat().layoutDirection();
1169 if (dir != Qt::LayoutDirectionAuto)
1172 dir = p->defaultTextOption.textDirection();
1173 if (dir != Qt::LayoutDirectionAuto)
1176 const QString buffer = p->buffer();
1178 const int pos = position();
1179 QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1180 QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1181 for (; it != end; ++it) {
1182 const QTextFragmentData * const frag = it.value();
1183 const QChar *p = buffer.constData() + frag->stringPosition;
1184 const QChar * const end = p + frag->size_array[0];
1186 switch(QChar::direction(p->unicode()))
1189 return Qt::LeftToRight;
1192 return Qt::RightToLeft;
1199 return Qt::LeftToRight;
1203 Returns the block's contents as plain text.
1205 \sa length(), charFormat(), blockFormat()
1207 QString QTextBlock::text() const
1212 const QString buffer = p->buffer();
1214 text.reserve(length());
1216 const int pos = position();
1217 QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1218 QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1219 for (; it != end; ++it) {
1220 const QTextFragmentData * const frag = it.value();
1221 text += QString::fromRawData(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1229 Returns the text document this text block belongs to, or 0 if the
1230 text block does not belong to any document.
1232 const QTextDocument *QTextBlock::document() const
1234 return p ? p->document() : 0;
1238 If the block represents a list item, returns the list that the item belongs
1239 to; otherwise returns 0.
1241 QTextList *QTextBlock::textList() const
1246 const QTextBlockFormat fmt = blockFormat();
1247 QTextObject *obj = p->document()->objectForFormat(fmt);
1248 return qobject_cast<QTextList *>(obj);
1254 Returns a pointer to a QTextBlockUserData object if previously set with
1255 setUserData() or a null pointer.
1257 QTextBlockUserData *QTextBlock::userData() const
1262 const QTextBlockData *b = p->blockMap().fragment(n);
1269 Attaches the given \a data object to the text block.
1271 QTextBlockUserData can be used to store custom settings. The
1272 ownership is passed to the underlying text document, i.e. the
1273 provided QTextBlockUserData object will be deleted if the
1274 corresponding text block gets deleted. The user data object is
1275 not stored in the undo history, so it will not be available after
1276 undoing the deletion of a text block.
1278 For example, if you write a programming editor in an IDE, you may
1279 want to let your user set breakpoints visually in your code for an
1280 integrated debugger. In a programming editor a line of text
1281 usually corresponds to one QTextBlock. The QTextBlockUserData
1282 interface allows the developer to store data for each QTextBlock,
1283 like for example in which lines of the source code the user has a
1284 breakpoint set. Of course this could also be stored externally,
1285 but by storing it inside the QTextDocument, it will for example be
1286 automatically deleted when the user deletes the associated
1287 line. It's really just a way to store custom information in the
1288 QTextDocument without using custom properties in QTextFormat which
1289 would affect the undo/redo stack.
1291 void QTextBlock::setUserData(QTextBlockUserData *data)
1296 const QTextBlockData *b = p->blockMap().fragment(n);
1297 if (data != b->userData)
1305 Returns the integer value previously set with setUserState() or -1.
1307 int QTextBlock::userState() const
1312 const QTextBlockData *b = p->blockMap().fragment(n);
1313 return b->userState;
1319 Stores the specified \a state integer value in the text block. This may be
1320 useful for example in a syntax highlighter to store a text parsing state.
1322 void QTextBlock::setUserState(int state)
1327 const QTextBlockData *b = p->blockMap().fragment(n);
1328 b->userState = state;
1334 Returns the blocks revision.
1336 \sa setRevision(), QTextDocument::revision()
1338 int QTextBlock::revision() const
1343 const QTextBlockData *b = p->blockMap().fragment(n);
1350 Sets a blocks revision to \a rev.
1352 \sa revision(), QTextDocument::revision()
1354 void QTextBlock::setRevision(int rev)
1359 const QTextBlockData *b = p->blockMap().fragment(n);
1366 Returns true if the block is visible; otherwise returns false.
1370 bool QTextBlock::isVisible() const
1375 const QTextBlockData *b = p->blockMap().fragment(n);
1382 Sets the block's visibility to \a visible.
1386 void QTextBlock::setVisible(bool visible)
1391 const QTextBlockData *b = p->blockMap().fragment(n);
1392 b->hidden = !visible;
1399 Returns the number of this block, or -1 if the block is invalid.
1401 \sa QTextCursor::blockNumber()
1404 int QTextBlock::blockNumber() const
1408 return p->blockMap().position(n, 1);
1414 Returns the first line number of this block, or -1 if the block is invalid.
1415 Unless the layout supports it, the line number is identical to the block number.
1417 \sa QTextBlock::blockNumber()
1420 int QTextBlock::firstLineNumber() const
1424 return p->blockMap().position(n, 2);
1431 Sets the line count to \a count.
1435 void QTextBlock::setLineCount(int count)
1439 p->blockMap().setSize(n, count, 2);
1444 Returns the line count. Not all document layouts support this feature.
1448 int QTextBlock::lineCount() const
1452 return p->blockMap().size(n, 2);
1457 Returns a text block iterator pointing to the beginning of the
1462 QTextBlock::iterator QTextBlock::begin() const
1467 int pos = position();
1468 int len = length() - 1; // exclude the fragment that holds the paragraph separator
1469 int b = p->fragmentMap().findNode(pos);
1470 int e = p->fragmentMap().findNode(pos+len);
1471 return iterator(p, b, e, b);
1475 Returns a text block iterator pointing to the end of the text
1478 \sa begin(), next(), previous()
1480 QTextBlock::iterator QTextBlock::end() const
1485 int pos = position();
1486 int len = length() - 1; // exclude the fragment that holds the paragraph separator
1487 int b = p->fragmentMap().findNode(pos);
1488 int e = p->fragmentMap().findNode(pos+len);
1489 return iterator(p, b, e, e);
1494 Returns the text block in the document after this block, or an empty
1495 text block if this is the last one.
1497 Note that the next block may be in a different frame or table to this block.
1499 \sa previous(), begin(), end()
1501 QTextBlock QTextBlock::next() const
1504 return QTextBlock();
1506 return QTextBlock(p, p->blockMap().next(n));
1510 Returns the text block in the document before this block, or an empty text
1511 block if this is the first one.
1513 Note that the next block may be in a different frame or table to this block.
1515 \sa next(), begin(), end()
1517 QTextBlock QTextBlock::previous() const
1520 return QTextBlock();
1522 return QTextBlock(p, p->blockMap().previous(n));
1527 Returns the text fragment the iterator currently points to.
1529 QTextFragment QTextBlock::iterator::fragment() const
1532 int formatIndex = p->fragmentMap().fragment(n)->format;
1534 ne = p->fragmentMap().next(ne);
1535 } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1536 return QTextFragment(p, n, ne);
1540 The prefix ++ operator (\c{++i}) advances the iterator to the
1541 next item in the hash and returns an iterator to the new current
1545 QTextBlock::iterator &QTextBlock::iterator::operator++()
1548 int formatIndex = p->fragmentMap().fragment(n)->format;
1550 ne = p->fragmentMap().next(ne);
1551 } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1557 The prefix -- operator (\c{--i}) makes the preceding item
1558 current and returns an iterator pointing to the new current item.
1561 QTextBlock::iterator &QTextBlock::iterator::operator--()
1563 n = p->fragmentMap().previous(n);
1568 int formatIndex = p->fragmentMap().fragment(n)->format;
1571 while (n != b && p->fragmentMap().fragment(n)->format != formatIndex) {
1573 n = p->fragmentMap().previous(n);
1582 \class QTextFragment
1585 \brief The QTextFragment class holds a piece of text in a
1586 QTextDocument with a single QTextCharFormat.
1589 \ingroup richtext-processing
1591 A text fragment describes a piece of text that is stored with a single
1592 character format. Text in which the character format changes can be
1593 represented by sequences of text fragments with different formats.
1595 If the user edits the text in a fragment and introduces a different
1596 character format, the fragment's text will be split at each point where
1597 the format changes, and new fragments will be created.
1598 For example, changing the style of some text in the middle of a
1599 sentence will cause the fragment to be broken into three separate fragments:
1600 the first and third with the same format as before, and the second with
1601 the new style. The first fragment will contain the text from the beginning
1602 of the sentence, the second will contain the text from the middle, and the
1603 third takes the text from the end of the sentence.
1605 \img qtextfragment-split.png
1607 A fragment's text and character format can be obtained with the text()
1608 and charFormat() functions. The length() function gives the length of
1609 the text in the fragment. position() gives the position in the document
1610 of the start of the fragment. To determine whether the fragment contains
1611 a particular position within the document, use the contains() function.
1613 \sa QTextDocument, {Rich Text Document Structure}
1617 \fn QTextFragment::QTextFragment(const QTextDocumentPrivate *priv, int f, int fe)
1622 \fn QTextFragment::QTextFragment()
1624 Creates a new empty text fragment.
1628 \fn QTextFragment::QTextFragment(const QTextFragment &other)
1630 Copies the content (text and format) of the \a other text fragment
1631 to this text fragment.
1635 \fn QTextFragment &QTextFragment::operator=(const QTextFragment
1638 Assigns the content (text and format) of the \a other text fragment
1639 to this text fragment.
1643 \fn bool QTextFragment::isValid() const
1645 Returns true if this is a valid text fragment (i.e. has a valid
1646 position in a document); otherwise returns false.
1650 \fn bool QTextFragment::operator==(const QTextFragment &other) const
1652 Returns true if this text fragment is the same (at the same
1653 position) as the \a other text fragment; otherwise returns false.
1657 \fn bool QTextFragment::operator!=(const QTextFragment &other) const
1659 Returns true if this text fragment is different (at a different
1660 position) from the \a other text fragment; otherwise returns
1665 \fn bool QTextFragment::operator<(const QTextFragment &other) const
1667 Returns true if this text fragment appears earlier in the document
1668 than the \a other text fragment; otherwise returns false.
1672 Returns the glyphs of this text fragment. The positions of the glyphs are
1673 relative to the position of the QTextBlock's layout.
1675 \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun()
1677 #if !defined(QT_NO_RAWFONT)
1678 QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const
1681 return QList<QGlyphRun>();
1683 int blockNode = p->blockMap().findNode(position());
1685 const QTextBlockData *blockData = p->blockMap().fragment(blockNode);
1686 QTextLayout *layout = blockData->layout;
1688 int blockPosition = p->blockMap().position(blockNode);
1690 pos = position() - blockPosition;
1694 return QList<QGlyphRun>();
1696 QList<QGlyphRun> ret;
1697 for (int i=0; i<layout->lineCount(); ++i) {
1698 QTextLine textLine = layout->lineAt(i);
1699 ret += textLine.glyphRuns(pos, len);
1704 #endif // QT_NO_RAWFONT
1707 Returns the position of this text fragment in the document.
1709 int QTextFragment::position() const
1712 return 0; // ### -1 instead?
1714 return p->fragmentMap().position(n);
1718 Returns the number of characters in the text fragment.
1722 int QTextFragment::length() const
1730 len += p->fragmentMap().size(f);
1731 f = p->fragmentMap().next(f);
1737 Returns true if the text fragment contains the text at the given
1738 \a position in the document; otherwise returns false.
1740 bool QTextFragment::contains(int position) const
1744 int pos = this->position();
1745 return position >= pos && position < pos + length();
1749 Returns the text fragment's character format.
1753 QTextCharFormat QTextFragment::charFormat() const
1756 return QTextCharFormat();
1757 const QTextFragmentData *data = p->fragmentMap().fragment(n);
1758 return p->formatCollection()->charFormat(data->format);
1762 Returns an index into the document's internal list of character formats
1763 for the text fragment's character format.
1765 \sa QTextDocument::allFormats()
1767 int QTextFragment::charFormatIndex() const
1771 const QTextFragmentData *data = p->fragmentMap().fragment(n);
1772 return data->format;
1776 Returns the text fragment's as plain text.
1778 \sa length(), charFormat()
1780 QString QTextFragment::text() const
1786 QString buffer = p->buffer();
1789 const QTextFragmentData * const frag = p->fragmentMap().fragment(f);
1790 result += QString(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1791 f = p->fragmentMap().next(f);