/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * * LXDE-Qt - a lightweight, Qt based, desktop toolset * http://razor-qt.org * * Copyright: 2013 Razor team * Authors: * Kuzma Shapran * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "actions.h" #include "org.lxqt.global_key_shortcuts.daemon.h" Actions::Actions(QObject *parent) : QObject(parent) , mServiceWatcher(new QDBusServiceWatcher("org.lxqt.global_key_shortcuts", QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this)) , mMultipleActionsBehaviour(MULTIPLE_ACTIONS_BEHAVIOUR_FIRST) { connect(mServiceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(on_daemonDisappeared(QString))); connect(mServiceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(on_daemonAppeared(QString))); mDaemonProxy = new org::lxqt::global_key_shortcuts::daemon("org.lxqt.global_key_shortcuts", "/daemon", QDBusConnection::sessionBus(), this); connect(mDaemonProxy, SIGNAL(actionAdded(qulonglong)), this, SLOT(on_actionAdded(qulonglong))); connect(mDaemonProxy, SIGNAL(actionEnabled(qulonglong, bool)), this, SLOT(on_actionEnabled(qulonglong, bool))); connect(mDaemonProxy, SIGNAL(clientActionSenderChanged(qulonglong, QString)), this, SLOT(on_clientActionSenderChanged(qulonglong, QString))); connect(mDaemonProxy, SIGNAL(actionModified(qulonglong)), this, SLOT(on_actionModified(qulonglong))); connect(mDaemonProxy, SIGNAL(actionRemoved(qulonglong)), this, SLOT(on_actionRemoved(qulonglong))); connect(mDaemonProxy, SIGNAL(actionShortcutChanged(qulonglong)), this, SLOT(on_actionShortcutChanged(qulonglong))); connect(mDaemonProxy, SIGNAL(actionsSwapped(qulonglong, qulonglong)), this, SLOT(on_actionsSwapped(qulonglong, qulonglong))); connect(mDaemonProxy, SIGNAL(multipleActionsBehaviourChanged(uint)), this, SLOT(on_multipleActionsBehaviourChanged(uint))); QTimer::singleShot(0, this, SLOT(delayedInit())); } Actions::~Actions() { } void Actions::delayedInit() { if (mDaemonProxy->isValid()) { on_daemonAppeared(QString()); } } void Actions::on_daemonDisappeared(const QString &) { clear(); emit daemonDisappeared(); } void Actions::on_daemonAppeared(const QString &) { init(); emit daemonAppeared(); } void Actions::init() { clear(); mGeneralActionInfo = getAllActions(); GeneralActionInfos::const_iterator M = mGeneralActionInfo.constEnd(); for (GeneralActionInfos::const_iterator I = mGeneralActionInfo.constBegin(); I != M; ++I) { if (I.value().type == "client") { QString shortcut; QString description; bool enabled = false; QDBusObjectPath path; if (getClientActionInfoById(I.key(), shortcut, description, enabled, path)) { ClientActionInfo info; info.shortcut = shortcut; info.description = description; info.enabled = enabled; info.path = path; mClientActionInfo[I.key()] = info; updateClientActionSender(I.key()); } } else if (I.value().type == "method") { QString shortcut; QString description; bool enabled = false; QString service; QDBusObjectPath path; QString interface; QString method; if (getMethodActionInfoById(I.key(), shortcut, description, enabled, service, path, interface, method)) { MethodActionInfo info; info.shortcut = shortcut; info.description = description; info.enabled = enabled; info.service = service; info.path = path; info.interface = interface; info.method = method; mMethodActionInfo[I.key()] = info; } } else if (I.value().type == "command") { QString shortcut; QString description; bool enabled = false; QString command; QStringList arguments; if (getCommandActionInfoById(I.key(), shortcut, description, enabled, command, arguments)) { CommandActionInfo info; info.shortcut = shortcut; info.description = description; info.enabled = enabled; info.command = command; info.arguments = arguments; mCommandActionInfo[I.key()] = info; } } } mMultipleActionsBehaviour = static_cast(getMultipleActionsBehaviour()); } void Actions::clear() { mGeneralActionInfo.clear(); mClientActionInfo.clear(); mMethodActionInfo.clear(); mCommandActionInfo.clear(); mMultipleActionsBehaviour = MULTIPLE_ACTIONS_BEHAVIOUR_FIRST; } QList Actions::allActionIds() const { return mGeneralActionInfo.keys(); } QPair Actions::actionById(qulonglong id) const { GeneralActionInfos::const_iterator I = mGeneralActionInfo.constFind(id); if (I == mGeneralActionInfo.constEnd()) { return qMakePair(false, GeneralActionInfo()); } return qMakePair(true, I.value()); } QList Actions::allClientActionIds() const { return mClientActionInfo.keys(); } QPair Actions::clientActionInfoById(qulonglong id) const { ClientActionInfos::const_iterator I = mClientActionInfo.constFind(id); if (I == mClientActionInfo.constEnd()) { return qMakePair(false, ClientActionInfo()); } return qMakePair(true, I.value()); } QList Actions::allMethodActionIds() const { return mMethodActionInfo.keys(); } QPair Actions::methodActionInfoById(qulonglong id) const { MethodActionInfos::const_iterator I = mMethodActionInfo.constFind(id); if (I == mMethodActionInfo.constEnd()) { return qMakePair(false, MethodActionInfo()); } return qMakePair(true, I.value()); } QList Actions::allCommandActionIds() const { return mCommandActionInfo.keys(); } QPair Actions::commandActionInfoById(qulonglong id) const { CommandActionInfos::const_iterator I = mCommandActionInfo.constFind(id); if (I == mCommandActionInfo.constEnd()) { return qMakePair(false, CommandActionInfo()); } return qMakePair(true, I.value()); } MultipleActionsBehaviour Actions::multipleActionsBehaviour() const { return mMultipleActionsBehaviour; } void Actions::do_actionAdded(qulonglong id) { QString shortcut; QString description; bool enabled = false; QString type; QString info; if (getActionById(id, shortcut, description, enabled, type, info)) { GeneralActionInfo generalActionInfo; generalActionInfo.shortcut = shortcut; generalActionInfo.description = description; generalActionInfo.enabled = enabled; generalActionInfo.type = type; generalActionInfo.info = info; mGeneralActionInfo[id] = generalActionInfo; } if (type == "client") { QDBusObjectPath path; if (getClientActionInfoById(id, shortcut, description, enabled, path)) { ClientActionInfo clientActionInfo; clientActionInfo.shortcut = shortcut; clientActionInfo.description = description; clientActionInfo.enabled = enabled; clientActionInfo.path = path; mClientActionInfo[id] = clientActionInfo; } } else if (type == "method") { QString service; QDBusObjectPath path; QString interface; QString method; if (getMethodActionInfoById(id, shortcut, description, enabled, service, path, interface, method)) { MethodActionInfo methodActionInfo; methodActionInfo.shortcut = shortcut; methodActionInfo.description = description; methodActionInfo.enabled = enabled; methodActionInfo.service = service; methodActionInfo.path = path; methodActionInfo.interface = interface; methodActionInfo.method = method; mMethodActionInfo[id] = methodActionInfo; } } else if (type == "command") { QString command; QStringList arguments; if (getCommandActionInfoById(id, shortcut, description, enabled, command, arguments)) { CommandActionInfo commandActionInfo; commandActionInfo.shortcut = shortcut; commandActionInfo.description = description; commandActionInfo.enabled = enabled; commandActionInfo.command = command; commandActionInfo.arguments = arguments; mCommandActionInfo[id] = commandActionInfo; } } } void Actions::on_actionAdded(qulonglong id) { do_actionAdded(id); emit actionAdded(id); } void Actions::on_actionEnabled(qulonglong id, bool enabled) { GeneralActionInfos::iterator GI = mGeneralActionInfo.find(id); if (GI != mGeneralActionInfo.end()) { GI.value().enabled = enabled; if (GI.value().type == "client") { ClientActionInfos::iterator DI = mClientActionInfo.find(id); if (DI != mClientActionInfo.end()) { DI.value().enabled = enabled; } } else if (GI.value().type == "method") { MethodActionInfos::iterator MI = mMethodActionInfo.find(id); if (MI != mMethodActionInfo.end()) { MI.value().enabled = enabled; } } else if (GI.value().type == "command") { CommandActionInfos::iterator CI = mCommandActionInfo.find(id); if (CI != mCommandActionInfo.end()) { CI.value().enabled = enabled; } } } emit actionEnabled(id, enabled); } void Actions::on_clientActionSenderChanged(qulonglong id, const QString &sender) { mClientActionSenders[id] = sender; emit actionModified(id); } void Actions::on_actionModified(qulonglong id) { do_actionAdded(id); emit actionModified(id); } void Actions::on_actionShortcutChanged(qulonglong id) { do_actionAdded(id); emit actionModified(id); } void Actions::on_actionsSwapped(qulonglong id1, qulonglong id2) { GeneralActionInfos::iterator GI1 = mGeneralActionInfo.find(id1); GeneralActionInfos::iterator GI2 = mGeneralActionInfo.find(id2); if ((GI1 != mGeneralActionInfo.end()) && (GI2 != mGeneralActionInfo.end())) { bool swapped = false; if (GI1.value().type == GI2.value().type) { if (GI1.value().type == "client") { ClientActionInfos::iterator DI1 = mClientActionInfo.find(id1); ClientActionInfos::iterator DI2 = mClientActionInfo.find(id2); if ((DI1 != mClientActionInfo.end()) && (DI2 != mClientActionInfo.end())) { ClientActionInfo clientActionInfo = DI1.value(); DI1.value() = DI2.value(); DI2.value() = clientActionInfo; swapped = true; } } else if (GI1.value().type == "method") { MethodActionInfos::iterator MI1 = mMethodActionInfo.find(id1); MethodActionInfos::iterator MI2 = mMethodActionInfo.find(id2); if ((MI1 != mMethodActionInfo.end()) && (MI2 != mMethodActionInfo.end())) { MethodActionInfo methodActionInfo = MI1.value(); MI1.value() = MI2.value(); MI2.value() = methodActionInfo; swapped = true; } } else if (GI1.value().type == "command") { CommandActionInfos::iterator CI1 = mCommandActionInfo.find(id1); CommandActionInfos::iterator CI2 = mCommandActionInfo.find(id2); if ((CI1 != mCommandActionInfo.end()) && (CI2 != mCommandActionInfo.end())) { CommandActionInfo commandActionInfo = CI1.value(); CI1.value() = CI2.value(); CI2.value() = commandActionInfo; swapped = true; } } } if (swapped) { GeneralActionInfo generalActionInfo = GI1.value(); GI1.value() = GI2.value(); GI2.value() = generalActionInfo; } else { do_actionRemoved(id1); do_actionRemoved(id2); do_actionAdded(id1); do_actionAdded(id2); } } emit actionsSwapped(id1, id2); } void Actions::do_actionRemoved(qulonglong id) { mGeneralActionInfo.remove(id); mClientActionInfo.remove(id); mMethodActionInfo.remove(id); mCommandActionInfo.remove(id); } void Actions::on_actionRemoved(qulonglong id) { do_actionRemoved(id); emit actionRemoved(id); } void Actions::on_multipleActionsBehaviourChanged(uint behaviour) { mMultipleActionsBehaviour = static_cast(behaviour); emit multipleActionsBehaviourChanged(mMultipleActionsBehaviour); } bool Actions::getClientActionInfoById(qulonglong id, QString &shortcut, QString &description, bool &enabled, QDBusObjectPath &path) { return mDaemonProxy->getClientActionInfoById(id, shortcut, description, enabled, path); } bool Actions::getMethodActionInfoById(qulonglong id, QString &shortcut, QString &description, bool &enabled, QString &service, QDBusObjectPath &path, QString &interface, QString &method) { return mDaemonProxy->getMethodActionInfoById(id, shortcut, description, enabled, service, path, interface, method); } bool Actions::getCommandActionInfoById(qulonglong id, QString &shortcut, QString &description, bool &enabled, QString &command, QStringList &arguments) { return mDaemonProxy->getCommandActionInfoById(id, shortcut, description, enabled, command, arguments); } QList Actions::getAllActionIds() { QDBusPendingReply > reply = mDaemonProxy->getAllActionIds(); reply.waitForFinished(); if (reply.isError()) { return QList(); } return reply.argumentAt<0>(); } bool Actions::getActionById(qulonglong id, QString &shortcut, QString &description, bool &enabled, QString &type, QString &info) { return mDaemonProxy->getActionById(id, shortcut, description, enabled, type, info); } QMap Actions::getAllActions() { QDBusPendingReply > reply = mDaemonProxy->getAllActions(); reply.waitForFinished(); if (reply.isError()) { return QMap(); } return reply.argumentAt<0>(); } uint Actions::getMultipleActionsBehaviour() { QDBusPendingReply reply = mDaemonProxy->getMultipleActionsBehaviour(); reply.waitForFinished(); if (reply.isError()) { return 0; } return reply.argumentAt<0>(); } QPair Actions::addMethodAction(const QString &shortcut, const QString &service, const QDBusObjectPath &path, const QString &interface, const QString &method, const QString &description) { QDBusPendingReply reply = mDaemonProxy->addMethodAction(shortcut, service, path, interface, method, description); reply.waitForFinished(); if (reply.isError()) { return qMakePair(QString(), 0ull); } return qMakePair(reply.argumentAt<0>(), reply.argumentAt<1>()); } QPair Actions::addCommandAction(const QString &shortcut, const QString &command, const QStringList &arguments, const QString &description) { QDBusPendingReply reply = mDaemonProxy->addCommandAction(shortcut, command, arguments, description); reply.waitForFinished(); if (reply.isError()) { return qMakePair(QString(), 0ull); } return qMakePair(reply.argumentAt<0>(), reply.argumentAt<1>()); } bool Actions::modifyActionDescription(const qulonglong &id, const QString &description) { QDBusPendingReply reply = mDaemonProxy->modifyActionDescription(id, description); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } bool Actions::modifyMethodAction(const qulonglong &id, const QString &service, const QDBusObjectPath &path, const QString &interface, const QString &method, const QString &description) { QDBusPendingReply reply = mDaemonProxy->modifyMethodAction(id, service, path, interface, method, description); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } bool Actions::modifyCommandAction(const qulonglong &id, const QString &command, const QStringList &arguments, const QString &description) { QDBusPendingReply reply = mDaemonProxy->modifyCommandAction(id, command, arguments, description); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } bool Actions::enableAction(qulonglong id, bool enabled) { QDBusPendingReply reply = mDaemonProxy->enableAction(id, enabled); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } bool Actions::isActionEnabled(qulonglong id) { QDBusPendingReply reply = mDaemonProxy->isActionEnabled(id); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } QString Actions::getClientActionSender(qulonglong id) { return mClientActionSenders[id]; } QString Actions::updateClientActionSender(qulonglong id) { QDBusPendingReply reply = mDaemonProxy->getClientActionSender(id); reply.waitForFinished(); if (reply.isError()) { return QString(); } QString sender = reply.argumentAt<0>(); mClientActionSenders[id] = sender; return sender; } QString Actions::changeShortcut(const qulonglong &id, const QString &shortcut) { QDBusPendingReply reply = mDaemonProxy->changeShortcut(id, shortcut); reply.waitForFinished(); if (reply.isError()) { return QString(); } return reply.argumentAt<0>(); } bool Actions::swapActions(const qulonglong &id1, const qulonglong &id2) { QDBusPendingReply reply = mDaemonProxy->swapActions(id1, id2); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } bool Actions::removeAction(const qulonglong &id) { QDBusPendingReply reply = mDaemonProxy->removeAction(id); reply.waitForFinished(); if (reply.isError()) { return false; } return reply.argumentAt<0>(); } void Actions::setMultipleActionsBehaviour(const MultipleActionsBehaviour &behaviour) { QDBusPendingReply reply = mDaemonProxy->setMultipleActionsBehaviour(behaviour); reply.waitForFinished(); } void Actions::grabShortcut(uint timeout) { QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(mDaemonProxy->grabShortcut(timeout), this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(grabShortcutFinished(QDBusPendingCallWatcher *))); } void Actions::cancelShortcutGrab() { mDaemonProxy->cancelShortcutGrab(); } void Actions::grabShortcutFinished(QDBusPendingCallWatcher *call) { QDBusPendingReply reply = *call; if (reply.isError()) { emit grabShortcutFailed(); } else { if (reply.argumentAt<1>()) { emit grabShortcutFailed(); } else { if (reply.argumentAt<2>()) { emit grabShortcutCancelled(); } else { if (reply.argumentAt<3>()) { emit grabShortcutTimedout(); } else { emit shortcutGrabbed(reply.argumentAt<0>()); } } } } call->deleteLater(); }