/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtextobject.h"
#include "qtextobject_p.h"
#include "qtextdocument.h"
#include "qtextformat_p.h"
#include "qtextdocument_p.h"
#include "qtextcursor.h"
#include "qtextlist.h"
#include "qabstracttextdocumentlayout.h"
#include "qtextengine_p.h"
#include "qdebug.h"

QT_BEGIN_NAMESPACE

// ### DOC: We ought to explain the CONCEPT of objectIndexes if
// relevant to the public API
/*!
    \class QTextObject
    \reentrant

    \brief The QTextObject class is a base class for different kinds
    of objects that can group parts of a QTextDocument together.

    \ingroup richtext-processing

    The common grouping text objects are lists (QTextList), frames
    (QTextFrame), and tables (QTextTable). A text object has an
    associated format() and document().

    There are essentially two kinds of text objects: those that are used
    with blocks (block formats), and those that are used with characters
    (character formats). The first kind are derived from QTextBlockGroup,
    and the second kind from QTextFrame.

    You rarely need to use this class directly. When creating custom text
    objects, you will also need to reimplement QTextDocument::createObject()
    which acts as a factory method for creating text objects.

    \sa QTextDocument, {Text Object Example}
*/

/*!
    \fn QTextObject::QTextObject(QTextDocument *document)

    Creates a new QTextObject for the given \a document.

    \warning This function should never be called directly, but only
    from QTextDocument::createObject().
*/
QTextObject::QTextObject(QTextDocument *doc)
    : QObject(*new QTextObjectPrivate(doc), doc)
{
}

/*!
  \fn QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *document)

  \internal
*/
QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc)
    : QObject(p, doc)
{
}

/*!
    Destroys the text object.

    \warning Text objects are owned by the document, so you should
    never destroy them yourself.
*/
QTextObject::~QTextObject()
{
}

/*!
    Returns the text object's format.

    \sa setFormat() document()
*/
QTextFormat QTextObject::format() const
{
    Q_D(const QTextObject);
    return d->pieceTable->formatCollection()->objectFormat(d->objectIndex);
}

/*!
    Returns the index of the object's format in the document's internal
    list of formats.

    \sa QTextDocument::allFormats()
*/
int QTextObject::formatIndex() const
{
    Q_D(const QTextObject);
    return d->pieceTable->formatCollection()->objectFormatIndex(d->objectIndex);
}


/*!
    Sets the text object's \a format.

    \sa format()
*/
void QTextObject::setFormat(const QTextFormat &format)
{
    Q_D(QTextObject);
    int idx = d->pieceTable->formatCollection()->indexForFormat(format);
    d->pieceTable->changeObjectFormat(this, idx);
}

/*!
    Returns the object index of this object. This can be used together with
    QTextFormat::setObjectIndex().
*/
int QTextObject::objectIndex() const
{
    Q_D(const QTextObject);
    return d->objectIndex;
}

/*!
    Returns the document this object belongs to.

    \sa format()
*/
QTextDocument *QTextObject::document() const
{
    return static_cast<QTextDocument *>(parent());
}

/*!
  \internal
*/
QTextDocumentPrivate *QTextObject::docHandle() const
{
    return static_cast<const QTextDocument *>(parent())->docHandle();
}

/*!
    \class QTextBlockGroup
    \reentrant

    \brief The QTextBlockGroup class provides a container for text blocks within
    a QTextDocument.

    \ingroup richtext-processing

    Block groups can be used to organize blocks of text within a document.
    They maintain an up-to-date list of the text blocks that belong to
    them, even when text blocks are being edited.

    Each group has a parent document which is specified when the group is
    constructed.

    Text blocks can be inserted into a group with blockInserted(), and removed
    with blockRemoved(). If a block's format is changed, blockFormatChanged()
    is called.

    The list of blocks in the group is returned by blockList(). Note that the
    blocks in the list are not necessarily adjacent elements in the document;
    for example, the top-level items in a multi-level list will be separated
    by the items in lower levels of the list.

    \sa QTextBlock QTextDocument
*/

void QTextBlockGroupPrivate::markBlocksDirty()
{
    for (int i = 0; i < blocks.count(); ++i) {
        const QTextBlock &block = blocks.at(i);
        pieceTable->documentChange(block.position(), block.length());
    }
}

/*!
    \fn QTextBlockGroup::QTextBlockGroup(QTextDocument *document)

    Creates a new new block group for the given \a document.

    \warning This function should only be called from
    QTextDocument::createObject().
*/
QTextBlockGroup::QTextBlockGroup(QTextDocument *doc)
    : QTextObject(*new QTextBlockGroupPrivate(doc), doc)
{
}

/*!
  \internal
*/
QTextBlockGroup::QTextBlockGroup(QTextBlockGroupPrivate &p, QTextDocument *doc)
    : QTextObject(p, doc)
{
}

/*!
    Destroys this block group; the blocks are not deleted, they simply
    don't belong to this block anymore.
*/
QTextBlockGroup::~QTextBlockGroup()
{
}

