src/corelib/kernel/qsignalmapper.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    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
       
   321