diff --git a/favoritesmodel.cpp b/favoritesmodel.cpp index fbd9e0357..a5625354e 100644 --- a/favoritesmodel.cpp +++ b/favoritesmodel.cpp @@ -1,334 +1,329 @@ /*************************************************************************** * Copyright (C) 2014-2015 by Eike Hein * * * * 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; either version 2 of the License, or * * (at your option) any later version. * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "favoritesmodel.h" #include "appentry.h" #include "contactentry.h" #include "fileentry.h" #include "systementry.h" #include "actionlist.h" #include FavoritesModel::FavoritesModel(QObject *parent) : AbstractModel(parent) , m_enabled(true) , m_maxFavorites(-1) , m_dropPlaceholderIndex(-1) { } FavoritesModel::~FavoritesModel() { qDeleteAll(m_entryList); } QString FavoritesModel::description() const { return i18n("Favorites"); } QVariant FavoritesModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() >= rowCount()) { return QVariant(); } if (index.row() == m_dropPlaceholderIndex) { if (role == Kicker::IsDropPlaceholderRole) { return true; } else { return QVariant(); } } int mappedIndex = index.row(); if (m_dropPlaceholderIndex != -1 && mappedIndex > m_dropPlaceholderIndex) { --mappedIndex; } const AbstractEntry *entry = m_entryList.at(mappedIndex); if (role == Qt::DisplayRole) { return entry->name(); } else if (role == Qt::DecorationRole) { return entry->icon(); } else if (role == Kicker::FavoriteIdRole) { return entry->id(); } else if (role == Kicker::HasActionListRole) { return entry->hasActions(); } else if (role == Kicker::ActionListRole) { return entry->actions(); } return QVariant(); } int FavoritesModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : m_entryList.count() + (m_dropPlaceholderIndex != -1 ? 1 : 0); } bool FavoritesModel::trigger(int row, const QString &actionId, const QVariant &argument) { if (row < 0 || row >= m_entryList.count()) { return false; } return m_entryList.at(row)->run(actionId, argument); } bool FavoritesModel::enabled() const { return m_enabled; } void FavoritesModel::setEnabled(bool enable) { if (m_enabled != enable) { m_enabled = enable; emit enabledChanged(); } } QStringList FavoritesModel::favorites() const { return m_favorites; } void FavoritesModel::setFavorites(const QStringList& favorites) { QStringList _favorites(favorites); _favorites.removeDuplicates(); if (_favorites != m_favorites) { m_favorites = _favorites; refresh(); } } int FavoritesModel::maxFavorites() const { return m_maxFavorites; } void FavoritesModel::setMaxFavorites(int max) { if (m_maxFavorites != max) { m_maxFavorites = max; if (m_maxFavorites != -1 && m_favorites.count() > m_maxFavorites) { refresh(); } emit maxFavoritesChanged(); } } bool FavoritesModel::isFavorite(const QString &id) const { return m_favorites.contains(id); } void FavoritesModel::addFavorite(const QString &id, int index) { if (!m_enabled || id.isEmpty()) { return; } if (m_maxFavorites != -1 && m_favorites.count() == m_maxFavorites) { return; } AbstractEntry *entry = favoriteFromId(id); if (!entry || !entry->isValid()) { delete entry; return; } setDropPlaceholderIndex(-1); int insertIndex = (index != -1) ? index : m_entryList.count(); beginInsertRows(QModelIndex(), insertIndex, insertIndex); m_entryList.insert(insertIndex, entry); m_favorites.insert(insertIndex, entry->id()); endInsertRows(); emit countChanged(); emit favoritesChanged(); } void FavoritesModel::removeFavorite(const QString &id) { if (!m_enabled || id.isEmpty()) { return; } int index = m_favorites.indexOf(id); if (index != -1) { setDropPlaceholderIndex(-1); beginRemoveRows(QModelIndex(), index, index); delete m_entryList[index]; m_entryList.removeAt(index); m_favorites.removeAt(index); endRemoveRows(); emit countChanged(); emit favoritesChanged(); } } void FavoritesModel::moveRow(int from, int to) { if (from >= m_favorites.count() || to >= m_favorites.count()) { return; } if (from == to) { return; } setDropPlaceholderIndex(-1); int modelTo = to + (to > from ? 1 : 0); bool ok = beginMoveRows(QModelIndex(), from, from, QModelIndex(), modelTo); if (ok) { m_entryList.move(from, to); m_favorites.move(from, to); endMoveRows(); emit favoritesChanged(); } } int FavoritesModel::dropPlaceholderIndex() const { return m_dropPlaceholderIndex; } void FavoritesModel::setDropPlaceholderIndex(int index) { if (index == -1 && m_dropPlaceholderIndex != -1) { beginRemoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex); m_dropPlaceholderIndex = index; endRemoveRows(); emit countChanged(); } else if (index != -1 && m_dropPlaceholderIndex == -1) { beginInsertRows(QModelIndex(), index, index); m_dropPlaceholderIndex = index; endInsertRows(); emit countChanged(); } else if (m_dropPlaceholderIndex != index) { int modelTo = index + (index > m_dropPlaceholderIndex ? 1 : 0); bool ok = beginMoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex, QModelIndex(), modelTo); if (ok) { m_dropPlaceholderIndex = index; endMoveRows(); } } } AbstractModel *FavoritesModel::favoritesModel() { return this; } void FavoritesModel::refresh() { beginResetModel(); setDropPlaceholderIndex(-1); int oldCount = m_entryList.count(); qDeleteAll(m_entryList); m_entryList.clear(); QStringList newFavorites; foreach(const QString &id, m_favorites) { AbstractEntry *entry = favoriteFromId(id); if (entry && entry->isValid()) { m_entryList << entry; newFavorites << entry->id(); if (m_maxFavorites != -1 && newFavorites.count() == m_maxFavorites) { break; } } else if (entry) { delete entry; } } m_favorites = newFavorites; endResetModel(); if (oldCount != m_entryList.count()) { emit countChanged(); } emit favoritesChanged(); } AbstractEntry *FavoritesModel::favoriteFromId(const QString &id) { const QUrl url(id); const QString &s = url.scheme(); if ((s.isEmpty() && id.contains(QStringLiteral(".desktop"))) || s == QStringLiteral("preferred")) { return new AppEntry(this, id); } else if (s == QStringLiteral("ktp")) { return new ContactEntry(this, id); + } else if (url.isValid() && !url.scheme().isEmpty()) { + return new FileEntry(this, url); } else { - AbstractEntry *entry = new SystemEntry(this, id); - - if (!entry->isValid()) { - delete entry; - return new FileEntry(this, url); - } - - return entry; + return new SystemEntry(this, id); } return nullptr; } diff --git a/systementry.cpp b/systementry.cpp index fb822ba23..ec527dad6 100644 --- a/systementry.cpp +++ b/systementry.cpp @@ -1,280 +1,286 @@ /*************************************************************************** * Copyright (C) 2015 by Eike Hein * * * * 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; either version 2 of the License, or * * (at your option) any later version. * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "systementry.h" #include #include #include #include #include #include #include #include #include #include "ksmserver_interface.h" #include KDisplayManager *SystemEntry::m_displayManager = new KDisplayManager(); SystemEntry::SystemEntry(AbstractModel *owner, Action action) : AbstractEntry(owner) , m_action(action) , m_valid(false) { init(); } SystemEntry::SystemEntry(AbstractModel *owner, const QString &id) : AbstractEntry(owner) , m_action(NoAction) , m_valid(false) { if (id == QStringLiteral("lock-screen")) { m_action = LockSession; } else if (id == QStringLiteral("logout")) { m_action = LogoutSession; } else if (id == QStringLiteral("save-session")) { m_action = SaveSession; } else if (id == QStringLiteral("switch-user")) { m_action = NewSession; } else if (id == QStringLiteral("suspend")) { m_action = SuspendToRam; } else if (id == QStringLiteral("hibernate")) { m_action = SuspendToDisk; } else if (id == QStringLiteral("reboot")) { m_action = Reboot; } else if (id == QStringLiteral("shutdown")) { m_action = Shutdown; } init(); } void SystemEntry::init() { switch (m_action) { case NoAction: m_valid = false; break; case LockSession: m_valid = KAuthorized::authorizeKAction("lock_screen"); break; case LogoutSession: case SaveSession: { bool authorize = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout"); if (m_action == SaveSession) { const KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General"); m_valid = authorize && c.readEntry("loginMode") == "restoreSavedSession"; } else { m_valid = authorize; } break; } case NewSession: m_valid = KAuthorized::authorizeKAction("start_new_session") && m_displayManager->isSwitchable() && m_displayManager->numReserve() >= 0; break; case SuspendToRam: m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::SuspendState); break; case SuspendToDisk: m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HibernateState); break; + case Reboot: + m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); + break; + case Shutdown: + m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); + break; default: m_valid = true; } } bool SystemEntry::isValid() const { return m_valid; } QIcon SystemEntry::icon() const { const QString &name = iconName(); if (!name.isEmpty()) { return QIcon::fromTheme(name, QIcon::fromTheme("unknown")); } return QIcon::fromTheme("unknown"); } QString SystemEntry::iconName() const { switch (m_action) { case LockSession: return "system-lock-screen"; break; case LogoutSession: return "system-log-out"; break; case SaveSession: return "system-save-session"; break; case NewSession: return "system-switch-user"; break; case SuspendToRam: return "system-suspend"; break; case SuspendToDisk: return "system-suspend-hibernate"; break; case Reboot: return "system-reboot"; break; case Shutdown: return "system-shutdown"; break; default: break; } return QString(); } QString SystemEntry::name() const { switch (m_action) { case LockSession: return i18n("Lock"); break; case LogoutSession: return i18n("Logout"); break; case SaveSession: return i18n("Save Session"); break; case NewSession: return i18n("New Session"); break; case SuspendToRam: return i18n("Suspend"); break; case SuspendToDisk: return i18n("Hibernate"); break; case Reboot: return i18n("Restart"); break; case Shutdown: return i18n("Shutdown"); break; default: break; } return QString(); } QString SystemEntry::id() const { switch (m_action) { case LockSession: return QStringLiteral("lock-screen"); break; case LogoutSession: return QStringLiteral("logout"); break; case SaveSession: return QStringLiteral("save-session"); break; case NewSession: return QStringLiteral("switch-user"); break; case SuspendToRam: return QStringLiteral("suspend"); break; case SuspendToDisk: return QStringLiteral("hibernate"); break; case Reboot: return QStringLiteral("reboot"); break; case Shutdown: return QStringLiteral("shutdown"); break; default: break; } return QString(); } bool SystemEntry::run(const QString& actionId, const QVariant &argument) { Q_UNUSED(actionId) Q_UNUSED(argument) switch (m_action) { case LockSession: { QDBusConnection bus = QDBusConnection::sessionBus(); QDBusInterface interface("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", bus); interface.asyncCall("Lock"); break; } case LogoutSession: KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeNone); break; case SaveSession: { org::kde::KSMServerInterface ksmserver(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QDBusConnection::sessionBus()); if (ksmserver.isValid()) { ksmserver.saveCurrentSession(); } break; } case NewSession: { QDBusConnection bus = QDBusConnection::sessionBus(); QDBusInterface interface("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", bus); interface.asyncCall("Lock"); m_displayManager->startReserve(); break; }; case SuspendToRam: Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, 0, 0); break; case SuspendToDisk: Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, 0, 0); break; case Reboot: KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); break; case Shutdown: KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); break; default: return false; } return true; } diff --git a/systemmodel.cpp b/systemmodel.cpp index 593919d12..ef028926f 100644 --- a/systemmodel.cpp +++ b/systemmodel.cpp @@ -1,101 +1,134 @@ /*************************************************************************** * Copyright (C) 2014-2015 by Eike Hein * * * * 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; either version 2 of the License, or * * (at your option) any later version. * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "systemmodel.h" #include "actionlist.h" #include "favoritesmodel.h" #include "systementry.h" +#include + +#include #include SystemModel::SystemModel(QObject *parent) : AbstractModel(parent) , m_favoritesModel(new FavoritesModel(this)) +{ + init(); + + const QString configFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/ksmserverrc"; + + KDirWatch *watch = new KDirWatch(this); + + watch->addFile(configFile); + + connect(watch, &KDirWatch::dirty, this, &SystemModel::refresh); + connect(watch, &KDirWatch::created, this, &SystemModel::refresh); +} + +SystemModel::~SystemModel() +{ + qDeleteAll(m_entryList); +} + +void SystemModel::init() { QList actions; actions << new SystemEntry(this, SystemEntry::LockSession); actions << new SystemEntry(this, SystemEntry::LogoutSession); actions << new SystemEntry(this, SystemEntry::SaveSession); actions << new SystemEntry(this, SystemEntry::NewSession); actions << new SystemEntry(this, SystemEntry::SuspendToRam); actions << new SystemEntry(this, SystemEntry::SuspendToDisk); actions << new SystemEntry(this, SystemEntry::Reboot); actions << new SystemEntry(this, SystemEntry::Shutdown); foreach(SystemEntry *entry, actions) { if (entry->isValid()) { m_entryList << entry; } else { delete entry; } } } -SystemModel::~SystemModel() -{ - qDeleteAll(m_entryList); -} - QString SystemModel::description() const { return i18n("System actions"); } QVariant SystemModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() >= m_entryList.count()) { return QVariant(); } const SystemEntry *entry = m_entryList.at(index.row()); if (role == Qt::DisplayRole) { return entry->name(); } else if (role == Qt::DecorationRole) { return entry->iconName(); } else if (role == Kicker::FavoriteIdRole) { return entry->id(); } return QVariant(); } int SystemModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : m_entryList.count(); } bool SystemModel::trigger(int row, const QString &actionId, const QVariant &argument) { Q_UNUSED(actionId) Q_UNUSED(argument) if (row >= 0 && row < m_entryList.count()) { m_entryList.at(row)->run(); return true; } return false; } AbstractModel* SystemModel::favoritesModel() { return m_favoritesModel; } + +void SystemModel::refresh() +{ + beginResetModel(); + + qDeleteAll(m_entryList); + m_entryList.clear(); + + init(); + + endResetModel(); + + emit countChanged(); + + m_favoritesModel->refresh(); +} diff --git a/systemmodel.h b/systemmodel.h index 995ff2a9a..1b3eab79a 100644 --- a/systemmodel.h +++ b/systemmodel.h @@ -1,50 +1,55 @@ /*************************************************************************** * Copyright (C) 2014-2015 by Eike Hein * * * * 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; either version 2 of the License, or * * (at your option) any later version. * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #ifndef SYSTEMMODEL_H #define SYSTEMMODEL_H #include "abstractmodel.h" class SystemEntry; class SystemModel : public AbstractModel { Q_OBJECT public: explicit SystemModel(QObject *parent = 0); ~SystemModel(); QString description() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; Q_INVOKABLE bool trigger(int row, const QString &actionId, const QVariant &argument); AbstractModel* favoritesModel(); + protected Q_SLOTS: + virtual void refresh(); + private: + void init(); + QList m_entryList; AbstractModel *m_favoritesModel; }; #endif