// ### DOC: Shouldn't this be insertBlock()?
/*!
    Appends the given \a block to the end of the group.

    \warning If you reimplement this function you must call the base
    class implementation.
*/
void QTextBlockGroup::blockInserted(const QTextBlock &block)
{
    Q_D(QTextBlockGroup);
    QTextBlockGroupPrivate::BlockList::Iterator it = qLowerBound(d->blocks.begin(), d->blocks.end(), block);
    d->blocks.insert(it, block);
    d->markBlocksDirty();
}

// ### DOC: Shouldn't this be removeBlock()?
/*!
    Removes the given \a block from the group; the block itself is not
    deleted, it simply isn't a member of this group anymore.
*/
void QTextBlockGroup::blockRemoved(const QTextBlock &block)
{
    Q_D(QTextBlockGroup);
    d->blocks.removeAll(block);
    d->markBlocksDirty();
    if (d->blocks.isEmpty()) {
        document()->docHandle()->deleteObject(this);
        return;
    }
}

/*!
    This function is called whenever the specified \a block of text is changed.
    The text block is a member of this group.

    The base class implementation does nothing.
*/
void QTextBlockGroup::blockFormatChanged(const QTextBlock &)
{
}

/*!
    Returns a (possibly empty) list of all the blocks that are part of
    the block group.
*/
QList<QTextBlock> QTextBlockGroup::blockList() const
{
    Q_D(const QTextBlockGroup);
    return d->blocks;
}



QTextFrameLayoutData::~QTextFrameLayoutData()
{
}


/*!
    \class QTextFrame
    \reentrant

    \brief The QTextFrame class represents a frame in a QTextDocument.

    \ingroup richtext-processing

    Text frames provide structure for the text in a document. They are used
    as generic containers for other document elements.
    Frames are usually created by using QTextCursor::insertFrame().

    \omit
    Each frame in a document consists of a frame start character,
    QChar(0xFDD0), followed by the frame's contents, followed by a
    frame end character, QChar(0xFDD1). The character formats of the
    start and end character contain a reference to the frame object's
    objectIndex.
    \endomit

    Frames can be used to create hierarchical structures in rich text documents.
    Each document has a root frame (QTextDocument::rootFrame()), and each frame
    beneath the root frame has a parent frame and a (possibly empty) list of
    child frames. The parent frame can be found with parentFrame(), and the
    childFrames() function provides a list of child frames.

    Each frame contains at least one text block to enable text cursors to
    insert new document elements within. As a result, the QTextFrame::iterator
    class is used to traverse both the blocks and child frames within a given
    frame. The first and last child elements in the frame can be found with
    begin() and end().

    A frame also has a format (specified using QTextFrameFormat) which can be set
    with setFormat() and read with format().

    Text cursors can be obtained that point to the first and last valid cursor
    positions within a frame; use the firstCursorPosition() and
    lastCursorPosition() functions for this. The frame's extent in the
    document can be found with firstPosition() and lastPosition().

    You can iterate over a frame's contents using the
    QTextFrame::iterator class: this provides read-only access to its
    internal list of text blocks and child frames.

    \sa QTextCursor QTextDocument
*/

/*!
    \typedef QTextFrame::Iterator

    Qt-style synonym for QTextFrame::iterator.
*/

/*!
    \fn QTextFrame *QTextFrame::iterator::parentFrame() const

    Returns the parent frame of the current frame.

    \sa currentFrame() QTextFrame::parentFrame()
*/

/*!
    \fn bool QTextFrame::iterator::operator==(const iterator &other) const

    Retuns true if the iterator is the same as the \a other iterator;
    otherwise returns false.
*/

/*!
    \fn bool QTextFrame::iterator::operator!=(const iterator &other) const

    Retuns true if the iterator is different from the \a other iterator;
    otherwise returns false.
*/

/*!
    \fn QTextFrame::iterator QTextFrame::iterator::operator++(int)

    The postfix ++ operator (\c{i++}) advances the iterator to the
    next item in the text frame, and returns an iterator to the old item.
*/

/*!
    \fn QTextFrame::iterator QTextFrame::iterator::operator--(int)

    The postfix -- operator (\c{i--}) makes the preceding item in the
    current frame, and returns an iterator to the old item.
*/

/*!
    \fn void QTextFrame::setFrameFormat(const QTextFrameFormat &format)

    Sets the frame's \a format.

    \sa frameFormat()
*/

/*!
    \fn QTextFrameFormat QTextFrame::frameFormat() const

    Returns the frame's format.

    \sa setFrameFormat()
*/

/*!
    \fn QTextFrame::QTextFrame(QTextDocument *document)

    Creates a new empty frame for the text \a document.
*/
QTextFrame::QTextFrame(QTextDocument *doc)
    : QTextObject(*new QTextFramePrivate(doc), doc)
{
}

// ### DOC: What does this do to child frames?
/*!
    Destroys the frame, and removes it from the document's layout.
*/
QTextFrame::~QTextFrame()
{
    Q_D(QTextFrame);
    delete d->layoutData;
}

/*!
    \internal
*/
QTextFrame::QTextFrame(QTextFramePrivate &p, QTextDocument *doc)
    : QTextObject(p, doc)
{
}

/*!
    Returns a (possibly empty) list of the frame's child frames.

    \sa parentFrame()
*/
QList<QTextFrame *> QTextFrame::childFrames() const
{
    Q_D(const QTextFrame);
    return d->childFrames;
}

