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.
64 \ingroup richtext-processing
66 The common grouping text objects are lists (QTextList), frames
67 (QTextFrame), and tables (QTextTable). A text object has an
68 associated format() and document().
70 There are essentially two kinds of text objects: those that are used
71 with blocks (block formats), and those that are used with characters
72 (character formats). The first kind are derived from QTextBlockGroup,
73 and the second kind from QTextFrame.
75 You rarely need to use this class directly. When creating custom text
76 objects, you will also need to reimplement QTextDocument::createObject()
77 which acts as a factory method for creating text objects.
79 \sa QTextDocument, {Text Object Example}
83 \fn QTextObject::QTextObject(QTextDocument *document)
85 Creates a new QTextObject for the given \a document.
87 \warning This function should never be called directly, but only
88 from QTextDocument::createObject().
90 QTextObject::QTextObject(QTextDocument *doc)
91 : QObject(*new QTextObjectPrivate(doc), doc)
96 \fn QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *document)
100 QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc)
106 Destroys the text object.
108 \warning Text objects are owned by the document, so you should
109 never destroy them yourself.
111 QTextObject::~QTextObject()
116 Returns the text object's format.
118 \sa setFormat(), document()
120 QTextFormat QTextObject::format() const
122 Q_D(const QTextObject);
123 return d->pieceTable->formatCollection()->objectFormat(d->objectIndex);
127 Returns the index of the object's format in the document's internal
130 \sa QTextDocument::allFormats()
132 int QTextObject::formatIndex() const
134 Q_D(const QTextObject);
135 return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex);
140 Sets the text object's \a format.
144 void QTextObject::setFormat(const QTextFormat &format)
147 int idx = d->pieceTable->formatCollection()->indexForFormat(format);
148 d->pieceTable->changeObjectFormat(this, idx);
152 Returns the object index of this object. This can be used together with
153 QTextFormat::setObjectIndex().
155 int QTextObject::objectIndex() const
157 Q_D(const QTextObject);
158 return d->objectIndex;
162 Returns the document this object belongs to.
166 QTextDocument *QTextObject::document() const
168 return static_cast<QTextDocument *>(parent());
174 QTextDocumentPrivate *QTextObject::docHandle() const
176 return static_cast<const QTextDocument *>(parent())->docHandle();
180 \class QTextBlockGroup
183 \brief The QTextBlockGroup class provides a container for text blocks within
186 \ingroup richtext-processing
188 Block groups can be used to organize blocks of text within a document.
189 They maintain an up-to-date list of the text blocks that belong to
190 them, even when text blocks are being edited.
192 Each group has a parent document which is specified when the group is
195 Text blocks can be inserted into a group with blockInserted(), and removed
196 with blockRemoved(). If a block's format is changed, blockFormatChanged()
199 The list of blocks in the group is returned by blockList(). Note that the
200 blocks in the list are not necessarily adjacent elements in the document;
201 for example, the top-level items in a multi-level list will be separated
202 by the items in lower levels of the list.
204 \sa QTextBlock, QTextDocument
207 void QTextBlockGroupPrivate::markBlocksDirty()
209 for (int i = 0; i < blocks.count(); ++i) {
210 const QTextBlock &block = blocks.at(i);
211 pieceTable->documentChange(block.position(), block.length());
216 \fn QTextBlockGroup::QTextBlockGroup(QTextDocument *document)
218 Creates a new new block group for the given \a document.
220 \warning This function should only be called from
221 QTextDocument::createObject().
223 QTextBlockGroup::QTextBlockGroup(QTextDocument *doc)
224 : QTextObject(*new QTextBlockGroupPrivate(doc), doc)
231 QTextBlockGroup::QTextBlockGroup(QTextBlockGroupPrivate &p, QTextDocument *doc)
232 : QTextObject(p, doc)
237 Destroys this block group; the blocks are not deleted, they simply
238 don't belong to this block anymore.
240 QTextBlockGroup::~QTextBlockGroup()
244 // ### DOC: Shouldn't this be insertBlock()?
246 Appends the given \a block to the end of the group.
248 \warning If you reimplement this function you must call the base
249 class implementation.
251 void QTextBlockGroup::blockInserted(const QTextBlock &block)
253 Q_D(QTextBlockGroup);
254 QTextBlockGroupPrivate::BlockList::Iterator it = qLowerBound(d->blocks.begin(), d->blocks.end(), block);
255 d->blocks.insert(it, block);
256 d->markBlocksDirty();
259 // ### DOC: Shouldn't this be removeBlock()?
261 Removes the given \a block from the group; the block itself is not
262 deleted, it simply isn't a member of this group anymore.
264 void QTextBlockGroup::blockRemoved(const QTextBlock &block)
266 Q_D(QTextBlockGroup);
267 d->blocks.removeAll(block);
268 d->markBlocksDirty();
269 if (d->blocks.isEmpty()) {
270 document()->docHandle()->deleteObject(this);
276 This function is called whenever the specified \a block of text is changed.
277 The text block is a member of this group.
279 The base class implementation does nothing.
281 void QTextBlockGroup::blockFormatChanged(const QTextBlock &)
286 Returns a (possibly empty) list of all the blocks that are part of
289 QList<QTextBlock> QTextBlockGroup::blockList() const
291 Q_D(const QTextBlockGroup);
297 QTextFrameLayoutData::~QTextFrameLayoutData()
306 \brief The QTextFrame class represents a frame in a QTextDocument.
308 \ingroup richtext-processing
310 Text frames provide structure for the text in a document. They are used
311 as generic containers for other document elements.
312 Frames are usually created by using QTextCursor::insertFrame().
315 Each frame in a document consists of a frame start character,
316 QChar(0xFDD0), followed by the frame's contents, followed by a
317 frame end character, QChar(0xFDD1). The character formats of the
318 start and end character contain a reference to the frame object's
322 Frames can be used to create hierarchical structures in rich text documents.
323 Each document has a root frame (QTextDocument::rootFrame()), and each frame
324 beneath the root frame has a parent frame and a (possibly empty) list of
325 child frames. The parent frame can be found with parentFrame(), and the
326 childFrames() function provides a list of child frames.
328 Each frame contains at least one text block to enable text cursors to
329 insert new document elements within. As a result, the QTextFrame::iterator
330 class is used to traverse both the blocks and child frames within a given
331 frame. The first and last child elements in the frame can be found with
334 A frame also has a format (specified using QTextFrameFormat) which can be set
335 with setFormat() and read with format().
337 Text cursors can be obtained that point to the first and last valid cursor
338 positions within a frame; use the firstCursorPosition() and
339 lastCursorPosition() functions for this. The frame's extent in the
340 document can be found with firstPosition() and lastPosition().
342 You can iterate over a frame's contents using the
343 QTextFrame::iterator class: this provides read-only access to its
344 internal list of text blocks and child frames.
346 \sa QTextCursor, QTextDocument
350 \typedef QTextFrame::Iterator
352 Qt-style synonym for QTextFrame::iterator.
356 \fn QTextFrame *QTextFrame::iterator::parentFrame() const
358 Returns the parent frame of the current frame.
360 \sa currentFrame(), QTextFrame::parentFrame()
364 \fn bool QTextFrame::iterator::operator==(const iterator &other) const
366 Retuns true if the iterator is the same as the \a other iterator;
367 otherwise returns false.
371 \fn bool QTextFrame::iterator::operator!=(const iterator &other) const
373 Retuns true if the iterator is different from the \a other iterator;
374 otherwise returns false.
378 \fn QTextFrame::iterator QTextFrame::iterator::operator++(int)
380 The postfix ++ operator (\c{i++}) advances the iterator to the
381 next item in the text frame, and returns an iterator to the old item.
385 \fn QTextFrame::iterator QTextFrame::iterator::operator--(int)
387 The postfix -- operator (\c{i--}) makes the preceding item in the
388 current frame, and returns an iterator to the old item.
392 \fn void QTextFrame::setFrameFormat(const QTextFrameFormat &format)
394 Sets the frame's \a format.
400 \fn QTextFrameFormat QTextFrame::frameFormat() const
402 Returns the frame's format.
408 \fn QTextFrame::QTextFrame(QTextDocument *document)
410 Creates a new empty frame for the text \a document.
412 QTextFrame::QTextFrame(QTextDocument *doc)
413 : QTextObject(*new QTextFramePrivate(doc), doc)
417 // ### DOC: What does this do to child frames?
419 Destroys the frame, and removes it from the document's layout.
421 QTextFrame::~QTextFrame()
424 delete d->layoutData;
430 QTextFrame::QTextFrame(QTextFramePrivate &p, QTextDocument *doc)
431 : QTextObject(p, doc)
436 Returns a (possibly empty) list of the frame's child frames.
440 QList<QTextFrame *> QTextFrame::childFrames() const
442 Q_D(const QTextFrame);
443 return d->childFrames;
447 Returns the frame's parent frame. If the frame is the root frame of a
448 document, this will return 0.
450 \sa childFrames(), QTextDocument::rootFrame()
452 QTextFrame *QTextFrame::parentFrame() const
454 Q_D(const QTextFrame);
455 return d->parentFrame;
460 Returns the first cursor position inside the frame.
462 \sa lastCursorPosition(), firstPosition(), lastPosition()
464 QTextCursor QTextFrame::firstCursorPosition() const
466 Q_D(const QTextFrame);
467 return QTextCursor(d->pieceTable, firstPosition());
471 Returns the last cursor position inside the frame.
473 \sa firstCursorPosition(), firstPosition(), lastPosition()
475 QTextCursor QTextFrame::lastCursorPosition() const
477 Q_D(const QTextFrame);
478 return QTextCursor(d->pieceTable, lastPosition());
482 Returns the first document position inside the frame.
484 \sa lastPosition(), firstCursorPosition(), lastCursorPosition()
486 int QTextFrame::firstPosition() const
488 Q_D(const QTextFrame);
489 if (!d->fragment_start)
491 return d->pieceTable->fragmentMap().position(d->fragment_start) + 1;
495 Returns the last document position inside the frame.
497 \sa firstPosition(), firstCursorPosition(), lastCursorPosition()
499 int QTextFrame::lastPosition() const
501 Q_D(const QTextFrame);
502 if (!d->fragment_end)
503 return d->pieceTable->length() - 1;
504 return d->pieceTable->fragmentMap().position(d->fragment_end);
510 QTextFrameLayoutData *QTextFrame::layoutData() const
512 Q_D(const QTextFrame);
513 return d->layoutData;
519 void QTextFrame::setLayoutData(QTextFrameLayoutData *data)
522 delete d->layoutData;
523 d->layoutData = data;
528 void QTextFramePrivate::fragmentAdded(QChar type, uint fragment)
530 if (type == QTextBeginningOfFrame) {
531 Q_ASSERT(!fragment_start);
532 fragment_start = fragment;
533 } else if (type == QTextEndOfFrame) {
534 Q_ASSERT(!fragment_end);
535 fragment_end = fragment;
536 } else if (type == QChar::ObjectReplacementCharacter) {
537 Q_ASSERT(!fragment_start);
538 Q_ASSERT(!fragment_end);
539 fragment_start = fragment;
540 fragment_end = fragment;
546 void QTextFramePrivate::fragmentRemoved(QChar type, uint fragment)
548 Q_UNUSED(fragment); // --release warning
549 if (type == QTextBeginningOfFrame) {
550 Q_ASSERT(fragment_start == fragment);
552 } else if (type == QTextEndOfFrame) {
553 Q_ASSERT(fragment_end == fragment);
555 } else if (type == QChar::ObjectReplacementCharacter) {
556 Q_ASSERT(fragment_start == fragment);
557 Q_ASSERT(fragment_end == fragment);
567 void QTextFramePrivate::remove_me()
570 if (fragment_start == 0 && fragment_end == 0
572 q->document()->docHandle()->deleteObject(q);
579 int index = parentFrame->d_func()->childFrames.indexOf(q);
581 // iterator over all children and move them to the parent
582 for (int i = 0; i < childFrames.size(); ++i) {
583 QTextFrame *c = childFrames.at(i);
584 parentFrame->d_func()->childFrames.insert(index, c);
585 c->d_func()->parentFrame = parentFrame;
588 Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q);
589 parentFrame->d_func()->childFrames.removeAt(index);
596 \class QTextFrame::iterator
599 \brief The iterator class provides an iterator for reading
600 the contents of a QTextFrame.
602 \ingroup richtext-processing
604 A frame consists of an arbitrary sequence of \l{QTextBlock}s and
605 child \l{QTextFrame}s. This class provides a way to iterate over the
606 child objects of a frame, and read their contents. It does not provide
607 a way to modify the contents of the frame.
612 \fn bool QTextFrame::iterator::atEnd() const
614 Returns true if the current item is the last item in the text frame.
618 Returns an iterator pointing to the first document element inside the frame.
619 Please see the document \l{STL-style-Iterators} for more information.
623 QTextFrame::iterator QTextFrame::begin() const
625 const QTextDocumentPrivate *priv = docHandle();
626 int b = priv->blockMap().findNode(firstPosition());
627 int e = priv->blockMap().findNode(lastPosition()+1);
628 return iterator(const_cast<QTextFrame *>(this), b, b, e);
632 Returns an iterator pointing to the position past the last document element inside the frame.
633 Please see the document \l{STL-Style Iterators} for more information.
636 QTextFrame::iterator QTextFrame::end() const
638 const QTextDocumentPrivate *priv = docHandle();
639 int b = priv->blockMap().findNode(firstPosition());
640 int e = priv->blockMap().findNode(lastPosition()+1);
641 return iterator(const_cast<QTextFrame *>(this), e, b, e);
645 Constructs an invalid iterator.
647 QTextFrame::iterator::iterator()
659 QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
669 Copy constructor. Constructs a copy of the \a other iterator.
671 QTextFrame::iterator::iterator(const iterator &other)
681 Assigns \a other to this iterator and returns a reference to
684 QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other)
695 Returns the current frame pointed to by the iterator, or 0 if the
696 iterator currently points to a block.
700 QTextFrame *QTextFrame::iterator::currentFrame() const
706 Returns the current block the iterator points to. If the iterator
707 points to a child frame, the returned block is invalid.
711 QTextBlock QTextFrame::iterator::currentBlock() const
715 return QTextBlock(f->docHandle(), cb);
719 Moves the iterator to the next frame or block.
721 \sa currentBlock(), currentFrame()
723 QTextFrame::iterator &QTextFrame::iterator::operator++()
725 const QTextDocumentPrivate *priv = f->docHandle();
726 const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
728 int end = cf->lastPosition() + 1;
729 cb = map.findNode(end);
736 if (!f->d_func()->childFrames.isEmpty()) {
737 int pos = map.position(cb);
738 // check if we entered a frame
739 QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
740 if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
741 QTextFrame *nf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
743 if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame && nf != f) {
747 Q_ASSERT(priv->buffer().at(frag->stringPosition) != QTextEndOfFrame);
757 Moves the iterator to the previous frame or block.
759 \sa currentBlock(), currentFrame()
761 QTextFrame::iterator &QTextFrame::iterator::operator--()
763 const QTextDocumentPrivate *priv = f->docHandle();
764 const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
766 int start = cf->firstPosition() - 1;
767 cb = map.findNode(start);
773 int pos = map.position(cb);
774 // check if we have to enter a frame
775 QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
776 if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
777 QTextFrame *pf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
779 if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame) {
781 } else if (priv->buffer().at(frag->stringPosition) == QTextEndOfFrame) {
790 cb = map.previous(cb);
797 \class QTextBlockUserData
800 \brief The QTextBlockUserData class is used to associate custom data with blocks of text.
803 \ingroup richtext-processing
805 QTextBlockUserData provides an abstract interface for container classes that are used
806 to associate application-specific user data with text blocks in a QTextDocument.
808 Generally, subclasses of this class provide functions to allow data to be stored
809 and retrieved, and instances are attached to blocks of text using
810 QTextBlock::setUserData(). This makes it possible to store additional data per text
811 block in a way that can be retrieved safely by the application.
813 Each subclass should provide a reimplementation of the destructor to ensure that any
814 private data is automatically cleaned up when user data objects are deleted.
820 Destroys the user data.
822 QTextBlockUserData::~QTextBlockUserData()
830 \brief The QTextBlock class provides a container for text fragments in a
833 \ingroup richtext-processing
835 A text block encapsulates a block or paragraph of text in a QTextDocument.
836 QTextBlock provides read-only access to the block/paragraph structure of
837 QTextDocuments. It is mainly of use if you want to implement your own
838 layouts for the visual representation of a QTextDocument, or if you want to
839 iterate over a document and write out the contents in your own custom
842 Text blocks are created by their parent documents. If you need to create
843 a new text block, or modify the contents of a document while examining its
844 contents, use the cursor-based interface provided by QTextCursor instead.
846 Each text block is located at a specific position() in a document().
847 The contents of the block can be obtained by using the text() function.
848 The length() function determines the block's size within the document
849 (including formatting characters).
850 The visual properties of the block are determined by its text layout(),
851 its charFormat(), and its blockFormat().
853 The next() and previous() functions enable iteration over consecutive
854 valid blocks in a document under the condition that the document is not
855 modified by other means during the iteration process. Note that, although
856 blocks are returned in sequence, adjacent blocks may come from different
857 places in the document structure. The validity of a block can be determined
858 by calling isValid().
860 QTextBlock provides comparison operators to make it easier to work with
861 blocks: \l operator==() compares two block for equality, \l operator!=()
862 compares two blocks for inequality, and \l operator<() determines whether
863 a block precedes another in the same document.
865 \img qtextblock-sequence.png
867 \sa QTextBlockFormat, QTextCharFormat, QTextFragment
871 \fn QTextBlock::QTextBlock(QTextDocumentPrivate *priv, int b)
877 \fn QTextBlock::QTextBlock()
883 \fn QTextBlock::QTextBlock(const QTextBlock &other)
885 Copies the \a other text block's attributes to this text block.
889 \fn bool QTextBlock::isValid() const
891 Returns true if this text block is valid; otherwise returns false.
894 bool QTextBlock::isValid() const
896 return p != 0 && p->blockMap().isValid(n);
900 \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)
902 Assigns the \a other text block to this text block.
906 \fn bool QTextBlock::operator==(const QTextBlock &other) const
908 Returns true if this text block is the same as the \a other text
913 \fn bool QTextBlock::operator!=(const QTextBlock &other) const
915 Returns true if this text block is different from the \a other
920 \fn bool QTextBlock::operator<(const QTextBlock &other) const
922 Returns true if this text block occurs before the \a other text
923 block in the document.
927 \class QTextBlock::iterator
930 \brief The QTextBlock::iterator class provides an iterator for reading
931 the contents of a QTextBlock.
933 \ingroup richtext-processing
935 A block consists of a sequence of text fragments. This class provides
936 a way to iterate over these, and read their contents. It does not provide
937 a way to modify the internal structure or contents of the block.
939 An iterator can be constructed and used to access the fragments within
940 a text block in the following way:
942 \snippet textblock-fragments/xmlwriter.cpp 4
943 \snippet textblock-fragments/xmlwriter.cpp 7
949 \typedef QTextBlock::Iterator
951 Qt-style synonym for QTextBlock::iterator.
955 \fn QTextBlock::iterator::iterator()
957 Constructs an iterator for this text block.
961 \fn QTextBlock::iterator::iterator(const iterator &other)
963 Copy constructor. Constructs a copy of the \a other iterator.
967 \fn bool QTextBlock::iterator::atEnd() const
969 Returns true if the current item is the last item in the text block.
973 \fn bool QTextBlock::iterator::operator==(const iterator &other) const
975 Retuns true if this iterator is the same as the \a other iterator;
976 otherwise returns false.
980 \fn bool QTextBlock::iterator::operator!=(const iterator &other) const
982 Retuns true if this iterator is different from the \a other iterator;
983 otherwise returns false.
987 \fn QTextBlock::iterator QTextBlock::iterator::operator++(int)
989 The postfix ++ operator (\c{i++}) advances the iterator to the
990 next item in the text block and returns an iterator to the old current
995 \fn QTextBlock::iterator QTextBlock::iterator::operator--(int)
997 The postfix -- operator (\c{i--}) makes the preceding item current and
998 returns an iterator to the old current item.
1002 \fn QTextDocumentPrivate *QTextBlock::docHandle() const
1008 \fn int QTextBlock::fragmentIndex() const
1014 Returns the index of the block's first character within the document.
1016 int QTextBlock::position() const
1021 return p->blockMap().position(n);
1025 Returns the length of the block in characters.
1027 \note The length returned includes all formatting characters,
1028 for example, newline.
1030 \sa text(), charFormat(), blockFormat()
1032 int QTextBlock::length() const
1037 return p->blockMap().size(n);
1041 Returns true if the given \a position is located within the text
1042 block; otherwise returns false.
1044 bool QTextBlock::contains(int position) const
1049 int pos = p->blockMap().position(n);
1050 int len = p->blockMap().size(n);
1051 return position >= pos && position < pos + len;
1055 Returns the QTextLayout that is used to lay out and display the
1058 Note that the returned QTextLayout object can only be modified from the
1059 documentChanged implementation of a QAbstractTextDocumentLayout subclass.
1060 Any changes applied from the outside cause undefined behavior.
1064 QTextLayout *QTextBlock::layout() const
1069 const QTextBlockData *b = p->blockMap().fragment(n);
1071 b->layout = new QTextLayout(*this);
1077 Clears the QTextLayout that is used to lay out and display the
1082 void QTextBlock::clearLayout()
1087 const QTextBlockData *b = p->blockMap().fragment(n);
1089 b->layout->clearLayout();
1093 Returns the QTextBlockFormat that describes block-specific properties.
1097 QTextBlockFormat QTextBlock::blockFormat() const
1100 return QTextFormat().toBlockFormat();
1102 return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format);
1106 Returns an index into the document's internal list of block formats
1107 for the text block's format.
1109 \sa QTextDocument::allFormats()
1111 int QTextBlock::blockFormatIndex() const
1116 return p->blockMap().fragment(n)->format;
1120 Returns the QTextCharFormat that describes the block's character
1121 format. The block's character format is used when inserting text into
1126 QTextCharFormat QTextBlock::charFormat() const
1129 return QTextFormat().toCharFormat();
1131 return p->formatCollection()->charFormat(charFormatIndex());
1135 Returns an index into the document's internal list of character formats
1136 for the text block's character format.
1138 \sa QTextDocument::allFormats()
1140 int QTextBlock::charFormatIndex() const
1145 return p->blockCharFormatIndex(n);
1151 Returns the resolved text direction.
1153 If the block has no explicit direction set, it will resolve the
1154 direction from the blocks content. Returns either Qt::LeftToRight
1157 \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection
1159 Qt::LayoutDirection QTextBlock::textDirection() const
1161 Qt::LayoutDirection dir = blockFormat().layoutDirection();
1162 if (dir != Qt::LayoutDirectionAuto)
1165 dir = p->defaultTextOption.textDirection();
1166 if (dir != Qt::LayoutDirectionAuto)
1169 const QString buffer = p->buffer();
1171 const int pos = position();
1172 QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1173 QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1174 for (; it != end; ++it) {
1175 const QTextFragmentData * const frag = it.value();
1176 const QChar *p = buffer.constData() + frag->stringPosition;
1177 const QChar * const end = p + frag->size_array[0];
1179 switch(QChar::direction(p->unicode()))
1182 return Qt::LeftToRight;
1185 return Qt::RightToLeft;
1192 return Qt::LeftToRight;
1196 Returns the block's contents as plain text.
1198 \sa length(), charFormat(), blockFormat()
1200 QString QTextBlock::text() const
1205 const QString buffer = p->buffer();
1207 text.reserve(length());
1209 const int pos = position();
1210 QTextDocumentPrivate::FragmentIterator it = p->find(pos);
1211 QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
1212 for (; it != end; ++it) {
1213 const QTextFragmentData * const frag = it.value();
1214 text += QString::fromRawData(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1222 Returns the text document this text block belongs to, or 0 if the
1223 text block does not belong to any document.
1225 const QTextDocument *QTextBlock::document() const
1227 return p ? p->document() : 0;
1231 If the block represents a list item, returns the list that the item belongs
1232 to; otherwise returns 0.
1234 QTextList *QTextBlock::textList() const
1239 const QTextBlockFormat fmt = blockFormat();
1240 QTextObject *obj = p->document()->objectForFormat(fmt);
1241 return qobject_cast<QTextList *>(obj);
1247 Returns a pointer to a QTextBlockUserData object if previously set with
1248 setUserData() or a null pointer.
1250 QTextBlockUserData *QTextBlock::userData() const
1255 const QTextBlockData *b = p->blockMap().fragment(n);
1262 Attaches the given \a data object to the text block.
1264 QTextBlockUserData can be used to store custom settings. The
1265 ownership is passed to the underlying text document, i.e. the
1266 provided QTextBlockUserData object will be deleted if the
1267 corresponding text block gets deleted. The user data object is
1268 not stored in the undo history, so it will not be available after
1269 undoing the deletion of a text block.
1271 For example, if you write a programming editor in an IDE, you may
1272 want to let your user set breakpoints visually in your code for an
1273 integrated debugger. In a programming editor a line of text
1274 usually corresponds to one QTextBlock. The QTextBlockUserData
1275 interface allows the developer to store data for each QTextBlock,
1276 like for example in which lines of the source code the user has a
1277 breakpoint set. Of course this could also be stored externally,
1278 but by storing it inside the QTextDocument, it will for example be
1279 automatically deleted when the user deletes the associated
1280 line. It's really just a way to store custom information in the
1281 QTextDocument without using custom properties in QTextFormat which
1282 would affect the undo/redo stack.
1284 void QTextBlock::setUserData(QTextBlockUserData *data)
1289 const QTextBlockData *b = p->blockMap().fragment(n);
1290 if (data != b->userData)
1298 Returns the integer value previously set with setUserState() or -1.
1300 int QTextBlock::userState() const
1305 const QTextBlockData *b = p->blockMap().fragment(n);
1306 return b->userState;
1312 Stores the specified \a state integer value in the text block. This may be
1313 useful for example in a syntax highlighter to store a text parsing state.
1315 void QTextBlock::setUserState(int state)
1320 const QTextBlockData *b = p->blockMap().fragment(n);
1321 b->userState = state;
1327 Returns the blocks revision.
1329 \sa setRevision(), QTextDocument::revision()
1331 int QTextBlock::revision() const
1336 const QTextBlockData *b = p->blockMap().fragment(n);
1343 Sets a blocks revision to \a rev.
1345 \sa revision(), QTextDocument::revision()
1347 void QTextBlock::setRevision(int rev)
1352 const QTextBlockData *b = p->blockMap().fragment(n);
1359 Returns true if the block is visible; otherwise returns false.
1363 bool QTextBlock::isVisible() const
1368 const QTextBlockData *b = p->blockMap().fragment(n);
1375 Sets the block's visibility to \a visible.
1379 void QTextBlock::setVisible(bool visible)
1384 const QTextBlockData *b = p->blockMap().fragment(n);
1385 b->hidden = !visible;
1392 Returns the number of this block, or -1 if the block is invalid.
1394 \sa QTextCursor::blockNumber()
1397 int QTextBlock::blockNumber() const
1401 return p->blockMap().position(n, 1);
1407 Returns the first line number of this block, or -1 if the block is invalid.
1408 Unless the layout supports it, the line number is identical to the block number.
1410 \sa QTextBlock::blockNumber()
1413 int QTextBlock::firstLineNumber() const
1417 return p->blockMap().position(n, 2);
1424 Sets the line count to \a count.
1428 void QTextBlock::setLineCount(int count)
1432 p->blockMap().setSize(n, count, 2);
1437 Returns the line count. Not all document layouts support this feature.
1441 int QTextBlock::lineCount() const
1445 return p->blockMap().size(n, 2);
1450 Returns a text block iterator pointing to the beginning of the
1455 QTextBlock::iterator QTextBlock::begin() const
1460 int pos = position();
1461 int len = length() - 1; // exclude the fragment that holds the paragraph separator
1462 int b = p->fragmentMap().findNode(pos);
1463 int e = p->fragmentMap().findNode(pos+len);
1464 return iterator(p, b, e, b);
1468 Returns a text block iterator pointing to the end of the text
1471 \sa begin(), next(), previous()
1473 QTextBlock::iterator QTextBlock::end() const
1478 int pos = position();
1479 int len = length() - 1; // exclude the fragment that holds the paragraph separator
1480 int b = p->fragmentMap().findNode(pos);
1481 int e = p->fragmentMap().findNode(pos+len);
1482 return iterator(p, b, e, e);
1487 Returns the text block in the document after this block, or an empty
1488 text block if this is the last one.
1490 Note that the next block may be in a different frame or table to this block.
1492 \sa previous(), begin(), end()
1494 QTextBlock QTextBlock::next() const
1497 return QTextBlock();
1499 return QTextBlock(p, p->blockMap().next(n));
1503 Returns the text block in the document before this block, or an empty text
1504 block if this is the first one.
1506 Note that the next block may be in a different frame or table to this block.
1508 \sa next(), begin(), end()
1510 QTextBlock QTextBlock::previous() const
1513 return QTextBlock();
1515 return QTextBlock(p, p->blockMap().previous(n));
1520 Returns the text fragment the iterator currently points to.
1522 QTextFragment QTextBlock::iterator::fragment() const
1525 int formatIndex = p->fragmentMap().fragment(n)->format;
1527 ne = p->fragmentMap().next(ne);
1528 } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1529 return QTextFragment(p, n, ne);
1533 The prefix ++ operator (\c{++i}) advances the iterator to the
1534 next item in the hash and returns an iterator to the new current
1538 QTextBlock::iterator &QTextBlock::iterator::operator++()
1541 int formatIndex = p->fragmentMap().fragment(n)->format;
1543 ne = p->fragmentMap().next(ne);
1544 } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
1550 The prefix -- operator (\c{--i}) makes the preceding item
1551 current and returns an iterator pointing to the new current item.
1554 QTextBlock::iterator &QTextBlock::iterator::operator--()
1556 n = p->fragmentMap().previous(n);
1561 int formatIndex = p->fragmentMap().fragment(n)->format;
1564 while (n != b && p->fragmentMap().fragment(n)->format != formatIndex) {
1566 n = p->fragmentMap().previous(n);
1575 \class QTextFragment
1578 \brief The QTextFragment class holds a piece of text in a
1579 QTextDocument with a single QTextCharFormat.
1581 \ingroup richtext-processing
1583 A text fragment describes a piece of text that is stored with a single
1584 character format. Text in which the character format changes can be
1585 represented by sequences of text fragments with different formats.
1587 If the user edits the text in a fragment and introduces a different
1588 character format, the fragment's text will be split at each point where
1589 the format changes, and new fragments will be created.
1590 For example, changing the style of some text in the middle of a
1591 sentence will cause the fragment to be broken into three separate fragments:
1592 the first and third with the same format as before, and the second with
1593 the new style. The first fragment will contain the text from the beginning
1594 of the sentence, the second will contain the text from the middle, and the
1595 third takes the text from the end of the sentence.
1597 \img qtextfragment-split.png
1599 A fragment's text and character format can be obtained with the text()
1600 and charFormat() functions. The length() function gives the length of
1601 the text in the fragment. position() gives the position in the document
1602 of the start of the fragment. To determine whether the fragment contains
1603 a particular position within the document, use the contains() function.
1605 \sa QTextDocument, {Rich Text Document Structure}
1609 \fn QTextFragment::QTextFragment(const QTextDocumentPrivate *priv, int f, int fe)
1614 \fn QTextFragment::QTextFragment()
1616 Creates a new empty text fragment.
1620 \fn QTextFragment::QTextFragment(const QTextFragment &other)
1622 Copies the content (text and format) of the \a other text fragment
1623 to this text fragment.
1627 \fn QTextFragment &QTextFragment::operator=(const QTextFragment
1630 Assigns the content (text and format) of the \a other text fragment
1631 to this text fragment.
1635 \fn bool QTextFragment::isValid() const
1637 Returns true if this is a valid text fragment (i.e. has a valid
1638 position in a document); otherwise returns false.
1642 \fn bool QTextFragment::operator==(const QTextFragment &other) const
1644 Returns true if this text fragment is the same (at the same
1645 position) as the \a other text fragment; otherwise returns false.
1649 \fn bool QTextFragment::operator!=(const QTextFragment &other) const
1651 Returns true if this text fragment is different (at a different
1652 position) from the \a other text fragment; otherwise returns
1657 \fn bool QTextFragment::operator<(const QTextFragment &other) const
1659 Returns true if this text fragment appears earlier in the document
1660 than the \a other text fragment; otherwise returns false.
1664 Returns the glyphs of this text fragment. The positions of the glyphs are
1665 relative to the position of the QTextBlock's layout.
1667 \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun()
1669 #if !defined(QT_NO_RAWFONT)
1670 QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const
1673 return QList<QGlyphRun>();
1675 int blockNode = p->blockMap().findNode(position());
1677 const QTextBlockData *blockData = p->blockMap().fragment(blockNode);
1678 QTextLayout *layout = blockData->layout;
1680 int blockPosition = p->blockMap().position(blockNode);
1682 pos = position() - blockPosition;
1686 return QList<QGlyphRun>();
1688 QList<QGlyphRun> ret;
1689 for (int i=0; i<layout->lineCount(); ++i) {
1690 QTextLine textLine = layout->lineAt(i);
1691 ret += textLine.glyphRuns(pos, len);
1696 #endif // QT_NO_RAWFONT
1699 Returns the position of this text fragment in the document.
1701 int QTextFragment::position() const
1704 return 0; // ### -1 instead?
1706 return p->fragmentMap().position(n);
1710 Returns the number of characters in the text fragment.
1714 int QTextFragment::length() const
1722 len += p->fragmentMap().size(f);
1723 f = p->fragmentMap().next(f);
1729 Returns true if the text fragment contains the text at the given
1730 \a position in the document; otherwise returns false.
1732 bool QTextFragment::contains(int position) const
1736 int pos = this->position();
1737 return position >= pos && position < pos + length();
1741 Returns the text fragment's character format.
1745 QTextCharFormat QTextFragment::charFormat() const
1748 return QTextCharFormat();
1749 const QTextFragmentData *data = p->fragmentMap().fragment(n);
1750 return p->formatCollection()->charFormat(data->format);
1754 Returns an index into the document's internal list of character formats
1755 for the text fragment's character format.
1757 \sa QTextDocument::allFormats()
1759 int QTextFragment::charFormatIndex() const
1763 const QTextFragmentData *data = p->fragmentMap().fragment(n);
1764 return data->format;
1768 Returns the text fragment's as plain text.
1770 \sa length(), charFormat()
1772 QString QTextFragment::text() const
1778 QString buffer = p->buffer();
1781 const QTextFragmentData * const frag = p->fragmentMap().fragment(f);
1782 result += QString(buffer.constData() + frag->stringPosition, frag->size_array[0]);
1783 f = p->fragmentMap().next(f);