1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include "qsignalmapper.h"
43
#ifndef QT_NO_SIGNALMAPPER
44
#include "qhash.h"
45
#include "qobject_p.h"
46
47
QT_BEGIN_NAMESPACE
48
49
class QSignalMapperPrivate : public QObjectPrivate
50
{
51
    Q_DECLARE_PUBLIC(QSignalMapper)
52
public:
53
    void _q_senderDestroyed() {
54
        Q_Q(QSignalMapper);
55
        q->removeMappings(q->sender());
56
    }
57
    QHash<QObject *, int> intHash;
58
    QHash<QObject *, QString> stringHash;
59
    QHash<QObject *, QWidget*> widgetHash;
60
    QHash<QObject *, QObject*> objectHash;
61
62
};
63
64
65
/*!
66
    \class QSignalMapper
67
    \brief The QSignalMapper class bundles signals from identifiable senders.
68
69
    \ingroup objectmodel
70
71
72
    This class collects a set of parameterless signals, and re-emits
73
    them with integer, string or widget parameters corresponding to
74
    the object that sent the signal.
75
76
    The class supports the mapping of particular strings or integers
77
    with particular objects using setMapping(). The objects' signals
78
    can then be connected to the map() slot which will emit the
79
    mapped() signal with the string or integer associated with the
80
    original signalling object. Mappings can be removed later using
81
    removeMappings().
82
83
    Example: Suppose we want to create a custom widget that contains
84
    a group of buttons (like a tool palette). One approach is to
85
    connect each button's \c clicked() signal to its own custom slot;
86
    but in this example we want to connect all the buttons to a
87
    single slot and parameterize the slot by the button that was
88
    clicked.
89
90
    Here's the definition of a simple custom widget that has a single
91
    signal, \c clicked(), which is emitted with the text of the button
92
    that was clicked:
93
94
    \snippet doc/src/snippets/qsignalmapper/buttonwidget.h 0
95
    \snippet doc/src/snippets/qsignalmapper/buttonwidget.h 1
96
97
    The only function that we need to implement is the constructor:
98
99
    \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 0
100
    \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 1
101
    \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 2
102
103
    A list of texts is passed to the constructor. A signal mapper is
104
    constructed and for each text in the list a QPushButton is
105
    created. We connect each button's \c clicked() signal to the
106
    signal mapper's map() slot, and create a mapping in the signal
107
    mapper from each button to the button's text. Finally we connect
108
    the signal mapper's mapped() signal to the custom widget's \c
109
    clicked() signal. When the user clicks a button, the custom
110
    widget will emit a single \c clicked() signal whose argument is
111
    the text of the button the user clicked.
112
113
    \sa QObject, QButtonGroup, QActionGroup
114
*/
115
116
/*!
117
    Constructs a QSignalMapper with parent \a parent.
118
*/
119
QSignalMapper::QSignalMapper(QObject* parent)
120
    : QObject(*new QSignalMapperPrivate, parent)
121
{
122
}
123
124
#ifdef QT3_SUPPORT
125
/*!
126
    \overload QSignalMapper()
127
    \obsolete
128
 */
129
QSignalMapper::QSignalMapper(QObject *parent, const char *name)
130
    : QObject(*new QSignalMapperPrivate, parent)
131
{
132
    setObjectName(QString::fromAscii(name));
133
}
134
#endif
135
136
/*!
137
    Destroys the QSignalMapper.
138
*/
139
QSignalMapper::~QSignalMapper()
140
{
141
}
142
143
/*!
144
    Adds a mapping so that when map() is signalled from the given \a
145
    sender, the signal mapped(\a id) is emitted.
146
147
    There may be at most one integer ID for each sender.
148
149
    \sa mapping()
150
*/
151
void QSignalMapper::setMapping(QObject *sender, int id)
152
{
153
    Q_D(QSignalMapper);
154
    d->intHash.insert(sender, id);
155
    connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed()));
156
}
157
158
/*!
159
    Adds a mapping so that when map() is signalled from the \a sender,
160
    the signal mapped(\a text ) is emitted.
161
162
    There may be at most one text for each sender.
163
*/
164
void QSignalMapper::setMapping(QObject *sender, const QString &text)
165
{
166
    Q_D(QSignalMapper);
167
    d->stringHash.insert(sender, text);
168
    connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed()));