/*!
    Returns the frame's parent frame. If the frame is the root frame of a
    document, this will return 0.

    \sa childFrames() QTextDocument::rootFrame()
*/
QTextFrame *QTextFrame::parentFrame() const
{
    Q_D(const QTextFrame);
    return d->parentFrame;
}


/*!
    Returns the first cursor position inside the frame.

    \sa lastCursorPosition() firstPosition() lastPosition()
*/
QTextCursor QTextFrame::firstCursorPosition() const
{
    Q_D(const QTextFrame);
    return QTextCursor(d->pieceTable, firstPosition());
}

/*!
    Returns the last cursor position inside the frame.

    \sa firstCursorPosition() firstPosition() lastPosition()
*/
QTextCursor QTextFrame::lastCursorPosition() const
{
    Q_D(const QTextFrame);
    return QTextCursor(d->pieceTable, lastPosition());
}

/*!
    Returns the first document position inside the frame.

    \sa lastPosition() firstCursorPosition() lastCursorPosition()
*/
int QTextFrame::firstPosition() const
{
    Q_D(const QTextFrame);
    if (!d->fragment_start)
        return 0;
    return d->pieceTable->fragmentMap().position(d->fragment_start) + 1;
}

/*!
    Returns the last document position inside the frame.

    \sa firstPosition() firstCursorPosition() lastCursorPosition()
*/
int QTextFrame::lastPosition() const
{
    Q_D(const QTextFrame);
    if (!d->fragment_end)
        return d->pieceTable->length() - 1;
    return d->pieceTable->fragmentMap().position(d->fragment_end);
}

/*!
  \internal
*/
QTextFrameLayoutData *QTextFrame::layoutData() const
{
    Q_D(const QTextFrame);
    return d->layoutData;
}

/*!
  \internal
*/
void QTextFrame::setLayoutData(QTextFrameLayoutData *data)
{
    Q_D(QTextFrame);
    delete d->layoutData;
    d->layoutData = data;
}



void QTextFramePrivate::fragmentAdded(const QChar &type, uint fragment)
{
    if (type == QTextBeginningOfFrame) {
        Q_ASSERT(!fragment_start);
        fragment_start = fragment;
    } else if (type == QTextEndOfFrame) {
        Q_ASSERT(!fragment_end);
        fragment_end = fragment;
    } else if (type == QChar::ObjectReplacementCharacter) {
        Q_ASSERT(!fragment_start);
        Q_ASSERT(!fragment_end);
        fragment_start = fragment;
        fragment_end = fragment;
    } else {
        Q_ASSERT(false);
    }
}

void QTextFramePrivate::fragmentRemoved(const QChar &type, uint fragment)
{
    Q_UNUSED(fragment); // --release warning
    if (type == QTextBeginningOfFrame) {
        Q_ASSERT(fragment_start == fragment);
        fragment_start = 0;
    } else if (type == QTextEndOfFrame) {
        Q_ASSERT(fragment_end == fragment);
        fragment_end = 0;
    } else if (type == QChar::ObjectReplacementCharacter) {
        Q_ASSERT(fragment_start == fragment);
        Q_ASSERT(fragment_end == fragment);
        fragment_start = 0;
        fragment_end = 0;
    } else {
        Q_ASSERT(false);
    }
    remove_me();
}


void QTextFramePrivate::remove_me()
{
    Q_Q(QTextFrame);
    if (fragment_start == 0 && fragment_end == 0
        && !parentFrame) {
        q->document()->docHandle()->deleteObject(q);
        return;
    }

    if (!parentFrame)
        return;

    int index = parentFrame->d_func()->childFrames.indexOf(q);

    // iterator over all children and move them to the parent
    for (int i = 0; i < childFrames.size(); ++i) {
        QTextFrame *c = childFrames.at(i);
        parentFrame->d_func()->childFrames.insert(index, c);
        c->d_func()->parentFrame = parentFrame;
        ++index;
    }
    Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q);
    parentFrame->d_func()->childFrames.removeAt(index);

    childFrames.clear();
    parentFrame = 0;
}

/*!
    \class QTextFrame::iterator
    \reentrant

    \brief The iterator class provides an iterator for reading
    the contents of a QTextFrame.

    \ingroup richtext-processing

    A frame consists of an arbitrary sequence of \l{QTextBlock}s and
    child \l{QTextFrame}s. This class provides a way to iterate over the
    child objects of a frame, and read their contents. It does not provide
    a way to modify the contents of the frame.

*/

/*!
    \fn bool QTextFrame::iterator::atEnd() const

    Returns true if the current item is the last item in the text frame.
*/

/*!
    Returns an iterator pointing to the first document element inside the frame.
    Please see the document \l{STL-style-Iterators} for more information.

    \sa end()
*/
QTextFrame::iterator QTextFrame::begin() const
{
    const QTextDocumentPrivate *priv = docHandle();
    int b = priv->blockMap().findNode(firstPosition());
    int e = priv->blockMap().findNode(lastPosition()+1);
    return iterator(const_cast<QTextFrame *>(this), b, b, e);
}

/*!
    Returns an iterator pointing to the position past the last document element inside the frame.
    Please see the document \l{STL-Style Iterators} for more information.    
    \sa begin()
*/
QTextFrame::iterator QTextFrame::end() const
{
    const QTextDocumentPrivate *priv = docHandle();
    int b = priv->blockMap().findNode(firstPosition());
    int e = priv->blockMap().findNode(lastPosition()+1);
    return iterator(const_cast<QTextFrame *>(this), e, b, e);
}

