1 /*
2  *  Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
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 or (at your option)
7  *  version 3 of the License.
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, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "SignalMultiplexer.h"
19 
20 #include "core/Global.h"
21 
SignalMultiplexer()22 SignalMultiplexer::SignalMultiplexer()
23 {
24 }
25 
~SignalMultiplexer()26 SignalMultiplexer::~SignalMultiplexer()
27 {
28     // disconnect all connections
29     setCurrentObject(nullptr);
30 }
31 
currentObject() const32 QObject* SignalMultiplexer::currentObject() const
33 {
34     return m_currentObject;
35 }
36 
setCurrentObject(QObject * object)37 void SignalMultiplexer::setCurrentObject(QObject* object)
38 {
39     // remove all Connections from the list whoes senders/receivers have been deleted
40     QMutableListIterator<Connection> i = m_connections;
41     while (i.hasNext()) {
42         const Connection& con = i.next();
43 
44         if (!con.sender && !con.receiver) {
45             i.remove();
46         }
47     }
48 
49     if (m_currentObject) {
50         for (const Connection& con : asConst(m_connections)) {
51             disconnect(con);
52         }
53     }
54 
55     m_currentObject = object;
56 
57     if (object) {
58         for (const Connection& con : asConst(m_connections)) {
59             connect(con);
60         }
61     }
62 }
63 
connect(QObject * sender,const char * signal,const char * slot)64 void SignalMultiplexer::connect(QObject* sender, const char* signal, const char* slot)
65 {
66     Q_ASSERT(sender);
67 
68     Connection con;
69     con.slot = slot;
70     con.sender = sender;
71     con.signal = signal;
72     m_connections << con;
73 
74     if (m_currentObject) {
75         connect(con);
76     }
77 }
78 
connect(const char * signal,QObject * receiver,const char * slot)79 void SignalMultiplexer::connect(const char* signal, QObject* receiver, const char* slot)
80 {
81     Q_ASSERT(receiver);
82 
83     Connection con;
84     con.receiver = receiver;
85     con.signal = signal;
86     con.slot = slot;
87     m_connections << con;
88 
89     if (m_currentObject) {
90         connect(con);
91     }
92 }
93 
disconnect(QObject * sender,const char * signal,const char * slot)94 void SignalMultiplexer::disconnect(QObject* sender, const char* signal, const char* slot)
95 {
96     Q_ASSERT(sender);
97 
98     QMutableListIterator<Connection> i = m_connections;
99     while (i.hasNext()) {
100         const Connection& con = i.next();
101 
102         if (con.sender == sender && qstrcmp(con.signal, signal) == 0 && qstrcmp(con.slot, slot) == 0) {
103             if (m_currentObject) {
104                 disconnect(con);
105             }
106             i.remove();
107         }
108     }
109 }
110 
disconnect(const char * signal,QObject * receiver,const char * slot)111 void SignalMultiplexer::disconnect(const char* signal, QObject* receiver, const char* slot)
112 {
113     Q_ASSERT(receiver);
114 
115     QMutableListIterator<Connection> i = m_connections;
116     while (i.hasNext()) {
117         const Connection& con = i.next();
118 
119         if (con.receiver == receiver && qstrcmp(con.signal, signal) == 0 && qstrcmp(con.slot, slot) == 0) {
120             if (m_currentObject) {
121                 disconnect(con);
122             }
123             i.remove();
124         }
125     }
126 }
127 
connect(const Connection & con)128 void SignalMultiplexer::connect(const Connection& con)
129 {
130     Q_ASSERT(con.sender || con.receiver);
131 
132     if (con.sender) {
133         QObject::connect(con.sender, con.signal, m_currentObject, con.slot);
134     }
135     else {
136         QObject::connect(m_currentObject, con.signal, con.receiver, con.slot);
137     }
138 }
139 
disconnect(const Connection & con)140 void SignalMultiplexer::disconnect(const Connection& con)
141 {
142     Q_ASSERT(con.sender || con.receiver);
143 
144     if (con.sender) {
145         QObject::disconnect(con.sender, con.signal, m_currentObject, con.slot);
146     }
147     else {
148         QObject::disconnect(m_currentObject, con.signal, con.receiver, con.slot);
149     }
150 }
151