1 /* 2 This file is part of the KDE Kontact Plugin Interface Library. 3 4 SPDX-FileCopyrightText: 2003, 2008 David Faure <faure@kde.org> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7 */ 8 9 #pragma once 10 11 #include "kontactinterface_export.h" 12 #include "plugin.h" 13 #include <memory> 14 class QCommandLineParser; 15 16 namespace KontactInterface 17 { 18 /** 19 * D-Bus Object that has the name of the standalone application (e.g. "kmail") 20 * and implements newInstance() so that running the separate application does 21 * the right thing when kontact is running. 22 * By default this means simply bringing the main window to the front, 23 * but newInstance can be reimplemented. 24 */ 25 class KONTACTINTERFACE_EXPORT UniqueAppHandler : public QObject 26 { 27 Q_OBJECT 28 // We implement the PIMUniqueApplication interface 29 Q_CLASSINFO("D-Bus Interface", "org.kde.PIMUniqueApplication") 30 31 public: 32 explicit UniqueAppHandler(Plugin *plugin); 33 ~UniqueAppHandler() override; 34 35 /// This must be reimplemented so that app-specific command line options can be parsed 36 virtual void loadCommandLineOptions(QCommandLineParser *parser) = 0; 37 38 Q_REQUIRED_RESULT Plugin *plugin() const; 39 40 /** 41 Sets the main QWidget @p widget associated with this application. 42 @param widget the QWidget to set as main 43 */ 44 static void setMainWidget(QWidget *widget); 45 46 /** 47 Returns the main widget, which will zero if setMainWidget() has not be called yet. 48 @since 4.6 49 */ 50 Q_REQUIRED_RESULT QWidget *mainWidget(); 51 52 public Q_SLOTS: // DBUS methods 53 int newInstance(const QByteArray &asn_id, const QStringList &args, const QString &workingDirectory); 54 bool load(); 55 56 protected: 57 virtual int activate(const QStringList &args, const QString &workingDirectory); 58 59 private: 60 class UniqueAppHandlerPrivate; 61 std::unique_ptr<UniqueAppHandlerPrivate> const d; 62 }; 63 64 /// Base class for UniqueAppHandler 65 class UniqueAppHandlerFactoryBase 66 { 67 public: ~UniqueAppHandlerFactoryBase()68 virtual ~UniqueAppHandlerFactoryBase() 69 { 70 } 71 virtual UniqueAppHandler *createHandler(Plugin *) = 0; 72 }; 73 74 /** 75 * Used by UniqueAppWatcher below, to create the above UniqueAppHandler object 76 * when necessary. 77 * The template argument is the UniqueAppHandler-derived class. 78 * This allows to remove the need to subclass UniqueAppWatcher. 79 */ 80 template<class T> class UniqueAppHandlerFactory : public UniqueAppHandlerFactoryBase 81 { 82 public: createHandler(Plugin * plugin)83 UniqueAppHandler *createHandler(Plugin *plugin) override 84 { 85 plugin->registerClient(); 86 return new T(plugin); 87 } 88 }; 89 90 /** 91 * If the standalone application is running by itself, we need to watch 92 * for when the user closes it, and activate the uniqueapphandler then. 93 * This prevents, on purpose, that the standalone app can be restarted. 94 * Kontact takes over from there. 95 * 96 */ 97 class KONTACTINTERFACE_EXPORT UniqueAppWatcher : public QObject 98 { 99 Q_OBJECT 100 101 public: 102 /** 103 * Create an instance of UniqueAppWatcher, which does everything necessary 104 * for the "unique application" behavior: create the UniqueAppHandler as soon 105 * as possible, i.e. either right now or when the standalone app is closed. 106 * 107 * @param factory templatized factory to create the handler. Example: 108 * ... Note that the watcher takes ownership of the factory. 109 * @param plugin is the plugin application 110 */ 111 UniqueAppWatcher(UniqueAppHandlerFactoryBase *factory, Plugin *plugin); 112 113 ~UniqueAppWatcher() override; 114 115 bool isRunningStandalone() const; 116 117 private Q_SLOTS: 118 void slotApplicationRemoved(const QString &name, const QString &oldOwner, const QString &newOwner); 119 120 private: 121 class UniqueAppWatcherPrivate; 122 std::unique_ptr<UniqueAppWatcherPrivate> const d; 123 }; 124 125 } // namespace 126 127