/*!
    Constructs an invalid iterator.
*/
QTextFrame::iterator::iterator()
{
    f = 0;
    b = 0;
    e = 0;
    cf = 0;
    cb = 0;
}

/*!
  \internal
*/
QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
{
    f = frame;
    b = begin;
    e = end;
    cf = 0;
    cb = block;
}

/*!
    Copy constructor. Constructs a copy of the \a other iterator.
*/
QTextFrame::iterator::iterator(const iterator &other)
{
    f = other.f;
    b = other.b;
    e = other.e;
    cf = other.cf;
    cb = other.cb;
}

/*!
    Assigns \a other to this iterator and returns a reference to
    this iterator.
*/
QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other)
{
    f = other.f;
    b = other.b;
    e = other.e;
    cf = other.cf;
    cb = other.cb;
    return *this;
}

/*!
    Returns the current frame pointed to by the iterator, or 0 if the
    iterator currently points to a block.

    \sa currentBlock()
*/
QTextFrame *QTextFrame::iterator::currentFrame() const
{
    return cf;
}

/*!
    Returns the current block the iterator points to. If the iterator
    points to a child frame, the returned block is invalid.

    \sa currentFrame()
*/
QTextBlock QTextFrame::iterator::currentBlock() const
{
    if (!f)
        return QTextBlock();
    return QTextBlock(f->docHandle(), cb);
}

/*!
    Moves the iterator to the next frame or block.

    \sa currentBlock() currentFrame()
*/
QTextFrame::iterator &QTextFrame::iterator::operator++()
{
    const QTextDocumentPrivate *priv = f->docHandle();
    const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
    if (cf) {
        int end = cf->lastPosition() + 1;
        cb = map.findNode(end);
        cf = 0;
    } else if (cb) {
        cb = map.next(cb);
        if (cb == e)
            return *this;

        if (!f->d_func()->childFrames.isEmpty()) {
            int pos = map.position(cb);
            // check if we entered a frame
            QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
            if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
                QTextFrame *nf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
                if (nf) {
                    if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame && nf != f) {
                        cf = nf;
                        cb = 0;
                    } else {
                        Q_ASSERT(priv->buffer().at(frag->stringPosition) != QTextEndOfFrame);
                    }
                }
            }
        }
    }
    return *this;
}

/*!
    Moves the iterator to the previous frame or block.

    \sa currentBlock() currentFrame()
*/
QTextFrame::iterator &QTextFrame::iterator::operator--()
{
    const QTextDocumentPrivate *priv = f->docHandle();
    const QTextDocumentPrivate::BlockMap &map = priv->blockMap();
    if (cf) {
        int start = cf->firstPosition() - 1;
        cb = map.findNode(start);
        cf = 0;
    } else {
        if (cb == b)
            goto end;
        if (cb != e) {
            int pos = map.position(cb);
            // check if we have to enter a frame
            QTextDocumentPrivate::FragmentIterator frag = priv->find(pos-1);
            if (priv->buffer().at(frag->stringPosition) != QChar::ParagraphSeparator) {
                QTextFrame *pf = qobject_cast<QTextFrame *>(priv->objectForFormat(frag->format));
                if (pf) {
                    if (priv->buffer().at(frag->stringPosition) == QTextBeginningOfFrame) {
                        Q_ASSERT(pf == f);
                    } else if (priv->buffer().at(frag->stringPosition) == QTextEndOfFrame) {
                        Q_ASSERT(pf != f);
                        cf = pf;
                        cb = 0;
                        goto end;
                    }
                }
            }
        }
        cb = map.previous(cb);
    }
 end:
    return *this;
}

/*!
    \class QTextBlockUserData
    \reentrant

    \brief The QTextBlockUserData class is used to associate custom data with blocks of text.
    \since 4.1

    \ingroup richtext-processing

    QTextBlockUserData provides an abstract interface for container classes that are used
    to associate application-specific user data with text blocks in a QTextDocument.

    Generally, subclasses of this class provide functions to allow data to be stored
    and retrieved, and instances are attached to blocks of text using
    QTextBlock::setUserData(). This makes it possible to store additional data per text
    block in a way that can be retrieved safely by the application.

    Each subclass should provide a reimplementation of the destructor to ensure that any
    private data is automatically cleaned up when user data objects are deleted.

    \sa QTextBlock
*/

/*!
    Destroys the user data.
*/
QTextBlockUserData::~QTextBlockUserData()
{
}

