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 */