1 /* 2 * Copyright (C) 2013 Nicolas Bonnefon and other contributors 3 * 4 * This file is part of glogg. 5 * 6 * glogg is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * glogg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "signalmux.h" 21 22 #include <algorithm> 23 #include <QObject> 24 25 #include "log.h" 26 27 SignalMux::SignalMux() : 28 connectionList_() 29 { 30 currentDocument_ = nullptr; 31 } 32 33 void SignalMux::connect( QObject *sender, 34 const char *signal, const char *slot ) 35 { 36 Connection new_connection = { 37 sender, 38 nullptr, 39 signal, 40 slot }; 41 42 connectionList_.push_back( new_connection ); 43 44 connect( new_connection ); 45 } 46 47 void SignalMux::disconnect( QObject *sender, 48 const char *signal, const char *slot ) 49 { 50 // Find any signal that match our description 51 auto connection = std::find_if( 52 connectionList_.begin(), connectionList_.end(), 53 [sender, signal, slot]( const Connection& c ) -> bool 54 { return ((QObject*)c.source == sender) && (c.sink == nullptr) && 55 (qstrcmp( c.signal, signal) == 0) && (qstrcmp( c.slot, slot) == 0); } ); 56 57 if ( connection != connectionList_.end() ) 58 { 59 disconnect( *connection ); 60 61 connectionList_.erase( connection ); 62 } 63 else 64 { 65 LOG( logERROR ) << "SignalMux disconnecting a non-existing signal"; 66 } 67 } 68 69 // Upstream signals 70 void SignalMux::connect( const char* signal, 71 QObject* receiver, const char* slot ) 72 { 73 Connection new_connection = { 74 nullptr, 75 receiver, 76 signal, 77 slot }; 78 79 connectionList_.push_back( new_connection ); 80 81 connect( new_connection ); 82 } 83 84 void SignalMux::disconnect( const char *signal, 85 QObject* receiver, const char *slot ) 86 { 87 // Find any signal that match our description 88 auto connection = std::find_if( 89 connectionList_.begin(), connectionList_.end(), 90 [receiver, signal, slot]( const Connection& c ) -> bool 91 { return ((QObject*)c.sink == receiver) && (c.source == nullptr) && 92 (qstrcmp( c.signal, signal) == 0) && (qstrcmp( c.slot, slot) == 0); } ); 93 94 if ( connection != connectionList_.end() ) 95 { 96 disconnect( *connection ); 97 98 connectionList_.erase( connection ); 99 } 100 else 101 { 102 LOG( logERROR ) << "SignalMux disconnecting a non-existing signal"; 103 } 104 } 105 106 void SignalMux::setCurrentDocument( QObject* current_document ) 107 { 108 currentDocument_ = current_document; 109 } 110 111 /* 112 * Private functions 113 */ 114 void SignalMux::connect( const Connection& connection ) 115 { 116 if ( currentDocument_ ) 117 { 118 if ( connection.source && ( ! connection.sink ) ) 119 { 120 // Downstream signal 121 QObject::connect( connection.source, connection.signal, 122 currentDocument_, connection.slot ); 123 } 124 else if ( ( ! connection.source ) && connection.sink ) 125 { 126 // Upstream signal 127 QObject::connect( currentDocument_, connection.signal, 128 connection.sink, connection.slot ); 129 } 130 else 131 { 132 LOG( logERROR ) << "SignalMux has an unexpected signal"; 133 } 134 } 135 } 136 137 void SignalMux::disconnect( const Connection& connection ) 138 { 139 if ( currentDocument_ ) 140 { 141 if ( connection.source && ( ! connection.sink ) ) 142 { 143 // Downstream signal 144 QObject::disconnect( connection.source, connection.signal, 145 currentDocument_, connection.slot ); 146 } 147 else if ( ( ! connection.source ) && connection.sink ) 148 { 149 // Upstream signal 150 QObject::disconnect( currentDocument_, connection.signal, 151 connection.sink, connection.slot ); 152 } 153 else 154 { 155 LOG( logERROR ) << "SignalMux has an unexpected signal"; 156 } 157 } 158 } 159