/*!
    \class QTextBlock
    \reentrant

    \brief The QTextBlock class provides a container for text fragments in a
    QTextDocument.

    \ingroup richtext-processing

    A text block encapsulates a block or paragraph of text in a QTextDocument.
    QTextBlock provides read-only access to the block/paragraph structure of
    QTextDocuments. It is mainly of use if you want to implement your own
    layouts for the visual representation of a QTextDocument, or if you want to
    iterate over a document and write out the contents in your own custom
    format.

    Text blocks are created by their parent documents. If you need to create
    a new text block, or modify the contents of a document while examining its
    contents, use the cursor-based interface provided by QTextCursor instead.

    Each text block is located at a specific position() in a document().
    The contents of the block can be obtained by using the text() function.
    The length() function determines the block's size within the document
    (including formatting characters).
    The visual properties of the block are determined by its text layout(),
    its charFormat(), and its blockFormat().

    The next() and previous() functions enable iteration over consecutive
    valid blocks in a document under the condition that the document is not
    modified by other means during the iteration process. Note that, although
    blocks are returned in sequence, adjacent blocks may come from different
    places in the document structure. The validity of a block can be determined
    by calling isValid().

    QTextBlock provides comparison operators to make it easier to work with
    blocks: \l operator==() compares two block for equality, \l operator!=()
    compares two blocks for inequality, and \l operator<() determines whether
    a block precedes another in the same document.

    \img qtextblock-sequence.png

    \sa QTextBlockFormat QTextCharFormat QTextFragment
 */

/*!
    \fn QTextBlock::QTextBlock(QTextDocumentPrivate *priv, int b)

    \internal
*/

/*!
    \fn QTextBlock::QTextBlock()

    \internal
*/

/*!
    \fn QTextBlock::QTextBlock(const QTextBlock &other)

    Copies the \a other text block's attributes to this text block.
*/

/*!
    \fn bool QTextBlock::isValid() const

    Returns true if this text block is valid; otherwise returns false.
*/

/*!
    \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)

    Assigns the \a other text block to this text block.
*/

/*!
    \fn bool QTextBlock::operator==(const QTextBlock &other) const

    Returns true if this text block is the same as the \a other text
    block.
*/

/*!
    \fn bool QTextBlock::operator!=(const QTextBlock &other) const

    Returns true if this text block is different from the \a other
    text block.
*/

/*!
    \fn bool QTextBlock::operator<(const QTextBlock &other) const

    Returns true if this text block occurs before the \a other text
    block in the document.
*/

/*!
    \class QTextBlock::iterator
    \reentrant

    \brief The QTextBlock::iterator class provides an iterator for reading
    the contents of a QTextBlock.

    \ingroup richtext-processing

    A block consists of a sequence of text fragments. This class provides
    a way to iterate over these, and read their contents. It does not provide
    a way to modify the internal structure or contents of the block.

    An iterator can be constructed and used to access the fragments within
    a text block in the following way:

    \snippet doc/src/snippets/textblock-fragments/xmlwriter.cpp 4
    \snippet doc/src/snippets/textblock-fragments/xmlwriter.cpp 7

    \sa QTextFragment
*/

/*!
    \typedef QTextBlock::Iterator

    Qt-style synonym for QTextBlock::iterator.
*/

/*!
    \fn QTextBlock::iterator::iterator()

    Constructs an iterator for this text block.
*/

/*!
    \fn QTextBlock::iterator::iterator(const iterator &other)

    Copy constructor. Constructs a copy of the \a other iterator.
*/

/*!
    \fn bool QTextBlock::iterator::atEnd() const

    Returns true if the current item is the last item in the text block.
*/

/*!
    \fn bool QTextBlock::iterator::operator==(const iterator &other) const

    Retuns true if this iterator is the same as the \a other iterator;
    otherwise returns false.
*/

/*!
    \fn bool QTextBlock::iterator::operator!=(const iterator &other) const

    Retuns true if this iterator is different from the \a other iterator;
    otherwise returns false.
*/

/*!
    \fn QTextBlock::iterator QTextBlock::iterator::operator++(int)

    The postfix ++ operator (\c{i++}) advances the iterator to the
    next item in the text block and returns an iterator to the old current
    item.
*/

/*!
    \fn QTextBlock::iterator QTextBlock::iterator::operator--(int)

    The postfix -- operator (\c{i--}) makes the preceding item current and
    returns an iterator to the old current item.
*/

/*!
    \fn QTextDocumentPrivate *QTextBlock::docHandle() const

    \internal
*/

/*!
    \fn int QTextBlock::fragmentIndex() const

    \internal
*/

/*!
    Returns the index of the block's first character within the document.
 */
int QTextBlock::position() const
{
    if (!p || !n)
        return 0;

    return p->blockMap().position(n);
}

/*!
    Returns the length of the block in characters.

    \note The length returned includes all formatting characters,
    for example, newline.

    \sa text() charFormat() blockFormat()
 */
int QTextBlock::length() const
{
    if (!p || !n)
        return 0;

    return p->blockMap().size(n);
}

/*!
    Returns true if the given \a position is located within the text
    block; otherwise returns false.
 */
bool QTextBlock::contains(int position) const
{
    if (!p || !n)
        return false;

    int pos = p->blockMap().position(n);
    int len = p->blockMap().size(n);
    return position >= pos && position < pos + len;
}

/*!
    Returns the QTextLayout that is used to lay out and display the
    block's contents.

    Note that the returned QTextLayout object can only be modified from the
    documentChanged implementation of a QAbstractTextDocumentLayout subclass.
    Any changes applied from the outside cause undefined behavior.

    \sa clearLayout()
 */
QTextLayout *QTextBlock::layout() const
{
    if (!p || !n)
        return 0;

    const QTextBlockData *b = p->blockMap().fragment(n);
    if (!b->layout)
        b->layout = new QTextLayout(*this);
    return b->layout;
}

