source: trunk/src/gui/text/qtextlist.cpp@ 890

Last change on this file since 890 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 9.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43#include "qtextlist.h"
44#include "qtextobject_p.h"
45#include "qtextcursor.h"
46#include "qtextdocument_p.h"
47#include <qdebug.h>
48
49QT_BEGIN_NAMESPACE
50
51class QTextListPrivate : public QTextBlockGroupPrivate
52{
53public:
54 QTextListPrivate(QTextDocument *doc)
55 : QTextBlockGroupPrivate(doc)
56 {
57 }
58};
59
60/*!
61 \class QTextList
62 \reentrant
63
64 \brief The QTextList class provides a decorated list of items in a QTextDocument.
65
66 \ingroup richtext-processing
67
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
71 alphabetical lists.
72
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.
77
78 \snippet doc/src/snippets/textdocument-lists/mainwindow.cpp 0
79
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.
82
83 The cursor's current list is found with \l{QTextCursor::currentList()}.
84
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.
89
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.
93
94 List items can be deleted by index with the removeItem() function.
95 remove() deletes the specified item in the list.
96
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
99 individual items.
100
101 \sa QTextBlock, QTextListFormat, QTextCursor
102*/
103
104/*!
105 \fn bool QTextList::isEmpty() const
106 \obsolete
107
108 Returns true if the list has no items; otherwise returns false.
109
110 \bold{Note:} Empty lists are automatically deleted by the QTextDocument that owns
111 them.
112
113 \sa count()
114*/
115
116/*! \internal
117 */
118QTextList::QTextList(QTextDocument *doc)
119 : QTextBlockGroup(*new QTextListPrivate(doc), doc)
120{
121}
122
123/*!
124 \internal
125*/
126QTextList::~QTextList()
127{
128}
129
130/*!
131 Returns the number of items in the list.
132*/
133int QTextList::count() const
134{
135 Q_D(const QTextList);
136 return d->blocks.count();
137}
138
139/*!
140 Returns the \a{i}-th text block in the list.
141
142 \sa count() itemText()
143*/
144QTextBlock QTextList::item(int i) const
145{
146 Q_D(const QTextList);
147 if (i < 0 || i >= d->blocks.size())
148 return QTextBlock();
149 return d->blocks.at(i);
150}
151
152/*!
153 \fn void QTextList::setFormat(const QTextListFormat &format)
154
155 Sets the list's format to \a format.
156*/
157
158/*!
159 \fn QTextListFormat QTextList::format() const
160
161 Returns the list's format.
162*/
163
164/*!
165 \fn int QTextList::itemNumber(const QTextBlock &block) const
166
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.
169*/
170int QTextList::itemNumber(const QTextBlock &blockIt) const
171{
172 Q_D(const QTextList);
173 return d->blocks.indexOf(blockIt);
174}
175
176/*!
177 \fn QString QTextList::itemText(const QTextBlock &block) const
178
179 Returns the text of the list item that corresponds to the given \a block.
180*/
181QString QTextList::itemText(const QTextBlock &blockIt) const
182{
183 Q_D(const QTextList);
184 int item = d->blocks.indexOf(blockIt) + 1;
185 if (item <= 0)
186 return QString();
187
188 QTextBlock block = d->blocks.at(item-1);
189 QTextBlockFormat blockFormat = block.blockFormat();
190
191 QString result;
192
193 const int style = format().style();
194
195 switch (style) {
196 case QTextListFormat::ListDecimal:
197 result = QString::number(item);
198 break;
199 // from the old richtext
200 case QTextListFormat::ListLowerAlpha:
201 case QTextListFormat::ListUpperAlpha:
202 {
203 const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a';
204
205 int c = item;
206 while (c > 0) {
207 c--;
208 result.prepend(QChar(baseChar + (c % 26)));
209 c /= 26;
210 }
211 }
212 break;
213 case QTextListFormat::ListLowerRoman:
214 case QTextListFormat::ListUpperRoman:
215 {
216 if (item < 5000) {
217 QByteArray romanNumeral;
218
219 // works for up to 4999 items
220 static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm";
221 static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM";
222 QByteArray romanSymbols; // wrap to have "mid"
223 if (style == QTextListFormat::ListLowerRoman)
224 romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower));
225 else
226 romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper));
227
228 int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
229 int n = item;
230 for (int i = 12; i >= 0; n %= c[i], i--) {
231 int q = n / c[i];
232 if (q > 0) {
233 int startDigit = i + (i+3)/4;
234 int numDigits;
235 if (i % 4) {
236 // c[i] == 4|5|9|40|50|90|400|500|900
237 if ((i-2) % 4) {
238 // c[i] == 4|9|40|90|400|900 => with subtraction (IV, IX, XL, XC, ...)
239 numDigits = 2;
240 }
241 else {
242 // c[i] == 5|50|500 (V, L, D)
243 numDigits = 1;
244 }
245 }
246 else {
247 // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...)
248 numDigits = q;
249 }
250
251 romanNumeral.append(romanSymbols.mid(startDigit, numDigits));
252 }
253 }
254 result = QString::fromLatin1(romanNumeral);
255 }
256 else {
257 result = QLatin1String("?");
258 }
259
260 }
261 break;
262 default:
263 Q_ASSERT(false);
264 }
265 if (blockIt.textDirection() == Qt::RightToLeft)
266 return result.prepend(QLatin1Char('.'));
267 return result + QLatin1Char('.');
268}
269
270/*!
271 Removes the item at item position \a i from the list. When the last item in the
272 list is removed, the list is automatically deleted by the QTextDocument that owns
273 it.
274
275 \sa add(), remove()
276*/
277void QTextList::removeItem(int i)
278{
279 Q_D(QTextList);
280 if (i < 0 || i >= d->blocks.size())
281 return;
282
283 QTextBlock block = d->blocks.at(i);
284 remove(block);
285}
286
287
288/*!
289 Removes the given \a block from the list.
290
291 \sa add(), removeItem()
292*/
293void QTextList::remove(const QTextBlock &block)
294{
295 QTextBlockFormat fmt = block.blockFormat();
296 fmt.setIndent(fmt.indent() + format().indent());
297 fmt.setObjectIndex(-1);
298 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
299}
300
301/*!
302 Makes the given \a block part of the list.
303
304 \sa remove(), removeItem()
305*/
306void QTextList::add(const QTextBlock &block)
307{
308 QTextBlockFormat fmt = block.blockFormat();
309 fmt.setObjectIndex(objectIndex());
310 block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat);
311}
312
313QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.