File indexing completed on 2024-05-12 15:56:59

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_SIGNAL_AUTO_CONNECTOR_H
0008 #define __KIS_SIGNAL_AUTO_CONNECTOR_H
0009 
0010 #include <QObject>
0011 #include <QPointer>
0012 #include <QVector>
0013 
0014 /**
0015  * A special wrapper class that represents a connection between two QObject objects.
0016  * It creates the connection on the construction and disconnects it on destruction.
0017  *
0018  * WARNING: never use QScopedPointer::reset() for updating the
0019  *          connection like:
0020  *
0021  * QScopedPointer<KisSignalAutoConnection> conn;
0022  * ...
0023  * void Something::setCanvas(KoCanvasBase * canvas) {
0024  *     conn.reset(new KisSignalAutoConnection(...));
0025  * }
0026  *
0027  * The object stored in a scoped pointer will be destructed *after*
0028  * the new object created which will cause you object to become
0029  * disconnected.
0030  *
0031  * Instead use two-stage updates:
0032  * conn.reset();
0033  * conn.reset(new KisSignalAutoConnection(...));
0034  */
0035 class KisSignalAutoConnection
0036 {
0037 public:
0038     /**
0039      * Creates a connection object and starts the requested connection
0040      */
0041     template<class Sender, class Signal, class Receiver, class Method>
0042     inline KisSignalAutoConnection(Sender sender, Signal signal,
0043                                   Receiver receiver, Method method,
0044                                   Qt::ConnectionType type = Qt::AutoConnection)
0045         : m_connection(QObject::connect(sender, signal, receiver, method, type))
0046     {
0047     }
0048 
0049     inline ~KisSignalAutoConnection()
0050     {
0051         QObject::disconnect(m_connection);
0052     }
0053 
0054 private:
0055     KisSignalAutoConnection(const KisSignalAutoConnection &rhs);
0056 
0057 private:
0058     QMetaObject::Connection m_connection;
0059 };
0060 
0061 typedef QSharedPointer<KisSignalAutoConnection> KisSignalAutoConnectionSP;
0062 
0063 
0064 /**
0065  * A class to store multiple connections and to be able to stop all of
0066  * them at once. It is handy when you need to reconnect some other
0067  * object to the current manager. Then you just call
0068  * connectionsStore.clear() and then call addConnection() again to
0069  * recreate them.
0070  */
0071 class KisSignalAutoConnectionsStore
0072 {
0073 public:
0074     /**
0075      * Connects \p sender to \p receiver with a connection of type \p type.
0076      * The connection is saved into the store so can be reset later with clear()
0077      *
0078      * \see addUniqueConnection()
0079      */
0080     template<class Sender, class Signal, class Receiver, class Method>
0081     inline void addConnection(Sender sender, Signal signal,
0082                               Receiver receiver, Method method,
0083                               Qt::ConnectionType type = Qt::AutoConnection)
0084     {
0085         m_connections.append(KisSignalAutoConnectionSP(
0086                                  new KisSignalAutoConnection(sender, signal,
0087                                                              receiver, method, type)));
0088     }
0089 
0090     /**
0091      * Convenience override for addConnection() that creates a unique connection
0092      *
0093      * \see addConnection()
0094      */
0095     template<class Sender, class Signal, class Receiver, class Method>
0096     inline void addUniqueConnection(Sender sender, Signal signal,
0097                                     Receiver receiver, Method method)
0098     {
0099         m_connections.append(KisSignalAutoConnectionSP(
0100                                  new KisSignalAutoConnection(sender, signal,
0101                                                              receiver, method, Qt::UniqueConnection)));
0102     }
0103 
0104     /**
0105      * Disconnects all the stored connections and removes them from the store
0106      */
0107     inline void clear() {
0108         m_connections.clear();
0109     }
0110 
0111     inline bool isEmpty() {
0112         return m_connections.isEmpty();
0113     }
0114 
0115 private:
0116     QVector<KisSignalAutoConnectionSP> m_connections;
0117 };
0118 
0119 #endif /* __KIS_SIGNAL_AUTO_CONNECTOR_H */