on 08ebccf help sign in
unity8/plugins/Unity/Launcher/backend/launcherbackend.cpp
261 lines 7.5 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * Authors:
5 * Michael Terry <michael.terry@canonical.com>
6 * Michael Zanetti <michael.zanetti@canonical.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 3.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
21#include "AccountsService.h"
22#include "launcherbackend.h"
24#include <QDir>
25#include <QDBusArgument>
26#include <QFileInfo>
28LauncherBackend::LauncherBackend(bool useStorage, QObject *parent):
29 QObject(parent),
30 m_accounts(nullptr)
32 if (useStorage) {
33 m_accounts = new AccountsService(this);
34 }
35 setUser(qgetenv("USER"));
38LauncherBackend::~LauncherBackend()
40 clearItems();
43void LauncherBackend::clearItems()
45 for (LauncherBackendItem &app: m_storedApps) {
46 delete app.settings;
47 }
48 m_storedApps.clear();
51QStringList LauncherBackend::storedApplications() const
53 auto files = QStringList();
54 for (const LauncherBackendItem &app: m_storedApps) {
55 files << app.settings->fileName();
56 }
57 return files;
60void LauncherBackend::setStoredApplications(const QStringList &appIds)
62 // Record all existing pinned apps, so we can notice them in new list
63 auto pinnedItems = QStringList();
64 for (LauncherBackendItem &app: m_storedApps) {
65 if (app.pinned) {
66 pinnedItems.append(app.settings->fileName());
67 }
68 }
70 clearItems();
72 for (const QString &appId: appIds) {
73 loadApp(makeAppDetails(appId, pinnedItems.contains(desktopFile(appId))));
74 }
76 syncToAccounts();
79QString LauncherBackend::desktopFile(const QString &appId) const
81 QFileInfo fileInfo(QDir("/usr/share/applications"), appId);
82 return fileInfo.absoluteFilePath();
85QString LauncherBackend::displayName(const QString &appId) const
87 auto desktopFile = parseDesktopFile(appId);
88 auto displayName = desktopFile->value("Desktop Entry/Name").toString();
89 delete desktopFile;
90 return displayName;
93QString LauncherBackend::icon(const QString &appId) const
95 auto desktopFile = parseDesktopFile(appId);
96 auto iconName = desktopFile->value("Desktop Entry/Icon").toString();
97 delete desktopFile;
99 if (!iconName.isEmpty()) {
100 QFileInfo iconFileInfo(iconName);
101 if (iconFileInfo.isRelative()) {
102 iconName = "image://gicon/" + iconName;
103 }
104 }
106 return iconName;
109bool LauncherBackend::isPinned(const QString &appId) const
111 auto index = findItem(appId);
112 if (index < 0) {
113 return false;
114 } else {
115 return m_storedApps[index].pinned;
116 }
119void LauncherBackend::setPinned(const QString &appId, bool pinned)
121 auto index = findItem(appId);
122 if (index >= 0 && !m_storedApps[index].pinned) {
123 m_storedApps[index].pinned = pinned;
124 syncToAccounts();
125 }
128QList<QuickListEntry> LauncherBackend::quickList(const QString &appId) const
130 // TODO: Get static (from .desktop file) and dynamic (from the app itself)
131 // entries and return them here. Frontend related entries (like "Pin to launcher")
132 // don't matter here. This is just the backend part.
133 // TODO: emit quickListChanged() when the dynamic part changes
134 Q_UNUSED(appId)
135 return QList<QuickListEntry>();
138int LauncherBackend::progress(const QString &appId) const
140 // TODO: Return value for progress emblem.
141 // TODO: emit progressChanged() when this value changes.
142 Q_UNUSED(appId)
143 return -1;
146int LauncherBackend::count(const QString &appId) const
148 // TODO: Return value for count emblem.
149 // TODO: emit countChanged() when this value changes.
150 Q_UNUSED(appId)
151 return 0;
154void LauncherBackend::setUser(const QString &username)
156 m_user = username;
157 syncFromAccounts();
160void LauncherBackend::triggerQuickListAction(const QString &appId, const QString &quickListId)
162 // TODO: execute the given quicklist action
163 Q_UNUSED(appId)
164 Q_UNUSED(quickListId)
167void LauncherBackend::syncFromAccounts()
169 QList<QVariantMap> apps;
170 bool defaults = true;
172 clearItems();
174 if (m_user != "" && m_accounts != nullptr) {
175 auto variant = m_accounts->getUserProperty(m_user, "launcher-items");
176 apps = qdbus_cast<QList<QVariantMap>>(variant.value<QDBusArgument>());
177 defaults = isDefaultsItem(apps);
178 }
180 // TODO: load default pinned ones from default config, instead of hardcoding here...
181 if (defaults) {
182 apps <<
183 makeAppDetails("dialer-app.desktop", true) <<
184 makeAppDetails("messaging-app.desktop", true) <<
185 makeAppDetails("address-book-app.desktop", true) <<
186 makeAppDetails("camera-app.desktop", true) <<
187 makeAppDetails("gallery-app.desktop", true) <<
188 makeAppDetails("facebook-webapp.desktop", true) <<
189 makeAppDetails("webbrowser-app.desktop", true) <<
190 makeAppDetails("twitter-webapp.desktop", true) <<
191 makeAppDetails("gmail-webapp.desktop", true) <<
192 makeAppDetails("ubuntu-weather-app.desktop", true) <<
193 makeAppDetails("notes-app.desktop", true) <<
194 makeAppDetails("calendar-app.desktop", true);
195 }
197 for (const QVariant &app: apps) {
198 loadApp(app.toMap());
199 }
202void LauncherBackend::syncToAccounts()
204 if (m_user != "" && m_accounts != nullptr) {
205 QList<QVariantMap> items;
207 for (LauncherBackendItem &app: m_storedApps) {
208 items << makeAppDetails(app.settings->fileName(), app.pinned);
209 }
211 m_accounts->setUserProperty(m_user, "launcher-items", QVariant::fromValue(items));
212 }
215QSettings *LauncherBackend::parseDesktopFile(const QString &appId) const
217 auto fullAppId = desktopFile(appId);
218 return new QSettings(fullAppId, QSettings::IniFormat);
221void LauncherBackend::loadApp(const QVariantMap &details)
223 auto appId = details.value("id").toString();
224 auto isPinned = details.value("is-pinned").toBool();
226 if (appId.isEmpty()) {
227 return;
228 }
230 LauncherBackendItem item;
231 item.settings = parseDesktopFile(appId);
232 item.pinned = isPinned;
233 m_storedApps.append(item);
236QVariantMap LauncherBackend::makeAppDetails(const QString &appId, bool pinned) const
238 QVariantMap details;
239 details.insert("id", appId);
240 details.insert("is-pinned", pinned);
241 return details;
244bool LauncherBackend::isDefaultsItem(const QList<QVariantMap> &apps) const
246 // To differentiate between an empty list and a list that hasn't been set
247 // yet (and should thus be populated with the defaults), we use a special
248 // list of one item with the 'defaults' field set to true.
249 return (apps.size() == 1 && apps[0].value("defaults").toBool());
252int LauncherBackend::findItem(const QString &appId) const
254 auto fullAppId = desktopFile(appId);
255 for (int i = 0; i < m_storedApps.size(); ++i) {
256 if (m_storedApps[i].settings->fileName() == fullAppId) {
257 return i;
258 }
259 }
260 return -1;