summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Thomas <echidnaman@kubuntu.org>2012-03-24 00:39:42 (GMT)
committerJonathan Thomas <echidnaman@kubuntu.org>2012-03-24 00:39:42 (GMT)
commit2524feb991b59435b766a0a7c03ed56931333385 (patch)
tree04da7ec805152f55e3cf26555751873e965347d0
parentdce62d635d5bd0a20d3655d113bd02b242fc1b11 (diff)
Multithread Application object creation. With this we can add a progress throbber to the Muon Software Center.
We couldn't do this very well before because Application creation was blocking and would have made any animation freeze. CCBUG:295045
-rw-r--r--libmuon/ApplicationBackend.cpp75
-rw-r--r--libmuon/ApplicationBackend.h10
2 files changed, 53 insertions, 32 deletions
diff --git a/libmuon/ApplicationBackend.cpp b/libmuon/ApplicationBackend.cpp
index 6aa399f..cea5501 100644
--- a/libmuon/ApplicationBackend.cpp
+++ b/libmuon/ApplicationBackend.cpp
@@ -21,6 +21,7 @@
#include "ApplicationBackend.h"
// Qt includes
+#include <QtConcurrentRun>
#include <QtCore/QDir>
#include <QtCore/QStringList>
@@ -46,8 +47,8 @@ ApplicationBackend::ApplicationBackend(QObject *parent)
, m_isReloading(false)
, m_currentTransaction(0)
{
- m_pkgBlacklist << "kdebase-runtime" << "kdepim-runtime" << "kdelibs5-plugins" << "kdelibs5-data";
-
+ m_watcher = new QFutureWatcher<QVector<Application*> >(this);
+ connect(m_watcher, SIGNAL(finished()), this, SLOT(setApplications()));
connect(this, SIGNAL(reloadFinished()), SIGNAL(updatesCountChanged()));
}
@@ -55,40 +56,29 @@ ApplicationBackend::~ApplicationBackend()
{
}
-void ApplicationBackend::setBackend(QApt::Backend *backend)
-{
- m_backend = backend;
- m_backend->setUndoRedoCacheSize(1);
- m_reviewsBackend->setAptBackend(m_backend);
- init();
-
- connect(m_backend, SIGNAL(workerEvent(QApt::WorkerEvent)),
- this, SLOT(workerEvent(QApt::WorkerEvent)));
- connect(m_backend, SIGNAL(errorOccurred(QApt::ErrorCode,QVariantMap)),
- this, SLOT(errorOccurred(QApt::ErrorCode,QVariantMap)));
-
- emit appBackendReady();
-}
-
-void ApplicationBackend::init()
+QVector<Application *> init(QApt::Backend *backend)
{
+ QVector<Application *> appList;
QDir appDir("/usr/share/app-install/desktop/");
QStringList fileList = appDir.entryList(QStringList("*.desktop"), QDir::Files);
+ QStringList pkgBlacklist;
+ pkgBlacklist << "kdebase-runtime" << "kdepim-runtime" << "kdelibs5-plugins" << "kdelibs5-data";
+
QList<Application *> tempList;
QSet<QString> packages;
foreach(const QString &fileName, fileList) {
- Application *app = new Application(appDir.filePath(fileName), m_backend);
+ Application *app = new Application(appDir.filePath(fileName), backend);
packages.insert(app->packageName());
tempList << app;
}
- foreach (QApt::Package *package, m_backend->availablePackages()) {
+ foreach (QApt::Package *package, backend->availablePackages()) {
//Don't create applications twice
if(packages.contains(package->name())) {
continue;
}
- Application *app = new Application(package, m_backend);
+ Application *app = new Application(package, backend);
tempList << app;
}
@@ -96,12 +86,8 @@ void ApplicationBackend::init()
bool added = false;
QApt::Package *pkg = app->package();
if (app->isValid()) {
- if ((pkg) && !m_pkgBlacklist.contains(pkg->latin1Name())) {
- m_appList << app;
- if (pkg->isInstalled()) {
- m_instOriginList << pkg->origin();
- }
- m_originList << pkg->origin();
+ if ((pkg) && !pkgBlacklist.contains(pkg->latin1Name())) {
+ appList << app;
added = true;
}
}
@@ -110,8 +96,43 @@ void ApplicationBackend::init()
delete app;
}
+ return appList;
+}
+
+void ApplicationBackend::setBackend(QApt::Backend *backend)
+{
+ m_backend = backend;
+ m_backend->setUndoRedoCacheSize(1);
+ m_reviewsBackend->setAptBackend(m_backend);
+
+ QFuture<QVector<Application*> > future = QtConcurrent::run(init, backend);
+ m_watcher->setFuture(future);
+
+ connect(m_backend, SIGNAL(workerEvent(QApt::WorkerEvent)),
+ this, SLOT(workerEvent(QApt::WorkerEvent)));
+ connect(m_backend, SIGNAL(errorOccurred(QApt::ErrorCode,QVariantMap)),
+ this, SLOT(errorOccurred(QApt::ErrorCode,QVariantMap)));
+}
+
+void ApplicationBackend::setApplications()
+{
+ m_appList = m_watcher->future().result();
+
+ // Populate origin lists
+ QApt::Package *pkg;
+ for (Application *app : m_appList) {
+ pkg = app->package();
+ if (pkg->isInstalled()) {
+ m_instOriginList << pkg->origin();
+ }
+
+ m_originList << pkg->origin();
+ }
+
m_originList.remove(QString());
m_instOriginList.remove(QString());
+
+ emit appBackendReady();
}
void ApplicationBackend::reload()
diff --git a/libmuon/ApplicationBackend.h b/libmuon/ApplicationBackend.h
index b85c9ea..a802a2f 100644
--- a/libmuon/ApplicationBackend.h
+++ b/libmuon/ApplicationBackend.h
@@ -21,13 +21,13 @@
#ifndef APPLICATIONBACKEND_H
#define APPLICATIONBACKEND_H
-#include <QtCore/QStringList>
+#include <QFutureWatcher>
#include <QtCore/QObject>
#include <QtCore/QQueue>
#include <QtCore/QSet>
-#include <QVector>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
-#include <LibQApt/Globals>
#include <LibQApt/Package>
#include "libmuonprivate_export.h"
@@ -75,11 +75,11 @@ private:
ReviewsBackend *m_reviewsBackend;
bool m_isReloading;
+ QFutureWatcher<QVector<Application*> >* m_watcher;
QVector<Application *> m_appList;
QSet<QString> m_originList;
QSet<QString> m_instOriginList;
QList<Application*> m_appLaunchList;
- QStringList m_pkgBlacklist;
QQueue<Transaction *> m_queue;
Transaction *m_currentTransaction;
QPair<QApt::WorkerEvent, Transaction *> m_workerState;
@@ -97,7 +97,7 @@ public Q_SLOTS:
void clearLaunchList();
private Q_SLOTS:
- void init();
+ void setApplications();
void runNextTransaction();
void workerEvent(QApt::WorkerEvent event);
void errorOccurred(QApt::ErrorCode error, const QVariantMap &details);