39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "qhelpprojectdata_p.h" |
42 #include "qhelpprojectdata_p.h" |
43 |
43 |
|
44 #include <QtCore/QCoreApplication> |
44 #include <QtCore/QDir> |
45 #include <QtCore/QDir> |
45 #include <QtCore/QFileInfo> |
46 #include <QtCore/QFileInfo> |
46 #include <QtCore/QStack> |
47 #include <QtCore/QStack> |
47 #include <QtCore/QMap> |
48 #include <QtCore/QMap> |
48 #include <QtCore/QRegExp> |
49 #include <QtCore/QRegExp> |
|
50 #include <QtCore/QUrl> |
49 #include <QtCore/QVariant> |
51 #include <QtCore/QVariant> |
50 #include <QtXml/QXmlStreamReader> |
52 #include <QtXml/QXmlStreamReader> |
51 |
53 |
52 QT_BEGIN_NAMESPACE |
54 QT_BEGIN_NAMESPACE |
53 |
55 |
74 void readTOC(); |
76 void readTOC(); |
75 void readKeywords(); |
77 void readKeywords(); |
76 void readFiles(); |
78 void readFiles(); |
77 void raiseUnknownTokenError(); |
79 void raiseUnknownTokenError(); |
78 void addMatchingFiles(const QString &pattern); |
80 void addMatchingFiles(const QString &pattern); |
|
81 bool hasValidSyntax(const QString &nameSpace, const QString &vFolder) const; |
79 |
82 |
80 QMap<QString, QStringList> dirEntriesCache; |
83 QMap<QString, QStringList> dirEntriesCache; |
81 }; |
84 }; |
82 |
85 |
83 void QHelpProjectDataPrivate::raiseUnknownTokenError() |
86 void QHelpProjectDataPrivate::raiseUnknownTokenError() |
84 { |
87 { |
85 raiseError(QObject::tr("Unknown token.")); |
88 raiseError(QCoreApplication::translate("QHelpProject", "Unknown token.")); |
86 } |
89 } |
87 |
90 |
88 void QHelpProjectDataPrivate::readData(const QByteArray &contents) |
91 void QHelpProjectDataPrivate::readData(const QByteArray &contents) |
89 { |
92 { |
90 addData(contents); |
93 addData(contents); |
93 if (isStartElement()) { |
96 if (isStartElement()) { |
94 if (name() == QLatin1String("QtHelpProject") |
97 if (name() == QLatin1String("QtHelpProject") |
95 && attributes().value(QLatin1String("version")) == QLatin1String("1.0")) |
98 && attributes().value(QLatin1String("version")) == QLatin1String("1.0")) |
96 readProject(); |
99 readProject(); |
97 else |
100 else |
98 raiseError(QObject::tr("Unknown token. Expected \"QtHelpProject\"!")); |
101 raiseError(QCoreApplication::translate("QHelpProject", |
|
102 "Unknown token. Expected \"QtHelpProject\"!")); |
99 } |
103 } |
100 } |
104 } |
101 |
105 |
102 if (hasError()) { |
106 if (hasError()) { |
103 raiseError(QObject::tr("Error in line %1: %2").arg(lineNumber()) |
107 raiseError(QCoreApplication::translate("QHelpProject", |
|
108 "Error in line %1: %2").arg(lineNumber()) |
104 .arg(errorString())); |
109 .arg(errorString())); |
105 } |
110 } |
106 } |
111 } |
107 |
112 |
108 void QHelpProjectDataPrivate::readProject() |
113 void QHelpProjectDataPrivate::readProject() |
110 while (!atEnd()) { |
115 while (!atEnd()) { |
111 readNext(); |
116 readNext(); |
112 if (isStartElement()) { |
117 if (isStartElement()) { |
113 if (name() == QLatin1String("virtualFolder")) { |
118 if (name() == QLatin1String("virtualFolder")) { |
114 virtualFolder = readElementText(); |
119 virtualFolder = readElementText(); |
115 if (virtualFolder.contains(QLatin1String("/"))) |
120 if (!hasValidSyntax(QLatin1String("test"), virtualFolder)) |
116 raiseError(QObject::tr("A virtual folder must not contain a \'/\' character!")); |
121 raiseError(QCoreApplication::translate("QHelpProject", |
|
122 "Virtual folder has invalid syntax.")); |
117 } else if (name() == QLatin1String("namespace")) { |
123 } else if (name() == QLatin1String("namespace")) { |
118 namespaceName = readElementText(); |
124 namespaceName = readElementText(); |
119 if (namespaceName.contains(QLatin1String("/"))) |
125 if (!hasValidSyntax(namespaceName, QLatin1String("test"))) |
120 raiseError(QObject::tr("A namespace must not contain a \'/\' character!")); |
126 raiseError(QCoreApplication::translate("QHelpProject", |
|
127 "Namespace has invalid syntax.")); |
121 } else if (name() == QLatin1String("customFilter")) { |
128 } else if (name() == QLatin1String("customFilter")) { |
122 readCustomFilter(); |
129 readCustomFilter(); |
123 } else if (name() == QLatin1String("filterSection")) { |
130 } else if (name() == QLatin1String("filterSection")) { |
124 readFilterSection(); |
131 readFilterSection(); |
125 } else if (name() == QLatin1String("metaData")) { |
132 } else if (name() == QLatin1String("metaData")) { |
126 QString n = attributes().value(QLatin1String("name")).toString(); |
133 QString n = attributes().value(QLatin1String("name")).toString(); |
127 if (!metaData.contains(n)) |
134 if (!metaData.contains(n)) |
128 metaData[n] = attributes().value(QLatin1String("value")).toString(); |
135 metaData[n] |
|
136 = attributes().value(QLatin1String("value")).toString(); |
129 else |
137 else |
130 metaData.insert(n, attributes().value(QLatin1String("value")).toString()); |
138 metaData.insert(n, attributes(). |
|
139 value(QLatin1String("value")).toString()); |
131 } else { |
140 } else { |
132 raiseUnknownTokenError(); |
141 raiseUnknownTokenError(); |
133 } |
142 } |
134 } else if (isEndElement() && name() == QLatin1String("QtHelpProject")) { |
143 } else if (isEndElement() && name() == QLatin1String("QtHelpProject")) { |
135 if (namespaceName.isEmpty()) |
144 if (namespaceName.isEmpty()) |
136 raiseError(QObject::tr("Missing namespace in QtHelpProject.")); |
145 raiseError(QCoreApplication::translate("QHelpProject", |
|
146 "Missing namespace in QtHelpProject.")); |
137 else if (virtualFolder.isEmpty()) |
147 else if (virtualFolder.isEmpty()) |
138 raiseError(QObject::tr("Missing virtual folder in QtHelpProject")); |
148 raiseError(QCoreApplication::translate("QHelpProject", |
|
149 "Missing virtual folder in QtHelpProject")); |
139 break; |
150 break; |
140 } |
151 } |
141 } |
152 } |
142 } |
153 } |
143 |
154 |
221 if (isStartElement()) { |
232 if (isStartElement()) { |
222 if (name() == QLatin1String("keyword")) { |
233 if (name() == QLatin1String("keyword")) { |
223 if (attributes().value(QLatin1String("ref")).toString().isEmpty() |
234 if (attributes().value(QLatin1String("ref")).toString().isEmpty() |
224 || (attributes().value(QLatin1String("name")).toString().isEmpty() |
235 || (attributes().value(QLatin1String("name")).toString().isEmpty() |
225 && attributes().value(QLatin1String("id")).toString().isEmpty())) |
236 && attributes().value(QLatin1String("id")).toString().isEmpty())) |
226 raiseError(QObject::tr("Missing attribute in keyword at line %1.") |
237 raiseError(QCoreApplication::translate("QHelpProject", |
227 .arg(lineNumber())); |
238 "Missing attribute in keyword at line %1.") |
228 filterSectionList.last().addIndex( |
239 .arg(lineNumber())); |
229 QHelpDataIndexItem(attributes().value(QLatin1String("name")).toString(), |
240 filterSectionList.last() |
230 attributes().value(QLatin1String("id")).toString(), |
241 .addIndex(QHelpDataIndexItem(attributes(). |
231 attributes().value(QLatin1String("ref")).toString())); |
242 value(QLatin1String("name")).toString(), |
|
243 attributes().value(QLatin1String("id")).toString(), |
|
244 attributes().value(QLatin1String("ref")).toString())); |
232 } else { |
245 } else { |
233 raiseUnknownTokenError(); |
246 raiseUnknownTokenError(); |
234 } |
247 } |
235 } else if (isEndElement()) { |
248 } else if (isEndElement()) { |
236 if (name() == QLatin1String("keyword")) |
249 if (name() == QLatin1String("keyword")) |
303 } |
316 } |
304 if (!matchFound) |
317 if (!matchFound) |
305 filterSectionList.last().addFile(pattern); |
318 filterSectionList.last().addFile(pattern); |
306 } |
319 } |
307 |
320 |
|
321 bool QHelpProjectDataPrivate::hasValidSyntax(const QString &nameSpace, |
|
322 const QString &vFolder) const |
|
323 { |
|
324 const QLatin1Char slash('/'); |
|
325 if (nameSpace.contains(slash) || vFolder.contains(slash)) |
|
326 return false; |
|
327 QUrl url; |
|
328 const QLatin1String scheme("qthelp"); |
|
329 url.setScheme(scheme); |
|
330 url.setHost(nameSpace); |
|
331 url.setPath(vFolder); |
|
332 |
|
333 const QString expectedUrl(scheme + QLatin1String("://") + nameSpace + slash + vFolder); |
|
334 return url.isValid() && url.toString() == expectedUrl; |
|
335 } |
|
336 |
308 /*! |
337 /*! |
309 \internal |
338 \internal |
310 \class QHelpProjectData |
339 \class QHelpProjectData |
311 \since 4.4 |
340 \since 4.4 |
312 \brief The QHelpProjectData class stores all information found |
341 \brief The QHelpProjectData class stores all information found |
344 bool QHelpProjectData::readData(const QString &fileName) |
373 bool QHelpProjectData::readData(const QString &fileName) |
345 { |
374 { |
346 d->rootPath = QFileInfo(fileName).absolutePath(); |
375 d->rootPath = QFileInfo(fileName).absolutePath(); |
347 QFile file(fileName); |
376 QFile file(fileName); |
348 if (!file.open(QIODevice::ReadOnly)) { |
377 if (!file.open(QIODevice::ReadOnly)) { |
349 d->errorMsg = QObject::tr("The input file %1 could not be opened!") |
378 d->errorMsg = QCoreApplication::translate("QHelpProject", |
350 .arg(fileName); |
379 "The input file %1 could not be opened!").arg(fileName); |
351 return false; |
380 return false; |
352 } |
381 } |
353 |
382 |
354 d->readData(file.readAll()); |
383 d->readData(file.readAll()); |
355 return !d->hasError(); |
384 return !d->hasError(); |