diff --git a/qt/Application.cc b/qt/Application.cc index 6b23c95bc..51e56dafd 100644 --- a/qt/Application.cc +++ b/qt/Application.cc @@ -11,9 +11,8 @@ #include #include -#include -#include #include +#include #include #include #include @@ -28,7 +27,7 @@ #include "AddData.h" #include "Application.h" -#include "DBusAdaptor.h" +#include "DBusInteropHelper.h" #include "Formatter.h" #include "MainWindow.h" #include "OptionsDialog.h" @@ -39,10 +38,6 @@ namespace { - const QString DBUS_SERVICE = QString::fromUtf8 ("com.transmissionbt.Transmission" ); - const QString DBUS_OBJECT_PATH = QString::fromUtf8 ("/com/transmissionbt/Transmission"); - const QString DBUS_INTERFACE = QString::fromUtf8 ("com.transmissionbt.Transmission" ); - const QLatin1String MY_CONFIG_NAME ("transmission"); const QLatin1String MY_READABLE_NAME ("transmission-qt"); @@ -162,41 +157,38 @@ Application::Application (int& argc, char ** argv): // try to delegate the work to an existing copy of Transmission // before starting ourselves... - QDBusConnection bus = QDBusConnection::sessionBus (); - if (bus.isConnected ()) - { - bool delegated = false; - for (const QString& filename: filenames) - { - QDBusMessage request = QDBusMessage::createMethodCall (DBUS_SERVICE, - DBUS_OBJECT_PATH, - DBUS_INTERFACE, - QString::fromUtf8 ("AddMetainfo")); - QList arguments; - AddData a (filename); - switch (a.type) - { - case AddData::URL: arguments.push_back (a.url.toString ()); break; - case AddData::MAGNET: arguments.push_back (a.magnet); break; - case AddData::FILENAME: arguments.push_back (QString::fromLatin1 (a.toBase64 ())); break; - case AddData::METAINFO: arguments.push_back (QString::fromLatin1 (a.toBase64 ())); break; - default: break; - } - request.setArguments (arguments); + DBusInteropHelper interopClient; + if (interopClient.isConnected ()) + { + bool delegated = false; + for (const QString& filename: filenames) + { + QString metainfo; - QDBusMessage response = bus.call (request); - //std::cerr << qPrintable (response.errorName ()) << std::endl; - //std::cerr << qPrintable (response.errorMessage ()) << std::endl; - arguments = response.arguments (); - delegated |= (arguments.size ()==1) && arguments[0].toBool (); - } + AddData a (filename); + switch (a.type) + { + case AddData::URL: metainfo = a.url.toString (); break; + case AddData::MAGNET: metainfo = a.magnet; break; + case AddData::FILENAME: metainfo = QString::fromLatin1 (a.toBase64 ()); break; + case AddData::METAINFO: metainfo = QString::fromLatin1 (a.toBase64 ()); break; + default: break; + } - if (delegated) - { - quitLater (); - return; - } - } + if (metainfo.isEmpty ()) + continue; + + const QVariant result = interopClient.addMetainfo (metainfo); + if (result.isValid () && result.toBool ()) + delegated = true; + } + + if (delegated) + { + quitLater (); + return; + } + } // set the fallback config dir if (configDir.isNull ()) @@ -302,15 +294,7 @@ Application::Application (int& argc, char ** argv): for (const QString& filename: filenames) addTorrent (filename); - // register as the dbus handler for Transmission - if (bus.isConnected ()) - { - new DBusAdaptor (this); - if (!bus.registerService (DBUS_SERVICE)) - std::cerr << "couldn't register " << qPrintable (DBUS_SERVICE) << std::endl; - if (!bus.registerObject (DBUS_OBJECT_PATH, this)) - std::cerr << "couldn't register " << qPrintable (DBUS_OBJECT_PATH) << std::endl; - } + DBusInteropHelper::registerObject (this); } void @@ -558,32 +542,31 @@ Application::raise () bool Application::notifyApp (const QString& title, const QString& body) const { + const QLatin1String dbusServiceName ("org.freedesktop.Notifications"); + const QLatin1String dbusInterfaceName ("org.freedesktop.Notifications"); + const QLatin1String dbusPath ("/org/freedesktop/Notifications"); + QDBusConnection bus = QDBusConnection::sessionBus (); - if (!bus.isConnected ()) + if (bus.isConnected ()) { - myWindow->trayIcon ().showMessage (title, body); - return true; + QDBusMessage m = QDBusMessage::createMethodCall (dbusServiceName, dbusPath, dbusInterfaceName, QLatin1String ("Notify")); + QVariantList args; + args.append (QLatin1String ("Transmission")); // app_name + args.append (0U); // replaces_id + args.append (QLatin1String ("transmission")); // icon + args.append (title); // summary + args.append (body); // body + args.append (QStringList ()); // actions - unused for plain passive popups + args.append (QVariantMap ()); // hints - unused atm + args.append (static_cast (-1)); // use the default timeout period + m.setArguments (args); + const QDBusReply replyMsg = bus.call (m); + if (replyMsg.isValid () && replyMsg.value () > 0) + return true; } - const QString dbusServiceName = QString::fromUtf8 ("org.freedesktop.Notifications"); - const QString dbusInterfaceName = QString::fromUtf8 ("org.freedesktop.Notifications"); - const QString dbusPath = QString::fromUtf8 ("/org/freedesktop/Notifications"); - - QDBusMessage m = QDBusMessage::createMethodCall (dbusServiceName, dbusPath, dbusInterfaceName, QString::fromUtf8 ("Notify")); - QList args; - args.append (QString::fromUtf8 ("Transmission")); // app_name - args.append (0U); // replaces_id - args.append (QString::fromUtf8 ("transmission")); // icon - args.append (title); // summary - args.append (body); // body - args.append (QStringList ()); // actions - unused for plain passive popups - args.append (QVariantMap ()); // hints - unused atm - args.append (static_cast (-1)); // use the default timeout period - m.setArguments (args); - QDBusMessage replyMsg = bus.call (m); - //std::cerr << qPrintable (replyMsg.errorName ()) << std::endl; - //std::cerr << qPrintable (replyMsg.errorMessage ()) << std::endl; - return (replyMsg.type () == QDBusMessage::ReplyMessage) && !replyMsg.arguments ().isEmpty (); + myWindow->trayIcon ().showMessage (title, body); + return true; } FaviconCache& Application::faviconCache () diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index d0ed8e553..2cde64209 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -29,7 +29,7 @@ set(${PROJECT_NAME}_SOURCES AddData.cc Application.cc ColumnResizer.cc - DBusAdaptor.cc + DBusInteropHelper.cc DetailsDialog.cc FaviconCache.cc FileTreeDelegate.cc @@ -44,6 +44,7 @@ set(${PROJECT_NAME}_SOURCES Formatter.cc FreeSpaceLabel.cc IconToolButton.cc + InteropObject.cc LicenseDialog.cc MainWindow.cc MakeDialog.cc @@ -77,7 +78,7 @@ set(${PROJECT_NAME}_HEADERS BaseDialog.h ColumnResizer.h CustomVariantType.h - DBusAdaptor.h + DBusInteropHelper.h DetailsDialog.h FaviconCache.h FileTreeDelegate.h @@ -92,6 +93,7 @@ set(${PROJECT_NAME}_HEADERS Formatter.h FreeSpaceLabel.h IconToolButton.h + InteropObject.h LicenseDialog.h MainWindow.h MakeDialog.h diff --git a/qt/DBusInteropHelper.cc b/qt/DBusInteropHelper.cc new file mode 100644 index 000000000..94f29310d --- /dev/null +++ b/qt/DBusInteropHelper.cc @@ -0,0 +1,56 @@ +/* + * This file Copyright (C) 2015 Mnemosyne LLC + * + * It may be used under the GNU GPL versions 2 or 3 + * or any future license endorsed by Mnemosyne LLC. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include + +#include "DBusInteropHelper.h" +#include "InteropObject.h" + +namespace +{ + const QLatin1String DBUS_SERVICE ("com.transmissionbt.Transmission"); + const QLatin1String DBUS_OBJECT_PATH ("/com/transmissionbt/Transmission"); + const QLatin1String DBUS_INTERFACE ("com.transmissionbt.Transmission"); +} + +bool +DBusInteropHelper::isConnected () const +{ + return !QDBusConnection::sessionBus ().isConnected (); +} + +QVariant +DBusInteropHelper::addMetainfo (const QString& metainfo) +{ + QDBusMessage request = QDBusMessage::createMethodCall (DBUS_SERVICE, DBUS_OBJECT_PATH, + DBUS_INTERFACE, QLatin1String ("AddMetainfo")); + request.setArguments (QVariantList () << metainfo); + + const QDBusReply response = QDBusConnection::sessionBus ().call (request); + return response.isValid () ? QVariant (response.value ()) : QVariant (); +} + +void +DBusInteropHelper::registerObject (QObject * parent) +{ + QDBusConnection bus = QDBusConnection::sessionBus (); + if (!bus.isConnected ()) + return; + + if (!bus.registerService (DBUS_SERVICE)) + std::cerr << "couldn't register " << qPrintable (DBUS_SERVICE) << std::endl; + if (!bus.registerObject (DBUS_OBJECT_PATH, new InteropObject (parent), QDBusConnection::ExportAllSlots)) + std::cerr << "couldn't register " << qPrintable (DBUS_OBJECT_PATH) << std::endl; +} diff --git a/qt/DBusInteropHelper.h b/qt/DBusInteropHelper.h new file mode 100644 index 000000000..1de98cfd1 --- /dev/null +++ b/qt/DBusInteropHelper.h @@ -0,0 +1,27 @@ +/* + * This file Copyright (C) 2015 Mnemosyne LLC + * + * It may be used under the GNU GPL versions 2 or 3 + * or any future license endorsed by Mnemosyne LLC. + * + * $Id$ + */ + +#ifndef QTR_DBUS_INTEROP_HELPER_H +#define QTR_DBUS_INTEROP_HELPER_H + +class QObject; +class QString; +class QVariant; + +class DBusInteropHelper +{ + public: + bool isConnected () const; + + QVariant addMetainfo (const QString& metainfo); + + static void registerObject (QObject * parent); +}; + +#endif // QTR_DBUS_INTEROP_HELPER_H diff --git a/qt/DBusAdaptor.cc b/qt/InteropObject.cc similarity index 54% rename from qt/DBusAdaptor.cc rename to qt/InteropObject.cc index 6e41cd83e..074185e36 100644 --- a/qt/DBusAdaptor.cc +++ b/qt/InteropObject.cc @@ -9,28 +9,27 @@ #include "AddData.h" #include "Application.h" -#include "DBusAdaptor.h" +#include "InteropObject.h" -DBusAdaptor::DBusAdaptor (Application* app): - QDBusAbstractAdaptor (app), - myApp (app) +InteropObject::InteropObject (QObject * parent): + QObject (parent) { } bool -DBusAdaptor::PresentWindow () +InteropObject::PresentWindow () { - myApp->raise (); + qApp->raise (); return true; } bool -DBusAdaptor::AddMetainfo (const QString& key) +InteropObject::AddMetainfo (const QString& metainfo) { - AddData addme (key); + AddData addme (metainfo); if (addme.type != addme.NONE) - myApp->addTorrent (addme); + qApp->addTorrent (addme); return true; } diff --git a/qt/DBusAdaptor.h b/qt/InteropObject.h similarity index 50% rename from qt/DBusAdaptor.h rename to qt/InteropObject.h index f09df97ea..4ae118481 100644 --- a/qt/DBusAdaptor.h +++ b/qt/InteropObject.h @@ -7,28 +7,22 @@ * $Id$ */ -#ifndef QTR_DBUS_ADAPTOR_H -#define QTR_DBUS_ADAPTOR_H +#ifndef QTR_INTEROP_OBJECT_H +#define QTR_INTEROP_OBJECT_H -#include +#include -class Application; - -class DBusAdaptor: public QDBusAbstractAdaptor +class InteropObject: public QObject { Q_OBJECT Q_CLASSINFO ("D-Bus Interface", "com.transmissionbt.Transmission") public: - DBusAdaptor (Application *); - virtual ~DBusAdaptor () {} + InteropObject (QObject * parent = nullptr); public slots: bool PresentWindow (); - bool AddMetainfo (const QString&); - - private: - Application * myApp; + bool AddMetainfo (const QString& metainfo); }; -#endif // QTR_DBUS_ADAPTOR_H +#endif // QTR_INTEROP_OBJECT_H