diff options
author | Eike Ziller <eike.ziller@qt.io> | 2023-02-21 14:11:40 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2023-04-11 11:56:42 +0000 |
commit | 584874f15ffccd878025057b81b4c5d82fb61936 (patch) | |
tree | 8d0e8cb37126475045177276c1beedf6605fd9dd /src/plugins/qtsupport/exampleslistmodel.cpp | |
parent | 41e78b9e57065311d3019c38e813b49e1323cc90 (diff) |
Move examples manifest parser in separate function
and file. To make it auto-testable.
Change-Id: I19d263bf080a0089eb9a4ec0f379c52446771c0a
Reviewed-by: David Schulz <david.schulz@qt.io>
(cherry picked from commit 7e7509744761cf8b42bdfbb5f6f849d432a3ec9f)
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/qtsupport/exampleslistmodel.cpp')
-rw-r--r-- | src/plugins/qtsupport/exampleslistmodel.cpp | 226 |
1 files changed, 15 insertions, 211 deletions
diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index 26af348ca76..700248e1f97 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -3,6 +3,7 @@ #include "exampleslistmodel.h" +#include "examplesparser.h" #include "qtsupporttr.h" #include <QBuffer> @@ -288,38 +289,11 @@ ExamplesViewController::ExamplesViewController(ExampleSetModel *exampleSetModel, updateExamples(); } -static QString fixStringForTags(const QString &string) -{ - QString returnString = string; - returnString.remove(QLatin1String("<i>")); - returnString.remove(QLatin1String("</i>")); - returnString.remove(QLatin1String("<tt>")); - returnString.remove(QLatin1String("</tt>")); - return returnString; -} - -static QStringList trimStringList(const QStringList &stringlist) -{ - return Utils::transform(stringlist, [](const QString &str) { return str.trimmed(); }); -} - -static QString relativeOrInstallPath(const QString &path, const QString &manifestPath, - const QString &installPath) -{ - const QChar slash = QLatin1Char('/'); - const QString relativeResolvedPath = manifestPath + slash + path; - const QString installResolvedPath = installPath + slash + path; - if (QFile::exists(relativeResolvedPath)) - return relativeResolvedPath; - if (QFile::exists(installResolvedPath)) - return installResolvedPath; - // doesn't exist, just return relative - return relativeResolvedPath; -} - static bool isValidExampleOrDemo(ExampleItem *item) { QTC_ASSERT(item, return false); + if (item->type == Tutorial) + return true; static QString invalidPrefix = QLatin1String("qthelp:////"); /* means that the qthelp url doesn't have any namespace */ QString reason; @@ -345,158 +319,6 @@ static bool isValidExampleOrDemo(ExampleItem *item) return ok || debugExamples(); } -static QList<ExampleItem *> parseExamples(QXmlStreamReader *reader, - const QString &projectsOffset, - const QString &examplesInstallPath) -{ - QList<ExampleItem *> result; - std::unique_ptr<ExampleItem> item; - const QChar slash = QLatin1Char('/'); - while (!reader->atEnd()) { - switch (reader->readNext()) { - case QXmlStreamReader::StartElement: - if (reader->name() == QLatin1String("example")) { - item = std::make_unique<ExampleItem>(); - item->type = Example; - QXmlStreamAttributes attributes = reader->attributes(); - item->name = attributes.value(QLatin1String("name")).toString(); - item->projectPath = attributes.value(QLatin1String("projectPath")).toString(); - item->hasSourceCode = !item->projectPath.isEmpty(); - item->projectPath = relativeOrInstallPath(item->projectPath, projectsOffset, examplesInstallPath); - item->imageUrl = attributes.value(QLatin1String("imageUrl")).toString(); - QPixmapCache::remove(item->imageUrl); - item->docUrl = attributes.value(QLatin1String("docUrl")).toString(); - item->isHighlighted = attributes.value(QLatin1String("isHighlighted")).toString() == QLatin1String("true"); - - } else if (reader->name() == QLatin1String("fileToOpen")) { - const QString mainFileAttribute = reader->attributes().value( - QLatin1String("mainFile")).toString(); - const QString filePath = relativeOrInstallPath( - reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement), - projectsOffset, examplesInstallPath); - item->filesToOpen.append(filePath); - if (mainFileAttribute.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) - item->mainFile = filePath; - } else if (reader->name() == QLatin1String("description")) { - item->description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("dependency")) { - item->dependencies.append(projectsOffset + slash + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("tags")) { - item->tags = trimStringList(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(','), Qt::SkipEmptyParts)); - } else if (reader->name() == QLatin1String("platforms")) { - item->platforms = trimStringList(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(','), Qt::SkipEmptyParts)); - } - break; - case QXmlStreamReader::EndElement: - if (reader->name() == QLatin1String("example")) { - if (isValidExampleOrDemo(item.get())) - result.push_back(item.release()); - } else if (reader->name() == QLatin1String("examples")) { - return result; - } - break; - default: // nothing - break; - } - } - return result; -} - -static QList<ExampleItem *> parseDemos(QXmlStreamReader *reader, - const QString &projectsOffset, - const QString &demosInstallPath) -{ - QList<ExampleItem *> result; - std::unique_ptr<ExampleItem> item; - const QChar slash = QLatin1Char('/'); - while (!reader->atEnd()) { - switch (reader->readNext()) { - case QXmlStreamReader::StartElement: - if (reader->name() == QLatin1String("demo")) { - item = std::make_unique<ExampleItem>(); - item->type = Demo; - QXmlStreamAttributes attributes = reader->attributes(); - item->name = attributes.value(QLatin1String("name")).toString(); - item->projectPath = attributes.value(QLatin1String("projectPath")).toString(); - item->hasSourceCode = !item->projectPath.isEmpty(); - item->projectPath = relativeOrInstallPath(item->projectPath, projectsOffset, demosInstallPath); - item->imageUrl = attributes.value(QLatin1String("imageUrl")).toString(); - QPixmapCache::remove(item->imageUrl); - item->docUrl = attributes.value(QLatin1String("docUrl")).toString(); - item->isHighlighted = attributes.value(QLatin1String("isHighlighted")).toString() == QLatin1String("true"); - } else if (reader->name() == QLatin1String("fileToOpen")) { - item->filesToOpen.append(relativeOrInstallPath(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement), - projectsOffset, demosInstallPath)); - } else if (reader->name() == QLatin1String("description")) { - item->description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("dependency")) { - item->dependencies.append(projectsOffset + slash + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("tags")) { - item->tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(',')); - } - break; - case QXmlStreamReader::EndElement: - if (reader->name() == QLatin1String("demo")) { - if (isValidExampleOrDemo(item.get())) - result.push_back(item.release()); - } else if (reader->name() == QLatin1String("demos")) { - return result; - } - break; - default: // nothing - break; - } - } - return result; -} - -static QList<ExampleItem *> parseTutorials(QXmlStreamReader *reader, const QString &projectsOffset) -{ - QList<ExampleItem *> result; - std::unique_ptr<ExampleItem> item = std::make_unique<ExampleItem>(); - const QChar slash = QLatin1Char('/'); - while (!reader->atEnd()) { - switch (reader->readNext()) { - case QXmlStreamReader::StartElement: - if (reader->name() == QLatin1String("tutorial")) { - item = std::make_unique<ExampleItem>(); - item->type = Tutorial; - QXmlStreamAttributes attributes = reader->attributes(); - item->name = attributes.value(QLatin1String("name")).toString(); - item->projectPath = attributes.value(QLatin1String("projectPath")).toString(); - item->hasSourceCode = !item->projectPath.isEmpty(); - item->projectPath.prepend(slash); - item->projectPath.prepend(projectsOffset); - item->imageUrl = Utils::StyleHelper::dpiSpecificImageFile( - attributes.value(QLatin1String("imageUrl")).toString()); - QPixmapCache::remove(item->imageUrl); - item->docUrl = attributes.value(QLatin1String("docUrl")).toString(); - item->isVideo = attributes.value(QLatin1String("isVideo")).toString() == QLatin1String("true"); - item->videoUrl = attributes.value(QLatin1String("videoUrl")).toString(); - item->videoLength = attributes.value(QLatin1String("videoLength")).toString(); - } else if (reader->name() == QLatin1String("fileToOpen")) { - item->filesToOpen.append(projectsOffset + slash + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("description")) { - item->description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("dependency")) { - item->dependencies.append(projectsOffset + slash + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); - } else if (reader->name() == QLatin1String("tags")) { - item->tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(',')); - } - break; - case QXmlStreamReader::EndElement: - if (reader->name() == QLatin1String("tutorial")) - result.push_back(item.release()); - else if (reader->name() == QLatin1String("tutorials")) - return result; - break; - default: // nothing - break; - } - } - return result; -} - void ExamplesViewController::updateExamples() { QString examplesInstallPath; @@ -509,41 +331,23 @@ void ExamplesViewController::updateExamples() QList<ExampleItem *> items; for (const QString &exampleSource : sources) { - QFile exampleFile(exampleSource); - if (!exampleFile.open(QIODevice::ReadOnly)) { - if (debugExamples()) - qWarning() << "ERROR: Could not open file" << exampleSource; - continue; + if (debugExamples()) { + qWarning() << QString::fromLatin1("Reading file \"%1\"...") + .arg(QFileInfo(exampleSource).absoluteFilePath()); } - QFileInfo fi(exampleSource); - QString offsetPath = fi.path(); - QDir examplesDir(offsetPath); - QDir demosDir(offsetPath); - - if (debugExamples()) - qWarning() << QString::fromLatin1("Reading file \"%1\"...").arg(fi.absoluteFilePath()); - QXmlStreamReader reader(&exampleFile); - while (!reader.atEnd()) - switch (reader.readNext()) { - case QXmlStreamReader::StartElement: - if (m_isExamples && reader.name() == QLatin1String("examples")) - items += parseExamples(&reader, examplesDir.path(), examplesInstallPath); - else if (m_isExamples && reader.name() == QLatin1String("demos")) - items += parseDemos(&reader, demosDir.path(), demosInstallPath); - else if (!m_isExamples && reader.name() == QLatin1String("tutorials")) - items += parseTutorials(&reader, examplesDir.path()); - break; - default: // nothing - break; + const expected_str<QList<ExampleItem *>> result + = parseExamples(exampleSource, examplesInstallPath, demosInstallPath, m_isExamples); + if (!result) { + if (debugExamples()) { + qWarning() << "ERROR: Could not read examples from" << exampleSource << ":" + << result.error(); } - - if (reader.hasError() && debugExamples()) { - qWarning().noquote().nospace() << "ERROR: Could not parse file as XML document (" - << exampleSource << "):" << reader.lineNumber() << ':' << reader.columnNumber() - << ": " << reader.errorString(); + continue; } + items += filtered(*result, isValidExampleOrDemo); } + if (m_isExamples) { if (m_exampleSetModel->selectedQtSupports(Android::Constants::ANDROID_DEVICE_TYPE)) { items = Utils::filtered(items, [](ExampleItem *item) { |