forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -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;
|
||||
if (debugExamples()) {
|
||||
qWarning() << QString::fromLatin1("Reading file \"%1\"...")
|
||||
.arg(QFileInfo(exampleSource).absoluteFilePath());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (reader.hasError() && debugExamples()) {
|
||||
qWarning().noquote().nospace() << "ERROR: Could not parse file as XML document ("
|
||||
<< exampleSource << "):" << reader.lineNumber() << ':' << reader.columnNumber()
|
||||
<< ": " << reader.errorString();
|
||||
}
|
||||
items += filtered(*result, isValidExampleOrDemo);
|
||||
}
|
||||
|
||||
if (m_isExamples) {
|
||||
if (m_exampleSetModel->selectedQtSupports(Android::Constants::ANDROID_DEVICE_TYPE)) {
|
||||
items = Utils::filtered(items, [](ExampleItem *item) {
|
||||
|
||||
Reference in New Issue
Block a user