1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qtextlist.h"
44 #include "qtextobject_p.h"
45 #include "qtextcursor.h"
46 #include "qtextdocument_p.h"
51 class QTextListPrivate : public QTextBlockGroupPrivate
54 QTextListPrivate(QTextDocument *doc)
55 : QTextBlockGroupPrivate(doc)
64 \brief The QTextList class provides a decorated list of items in a QTextDocument.
66 \ingroup richtext-processing
68 A list contains a sequence of text blocks, each of which is marked with a
69 bullet point or other symbol. Multiple levels of lists can be used, and
70 the automatic numbering feature provides support for ordered numeric and
73 Lists are created by using a text cursor to insert an empty list at the
74 current position or by moving existing text into a new list.
75 The \l{QTextCursor::insertList()} function inserts an empty block into the
76 document at the cursor position, and makes it the first item in a list.
78 \snippet doc/src/snippets/textdocument-lists/mainwindow.cpp 0
80 The \l{QTextCursor::createList()} function takes the contents of the
81 cursor's current block and turns it into the first item of a new list.
83 The cursor's current list is found with \l{QTextCursor::currentList()}.
85 The number of items in a list is given by count(). Each item can be
86 obtained by its index in the list with the item() function. Similarly,
87 the index of a given item can be found with itemNumber(). The text of
88 each item can be found with the itemText() function.
90 Note that the items in the list may not be adjacent elements in the
91 document. For example, the top-level items in a multi-level list will
92 be separated by the items in lower levels of the list.
94 List items can be deleted by index with the removeItem() function.
95 remove() deletes the specified item in the list.
97 The list's format is set with setFormat() and read with format().
98 The format describes the decoration of the list itself, and not the
101 \sa QTextBlock, QTextListFormat, QTextCursor
105 \fn bool QTextList::isEmpty() const
108 Returns true if the list has no items; otherwise returns false.
110 \bold{Note:} Empty lists are automatically deleted by the QTextDocument that owns
118 QTextList::QTextList(QTextDocument *doc)
119 : QTextBlockGroup(*new QTextListPrivate(doc), doc)
126 QTextList::~QTextList()
131 Returns the number of items in the list.
133 int QTextList::count() const
135 Q_D(const QTextList);
136 return d->blocks.count();
140 Returns the \a{i}-th text block in the list.
142 \sa count() itemText()
144 QTextBlock QTextList::item(int i) const
146 Q_D(const QTextList);
147 if (i < 0 || i >= d->blocks.size())
149 return d->blocks.at(i);
153 \fn void QTextList::setFormat(const QTextListFormat &format)
155 Sets the list's format to \a format.
159 \fn QTextListFormat QTextList::format() const
161 Returns the list's format.
165 \fn int QTextList::itemNumber(const QTextBlock &block) const
167 Returns the index of the list item that corresponds to the given \a block.
168 Returns -1 if the block was not present in the list.
170 int QTextList::itemNumber(const QTextBlock &blockIt) const
172 Q_D(const QTextList);
173 return d->blocks.indexOf(blockIt);
177 \fn QString QTextList::itemText(const QTextBlock &block) const
179 Returns the text of the list item that corresponds to the given \a block.
181 QString QTextList::itemText(const QTextBlock &blockIt) const
183 Q_D(const QTextList);
184 int item = d->blocks.indexOf(blockIt) + 1;
188 QTextBlock block = d->blocks.at(item-1);
189 QTextBlockFormat blockFormat = block.blockFormat();
193 const int style = format().style();
194 QString numberPrefix;
195 QString numberSuffix = QLatin1String(".");
197 if (format().hasProperty(QTextFormat::ListNumberPrefix))
198 numberPrefix = format().numberPrefix();
199 if (format().hasProperty(QTextFormat::ListNumberSuffix))
200 numberSuffix = format().numberSuffix();
203 case QTextListFormat::ListDecimal:
204 result = QString::number(item);
206 // from the old richtext
207 case QTextListFormat::ListLowerAlpha:
208 case QTextListFormat::ListUpperAlpha:
210 const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a';
215 result.prepend(QChar(baseChar + (c % 26)));
220 case QTextListFormat::ListLowerRoman:
221 case QTextListFormat::ListUpperRoman:
224 QByteArray romanNumeral;
226 // works for up to 4999 items
227 static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm";
228 static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM";
229 QByteArray romanSymbols; // wrap to have "mid"
230 if (style == QTextListFormat::ListLowerRoman)
231 romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower));
233 romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper));
235 int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
237 for (int i = 12; i >= 0; n %= c[i], i--) {
240 int startDigit = i + (i+3)/4;
243 // c[i] == 4|5|9|40|50|90|400|500|900
245 // c[i] == 4|9|40|90|400|900 => with subtraction (IV, IX, XL, XC, ...)
249 // c[i] == 5|50|500 (V, L, D)
254 // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...)
258 romanNumeral.append(romanSymbols.mid(startDigit, numDigits));
261 result = QString::fromLatin1(romanNumeral);
264 result = QLatin1String("?");
272 if (blockIt.textDirection() == Qt::RightToLeft)
273 return numberSuffix + result + numberPrefix;
275 return numberPrefix + result + numberSuffix;
279 Removes the item at item position \a i from the list. When the last item in the
280 list is removed, the list is automatically deleted by the QTextDocument that owns
285 void QTextList::removeItem(int i)
288 if (i < 0 || i >= d->blocks.size())
291 QTextBlock block = d->blocks.at(i);
297 Removes the given \a block from the list.
299 \sa add(), removeItem()
301 void QTextList::remove(const QTextBlock &block)
303 QTextBlockFormat fmt = block.blockFormat();
304 fmt.setIndent(fmt.indent() + format().indent());
305 fmt.setObjectIndex(-1);
306 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
310 Makes the given \a block part of the list.
312 \sa remove(), removeItem()
314 void QTextList::add(const QTextBlock &block)
316 QTextBlockFormat fmt = block.blockFormat();
317 fmt.setObjectIndex(objectIndex());
318 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);