1 /*
2  *  Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #ifndef __KIS_SIGNALS_BLOCKER_H
20 #define __KIS_SIGNALS_BLOCKER_H
21 
22 #include <QObject>
23 #include <QVector>
24 
25 /**
26  * Block QObject's signals in a safe and sane way.
27  *
28  * Avoid using direct calls to QObject::blockSignals(bool),
29  * because:
30  *
31  * 1) They are not safe. One beautifully sunny day someone (it might
32  *    easily be you yourself) will forget about these call and will put
33  *    a 'return' statement somewhere among the lines. Surely this is
34  *    not what you expect to happen.
35  *
36  * 2) Two lines of blocking for every line of access can easily make
37  *    the code unreadable.
38  */
39 
40 class KisSignalsBlocker
41 {
42 public:
43     /**
44      * Six should be enough for all usage cases! (c)
45      */
46     KisSignalsBlocker(QObject *o1,
47                       QObject *o2,
48                       QObject *o3 = 0,
49                       QObject *o4 = 0,
50                       QObject *o5 = 0,
51                       QObject *o6 = 0)
52     {
53         if (o1) addObject(o1);
54         if (o2) addObject(o2);
55         if (o3) addObject(o3);
56         if (o4) addObject(o4);
57         if (o5) addObject(o5);
58         if (o6) addObject(o6);
59 
60         blockObjects();
61     }
62 
KisSignalsBlocker(QObject * object)63     KisSignalsBlocker(QObject *object)
64     {
65         addObject(object);
66         blockObjects();
67     }
68 
~KisSignalsBlocker()69     ~KisSignalsBlocker()
70     {
71         QVector<QObject*>::iterator it = m_objects.end();
72         QVector<QObject*>::iterator begin = m_objects.begin();
73 
74         while (it != begin) {
75             --it;
76             (*it)->blockSignals(false);
77         }
78     }
79 
80 private:
blockObjects()81     void blockObjects() {
82         Q_FOREACH (QObject *object, m_objects) {
83             object->blockSignals(true);
84         }
85     }
86 
addObject(QObject * object)87     inline void addObject(QObject *object) {
88         m_objects.append(object);
89     }
90 
91 private:
92     Q_DISABLE_COPY(KisSignalsBlocker)
93 
94 private:
95     QVector<QObject*> m_objects;
96 };
97 
98 #endif /* __KIS_SIGNALS_BLOCKER_H */
99