File indexing completed on 2024-05-12 15:57:03
0001 /**************************************************************************** 0002 ** 0003 ** SPDX-FileCopyrightText: 2016 The Qt Company Ltd. 0004 ** Contact: https://www.qt.io/licensing/ 0005 ** 0006 ** This file is part of the QtCore module of the Qt Toolkit. 0007 ** 0008 ** SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KFQF-Accepted-GPL OR LicenseRef-Qt-Commercial 0009 ** 0010 ****************************************************************************/ 0011 0012 #include "KisSignalMapper.h" 0013 #include "qhash.h" 0014 0015 class KisSignalMapper::Private 0016 { 0017 public: 0018 0019 Private(KisSignalMapper *_q) 0020 :q(_q) 0021 {} 0022 0023 void _q_senderDestroyed() { 0024 q->removeMappings(q->sender()); 0025 } 0026 QHash<QObject *, int> intHash; 0027 QHash<QObject *, QString> stringHash; 0028 QHash<QObject *, QWidget*> widgetHash; 0029 QHash<QObject *, QObject*> objectHash; 0030 0031 0032 KisSignalMapper *q; 0033 }; 0034 0035 /*! 0036 \class KisSignalMapper 0037 \inmodule QtCore 0038 \obsolete The recommended solution is connecting the signal to a lambda. 0039 \brief The KisSignalMapper class bundles signals from identifiable senders. 0040 0041 \ingroup objectmodel 0042 0043 0044 This class collects a set of parameterless signals, and re-emits 0045 them with integer, string or widget parameters corresponding to 0046 the object that sent the signal. 0047 0048 The class supports the mapping of particular strings or integers 0049 with particular objects using setMapping(). The objects' signals 0050 can then be connected to the map() slot which will emit the 0051 mapped() signal with the string or integer associated with the 0052 original signaling object. Mappings can be removed later using 0053 removeMappings(). 0054 0055 Example: Suppose we want to create a custom widget that contains 0056 a group of buttons (like a tool palette). One approach is to 0057 connect each button's \c clicked() signal to its own custom slot; 0058 but in this example we want to connect all the buttons to a 0059 single slot and parameterize the slot by the button that was 0060 clicked. 0061 0062 Here's the definition of a simple custom widget that has a single 0063 signal, \c clicked(), which is emitted with the text of the button 0064 that was clicked: 0065 0066 \snippet KisSignalMapper/buttonwidget.h 0 0067 \snippet KisSignalMapper/buttonwidget.h 1 0068 0069 The only function that we need to implement is the constructor: 0070 0071 \snippet KisSignalMapper/buttonwidget.cpp 0 0072 \snippet KisSignalMapper/buttonwidget.cpp 1 0073 \snippet KisSignalMapper/buttonwidget.cpp 2 0074 0075 A list of texts is passed to the constructor. A signal mapper is 0076 constructed and for each text in the list a QPushButton is 0077 created. We connect each button's \c clicked() signal to the 0078 signal mapper's map() slot, and create a mapping in the signal 0079 mapper from each button to the button's text. Finally we connect 0080 the signal mapper's mapped() signal to the custom widget's \c 0081 clicked() signal. When the user clicks a button, the custom 0082 widget will emit a single \c clicked() signal whose argument is 0083 the text of the button the user clicked. 0084 0085 This class was mostly useful before lambda functions could be used as 0086 slots. The example above can be rewritten simpler without KisSignalMapper 0087 by connecting to a lambda function. 0088 0089 \snippet KisSignalMapper/buttonwidget.cpp 3 0090 0091 \sa QObject, QButtonGroup, QActionGroup 0092 */ 0093 0094 /*! 0095 Constructs a KisSignalMapper with parent \a parent. 0096 */ 0097 KisSignalMapper::KisSignalMapper(QObject* parent) 0098 : QObject(parent) 0099 , d(new Private(this)) 0100 { 0101 } 0102 0103 /*! 0104 Destroys the KisSignalMapper. 0105 */ 0106 KisSignalMapper::~KisSignalMapper() 0107 { 0108 } 0109 0110 /*! 0111 Adds a mapping so that when map() is signalled from the given \a 0112 sender, the signal mapped(\a id) is emitted. 0113 0114 There may be at most one integer ID for each sender. 0115 0116 \sa mapping() 0117 */ 0118 void KisSignalMapper::setMapping(QObject *sender, int id) 0119 { 0120 d->intHash.insert(sender, id); 0121 connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed())); 0122 } 0123 0124 /*! 0125 Adds a mapping so that when map() is signalled from the \a sender, 0126 the signal mapped(\a text ) is emitted. 0127 0128 There may be at most one text for each sender. 0129 */ 0130 void KisSignalMapper::setMapping(QObject *sender, const QString &text) 0131 { 0132 d->stringHash.insert(sender, text); 0133 connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed())); 0134 } 0135 0136 /*! 0137 Adds a mapping so that when map() is signalled from the \a sender, 0138 the signal mapped(\a widget ) is emitted. 0139 0140 There may be at most one widget for each sender. 0141 */ 0142 void KisSignalMapper::setMapping(QObject *sender, QWidget *widget) 0143 { 0144 d->widgetHash.insert(sender, widget); 0145 connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed())); 0146 } 0147 0148 /*! 0149 Adds a mapping so that when map() is signalled from the \a sender, 0150 the signal mapped(\a object ) is emitted. 0151 0152 There may be at most one object for each sender. 0153 */ 0154 void KisSignalMapper::setMapping(QObject *sender, QObject *object) 0155 { 0156 d->objectHash.insert(sender, object); 0157 connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed())); 0158 } 0159 0160 /*! 0161 Returns the sender QObject that is associated with the \a id. 0162 0163 \sa setMapping() 0164 */ 0165 QObject *KisSignalMapper::mapping(int id) const 0166 { 0167 return d->intHash.key(id); 0168 } 0169 0170 /*! 0171 \overload mapping() 0172 */ 0173 QObject *KisSignalMapper::mapping(const QString &id) const 0174 { 0175 return d->stringHash.key(id); 0176 } 0177 0178 /*! 0179 \overload mapping() 0180 0181 Returns the sender QObject that is associated with the \a widget. 0182 */ 0183 QObject *KisSignalMapper::mapping(QWidget *widget) const 0184 { 0185 return d->widgetHash.key(widget); 0186 } 0187 0188 /*! 0189 \overload mapping() 0190 0191 Returns the sender QObject that is associated with the \a object. 0192 */ 0193 QObject *KisSignalMapper::mapping(QObject *object) const 0194 { 0195 return d->objectHash.key(object); 0196 } 0197 0198 /*! 0199 Removes all mappings for \a sender. 0200 0201 This is done automatically when mapped objects are destroyed. 0202 0203 \note This does not disconnect any signals. If \a sender is not destroyed 0204 then this will need to be done explicitly if required. 0205 */ 0206 void KisSignalMapper::removeMappings(QObject *sender) 0207 { 0208 d->intHash.remove(sender); 0209 d->stringHash.remove(sender); 0210 d->widgetHash.remove(sender); 0211 d->objectHash.remove(sender); 0212 } 0213 0214 /*! 0215 This slot emits signals based on which object sends signals to it. 0216 */ 0217 void KisSignalMapper::map() { map(sender()); } 0218 0219 /*! 0220 This slot emits signals based on the \a sender object. 0221 */ 0222 void KisSignalMapper::map(QObject *sender) 0223 { 0224 if (d->intHash.contains(sender)) 0225 emit mapped(d->intHash.value(sender)); 0226 if (d->stringHash.contains(sender)) 0227 emit mapped(d->stringHash.value(sender)); 0228 if (d->widgetHash.contains(sender)) 0229 emit mapped(d->widgetHash.value(sender)); 0230 if (d->objectHash.contains(sender)) 0231 emit mapped(d->objectHash.value(sender)); 0232 } 0233 0234 0235 /*! 0236 \fn void KisSignalMapper::mapped(int i) 0237 0238 This signal is emitted when map() is signalled from an object that 0239 has an integer mapping set. The object's mapped integer is passed 0240 in \a i. 0241 0242 \sa setMapping() 0243 */ 0244 0245 /*! 0246 \fn void KisSignalMapper::mapped(const QString &text) 0247 0248 This signal is emitted when map() is signalled from an object that 0249 has a string mapping set. The object's mapped string is passed in 0250 \a text. 0251 0252 \sa setMapping() 0253 */ 0254 0255 /*! 0256 \fn void KisSignalMapper::mapped(QWidget *widget) 0257 0258 This signal is emitted when map() is signalled from an object that 0259 has a widget mapping set. The object's mapped widget is passed in 0260 \a widget. 0261 0262 \sa setMapping() 0263 */ 0264 0265 /*! 0266 \fn void KisSignalMapper::mapped(QObject *object) 0267 0268 This signal is emitted when map() is signalled from an object that 0269 has an object mapping set. The object provided by the map is passed in 0270 \a object. 0271 0272 \sa setMapping() 0273 */ 0274 0275 #include "moc_KisSignalMapper.cpp" 0276