/* * Copyright (C) 2013 Nicolas Bonnefon and other contributors * * This file is part of glogg. * * glogg is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * glogg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with glogg. If not, see . */ #include "signalmux.h" #include #include #include "log.h" SignalMux::SignalMux() : connectionList_() { currentDocument_ = nullptr; } void SignalMux::connect( QObject *sender, const char *signal, const char *slot ) { Connection new_connection = { sender, nullptr, signal, slot }; connectionList_.push_back( new_connection ); connect( new_connection ); } void SignalMux::disconnect( QObject *sender, const char *signal, const char *slot ) { // Find any signal that match our description auto connection = std::find_if( connectionList_.begin(), connectionList_.end(), [sender, signal, slot]( const Connection& c ) -> bool { return ((QObject*)c.source == sender) && (c.sink == nullptr) && (qstrcmp( c.signal, signal) == 0) && (qstrcmp( c.slot, slot) == 0); } ); if ( connection != connectionList_.end() ) { disconnect( *connection ); connectionList_.erase( connection ); } else { LOG( logERROR ) << "SignalMux disconnecting a non-existing signal"; } } // Upstream signals void SignalMux::connect( const char* signal, QObject* receiver, const char* slot ) { Connection new_connection = { nullptr, receiver, signal, slot }; connectionList_.push_back( new_connection ); connect( new_connection ); } void SignalMux::disconnect( const char *signal, QObject* receiver, const char *slot ) { // Find any signal that match our description auto connection = std::find_if( connectionList_.begin(), connectionList_.end(), [receiver, signal, slot]( const Connection& c ) -> bool { return ((QObject*)c.sink == receiver) && (c.source == nullptr) && (qstrcmp( c.signal, signal) == 0) && (qstrcmp( c.slot, slot) == 0); } ); if ( connection != connectionList_.end() ) { disconnect( *connection ); connectionList_.erase( connection ); } else { LOG( logERROR ) << "SignalMux disconnecting a non-existing signal"; } } void SignalMux::setCurrentDocument( QObject* current_document ) { // First disconnect everything to/from the old document for ( auto c: connectionList_ ) disconnect( c ); currentDocument_ = current_document; // And now connect to/from the new document for ( auto c: connectionList_ ) connect( c ); // And ask the doc to emit all state signals MuxableDocumentInterface* doc = dynamic_cast( current_document ); if ( doc ) doc->sendAllStateSignals(); } /* * Private functions */ void SignalMux::connect( const Connection& connection ) { if ( currentDocument_ ) { LOG( logDEBUG ) << "SignalMux::connect"; if ( connection.source && ( ! connection.sink ) ) { // Downstream signal QObject::connect( connection.source, connection.signal, currentDocument_, connection.slot ); } else if ( ( ! connection.source ) && connection.sink ) { // Upstream signal QObject::connect( currentDocument_, connection.signal, connection.sink, connection.slot ); } else { LOG( logERROR ) << "SignalMux has an unexpected signal"; } } } void SignalMux::disconnect( const Connection& connection ) { if ( currentDocument_ ) { LOG( logDEBUG ) << "SignalMux::disconnect"; if ( connection.source && ( ! connection.sink ) ) { // Downstream signal QObject::disconnect( connection.source, connection.signal, currentDocument_, connection.slot ); } else if ( ( ! connection.source ) && connection.sink ) { // Upstream signal QObject::disconnect( currentDocument_, connection.signal, connection.sink, connection.slot ); } else { LOG( logERROR ) << "SignalMux has an unexpected signal"; } } }