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