source: trunk/tools/assistant/lib/qhelpprojectdata.cpp@ 500

Last change on this file since 500 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the Qt Assistant of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qhelpprojectdata_p.h"
43
44#include <QtCore/QFileInfo>
45#include <QtCore/QStack>
46#include <QtCore/QMap>
47#include <QtCore/QVariant>
48#include <QtXml/QXmlStreamReader>
49
50QT_BEGIN_NAMESPACE
51
52class QHelpProjectDataPrivate : public QXmlStreamReader
53{
54public:
55 void readData(const QByteArray &contents);
56
57 QString virtualFolder;
58 QString namespaceName;
59 QString rootPath;
60
61 QStringList fileList;
62 QList<QHelpDataCustomFilter> customFilterList;
63 QList<QHelpDataFilterSection> filterSectionList;
64 QMap<QString, QVariant> metaData;
65
66 QString errorMsg;
67
68private:
69 void readProject();
70 void readCustomFilter();
71 void readFilterSection();
72 void readTOC();
73 void readKeywords();
74 void readFiles();
75 void raiseUnknownTokenError();
76};
77
78void QHelpProjectDataPrivate::raiseUnknownTokenError()
79{
80 raiseError(QObject::tr("Unknown token."));
81}
82
83void QHelpProjectDataPrivate::readData(const QByteArray &contents)
84{
85 addData(contents);
86 while (!atEnd()) {
87 readNext();
88 if (isStartElement()) {
89 if (name() == QLatin1String("QtHelpProject")
90 && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
91 readProject();
92 else
93 raiseError(QObject::tr("Unknown token. Expected \"QtHelpProject\"!"));
94 }
95 }
96
97 if (hasError()) {
98 raiseError(QObject::tr("Error in line %1: %2").arg(lineNumber())
99 .arg(errorString()));
100 }
101}
102
103void QHelpProjectDataPrivate::readProject()
104{
105 while (!atEnd()) {
106 readNext();
107 if (isStartElement()) {
108 if (name() == QLatin1String("virtualFolder")) {
109 virtualFolder = readElementText();
110 if (virtualFolder.contains(QLatin1String("/")))
111 raiseError(QObject::tr("A virtual folder must not contain a \'/\' character!"));
112 } else if (name() == QLatin1String("namespace")) {
113 namespaceName = readElementText();
114 if (namespaceName.contains(QLatin1String("/")))
115 raiseError(QObject::tr("A namespace must not contain a \'/\' character!"));
116 } else if (name() == QLatin1String("customFilter")) {
117 readCustomFilter();
118 } else if (name() == QLatin1String("filterSection")) {
119 readFilterSection();
120 } else if (name() == QLatin1String("metaData")) {
121 QString n = attributes().value(QLatin1String("name")).toString();
122 if (!metaData.contains(n))
123 metaData[n] = attributes().value(QLatin1String("value")).toString();
124 else
125 metaData.insert(n, attributes().value(QLatin1String("value")).toString());
126 } else {
127 raiseUnknownTokenError();
128 }
129 } else if (isEndElement() && name() == QLatin1String("QtHelpProject")) {
130 if (namespaceName.isEmpty())
131 raiseError(QObject::tr("Missing namespace in QtHelpProject."));
132 else if (virtualFolder.isEmpty())
133 raiseError(QObject::tr("Missing virtual folder in QtHelpProject"));
134 break;
135 }
136 }
137}
138
139void QHelpProjectDataPrivate::readCustomFilter()
140{
141 QHelpDataCustomFilter filter;
142 filter.name = attributes().value(QLatin1String("name")).toString();
143 while (!atEnd()) {
144 readNext();
145 if (isStartElement()) {
146 if (name() == QLatin1String("filterAttribute"))
147 filter.filterAttributes.append(readElementText());
148 else
149 raiseUnknownTokenError();
150 } else if (isEndElement() && name() == QLatin1String("customFilter")) {
151 break;
152 }
153 }
154 customFilterList.append(filter);
155}
156
157void QHelpProjectDataPrivate::readFilterSection()
158{
159 filterSectionList.append(QHelpDataFilterSection());
160 while (!atEnd()) {
161 readNext();
162 if (isStartElement()) {
163 if (name() == QLatin1String("filterAttribute"))
164 filterSectionList.last().addFilterAttribute(readElementText());
165 else if (name() == QLatin1String("toc"))
166 readTOC();
167 else if (name() == QLatin1String("keywords"))
168 readKeywords();
169 else if (name() == QLatin1String("files"))
170 readFiles();
171 else
172 raiseUnknownTokenError();
173 } else if (isEndElement() && name() == QLatin1String("filterSection")) {
174 break;
175 }
176 }
177}
178
179void QHelpProjectDataPrivate::readTOC()
180{
181 QStack<QHelpDataContentItem*> contentStack;
182 QHelpDataContentItem *itm = 0;
183 while (!atEnd()) {
184 readNext();
185 if (isStartElement()) {
186 if (name() == QLatin1String("section")) {
187 QString title = attributes().value(QLatin1String("title")).toString();
188 QString ref = attributes().value(QLatin1String("ref")).toString();
189 if (contentStack.isEmpty()) {
190 itm = new QHelpDataContentItem(0, title, ref);
191 filterSectionList.last().addContent(itm);
192 } else {
193 itm = new QHelpDataContentItem(contentStack.top(), title, ref);
194 }
195 contentStack.push(itm);
196 } else {
197 raiseUnknownTokenError();
198 }
199 } else if (isEndElement()) {
200 if (name() == QLatin1String("section")) {
201 contentStack.pop();
202 continue;
203 } else if (name() == QLatin1String("toc") && contentStack.isEmpty()) {
204 break;
205 } else {
206 raiseUnknownTokenError();
207 }
208 }
209 }
210}
211
212void QHelpProjectDataPrivate::readKeywords()
213{
214 while (!atEnd()) {
215 readNext();
216 if (isStartElement()) {
217 if (name() == QLatin1String("keyword")) {
218 if (attributes().value(QLatin1String("ref")).toString().isEmpty()
219 || (attributes().value(QLatin1String("name")).toString().isEmpty()
220 && attributes().value(QLatin1String("id")).toString().isEmpty()))
221 raiseError(QObject::tr("Missing attribute in keyword at line %1.")
222 .arg(lineNumber()));
223 filterSectionList.last().addIndex(
224 QHelpDataIndexItem(attributes().value(QLatin1String("name")).toString(),
225 attributes().value(QLatin1String("id")).toString(),
226 attributes().value(QLatin1String("ref")).toString()));
227 } else {
228 raiseUnknownTokenError();
229 }
230 } else if (isEndElement()) {
231 if (name() == QLatin1String("keyword"))
232 continue;
233 else if (name() == QLatin1String("keywords"))
234 break;
235 else
236 raiseUnknownTokenError();
237 }
238 }
239}
240
241void QHelpProjectDataPrivate::readFiles()
242{
243 while (!atEnd()) {
244 readNext();
245 if (isStartElement()) {
246 if (name() == QLatin1String("file"))
247 filterSectionList.last().addFile(readElementText());
248 else
249 raiseUnknownTokenError();
250 } else if (isEndElement()) {
251 if (name() == QLatin1String("file"))
252 continue;
253 else if (name() == QLatin1String("files"))
254 break;
255 else
256 raiseUnknownTokenError();
257 }
258 }
259}
260
261
262
263/*!
264 \internal
265 \class QHelpProjectData
266 \since 4.4
267 \brief The QHelpProjectData class stores all information found
268 in a Qt help project file.
269
270 The structure is filled with data by calling readData(). The
271 specified file has to have the Qt help project file format in
272 order to be read successfully. Possible reading errors can be
273 retrieved by calling errorMessage().
274*/
275
276/*!
277 Constructs a Qt help project data structure.
278*/
279QHelpProjectData::QHelpProjectData()
280{
281 d = new QHelpProjectDataPrivate;
282}
283
284/*!
285 Destroys the help project data.
286*/
287QHelpProjectData::~QHelpProjectData()
288{
289 delete d;
290}
291
292/*!
293 Reads the file \a fileName and stores the help data. The file has to
294 have the Qt help project file format. Returns true if the file
295 was successfully read, otherwise false.
296
297 \sa errorMessage()
298*/
299bool QHelpProjectData::readData(const QString &fileName)
300{
301 d->rootPath = QFileInfo(fileName).absolutePath();
302 QFile file(fileName);
303 if (!file.open(QIODevice::ReadOnly)) {
304 d->errorMsg = QObject::tr("The input file %1 could not be opened!")
305 .arg(fileName);
306 return false;
307 }
308
309 d->readData(file.readAll());
310 return !d->hasError();
311}
312
313/*!
314 Returns an error message if the reading of the Qt help project
315 file failed. Otherwise, an empty QString is returned.
316
317 \sa readData()
318*/
319QString QHelpProjectData::errorMessage() const
320{
321 if (d->hasError())
322 return d->errorString();
323 return d->errorMsg;
324}
325
326/*!
327 \reimp
328*/
329QString QHelpProjectData::namespaceName() const
330{
331 return d->namespaceName;
332}
333
334/*!
335 \reimp
336*/
337QString QHelpProjectData::virtualFolder() const
338{
339 return d->virtualFolder;
340}
341
342/*!
343 \reimp