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