/*!
    \since 4.4
    Clears the QTextLayout that is used to lay out and display the
    block's contents.

    \sa layout()
 */
void QTextBlock::clearLayout()
{
    if (!p || !n)
        return;

    const QTextBlockData *b = p->blockMap().fragment(n);
    if (b->layout)
        b->layout->clearLayout();
}

/*!
    Returns the QTextBlockFormat that describes block-specific properties.

    \sa charFormat()
 */
QTextBlockFormat QTextBlock::blockFormat() const
{
    if (!p || !n)
        return QTextFormat().toBlockFormat();

    return p->formatCollection()->blockFormat(p->blockMap().fragment(n)->format);
}

/*!
    Returns an index into the document's internal list of block formats
    for the text block's format.

    \sa QTextDocument::allFormats()
*/
int QTextBlock::blockFormatIndex() const
{
    if (!p || !n)
        return -1;

    return p->blockMap().fragment(n)->format;
}

/*!
    Returns the QTextCharFormat that describes the block's character
    format. The block's character format is used when inserting text into
    an empty block.

    \sa blockFormat()
 */
QTextCharFormat QTextBlock::charFormat() const
{
    if (!p || !n)
        return QTextFormat().toCharFormat();

    return p->formatCollection()->charFormat(charFormatIndex());
}

/*!
    Returns an index into the document's internal list of character formats
    for the text block's character format.

    \sa QTextDocument::allFormats()
*/
int QTextBlock::charFormatIndex() const
{
    if (!p || !n)
        return -1;

    return p->blockCharFormatIndex(n);
}

/*!
  \since 4.7

  Returns the resolved text direction.

  If the block has no explicit direction set, it will resolve the
  direction from the blocks content. Returns either Qt::LeftToRight
  or Qt::RightToLeft.

  \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection
*/
Qt::LayoutDirection QTextBlock::textDirection() const
{
    Qt::LayoutDirection dir = blockFormat().layoutDirection();
    if (dir != Qt::LayoutDirectionAuto)
        return dir;

    dir = p->defaultTextOption.textDirection();
    if (dir != Qt::LayoutDirectionAuto)
        return dir;

    const QString buffer = p->buffer();

    const int pos = position();
    QTextDocumentPrivate::FragmentIterator it = p->find(pos);
    QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
    for (; it != end; ++it) {
        const QTextFragmentData * const frag = it.value();
        const QChar *p = buffer.constData() + frag->stringPosition;
        const QChar * const end = p + frag->size_array[0];
        while (p < end) {
            switch(QChar::direction(p->unicode()))
            {
            case QChar::DirL:
                return Qt::LeftToRight;
            case QChar::DirR:
            case QChar::DirAL:
                return Qt::RightToLeft;
            default:
                break;
            }
            ++p;
        }
    }
    return Qt::LeftToRight;
}

/*!
    Returns the block's contents as plain text.

    \sa length() charFormat() blockFormat()
 */
QString QTextBlock::text() const
{
    if (!p || !n)
        return QString();

    const QString buffer = p->buffer();
    QString text;
    text.reserve(length());

    const int pos = position();
    QTextDocumentPrivate::FragmentIterator it = p->find(pos);
    QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
    for (; it != end; ++it) {
        const QTextFragmentData * const frag = it.value();
        text += QString::fromRawData(buffer.constData() + frag->stringPosition, frag->size_array[0]);
    }

    return text;
}


/*!
    Returns the text document this text block belongs to, or 0 if the
    text block does not belong to any document.
*/
const QTextDocument *QTextBlock::document() const
{
    return p ? p->document() : 0;
}

/*!
    If the block represents a list item, returns the list that the item belongs
    to; otherwise returns 0.
*/
QTextList *QTextBlock::textList() const
{
    if (!isValid())
        return 0;

    const QTextBlockFormat fmt = blockFormat();
    QTextObject *obj = p->document()->objectForFormat(fmt);
    return qobject_cast<QTextList *>(obj);
}

/*!
    \since 4.1

    Returns a pointer to a QTextBlockUserData object if previously set with
    setUserData() or a null pointer.
*/
QTextBlockUserData *QTextBlock::userData() const
{
    if (!p || !n)
        return 0;

    const QTextBlockData *b = p->blockMap().fragment(n);
    return b->userData;
}

/*!
    \since 4.1

    Attaches the given \a data object to the text block.

    QTextBlockUserData can be used to store custom settings.  The
    ownership is passed to the underlying text document, i.e. the
    provided QTextBlockUserData object will be deleted if the
    corresponding text block gets deleted. The user data object is
    not stored in the undo history, so it will not be available after
    undoing the deletion of a text block.

    For example, if you write a programming editor in an IDE, you may
    want to let your user set breakpoints visually in your code for an
    integrated debugger. In a programming editor a line of text
    usually corresponds to one QTextBlock. The QTextBlockUserData
    interface allows the developer to store data for each QTextBlock,
    like for example in which lines of the source code the user has a
    breakpoint set. Of course this could also be stored externally,
    but by storing it inside the QTextDocument, it will for example be
    automatically deleted when the user deletes the associated
    line. It's really just a way to store custom information in the
    QTextDocument without using custom properties in QTextFormat which
    would affect the undo/redo stack.
*/
void QTextBlock::setUserData(QTextBlockUserData *data)
{
    if (!p || !n)
        return;

    const QTextBlockData *b = p->blockMap().fragment(n);
    if (data != b->userData)
        delete b->userData;
    b->userData = data;
}

