File indexing completed on 2024-05-19 05:21:25
0001 /* 0002 This file is part of the KDE Kontact Plugin Interface Library. 0003 0004 SPDX-FileCopyrightText: 2003, 2008 David Faure <faure@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #pragma once 0010 0011 #include "kontactinterface_export.h" 0012 #include "plugin.h" 0013 #include <memory> 0014 class QCommandLineParser; 0015 0016 namespace KontactInterface 0017 { 0018 /** 0019 * D-Bus Object that has the name of the standalone application (e.g. "kmail") 0020 * and implements newInstance() so that running the separate application does 0021 * the right thing when kontact is running. 0022 * By default this means simply bringing the main window to the front, 0023 * but newInstance can be reimplemented. 0024 */ 0025 class KONTACTINTERFACE_EXPORT UniqueAppHandler : public QObject 0026 { 0027 Q_OBJECT 0028 // We implement the PIMUniqueApplication interface 0029 Q_CLASSINFO("D-Bus Interface", "org.kde.PIMUniqueApplication") 0030 0031 public: 0032 explicit UniqueAppHandler(Plugin *plugin); 0033 ~UniqueAppHandler() override; 0034 0035 /// This must be reimplemented so that app-specific command line options can be parsed 0036 virtual void loadCommandLineOptions(QCommandLineParser *parser) = 0; 0037 0038 [[nodiscard]] Plugin *plugin() const; 0039 0040 /** 0041 Sets the main QWidget @p widget associated with this application. 0042 @param widget the QWidget to set as main 0043 */ 0044 static void setMainWidget(QWidget *widget); 0045 0046 /** 0047 Returns the main widget, which will zero if setMainWidget() has not be called yet. 0048 @since 4.6 0049 */ 0050 [[nodiscard]] QWidget *mainWidget(); 0051 0052 public Q_SLOTS: // DBUS methods 0053 int newInstance(const QByteArray &asn_id, const QStringList &args, const QString &workingDirectory); 0054 bool load(); 0055 0056 protected: 0057 virtual int activate(const QStringList &args, const QString &workingDirectory); 0058 0059 private: 0060 class UniqueAppHandlerPrivate; 0061 std::unique_ptr<UniqueAppHandlerPrivate> const d; 0062 }; 0063 0064 /// Base class for UniqueAppHandler 0065 class UniqueAppHandlerFactoryBase 0066 { 0067 public: 0068 virtual ~UniqueAppHandlerFactoryBase() = default; 0069 virtual UniqueAppHandler *createHandler(Plugin *) = 0; 0070 }; 0071 0072 /** 0073 * Used by UniqueAppWatcher below, to create the above UniqueAppHandler object 0074 * when necessary. 0075 * The template argument is the UniqueAppHandler-derived class. 0076 * This allows to remove the need to subclass UniqueAppWatcher. 0077 */ 0078 template<class T> 0079 class UniqueAppHandlerFactory : public UniqueAppHandlerFactoryBase 0080 { 0081 public: 0082 UniqueAppHandler *createHandler(Plugin *plugin) override 0083 { 0084 plugin->registerClient(); 0085 return new T(plugin); 0086 } 0087 }; 0088 0089 /** 0090 * If the standalone application is running by itself, we need to watch 0091 * for when the user closes it, and activate the uniqueapphandler then. 0092 * This prevents, on purpose, that the standalone app can be restarted. 0093 * Kontact takes over from there. 0094 * 0095 */ 0096 class KONTACTINTERFACE_EXPORT UniqueAppWatcher : public QObject 0097 { 0098 Q_OBJECT 0099 0100 public: 0101 /** 0102 * Create an instance of UniqueAppWatcher, which does everything necessary 0103 * for the "unique application" behavior: create the UniqueAppHandler as soon 0104 * as possible, i.e. either right now or when the standalone app is closed. 0105 * 0106 * @param factory templatized factory to create the handler. Example: 0107 * ... Note that the watcher takes ownership of the factory. 0108 * @param plugin is the plugin application 0109 */ 0110 UniqueAppWatcher(UniqueAppHandlerFactoryBase *factory, Plugin *plugin); 0111 0112 ~UniqueAppWatcher() override; 0113 0114 bool isRunningStandalone() const; 0115 0116 private Q_SLOTS: 0117 KONTACTINTERFACE_NO_EXPORT void slotApplicationRemoved(const QString &name, const QString &oldOwner, const QString &newOwner); 0118 0119 private: 0120 class UniqueAppWatcherPrivate; 0121 std::unique_ptr<UniqueAppWatcherPrivate> const d; 0122 }; 0123 0124 } // namespace