File indexing completed on 2024-05-12 15:56:59

0001 /*
0002  *  SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_SIGNALS_BLOCKER_H
0008 #define __KIS_SIGNALS_BLOCKER_H
0009 
0010 #include <QObject>
0011 #include <QVector>
0012 
0013 /**
0014  * Block QObject's signals in a safe and sane way.
0015  *
0016  * Avoid using direct calls to QObject::blockSignals(bool),
0017  * because:
0018  *
0019  * 1) They are not safe. One beautifully sunny day someone (it might
0020  *    easily be you yourself) will forget about these call and will put
0021  *    a 'return' statement somewhere among the lines. Surely this is
0022  *    not what you expect to happen.
0023  *
0024  * 2) Two lines of blocking for every line of access can easily make
0025  *    the code unreadable.
0026  */
0027 
0028 class KisSignalsBlocker
0029 {
0030 public:
0031     /**
0032      * Six should be enough for all usage cases! (c)
0033      */
0034     KisSignalsBlocker(QObject *o1,
0035                       QObject *o2,
0036                       QObject *o3 = 0,
0037                       QObject *o4 = 0,
0038                       QObject *o5 = 0,
0039                       QObject *o6 = 0)
0040     {
0041         if (o1) addObject(o1);
0042         if (o2) addObject(o2);
0043         if (o3) addObject(o3);
0044         if (o4) addObject(o4);
0045         if (o5) addObject(o5);
0046         if (o6) addObject(o6);
0047 
0048         blockObjects();
0049     }
0050 
0051     KisSignalsBlocker(QObject *object)
0052     {
0053         addObject(object);
0054         blockObjects();
0055     }
0056 
0057     ~KisSignalsBlocker()
0058     {
0059         auto it = m_objects.end();
0060         auto begin = m_objects.begin();
0061 
0062         while (it != begin) {
0063             --it;
0064             it->first->blockSignals(it->second);
0065         }
0066     }
0067 
0068 private:
0069     void blockObjects() {
0070         for (auto it = m_objects.begin(); it != m_objects.end(); ++it) {
0071             it->first->blockSignals(true);
0072         }
0073     }
0074 
0075     inline void addObject(QObject *object) {
0076         m_objects.append(qMakePair(object, object->signalsBlocked()));
0077     }
0078 
0079 private:
0080     Q_DISABLE_COPY(KisSignalsBlocker)
0081 
0082 private:
0083     QVector<QPair<QObject*,bool>> m_objects;
0084 };
0085 
0086 #endif /* __KIS_SIGNALS_BLOCKER_H */