/*!
    \since 4.1

    Returns the integer value previously set with setUserState() or -1.
*/
int QTextBlock::userState() const
{
    if (!p || !n)
        return -1;

    const QTextBlockData *b = p->blockMap().fragment(n);
    return b->userState;
}

/*!
    \since 4.1

    Stores the specified \a state integer value in the text block. This may be
    useful for example in a syntax highlighter to store a text parsing state.
*/
void QTextBlock::setUserState(int state)
{
    if (!p || !n)
        return;

    const QTextBlockData *b = p->blockMap().fragment(n);
    b->userState = state;
}

/*!
    \since 4.4

    Returns the blocks revision.

    \sa setRevision(), QTextDocument::revision()
*/
int QTextBlock::revision() const
{
    if (!p || !n)
        return -1;

    const QTextBlockData *b = p->blockMap().fragment(n);
    return b->revision;
}

/*!
    \since 4.4

    Sets a blocks revision to \a rev.

    \sa revision(), QTextDocument::revision()
*/
void QTextBlock::setRevision(int rev)
{
    if (!p || !n)
        return;

    const QTextBlockData *b = p->blockMap().fragment(n);
    b->revision = rev;
}

/*!
    \since 4.4

    Returns true if the block is visible; otherwise returns false.

    \sa setVisible()
*/
bool QTextBlock::isVisible() const
{
    if (!p || !n)
        return true;

    const QTextBlockData *b = p->blockMap().fragment(n);
    return !b->hidden;
}

/*!
    \since 4.4

    Sets the block's visibility to \a visible.

    \sa isVisible()
*/
void QTextBlock::setVisible(bool visible)
{
    if (!p || !n)
        return;

    const QTextBlockData *b = p->blockMap().fragment(n);
    b->hidden = !visible;
}


/*!
\since 4.4

    Returns the number of this block, or -1 if the block is invalid.

    \sa QTextCursor::blockNumber()

*/
int QTextBlock::blockNumber() const
{
    if (!p || !n)
        return -1;
    return p->blockMap().position(n, 1);
}

/*!
\since 4.5

    Returns the first line number of this block, or -1 if the block is invalid.
    Unless the layout supports it, the line number is identical to the block number.

    \sa QTextBlock::blockNumber()

*/
int QTextBlock::firstLineNumber() const
{
    if (!p || !n)
        return -1;
    return p->blockMap().position(n, 2);
}


/*!
\since 4.5

Sets the line count to \a count.

\sa lineCount()
*/
void QTextBlock::setLineCount(int count)
{
    if (!p || !n)
        return;
    p->blockMap().setSize(n, count, 2);
}
/*!
\since 4.5

Returns the line count. Not all document layouts support this feature.

\sa setLineCount()
 */
int QTextBlock::lineCount() const
{
    if (!p || !n)
        return -1;
    return p->blockMap().size(n, 2);
}


/*!
    Returns a text block iterator pointing to the beginning of the
    text block.

    \sa end()
*/
QTextBlock::iterator QTextBlock::begin() const
{
    if (!p || !n)
        return iterator();

    int pos = position();
    int len = length() - 1; // exclude the fragment that holds the paragraph separator
    int b = p->fragmentMap().findNode(pos);
    int e = p->fragmentMap().findNode(pos+len);
    return iterator(p, b, e, b);
}

/*!
    Returns a text block iterator pointing to the end of the text
    block.

    \sa begin() next() previous()
*/
QTextBlock::iterator QTextBlock::end() const
{
    if (!p || !n)
        return iterator();

    int pos = position();
    int len = length() - 1; // exclude the fragment that holds the paragraph separator
    int b = p->fragmentMap().findNode(pos);
    int e = p->fragmentMap().findNode(pos+len);
    return iterator(p, b, e, e);
}


/*!
    Returns the text block in the document after this block, or an empty
    text block if this is the last one.

    Note that the next block may be in a different frame or table to this block.

    \sa previous() begin() end()
*/
QTextBlock QTextBlock::next() const
{
    if (!isValid() || !p->blockMap().isValid(n))
        return QTextBlock();

    return QTextBlock(p, p->blockMap().next(n));
}

/*!
    Returns the text block in the document before this block, or an empty text
    block if this is the first one.

    Note that the next block may be in a different frame or table to this block.

    \sa next() begin() end()
*/
QTextBlock QTextBlock::previous() const
{
    if (!p)
        return QTextBlock();

    return QTextBlock(p, p->blockMap().previous(n));
}


/*!
    Returns the text fragment the iterator currently points to.
*/
QTextFragment QTextBlock::iterator::fragment() const
{
    int ne = n;
    int formatIndex = p->fragmentMap().fragment(n)->format;
    do {
        ne = p->fragmentMap().next(ne);
    } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
    return QTextFragment(p, n, ne);
}

/*!
    The prefix ++ operator (\c{++i}) advances the iterator to the
    next item in the hash and returns an iterator to the new current
    item.
*/

