src/gui/text/qtextlist.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/text/qtextlist.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtextlist.h"
+#include "qtextobject_p.h"
+#include "qtextcursor.h"
+#include "qtextdocument_p.h"
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTextListPrivate : public QTextBlockGroupPrivate
+{
+public:
+    QTextListPrivate(QTextDocument *doc)
+        : QTextBlockGroupPrivate(doc)
+    {
+    }
+};
+
+/*!
+    \class QTextList
+    \reentrant
+
+    \brief The QTextList class provides a decorated list of items in a QTextDocument.
+
+    \ingroup richtext-processing
+
+    A list contains a sequence of text blocks, each of which is marked with a
+    bullet point or other symbol. Multiple levels of lists can be used, and
+    the automatic numbering feature provides support for ordered numeric and
+    alphabetical lists.
+
+    Lists are created by using a text cursor to insert an empty list at the
+    current position or by moving existing text into a new list.
+    The \l{QTextCursor::insertList()} function inserts an empty block into the
+    document at the cursor position, and makes it the first item in a list.
+
+    \snippet doc/src/snippets/textdocument-lists/mainwindow.cpp 0
+
+    The \l{QTextCursor::createList()} function takes the contents of the
+    cursor's current block and turns it into the first item of a new list.
+
+    The cursor's current list is found with \l{QTextCursor::currentList()}.
+
+    The number of items in a list is given by count(). Each item can be
+    obtained by its index in the list with the item() function. Similarly,
+    the index of a given item can be found with itemNumber(). The text of
+    each item can be found with the itemText() function.
+
+    Note that the items in the list may not be 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.
+
+    List items can be deleted by index with the removeItem() function.
+    remove() deletes the specified item in the list.
+
+    The list's format is set with setFormat() and read with format().
+    The format describes the decoration of the list itself, and not the
+    individual items.
+
+    \sa QTextBlock, QTextListFormat, QTextCursor
+*/
+
+/*!
+    \fn bool QTextList::isEmpty() const
+    \obsolete
+
+    Returns true if the list has no items; otherwise returns false.
+
+    \bold{Note:} Empty lists are automatically deleted by the QTextDocument that owns
+    them.
+
+    \sa count()
+*/
+
+/*! \internal
+ */
+QTextList::QTextList(QTextDocument *doc)
+    : QTextBlockGroup(*new QTextListPrivate(doc), doc)
+{
+}
+
+/*!
+  \internal
+*/
+QTextList::~QTextList()
+{
+}
+
+/*!
+    Returns the number of items in the list.
+*/
+int QTextList::count() const
+{
+    Q_D(const QTextList);
+    return d->blocks.count();
+}
+
+/*!
+    Returns the \a{i}-th text block in the list.
+
+    \sa count() itemText()
+*/
+QTextBlock QTextList::item(int i) const
+{
+    Q_D(const QTextList);
+    if (i < 0 || i >= d->blocks.size())
+        return QTextBlock();
+    return d->blocks.at(i);
+}
+
+/*!
+    \fn void QTextList::setFormat(const QTextListFormat &format)
+
+    Sets the list's format to \a format.
+*/
+
+/*!
+    \fn QTextListFormat QTextList::format() const
+
+    Returns the list's format.
+*/
+
+/*!
+    \fn int QTextList::itemNumber(const QTextBlock &block) const
+
+    Returns the index of the list item that corresponds to the given \a block.
+    Returns -1 if the block was not present in the list.
+*/
+int QTextList::itemNumber(const QTextBlock &blockIt) const
+{
+    Q_D(const QTextList);
+    return d->blocks.indexOf(blockIt);
+}
+
+/*!
+    \fn QString QTextList::itemText(const QTextBlock &block) const
+
+    Returns the text of the list item that corresponds to the given \a block.
+*/
+QString QTextList::itemText(const QTextBlock &blockIt) const
+{
+    Q_D(const QTextList);
+    int item = d->blocks.indexOf(blockIt) + 1;
+    if (item <= 0)
+        return QString();
+
+    QTextBlock block = d->blocks.at(item-1);
+    QTextBlockFormat blockFormat = block.blockFormat();
+
+    QString result;
+
+    const int style = format().style();
+
+    switch (style) {
+        case QTextListFormat::ListDecimal:
+            result = QString::number(item);
+            break;
+            // from the old richtext
+        case QTextListFormat::ListLowerAlpha:
+        case QTextListFormat::ListUpperAlpha:
+            {
+                const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a';
+
+                int c = item;
+                while (c > 0) {
+                    c--;
+                    result.prepend(QChar(baseChar + (c % 26)));
+                    c /= 26;
+                }
+            }
+            break;
+        case QTextListFormat::ListLowerRoman:
+        case QTextListFormat::ListUpperRoman:
+            {
+                if (item < 5000) {
+                    QByteArray romanNumeral;
+
+                    // works for up to 4999 items
+                    static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm";
+                    static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM";
+                    QByteArray romanSymbols; // wrap to have "mid"
+                    if (style == QTextListFormat::ListLowerRoman)
+                        romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower));
+                    else
+                        romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper));
+
+                    int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
+                    int n = item;
+                    for (int i = 12; i >= 0; n %= c[i], i--) {
+                        int q = n / c[i];
+                        if (q > 0) {
+                            int startDigit = i + (i+3)/4;
+                            int numDigits;
+                            if (i % 4) { 
+                                // c[i] == 4|5|9|40|50|90|400|500|900
+                                if ((i-2) % 4) {
+                                    // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...)
+                                    numDigits = 2;
+                                }
+                                else {
+                                    // c[i] == 5|50|500 (V, L, D)
+                                    numDigits = 1;
+                                }
+                            }
+                            else {
+                                // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...)
+                                numDigits = q;
+                            }
+
+                            romanNumeral.append(romanSymbols.mid(startDigit, numDigits));
+                        }
+                    }
+                    result = QString::fromLatin1(romanNumeral);
+                }
+                else {
+                    result = QLatin1String("?");
+                }
+
+	    }
+	    break;
+        default:
+            Q_ASSERT(false);
+    }
+    if (blockFormat.layoutDirection() == Qt::RightToLeft)
+        return result.prepend(QLatin1Char('.'));
+    return result + QLatin1Char('.');
+}
+
+/*!
+    Removes the item at item position \a i from the list. When the last item in the
+    list is removed, the list is automatically deleted by the QTextDocument that owns
+    it.
+
+    \sa add(), remove()
+*/
+void QTextList::removeItem(int i)
+{
+    Q_D(QTextList);
+    if (i < 0 || i >= d->blocks.size())
+        return;
+
+    QTextBlock block = d->blocks.at(i);
+    remove(block);
+}
+
+
+/*!
+    Removes the given \a block from the list.
+
+    \sa add(), removeItem()
+*/
+void QTextList::remove(const QTextBlock &block)
+{
+    QTextBlockFormat fmt = block.blockFormat();
+    fmt.setIndent(fmt.indent() + format().indent());
+    fmt.setObjectIndex(-1);
+    block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
+}
+
+/*!
+    Makes the given \a block part of the list.
+
+    \sa remove(), removeItem()
+*/
+void QTextList::add(const QTextBlock &block)
+{
+    QTextBlockFormat fmt = block.blockFormat();
+    fmt.setObjectIndex(objectIndex());
+    block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
+}
+
+QT_END_NAMESPACE