2 * Copyright (C) 2016 Canonical, Ltd.
3 * Copyright (C) 2020 UBports Foundation.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include "appdrawermodel.h"
19#include "ualwrapper.h"
20#include "xdgwatcher.h"
24#include <QtConcurrentRun>
26static std::shared_ptr<LauncherItem> makeSharedLauncherItem(
27 const QString &appId, const QString &name, const QString &icon, QObject * parent)
29 return std::shared_ptr<LauncherItem>(
30 new LauncherItem(appId, name, icon, parent),
31 [] (LauncherItem *item) { item->deleteLater(); });
34AppDrawerModel::AppDrawerModel(QObject *parent):
35 AppDrawerModelInterface(parent),
36 m_ual(new UalWrapper(this)),
37 m_xdgWatcher(new XdgWatcher(this)),
40 connect(&m_refreshFutureWatcher, &QFutureWatcher<ItemList>::finished,
41 this, &AppDrawerModel::onRefreshFinished);
43 // keep this a queued connection as it's coming from another thread.
44 connect(m_xdgWatcher, &XdgWatcher::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
45 connect(m_xdgWatcher, &XdgWatcher::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
46 connect(m_xdgWatcher, &XdgWatcher::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
51int AppDrawerModel::rowCount(const QModelIndex &parent) const
54 return m_list.count();
57QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
61 return m_list.at(index.row())->appId();
63 return m_list.at(index.row())->name();
65 return m_list.at(index.row())->icon();
67 return m_list.at(index.row())->keywords();
69 return m_list.at(index.row())->popularity();
75void AppDrawerModel::appAdded(const QString &appId)
78 // Will be replaced by the refresh result anyway.
81 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
83 qWarning() << "App added signal received but failed to get app info for app" << appId;
87 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
88 auto item = makeSharedLauncherItem(appId, info.name, info.icon, /* parent */ nullptr);
89 item->setKeywords(info.keywords);
90 item->setPopularity(info.popularity);
91 m_list.append(std::move(item));
95void AppDrawerModel::appRemoved(const QString &appId)
98 // Will be replaced by the refresh result anyway.
102 for (int i = 0; i < m_list.count(); i++) {
103 if (m_list.at(i)->appId() == appId) {
109 qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
112 beginRemoveRows(QModelIndex(), idx, idx);
113 m_list.removeAt(idx);
117void AppDrawerModel::appInfoChanged(const QString &appId)
120 // Will be replaced by the refresh result anyway.
123 std::shared_ptr<LauncherItem> item;
126 for(int i = 0; i < m_list.count(); i++) {
127 if (m_list.at(i)->appId() == appId) {
138 UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
139 item->setPopularity(info.popularity);
140 Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
143bool AppDrawerModel::refreshing() {
147void AppDrawerModel::refresh() {
151 m_refreshFutureWatcher.setFuture(QtConcurrent::run([](QThread *thread) {
154 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
155 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
157 qWarning() << "Failed to get app info for app" << appId;
160 // We don't pass parent in because this may run after the model is destroyed.
161 // (And, in fact, we can't, because the model is in a diferent thread.)
162 auto item = makeSharedLauncherItem(appId, info.name, info.icon, /* parent */ nullptr);
163 item->setKeywords(info.keywords);
164 item->setPopularity(info.popularity);
165 item->moveToThread(thread);
166 list.append(std::move(item));
173 Q_EMIT refreshingChanged();
176void AppDrawerModel::onRefreshFinished() {
177 if (m_refreshFutureWatcher.isCanceled())
178 // This is the result of setting canceled future below.
183 m_list = m_refreshFutureWatcher.result();
184 // Remove the future & its result, so that future modifications won't
186 m_refreshFutureWatcher.setFuture(QFuture<ItemList>());
190 m_refreshing = false;
191 Q_EMIT refreshingChanged();
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list