/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Michael Terry * Michael Zanetti * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "AccountsService.h" #include "launcherbackend.h" #include #include LauncherBackend::LauncherBackend(bool useStorage, QObject *parent): QObject(parent), m_accounts(nullptr) { if (useStorage) { m_accounts = new AccountsService(this); } setUser(qgetenv("USER")); } LauncherBackend::~LauncherBackend() { clearItems(); } void LauncherBackend::clearItems() { for (LauncherBackendItem &app: m_storedApps) { delete app.settings; } m_storedApps.clear(); } QStringList LauncherBackend::storedApplications() const { auto files = QStringList(); for (const LauncherBackendItem &app: m_storedApps) { files << app.settings->fileName(); } return files; } void LauncherBackend::setStoredApplications(const QStringList &appIds) { // Record all existing pinned apps, so we can notice them in new list auto pinnedItems = QStringList(); for (LauncherBackendItem &app: m_storedApps) { if (app.pinned) { pinnedItems.append(app.settings->fileName()); } } clearItems(); for (const QString &appId: appIds) { loadDesktopFile(appId, pinnedItems.contains(desktopFile(appId))); } syncToAccounts(); } QString LauncherBackend::desktopFile(const QString &appId) const { QFileInfo fileInfo(QDir("/usr/share/applications"), appId); return fileInfo.absoluteFilePath(); } QString LauncherBackend::displayName(const QString &appId) const { auto desktopFile = parseDesktopFile(appId); auto displayName = desktopFile->value("Desktop Entry/Name").toString(); delete desktopFile; return displayName; } QString LauncherBackend::icon(const QString &appId) const { auto desktopFile = parseDesktopFile(appId); auto iconName = desktopFile->value("Desktop Entry/Icon").toString(); delete desktopFile; if (!iconName.isEmpty()) { QFileInfo iconFileInfo(iconName); if (iconFileInfo.isRelative()) { iconName = "image://gicon/" + iconName; } } return iconName; } bool LauncherBackend::isPinned(const QString &appId) const { auto index = findItem(appId); if (index < 0) { return false; } else { return m_storedApps[index].pinned; } } void LauncherBackend::setPinned(const QString &appId, bool pinned) { auto index = findItem(appId); if (index >= 0 && !m_storedApps[index].pinned) { m_storedApps[index].pinned = pinned; syncToAccounts(); } } QList LauncherBackend::quickList(const QString &appId) const { // TODO: Get static (from .desktop file) and dynamic (from the app itself) // entries and return them here. Frontend related entries (like "Pin to launcher") // don't matter here. This is just the backend part. // TODO: emit quickListChanged() when the dynamic part changes Q_UNUSED(appId) return QList(); } int LauncherBackend::progress(const QString &appId) const { // TODO: Return value for progress emblem. // TODO: emit progressChanged() when this value changes. Q_UNUSED(appId) return -1; } int LauncherBackend::count(const QString &appId) const { // TODO: Return value for count emblem. // TODO: emit countChanged() when this value changes. Q_UNUSED(appId) return 0; } void LauncherBackend::setUser(const QString &username) { m_user = username; syncFromAccounts(); } void LauncherBackend::triggerQuickListAction(const QString &appId, const QString &quickListId) { // TODO: execute the given quicklist action Q_UNUSED(appId) Q_UNUSED(quickListId) } void LauncherBackend::syncFromAccounts() { auto appIds = QStringList(); if (m_user != "" && m_accounts != nullptr) { appIds = m_accounts->getUserProperty(m_user, "launcher-items").toStringList(); } // TODO: load default pinned ones from default config, instead of hardcoding here... if (appIds.isEmpty()) { appIds << "phone-app.desktop" << "camera-app.desktop" << "gallery-app.desktop" << "facebook-webapp.desktop" << "webbrowser-app.desktop" << "twitter-webapp.desktop" << "gmail-webapp.desktop" << "ubuntu-weather-app.desktop" << "notes-app.desktop" << "calendar-app.desktop"; } setStoredApplications(appIds); // Mark all apps as pinned (since we just refreshed the set) for (LauncherBackendItem &app: m_storedApps) { app.pinned = true; } } void LauncherBackend::syncToAccounts() { auto pinnedItems = QStringList(); for (LauncherBackendItem &app: m_storedApps) { if (app.pinned) { pinnedItems.append(app.settings->fileName()); } } if (m_user != "" && m_accounts != nullptr) { m_accounts->setUserProperty(m_user, "launcher-items", QVariant(pinnedItems)); } } QSettings *LauncherBackend::parseDesktopFile(const QString &appId) const { auto fullAppId = desktopFile(appId); return new QSettings(fullAppId, QSettings::IniFormat); } bool LauncherBackend::loadDesktopFile(const QString &appId, bool isPinned) { auto item = LauncherBackendItem(); item.settings = parseDesktopFile(appId); item.pinned = isPinned; m_storedApps.append(item); return true; // QSettings doesn't really indicate a failure mode right now } int LauncherBackend::findItem(const QString &appId) const { auto fullAppId = desktopFile(appId); for (int i = 0; i < m_storedApps.size(); ++i) { if (m_storedApps[i].settings->fileName() == fullAppId) { return i; } } return -1; }