QTextBlock::iterator &QTextBlock::iterator::operator++()
{
    int ne = n;
    int formatIndex = p->fragmentMap().fragment(n)->format;
    do {
        ne = p->fragmentMap().next(ne);
    } while (ne != e && p->fragmentMap().fragment(ne)->format == formatIndex);
    n = ne;
    return *this;
}

/*!
    The prefix -- operator (\c{--i}) makes the preceding item
    current and returns an iterator pointing to the new current item.
*/

QTextBlock::iterator &QTextBlock::iterator::operator--()
{
    n = p->fragmentMap().previous(n);

    if (n == b)
        return *this;

    int formatIndex = p->fragmentMap().fragment(n)->format;
    int last = n;

    while (n != b && p->fragmentMap().fragment(n)->format != formatIndex) {
        last = n;
        n = p->fragmentMap().previous(n);
    }

    n = last;
    return *this;
}


/*!
    \class QTextFragment
    \reentrant

    \brief The QTextFragment class holds a piece of text in a
    QTextDocument with a single QTextCharFormat.

    \ingroup richtext-processing

    A text fragment describes a piece of text that is stored with a single
    character format. Text in which the character format changes can be
    represented by sequences of text fragments with different formats.

    If the user edits the text in a fragment and introduces a different
    character format, the fragment's text will be split at each point where
    the format changes, and new fragments will be created.
    For example, changing the style of some text in the middle of a
    sentence will cause the fragment to be broken into three separate fragments:
    the first and third with the same format as before, and the second with
    the new style. The first fragment will contain the text from the beginning
    of the sentence, the second will contain the text from the middle, and the
    third takes the text from the end of the sentence.

    \img qtextfragment-split.png

    A fragment's text and character format can be obtained with the text()
    and charFormat() functions. The length() function gives the length of
    the text in the fragment. position() gives the position in the document
    of the start of the fragment. To determine whether the fragment contains
    a particular position within the document, use the contains() function.

    \sa QTextDocument, {Rich Text Document Structure}
*/

/*!
    \fn QTextFragment::QTextFragment(const QTextDocumentPrivate *priv, int f, int fe)
    \internal
*/

/*!
    \fn QTextFragment::QTextFragment()

    Creates a new empty text fragment.
*/

/*!
    \fn QTextFragment::QTextFragment(const QTextFragment &other)

    Copies the content (text and format) of the \a other text fragment
    to this text fragment.
*/

/*!
    \fn QTextFragment &QTextFragment::operator=(const QTextFragment
    &other)

    Assigns the content (text and format) of the \a other text fragment
    to this text fragment.
*/

/*!
    \fn bool QTextFragment::isValid() const

    Returns true if this is a valid text fragment (i.e. has a valid
    position in a document); otherwise returns false.
*/

/*!
    \fn bool QTextFragment::operator==(const QTextFragment &other) const

    Returns true if this text fragment is the same (at the same
    position) as the \a other text fragment; otherwise returns false.
*/

/*!
    \fn bool QTextFragment::operator!=(const QTextFragment &other) const

    Returns true if this text fragment is different (at a different
    position) from the \a other text fragment; otherwise returns
    false.
*/

/*!
    \fn bool QTextFragment::operator<(const QTextFragment &other) const

    Returns true if this text fragment appears earlier in the document
    than the \a other text fragment; otherwise returns false.
*/


/*!
    Returns the position of this text fragment in the document.
*/
int QTextFragment::position() const
{
    if (!p || !n)
        return 0; // ### -1 instead?

    return p->fragmentMap().position(n);
}

/*!
    Returns the number of characters in the text fragment.

    \sa text()
*/
int QTextFragment::length() const
{
    if (!p || !n)
        return 0;

    int len = 0;
    int f = n;
    while (f != ne) {
        len += p->fragmentMap().size(f);
        f = p->fragmentMap().next(f);
    }
    return len;
}

/*!
    Returns true if the text fragment contains the text at the given
    \a position in the document; otherwise returns false.
*/
bool QTextFragment::contains(int position) const
{
    if (!p || !n)
        return false;
    int pos = this->position();
    return position >= pos && position < pos + length();
}

/*!
    Returns the text fragment's character format.

    \sa text()
*/
QTextCharFormat QTextFragment::charFormat() const
{
    if (!p || !n)
        return QTextCharFormat();
    const QTextFragmentData *data = p->fragmentMap().fragment(n);
    return p->formatCollection()->charFormat(data->format);
}

/*!
    Returns an index into the document's internal list of character formats
    for the text fragment's character format.

    \sa QTextDocument::allFormats()
*/
int QTextFragment::charFormatIndex() const
{
    if (!p || !n)
        return -1;
    const QTextFragmentData *data = p->fragmentMap().fragment(n);
    return data->format;
}

/*!
    Returns the text fragment's as plain text.

    \sa length(), charFormat()
*/
QString QTextFragment::text() const
{
    if (!p || !n)
        return QString();

    QString result;
    QString buffer = p->buffer();
    int f = n;
    while (f != ne) {
        const QTextFragmentData * const frag = p->fragmentMap().fragment(f);
        result += QString(buffer.constData() + frag->stringPosition, frag->size_array[0]);
        f = p->fragmentMap().next(f);
    }
    return result;
}

QT_END_NAMESPACE
