diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2018-11-01 12:56:22 +0200 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2019-02-04 11:43:52 +0000 |
commit | 11671d67a0e43e4cda6b206d3a27347d2bc4dab7 (patch) | |
tree | 12cee1e87c199c9542b5a48c2fbb8ca3ea1550ce | |
parent | de673f9aef239c93bb7935efd550c9380ecbfbaa (diff) |
Use a signal instead of an event inside ApplicationsModel
Also don't leak the created IndexingThread.
Task-number: QTBUG-70548
Change-Id: I97a070067b045d3604ce2b8824022877049d9a87
Reviewed-by: Sami Nurmenniemi <sami.nurmenniemi@qt.io>
-rw-r--r-- | src/applicationsmodel.cpp | 141 | ||||
-rw-r--r-- | src/applicationsmodel.h | 6 | ||||
-rw-r--r-- | src/applicationsmodel_p.h | 52 | ||||
-rw-r--r-- | startup.pro | 1 |
4 files changed, 115 insertions, 85 deletions
diff --git a/src/applicationsmodel.cpp b/src/applicationsmodel.cpp index b0818da..9fb4487 100644 --- a/src/applicationsmodel.cpp +++ b/src/applicationsmodel.cpp @@ -27,6 +27,7 @@ ** ****************************************************************************/ #include "applicationsmodel.h" +#include "applicationsmodel_p.h" #include <QCoreApplication> #include <QDirIterator> @@ -38,18 +39,6 @@ #include <QJsonObject> #include <QXmlStreamReader> -const QEvent::Type RESULT_EVENT = static_cast<QEvent::Type>(QEvent::User + 1); -class ResultEvent : public QEvent -{ -public: - ResultEvent(const QList<AppData> &r) - : QEvent(RESULT_EVENT) - , results(r) - { - } - QList<AppData> results; -}; - static bool appOrder(const AppData& a, const AppData& b) { if (a.priority != b.priority) @@ -57,87 +46,78 @@ static bool appOrder(const AppData& a, const AppData& b) return a.name < b.name; } -class IndexingThread : public QThread +void IndexingThread::run() { -public: - - void run() final - { - QList<AppData> results; - QList<QString> roots = root.split(":"); - target = qgetenv("B2QT_BASE") + "-" + qgetenv("B2QT_PLATFORM"); - foreach (const QString &root, roots) { - if (QFile::exists(root + "/demos.xml")) { + QList<AppData> results; + QList<QString> roots = root.split(":"); + target = qgetenv("B2QT_BASE") + "-" + qgetenv("B2QT_PLATFORM"); + foreach (const QString &root, roots) { + if (QFile::exists(root + "/demos.xml")) { - QFile file(root + "/demos.xml"); + QFile file(root + "/demos.xml"); - if (!file.open(QIODevice::ReadOnly)) - break; + if (!file.open(QIODevice::ReadOnly)) + break; - QXmlStreamReader xml(&file); + QXmlStreamReader xml(&file); - AppData data; - bool exclude = false; + AppData data; + bool exclude = false; - while (!xml.atEnd()) { - switch (xml.readNext()) { + while (!xml.atEnd()) { + switch (xml.readNext()) { - case QXmlStreamReader::StartElement: - if (xml.name().toString().toLower() == "application") { + case QXmlStreamReader::StartElement: + if (xml.name().toString().toLower() == "application") { - const QStringList excludeList = xml.attributes().value("exclude").toString().split(QStringLiteral(";")); + const QStringList excludeList = xml.attributes().value("exclude").toString().split(QStringLiteral(";")); - exclude = excludeList.contains(target) || excludeList.contains(QStringLiteral("all")); + exclude = excludeList.contains(target) || excludeList.contains(QStringLiteral("all")); - if (exclude) - break; + if (exclude) + break; - data.name = xml.attributes().value("title").toString().trimmed(); + data.name = xml.attributes().value("title").toString().trimmed(); - QString path = xml.attributes().value("location").toString(); - data.location = QUrl::fromLocalFile(path); + QString path = xml.attributes().value("location").toString(); + data.location = QUrl::fromLocalFile(path); - data.main = QString("/%1").arg(xml.attributes().value("main").toString()); + data.main = QString("/%1").arg(xml.attributes().value("main").toString()); - QString imageName = xml.attributes().value("icon").toString(); + QString imageName = xml.attributes().value("icon").toString(); - data.icon = QFile::exists(imageName) - ? QUrl::fromLocalFile(imageName) - : QUrl("qrc:///qml/images/codeless.png"); + data.icon = QFile::exists(imageName) + ? QUrl::fromLocalFile(imageName) + : QUrl("qrc:///qml/images/codeless.png"); - data.priority = xml.attributes().value("priority").toInt(); + data.priority = xml.attributes().value("priority").toInt(); - } else if (xml.name().toString().toLower() == "description") { - data.description = xml.readElementText().trimmed(); - } - break; + } else if (xml.name().toString().toLower() == "description") { + data.description = xml.readElementText().trimmed(); + } + break; - case QXmlStreamReader::EndElement: - if (xml.name().toString().toLower() == "application" && !exclude) - results << data; - break; + case QXmlStreamReader::EndElement: + if (xml.name().toString().toLower() == "application" && !exclude) + results << data; + break; - default: - break; - } + default: + break; } - - if (xml.error() != QXmlStreamReader::NoError) - qWarning("XML Parser error: %s", qPrintable(xml.errorString())); } - } - - std::sort(results.begin(), results.end(), appOrder); - qDebug() << "Indexer: all done... total:" << results.size(); - QCoreApplication::postEvent(model, new ResultEvent(results)); + if (xml.error() != QXmlStreamReader::NoError) + qWarning("XML Parser error: %s", qPrintable(xml.errorString())); + } } - QString root; - ApplicationsModel *model = nullptr; - QString target; -}; + std::sort(results.begin(), results.end(), appOrder); + + qDebug() << "Indexer: all done... total:" << results.size(); + emit indexingFinished(results); +} ApplicationsModel::ApplicationsModel(QObject *parent) : QAbstractItemModel(parent) @@ -161,22 +141,13 @@ void ApplicationsModel::initialize(const QString &appsRoot) auto *thread = new IndexingThread; thread->root = appsRoot; thread->model = this; + qRegisterMetaType<QList<AppData>>("QList<AppData>"); + connect(thread, &IndexingThread::indexingFinished, + this, &ApplicationsModel::handleIndexingResult); + connect(thread, &QThread::finished, thread, &QObject::deleteLater); thread->start(); } -bool ApplicationsModel::event(QEvent *e) -{ - if (e->type() == RESULT_EVENT) { - beginResetModel(); - m_data = static_cast<ResultEvent *>(e)->results; - endResetModel(); - emit ready(); - return true; - } - - return QAbstractItemModel::event(e); -} - QVariant ApplicationsModel::data(const QModelIndex &index, int role) const { Q_ASSERT(index.row() >= 0 && index.row() < m_data.size()); @@ -237,3 +208,11 @@ QVariant ApplicationsModel::query(int i, const QString &name) const return QVariant(); } + +void ApplicationsModel::handleIndexingResult(QList<AppData> results) +{ + beginResetModel(); + m_data = results; + endResetModel(); + emit ready(); +} diff --git a/src/applicationsmodel.h b/src/applicationsmodel.h index bcded00..74122e1 100644 --- a/src/applicationsmodel.h +++ b/src/applicationsmodel.h @@ -77,10 +77,8 @@ public: signals: void ready(); - - -protected: - bool event(QEvent *e); +private slots: + void handleIndexingResult(QList<AppData> results); private: diff --git a/src/applicationsmodel_p.h b/src/applicationsmodel_p.h new file mode 100644 index 0000000..7ae5368 --- /dev/null +++ b/src/applicationsmodel_p.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Device Creation. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef APPLICATIONSMODEL_P_H +#define APPLICATIONSMODEL_P_H + +#include "applicationsmodel.h" + +#include <QThread> + +class IndexingThread : public QThread +{ + Q_OBJECT +public: + virtual ~IndexingThread() = default; + void run() final; + +signals: + void indexingFinished(QList<AppData> results); + +public: + QString root; + ApplicationsModel *model = nullptr; + QString target; +}; + +#endif // APPLICATIONSMODEL_P_H diff --git a/startup.pro b/startup.pro index 2aa5599..aecf0aa 100644 --- a/startup.pro +++ b/startup.pro @@ -11,6 +11,7 @@ qtHaveModule(webengine) { HEADERS += \ src/engine.h \ src/applicationsmodel.h \ + src/applicationsmodel_p.h \ src/fpscounter.h \ src/applicationsettings.h \ src/settingsmanager.h \ |