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 #include "kis_acyclic_signal_connector.h"
20 
21 #include "kis_debug.h"
22 
23 
KisAcyclicSignalConnector(QObject * parent)24 KisAcyclicSignalConnector::KisAcyclicSignalConnector(QObject *parent)
25     : QObject(parent),
26       m_signalsBlocked(0)
27 {
28 }
29 
~KisAcyclicSignalConnector()30 KisAcyclicSignalConnector::~KisAcyclicSignalConnector()
31 {
32 }
33 
connectForwardDouble(QObject * sender,const char * signal,QObject * receiver,const char * method)34 void KisAcyclicSignalConnector::connectForwardDouble(QObject *sender, const char *signal,
35                                                   QObject *receiver, const char *method)
36 {
37 
38     connect(sender, signal, this, SLOT(forwardSlotDouble(double)), Qt::UniqueConnection);
39     connect(this, SIGNAL(forwardSignalDouble(double)), receiver, method, Qt::UniqueConnection);
40 }
41 
connectBackwardDouble(QObject * sender,const char * signal,QObject * receiver,const char * method)42 void KisAcyclicSignalConnector::connectBackwardDouble(QObject *sender, const char *signal,
43                                                    QObject *receiver, const char *method)
44 {
45 
46     connect(sender, signal, this, SLOT(backwardSlotDouble(double)), Qt::UniqueConnection);
47     connect(this, SIGNAL(backwardSignalDouble(double)), receiver, method, Qt::UniqueConnection);
48 }
49 
connectForwardInt(QObject * sender,const char * signal,QObject * receiver,const char * method)50 void KisAcyclicSignalConnector::connectForwardInt(QObject *sender, const char *signal,
51                                                   QObject *receiver, const char *method)
52 {
53 
54     connect(sender, signal, this, SLOT(forwardSlotInt(int)), Qt::UniqueConnection);
55     connect(this, SIGNAL(forwardSignalInt(int)), receiver, method, Qt::UniqueConnection);
56 }
57 
connectBackwardInt(QObject * sender,const char * signal,QObject * receiver,const char * method)58 void KisAcyclicSignalConnector::connectBackwardInt(QObject *sender, const char *signal,
59                                                    QObject *receiver, const char *method)
60 {
61 
62     connect(sender, signal, this, SLOT(backwardSlotInt(int)), Qt::UniqueConnection);
63     connect(this, SIGNAL(backwardSignalInt(int)), receiver, method, Qt::UniqueConnection);
64 }
65 
connectForwardBool(QObject * sender,const char * signal,QObject * receiver,const char * method)66 void KisAcyclicSignalConnector::connectForwardBool(QObject *sender, const char *signal,
67                                                   QObject *receiver, const char *method)
68 {
69 
70     connect(sender, signal, this, SLOT(forwardSlotBool(bool)), Qt::UniqueConnection);
71     connect(this, SIGNAL(forwardSignalBool(bool)), receiver, method, Qt::UniqueConnection);
72 }
73 
connectBackwardBool(QObject * sender,const char * signal,QObject * receiver,const char * method)74 void KisAcyclicSignalConnector::connectBackwardBool(QObject *sender, const char *signal,
75                                                    QObject *receiver, const char *method)
76 {
77 
78     connect(sender, signal, this, SLOT(backwardSlotBool(bool)), Qt::UniqueConnection);
79     connect(this, SIGNAL(backwardSignalBool(bool)), receiver, method, Qt::UniqueConnection);
80 }
81 
connectForwardVoid(QObject * sender,const char * signal,QObject * receiver,const char * method)82 void KisAcyclicSignalConnector::connectForwardVoid(QObject *sender, const char *signal,
83                                                   QObject *receiver, const char *method)
84 {
85 
86     connect(sender, signal, this, SLOT(forwardSlotVoid()), Qt::UniqueConnection);
87     connect(this, SIGNAL(forwardSignalVoid()), receiver, method, Qt::UniqueConnection);
88 }
89 
connectBackwardVoid(QObject * sender,const char * signal,QObject * receiver,const char * method)90 void KisAcyclicSignalConnector::connectBackwardVoid(QObject *sender, const char *signal,
91                                                  QObject *receiver, const char *method)
92 {
93 
94     connect(sender, signal, this, SLOT(backwardSlotVoid()), Qt::UniqueConnection);
95     connect(this, SIGNAL(backwardSignalVoid()), receiver, method, Qt::UniqueConnection);
96 }
97 
connectForwardVariant(QObject * sender,const char * signal,QObject * receiver,const char * method)98 void KisAcyclicSignalConnector::connectForwardVariant(QObject *sender, const char *signal,
99                                                   QObject *receiver, const char *method)
100 {
101 
102     connect(sender, signal, this, SLOT(forwardSlotVariant(QVariant)), Qt::UniqueConnection);
103     connect(this, SIGNAL(forwardSignalVariant(QVariant)), receiver, method, Qt::UniqueConnection);
104 }
105 
connectBackwardVariant(QObject * sender,const char * signal,QObject * receiver,const char * method)106 void KisAcyclicSignalConnector::connectBackwardVariant(QObject *sender, const char *signal,
107                                                        QObject *receiver, const char *method)
108 {
109     connect(sender, signal, this, SLOT(backwardSlotVariant(QVariant)), Qt::UniqueConnection);
110     connect(this, SIGNAL(backwardSignalVariant(QVariant)), receiver, method, Qt::UniqueConnection);
111 }
112 
connectForwardResourcePair(QObject * sender,const char * signal,QObject * receiver,const char * method)113 void KisAcyclicSignalConnector::connectForwardResourcePair(QObject *sender, const char *signal, QObject *receiver, const char *method)
114 {
115     connect(sender, signal, this, SLOT(forwardSlotResourcePair(int,QVariant)), Qt::UniqueConnection);
116     connect(this, SIGNAL(forwardSignalResourcePair(int,QVariant)), receiver, method, Qt::UniqueConnection);
117 }
118 
connectBackwardResourcePair(QObject * sender,const char * signal,QObject * receiver,const char * method)119 void KisAcyclicSignalConnector::connectBackwardResourcePair(QObject *sender, const char *signal, QObject *receiver, const char *method)
120 {
121     connect(sender, signal, this, SLOT(backwardSlotResourcePair(int,QVariant)), Qt::UniqueConnection);
122     connect(this, SIGNAL(backwardSignalResourcePair(int,QVariant)), receiver, method, Qt::UniqueConnection);
123 }
124 
connectForwardKoColor(QObject * sender,const char * signal,QObject * receiver,const char * method)125 void KisAcyclicSignalConnector::connectForwardKoColor(QObject *sender, const char *signal, QObject *receiver, const char *method)
126 {
127     connect(sender, signal, this, SLOT(forwardSlotKoColor(KoColor)), Qt::UniqueConnection);
128     connect(this, SIGNAL(forwardSignalKoColor(KoColor)), receiver, method, Qt::UniqueConnection);
129 }
130 
connectBackwardKoColor(QObject * sender,const char * signal,QObject * receiver,const char * method)131 void KisAcyclicSignalConnector::connectBackwardKoColor(QObject *sender, const char *signal, QObject *receiver, const char *method)
132 {
133     connect(sender, signal, this, SLOT(backwardSlotKoColor(KoColor)), Qt::UniqueConnection);
134     connect(this, SIGNAL(backwardSignalKoColor(KoColor)), receiver, method, Qt::UniqueConnection);
135 }
136 
lock()137 void KisAcyclicSignalConnector::lock()
138 {
139     if (m_parentConnector) {
140         m_parentConnector->lock();
141     } else {
142         coordinatedLock();
143 
144         Q_FOREACH(QPointer<KisAcyclicSignalConnector> conn, m_coordinatedConnectors) {
145             if (!conn) continue;
146             conn->coordinatedLock();
147         }
148     }
149 }
150 
unlock()151 void KisAcyclicSignalConnector::unlock()
152 {
153     if (m_parentConnector) {
154         m_parentConnector->unlock();
155     } else {
156         Q_FOREACH(QPointer<KisAcyclicSignalConnector> conn, m_coordinatedConnectors) {
157             if (!conn) continue;
158             conn->coordinatedUnlock();
159         }
160 
161         coordinatedUnlock();
162     }
163 }
164 
isLocked() const165 bool KisAcyclicSignalConnector::isLocked() const
166 {
167     return m_signalsBlocked;
168 }
169 
coordinatedLock()170 void KisAcyclicSignalConnector::coordinatedLock()
171 {
172     m_signalsBlocked++;
173 }
174 
coordinatedUnlock()175 void KisAcyclicSignalConnector::coordinatedUnlock()
176 {
177     m_signalsBlocked--;
178 }
179 
createCoordinatedConnector()180 KisAcyclicSignalConnector *KisAcyclicSignalConnector::createCoordinatedConnector()
181 {
182     KisAcyclicSignalConnector *conn = new KisAcyclicSignalConnector(this);
183     conn->m_parentConnector = this;
184     m_coordinatedConnectors.append(conn);
185     return conn;
186 }
187 
forwardSlotDouble(double value)188 void KisAcyclicSignalConnector::forwardSlotDouble(double value)
189 {
190     if (m_signalsBlocked) return;
191 
192     lock();
193     emit forwardSignalDouble(value);
194     unlock();
195 }
196 
backwardSlotDouble(double value)197 void KisAcyclicSignalConnector::backwardSlotDouble(double value)
198 {
199     if (m_signalsBlocked) return;
200 
201     lock();
202     emit backwardSignalDouble(value);
203     unlock();
204 }
205 
forwardSlotInt(int value)206 void KisAcyclicSignalConnector::forwardSlotInt(int value)
207 {
208     if (m_signalsBlocked) return;
209 
210     lock();
211     emit forwardSignalInt(value);
212     unlock();
213 }
214 
backwardSlotInt(int value)215 void KisAcyclicSignalConnector::backwardSlotInt(int value)
216 {
217     if (m_signalsBlocked) return;
218 
219     lock();
220     emit backwardSignalInt(value);
221     unlock();
222 }
223 
forwardSlotBool(bool value)224 void KisAcyclicSignalConnector::forwardSlotBool(bool value)
225 {
226     if (m_signalsBlocked) return;
227 
228     lock();
229     emit forwardSignalBool(value);
230     unlock();
231 }
232 
backwardSlotBool(bool value)233 void KisAcyclicSignalConnector::backwardSlotBool(bool value)
234 {
235     if (m_signalsBlocked) return;
236 
237     lock();
238     emit backwardSignalBool(value);
239     unlock();
240 }
241 
forwardSlotVoid()242 void KisAcyclicSignalConnector::forwardSlotVoid()
243 {
244     if (m_signalsBlocked) return;
245 
246     lock();
247     emit forwardSignalVoid();
248     unlock();
249 }
250 
backwardSlotVoid()251 void KisAcyclicSignalConnector::backwardSlotVoid()
252 {
253     if (m_signalsBlocked) return;
254 
255     lock();
256     emit backwardSignalVoid();
257     unlock();
258 }
259 
forwardSlotVariant(const QVariant & value)260 void KisAcyclicSignalConnector::forwardSlotVariant(const QVariant &value)
261 {
262     if (m_signalsBlocked) return;
263 
264     lock();
265     emit forwardSignalVariant(value);
266     unlock();
267 }
268 
backwardSlotVariant(const QVariant & value)269 void KisAcyclicSignalConnector::backwardSlotVariant(const QVariant &value)
270 {
271     if (m_signalsBlocked) return;
272 
273     lock();
274     emit backwardSignalVariant(value);
275     unlock();
276 }
277 
forwardSlotResourcePair(int key,const QVariant & resource)278 void KisAcyclicSignalConnector::forwardSlotResourcePair(int key, const QVariant &resource)
279 {
280     if (m_signalsBlocked) return;
281 
282     lock();
283     emit forwardSignalResourcePair(key, resource);
284     unlock();
285 }
286 
backwardSlotResourcePair(int key,const QVariant & resource)287 void KisAcyclicSignalConnector::backwardSlotResourcePair(int key, const QVariant &resource)
288 {
289     if (m_signalsBlocked) return;
290 
291     lock();
292     emit backwardSignalResourcePair(key, resource);
293     unlock();
294 }
295 
forwardSlotKoColor(const KoColor & value)296 void KisAcyclicSignalConnector::forwardSlotKoColor(const KoColor &value)
297 {
298     if (m_signalsBlocked) return;
299 
300     lock();
301     emit forwardSignalKoColor(value);
302     unlock();
303 }
304 
backwardSlotKoColor(const KoColor & value)305 void KisAcyclicSignalConnector::backwardSlotKoColor(const KoColor &value)
306 {
307     if (m_signalsBlocked) return;
308 
309     lock();
310     emit backwardSignalKoColor(value);
311     unlock();
312 }
313