summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2018-11-01 12:56:22 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2019-02-04 11:43:52 +0000
commit11671d67a0e43e4cda6b206d3a27347d2bc4dab7 (patch)
tree12cee1e87c199c9542b5a48c2fbb8ca3ea1550ce
parentde673f9aef239c93bb7935efd550c9380ecbfbaa (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.cpp141
-rw-r--r--src/applicationsmodel.h6
-rw-r--r--src/applicationsmodel_p.h52
-rw-r--r--startup.pro1
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 \