17 #include "launchermodelas.h"
18 #include "launcheritem.h"
19 #include "AccountsServiceDBusAdaptor.h"
20 #include <unity/shell/application/ApplicationInfoInterface.h>
22 #include <QDesktopServices>
24 #include <QDBusArgument>
28 LauncherModel::LauncherModel(QObject *parent):
29 LauncherModelInterface(parent),
30 m_accounts(new AccountsServiceDBusAdaptor(this)),
33 connect(m_accounts, &AccountsServiceDBusAdaptor::propertiesChanged,
this, &LauncherModel::propertiesChanged);
37 LauncherModel::~LauncherModel()
39 while (!m_list.empty()) {
40 m_list.takeFirst()->deleteLater();
44 int LauncherModel::rowCount(
const QModelIndex &parent)
const
47 return m_list.count();
50 QVariant LauncherModel::data(const QModelIndex &index,
int role)
const
52 LauncherItem *item = m_list.at(index.row());
61 return item->pinned();
64 case RoleCountVisible:
65 return item->countVisible();
67 return item->progress();
69 return item->focused();
71 return item->running();
77 void LauncherModel::setAlerting(
const QString &appId,
bool alerting)
81 qWarning() << "This is a read only implementation. Cannot set alert-state of items.";
84 unity::shell::launcher::LauncherItemInterface *LauncherModel::get(
int index)
const
86 if (index < 0 || index >= m_list.count()) {
89 return m_list.at(index);
92 void LauncherModel::move(
int oldIndex,
int newIndex)
96 qWarning() << "This is a read only implementation. Cannot move items.";
99 void LauncherModel::pin(const QString &appId,
int index)
103 qWarning() << "This is a read only implementation. Cannot pin items";
106 void LauncherModel::requestRemove(const QString &appId)
109 qWarning() << "This is a read only implementation. Cannot remove items";
112 void LauncherModel::quickListActionInvoked(const QString &appId,
int actionIndex)
114 int index = findApplication(appId);
119 LauncherItem *item = m_list.at(index);
120 QuickListModel *model = qobject_cast<QuickListModel*>(item->quickList());
122 QString actionId = model->get(actionIndex).actionId();
125 if (actionId == QLatin1String(
"launch_item")) {
126 QDesktopServices::openUrl(getUrlForAppId(appId));
135 void LauncherModel::setUser(
const QString &username)
137 if (m_user != username) {
143 QString LauncherModel::getUrlForAppId(
const QString &appId)
const
146 if (appId.isEmpty()) {
150 if (!appId.contains(
'_')) {
151 return "application:///" + appId +
".desktop";
154 QStringList parts = appId.split(
'_');
155 QString
package = parts.value(0);
156 QString app = parts.value(1, QStringLiteral(
"first-listed-app"));
157 return "appid://" +
package + "/" + app + "/current-user-version";
160 ApplicationManagerInterface *LauncherModel::applicationManager()
const
165 void LauncherModel::setApplicationManager(unity::shell::application::ApplicationManagerInterface *appManager)
168 qWarning() << "This plugin syncs all its states from AccountsService. Not using ApplicationManager.";
172 bool LauncherModel::onlyPinned()
const
177 void LauncherModel::setOnlyPinned(
bool onlyPinned)
179 if (m_onlyPinned != onlyPinned) {
180 m_onlyPinned = onlyPinned;
181 Q_EMIT onlyPinnedChanged();
186 int LauncherModel::findApplication(
const QString &appId)
188 for (
int i = 0; i < m_list.count(); ++i) {
189 LauncherItem *item = m_list.at(i);
190 if (item->appId() == appId) {
197 void LauncherModel::refresh()
199 if (!m_accounts || m_user.isEmpty()) {
200 refreshWithItems(QList<QVariantMap>());
202 QDBusPendingCall pendingCall = m_accounts->getUserPropertyAsync(m_user, QStringLiteral(
"com.canonical.unity.AccountsService"), QStringLiteral(
"LauncherItems"));
203 QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pendingCall,
this);
204 connect(watcher, &QDBusPendingCallWatcher::finished,
205 this, [
this](QDBusPendingCallWatcher* watcher) {
207 QDBusPendingReply<QVariant> reply = *watcher;
208 watcher->deleteLater();
209 if (reply.isError()) {
210 qWarning() <<
"Failed to refresh LauncherItems" << reply.error().message();
214 refreshWithItems(qdbus_cast<QList<QVariantMap>>(reply.value().value<QDBusArgument>()));
219 void LauncherModel::refreshWithItems(
const QList<QVariantMap> &items)
222 QList<LauncherItem*> toBeRemoved;
224 Q_FOREACH (LauncherItem* item, m_list) {
226 Q_FOREACH(
const QVariant &asItem, items) {
227 QVariantMap cachedMap = asItem.toMap();
228 if (cachedMap.value(QStringLiteral(
"id")).toString() == item->appId()) {
230 if (!m_onlyPinned || cachedMap.value(QStringLiteral(
"pinned")).toBool()) {
232 item->setName(cachedMap.value(QStringLiteral(
"name")).toString());
233 item->setIcon(cachedMap.value(QStringLiteral(
"icon")).toString());
234 item->setCount(cachedMap.value(QStringLiteral(
"count")).toInt());
235 item->setCountVisible(cachedMap.value(QStringLiteral(
"countVisible")).toBool());
236 item->setProgress(cachedMap.value(QStringLiteral(
"progress")).toInt());
237 item->setRunning(cachedMap.value(QStringLiteral(
"running")).toBool());
239 int idx = m_list.indexOf(item);
240 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleIcon, RoleCount, RoleCountVisible, RoleRunning, RoleProgress});
246 toBeRemoved.append(item);
250 Q_FOREACH (LauncherItem* item, toBeRemoved) {
251 int idx = m_list.indexOf(item);
252 beginRemoveRows(QModelIndex(), idx, idx);
253 m_list.takeAt(idx)->deleteLater();
259 for (
int asIndex = 0; asIndex < items.count(); ++asIndex) {
260 QVariant entry = items.at(asIndex);
262 if (m_onlyPinned && !entry.toMap().value(QStringLiteral(
"pinned")).toBool()) {
267 int newPosition = asIndex - skipped;
270 for (
int i = 0; i < m_list.count(); ++i) {
271 if (m_list.at(i)->appId() == entry.toMap().value(QStringLiteral(
"id")).toString()) {
277 if (itemIndex == -1) {
278 QVariantMap cachedMap = entry.toMap();
280 LauncherItem *item =
new LauncherItem(cachedMap.value(QStringLiteral(
"id")).toString(),
281 cachedMap.value(QStringLiteral(
"name")).toString(),
282 cachedMap.value(QStringLiteral(
"icon")).toString(),
284 item->setPinned(
true);
285 item->setCount(cachedMap.value(QStringLiteral(
"count")).toInt());
286 item->setCountVisible(cachedMap.value(QStringLiteral(
"countVisible")).toBool());
287 item->setProgress(cachedMap.value(QStringLiteral(
"progress")).toInt());
288 item->setRunning(cachedMap.value(QStringLiteral(
"running")).toBool());
289 beginInsertRows(QModelIndex(), newPosition, newPosition);
290 m_list.insert(newPosition, item);
292 }
else if (itemIndex != newPosition) {
295 beginMoveRows(QModelIndex(), itemIndex, itemIndex, QModelIndex(), newPosition);
296 m_list.move(itemIndex, newPosition);
302 void LauncherModel::propertiesChanged(
const QString &user,
const QString &interface,
const QStringList &changed)
304 if (user != m_user || interface != QLatin1String(
"com.canonical.unity.AccountsService") || !changed.contains(QStringLiteral(
"LauncherItems"))) {