@@ -21,7 +21,8 @@
2121#include <QDateTime>
2222
2323AppDrawerModel::AppDrawerModel(QObject *parent):
24− AppDrawerModelInterface(parent)
24+ AppDrawerModelInterface(parent),
25+ m_ual(new UalWrapper(this))
2526{
2627 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
2728 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
@@ -29,10 +30,16 @@ AppDrawerModel::AppDrawerModel(QObject *parent):
2930 qWarning() << "Failed to get app info for app" << appId;
3031 continue;
3132 }
32− m_list.append(new LauncherItem(appId, info.name, info.icon, this));
33− m_list.last()->setKeywords(info.keywords);
33+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
34+ item->setKeywords(info.keywords);
35+ item->setPopularity(info.popularity);
36+ m_list.append(item);
3437 }
35− qsrand(QDateTime::currentMSecsSinceEpoch() / 100);
38+
39+ // keep this a queued connection as it's coming from another thread.
40+ connect(m_ual, &UalWrapper::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
41+ connect(m_ual, &UalWrapper::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
42+ connect(m_ual, &UalWrapper::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
3643}
3744
3845int AppDrawerModel::rowCount(const QModelIndex &parent) const
@@ -53,10 +60,64 @@ QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
5360 case RoleKeywords:
5461 return m_list.at(index.row())->keywords();
5562 case RoleUsage:
56− // FIXME: u-a-l needs to provide API for usage stats.
57− // don't forget to drop the qsrand() call in the ctor when dropping this.
58− return qrand();
63+ return m_list.at(index.row())->popularity();
5964 }
6065
6166 return QVariant();
6267}
68+
69+void AppDrawerModel::appAdded(const QString &appId)
70+{
71+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
72+ if (!info.valid) {
73+ qWarning() << "App added signal received but failed to get app info for app" << appId;
74+ return;
75+ }
76+
77+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
78+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
79+ item->setKeywords(info.keywords);
80+ item->setPopularity(info.popularity);
81+ m_list.append(item);
82+ endInsertRows();
83+}
84+
85+void AppDrawerModel::appRemoved(const QString &appId)
86+{
87+ int idx = -1;
88+ for (int i = 0; i < m_list.count(); i++) {
89+ if (m_list.at(i)->appId() == appId) {
90+ idx = i;
91+ break;
92+ }
93+ }
94+ if (idx < 0) {
95+ qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
96+ return;
97+ }
98+ beginRemoveRows(QModelIndex(), idx, idx);
99+ m_list.takeAt(idx)->deleteLater();
100+ endRemoveRows();
101+}
102+
103+void AppDrawerModel::appInfoChanged(const QString &appId)
104+{
105+ LauncherItem *item = nullptr;
106+ int idx = -1;
107+
108+ for(int i = 0; i < m_list.count(); i++) {
109+ if (m_list.at(i)->appId() == appId) {
110+ item = m_list.at(i);
111+ idx = i;
112+ break;
113+ }
114+ }
115+
116+ if (!item) {
117+ return;
118+ }
119+
120+ UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
121+ item->setPopularity(info.popularity);
122+ Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
123+}