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