1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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.
67 \ingroup richtext-processing
69 A list contains a sequence of text blocks, each of which is marked with a
70 bullet point or other symbol. Multiple levels of lists can be used, and
71 the automatic numbering feature provides support for ordered numeric and
74 Lists are created by using a text cursor to insert an empty list at the
75 current position or by moving existing text into a new list.
76 The \l{QTextCursor::insertList()} function inserts an empty block into the
77 document at the cursor position, and makes it the first item in a list.
79 \snippet textdocument-lists/mainwindow.cpp 0
81 The \l{QTextCursor::createList()} function takes the contents of the
82 cursor's current block and turns it into the first item of a new list.
84 The cursor's current list is found with \l{QTextCursor::currentList()}.
86 The number of items in a list is given by count(). Each item can be
87 obtained by its index in the list with the item() function. Similarly,
88 the index of a given item can be found with itemNumber(). The text of
89 each item can be found with the itemText() function.
91 Note that the items in the list may not be adjacent elements in the
92 document. For example, the top-level items in a multi-level list will
93 be separated by the items in lower levels of the list.
95 List items can be deleted by index with the removeItem() function.
96 remove() deletes the specified item in the list.
98 The list's format is set with setFormat() and read with format().
99 The format describes the decoration of the list itself, and not the
102 \sa QTextBlock, QTextListFormat, QTextCursor
106 \fn bool QTextList::isEmpty() const
109 Returns true if the list has no items; otherwise returns false.
111 \b{Note:} Empty lists are automatically deleted by the QTextDocument that owns
119 QTextList::QTextList(QTextDocument *doc)
120 : QTextBlockGroup(*new QTextListPrivate(doc), doc)
127 QTextList::~QTextList()
132 Returns the number of items in the list.
134 int QTextList::count() const
136 Q_D(const QTextList);
137 return d->blocks.count();
141 Returns the \a{i}-th text block in the list.
143 \sa count(), itemText()
145 QTextBlock QTextList::item(int i) const
147 Q_D(const QTextList);
148 if (i < 0 || i >= d->blocks.size())
150 return d->blocks.at(i);
154 \fn void QTextList::setFormat(const QTextListFormat &format)
156 Sets the list's format to \a format.
160 \fn QTextListFormat QTextList::format() const
162 Returns the list's format.
166 \fn int QTextList::itemNumber(const QTextBlock &block) const
168 Returns the index of the list item that corresponds to the given \a block.
169 Returns -1 if the block was not present in the list.
171 int QTextList::itemNumber(const QTextBlock &blockIt) const
173 Q_D(const QTextList);
174 return d->blocks.indexOf(blockIt);
178 \fn QString QTextList::itemText(const QTextBlock &block) const
180 Returns the text of the list item that corresponds to the given \a block.
182 QString QTextList::itemText(const QTextBlock &blockIt) const
184 Q_D(const QTextList);
185 int item = d->blocks.indexOf(blockIt) + 1;
189 QTextBlock block = d->blocks.at(item-1);
190 QTextBlockFormat blockFormat = block.blockFormat();
194 const int style = format().style();
195 QString numberPrefix;
196 QString numberSuffix = QLatin1String(".");
198 if (format().hasProperty(QTextFormat::ListNumberPrefix))
199 numberPrefix = format().numberPrefix();
200 if (format().hasProperty(QTextFormat::ListNumberSuffix))
201 numberSuffix = format().numberSuffix();
204 case QTextListFormat::ListDecimal:
205 result = QString::number(item);
207 // from the old richtext
208 case QTextListFormat::ListLowerAlpha:
209 case QTextListFormat::ListUpperAlpha:
211 const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a';
216 result.prepend(QChar(baseChar + (c % 26)));
221 case QTextListFormat::ListLowerRoman:
222 case QTextListFormat::ListUpperRoman:
225 QByteArray romanNumeral;
227 // works for up to 4999 items
228 static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm";
229 static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM";
230 QByteArray romanSymbols; // wrap to have "mid"
231 if (style == QTextListFormat::ListLowerRoman)
232 romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower));
234 romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper));
236 int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
238 for (int i = 12; i >= 0; n %= c[i], i--) {
241 int startDigit = i + (i+3)/4;
244 // c[i] == 4|5|9|40|50|90|400|500|900
246 // c[i] == 4|9|40|90|400|900 => with subtraction (IV, IX, XL, XC, ...)
250 // c[i] == 5|50|500 (V, L, D)
255 // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...)
259 romanNumeral.append(romanSymbols.mid(startDigit, numDigits));
262 result = QString::fromLatin1(romanNumeral);
265 result = QLatin1String("?");
273 if (blockIt.textDirection() == Qt::RightToLeft)
274 return numberSuffix + result + numberPrefix;
276 return numberPrefix + result + numberSuffix;
280 Removes the item at item position \a i from the list. When the last item in the
281 list is removed, the list is automatically deleted by the QTextDocument that owns
286 void QTextList::removeItem(int i)
289 if (i < 0 || i >= d->blocks.size())
292 QTextBlock block = d->blocks.at(i);
298 Removes the given \a block from the list.
300 \sa add(), removeItem()
302 void QTextList::remove(const QTextBlock &block)
304 QTextBlockFormat fmt = block.blockFormat();
305 fmt.setIndent(fmt.indent() + format().indent());
306 fmt.setObjectIndex(-1);
307 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
311 Makes the given \a block part of the list.
313 \sa remove(), removeItem()
315 void QTextList::add(const QTextBlock &block)
317 QTextBlockFormat fmt = block.blockFormat();
318 fmt.setObjectIndex(objectIndex());
319 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);