169
}
170
171
/*!
172
    Adds a mapping so that when map() is signalled from the \a sender,
173
    the signal mapped(\a widget ) is emitted.
174
175
    There may be at most one widget for each sender.
176
*/
177
void QSignalMapper::setMapping(QObject *sender, QWidget *widget)
178
{
179
    Q_D(QSignalMapper);
180
    d->widgetHash.insert(sender, widget);
181
    connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed()));
182
}
183
184
/*!
185
    Adds a mapping so that when map() is signalled from the \a sender,
186
    the signal mapped(\a object ) is emitted.
187
188
    There may be at most one object for each sender.
189
*/
190
void QSignalMapper::setMapping(QObject *sender, QObject *object)
191
{
192
    Q_D(QSignalMapper);
193
    d->objectHash.insert(sender, object);
194
    connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed()));
195
}
196
197
/*!
198
    Returns the sender QObject that is associated with the \a id.
199
200
    \sa setMapping()
201
*/
202
QObject *QSignalMapper::mapping(int id) const
203
{
204
    Q_D(const QSignalMapper);
205
    return d->intHash.key(id);
206
}
207
208
/*!
209
    \overload mapping()
210
*/
211
QObject *QSignalMapper::mapping(const QString &id) const
212
{
213
    Q_D(const QSignalMapper);
214
    return d->stringHash.key(id);
215
}
216
217
/*!
218
    \overload mapping()
219
220
    Returns the sender QObject that is associated with the \a widget.
221
*/
222
QObject *QSignalMapper::mapping(QWidget *widget) const
223
{
224
    Q_D(const QSignalMapper);
225
    return d->widgetHash.key(widget);
226
}
227
228
/*!
229
    \overload mapping()
230
231
    Returns the sender QObject that is associated with the \a object.
232
*/
233
QObject *QSignalMapper::mapping(QObject *object) const
234
{
235
    Q_D(const QSignalMapper);
236
    return d->objectHash.key(object);
237
}
238
239
/*!
240
    Removes all mappings for \a sender.
241
242
    This is done automatically when mapped objects are destroyed.
243
*/
244
void QSignalMapper::removeMappings(QObject *sender)
245
{
246
    Q_D(QSignalMapper);
247
248
    d->intHash.remove(sender);
249
    d->stringHash.remove(sender);
250
    d->widgetHash.remove(sender);
251
    d->objectHash.remove(sender);
252
}
253
254
/*!
255
    This slot emits signals based on which object sends signals to it.
256
*/
257
void QSignalMapper::map() { map(sender()); }
258
259
/*!
260
    This slot emits signals based on the \a sender object.
261
*/
262
void QSignalMapper::map(QObject *sender)
263
{
264
    Q_D(QSignalMapper);
265
    if (d->intHash.contains(sender))
266
        emit mapped(d->intHash.value(sender));
267
    if (d->stringHash.contains(sender))
268
        emit mapped(d->stringHash.value(sender));
269
    if (d->widgetHash.contains(sender))
270
        emit mapped(d->widgetHash.value(sender));
271
    if (d->objectHash.contains(sender))
272
        emit mapped(d->objectHash.value(sender));
273
}
274
275
276
/*!
277
    \fn void QSignalMapper::mapped(int i)
278
279
    This signal is emitted when map() is signalled from an object that
280
    has an integer mapping set. The object's mapped integer is passed
281
    in \a i.
282
283
    \sa setMapping()
284
*/
285
286
/*!
287
    \fn void QSignalMapper::mapped(const QString &text)
288
289
    This signal is emitted when map() is signalled from an object that
290
    has a string mapping set. The object's mapped string is passed in
291
    \a text.
292
293
    \sa setMapping()
294
*/
295
296
/*!
297
    \fn void QSignalMapper::mapped(QWidget *widget)
298
299
    This signal is emitted when map() is signalled from an object that
300
    has a widget mapping set. The object's mapped widget is passed in
301
    \a widget.
302
303
    \sa setMapping()
304
*/
305
306
/*!
307
    \fn void QSignalMapper::mapped(QObject *object)
308
309
    This signal is emitted when map() is signalled from an object that
310
    has an object mapping set. The object provided by the map is passed in
311
    \a object.
312
313
    \sa setMapping()
314
*/
315
316
QT_END_NAMESPACE
317
318
#include "moc_qsignalmapper.cpp"
319
320
#endif // QT_NO_SIGNALMAPPER