diff options
Diffstat (limited to 'interfaces/kimproxy/library/kimproxy.cpp')
-rw-r--r-- | interfaces/kimproxy/library/kimproxy.cpp | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/interfaces/kimproxy/library/kimproxy.cpp b/interfaces/kimproxy/library/kimproxy.cpp deleted file mode 100644 index e8118b8bc..000000000 --- a/interfaces/kimproxy/library/kimproxy.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - kimproxy.cpp - - IM service library for KDE - - Copyright (c) 2004 Will Stephenson <lists@stevello.free-online.co.uk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqglobal.h> -#include <tqpixmapcache.h> -#include <dcopclient.h> -#include <kapplication.h> -#include <kdcopservicestarter.h> -#include <kdebug.h> -#include <kmessagebox.h> -#include <ksimpleconfig.h> -#include <kiconloader.h> -#include <kservice.h> -#include <kservicetype.h> - -#include "kimiface_stub.h" - -#include "kimproxy.h" - -static KStaticDeleter<KIMProxy> _staticDeleter; - -KIMProxy * KIMProxy::s_instance = 0L; - -struct AppPresenceCurrent -{ - TQCString appId; - int presence; -}; - -class ContactPresenceListCurrent : public TQValueList<AppPresenceCurrent> -{ - public: - // return value indicates if the supplied parameter was better than any existing presence - bool update( const AppPresenceCurrent ); - AppPresenceCurrent best(); -}; - - -struct KIMProxy::Private -{ - DCOPClient * dc; - // list of the strings in use by KIMIface - TQStringList presence_strings; - // list of the icon names in use by KIMIface - TQStringList presence_icons; - // map of presences - PresenceStringMap presence_map; -}; - -bool ContactPresenceListCurrent::update( AppPresenceCurrent ap ) -{ - if ( isEmpty() ) - { - append( ap ); - return true; - } - - bool bestChanged = false; - AppPresenceCurrent best; - best.presence = -1; - ContactPresenceListCurrent::iterator it = begin(); - const ContactPresenceListCurrent::iterator itEnd = end(); - ContactPresenceListCurrent::iterator existing = itEnd; - - while ( it != itEnd ) - { - if ( (*it).presence > best.presence ) - best = (*it); - if ( (*it).appId == ap.appId ) - existing = it; - ++it; - } - - if ( ap.presence > best.presence || - best.appId == ap.appId ) - bestChanged = true; - - if ( existing != itEnd ) - { - remove( existing ); - append( ap ); - } - return bestChanged; -} - -AppPresenceCurrent ContactPresenceListCurrent::best() -{ - AppPresenceCurrent best; - best.presence = -1; - ContactPresenceListCurrent::iterator it = begin(); - const ContactPresenceListCurrent::iterator itEnd = end(); - while ( it != itEnd ) - { - if ( (*it).presence > best.presence ) - best = (*it); - ++it; - } - // if it's still -1 here, we have no presence data, so we return Unknown - if ( best.presence == -1 ) - best.presence = 0; - return best; -} - -// int bestPresence( AppPresence* ap ) -// { -// Q_ASSERT( ap ); -// AppPresence::const_iterator it; -// it = ap->begin(); -// int best = 0; // unknown -// if ( it != ap->end() ) -// { -// best = it.data(); -// ++it; -// for ( ; it != ap->end(); ++it ) -// { -// if ( it.data() > best ) -// best = it.data(); -// } -// } -// return best; -// } -// -// TQCString bestAppId( AppPresence* ap ) -// { -// Q_ASSERT( ap ); -// AppPresence::const_iterator it; -// TQCString bestAppId; -// it = ap->begin(); -// if ( it != ap->end() ) -// { -// int best = it.data(); -// bestAppId = it.key(); -// ++it; -// for ( ; it != ap->end(); ++it ) -// { -// if ( it.data() > best ) -// { -// best = it.data(); -// bestAppId = it.key(); -// } -// } -// } -// return bestAppId; -// } - -KIMProxy * KIMProxy::instance( DCOPClient * client ) -{ - if ( client ) - { - if ( !s_instance ) - _staticDeleter.setObject( s_instance, new KIMProxy( client ) ); - return s_instance; - } - else - return 0L; -} - -KIMProxy::KIMProxy( DCOPClient* dc ) : DCOPObject( "KIMProxyIface" ), TQObject(), d( new Private ) -{ - m_im_client_stubs.setAutoDelete( true ); - - d->dc = dc; - m_initialized = false; - connect( d->dc, TQT_SIGNAL( applicationRemoved( const TQCString& ) ) , this, TQT_SLOT( unregisteredFromDCOP( const TQCString& ) ) ); - connect( d->dc, TQT_SIGNAL( applicationRegistered( const TQCString& ) ) , this, TQT_SLOT( registeredToDCOP( const TQCString& ) ) ); - d->dc->setNotifications( true ); - - d->presence_strings.append( "Unknown" ); - d->presence_strings.append( "Offline" ); - d->presence_strings.append( "Connecting" ); - d->presence_strings.append( "Away" ); - d->presence_strings.append( "Online" ); - - d->presence_icons.append( "presence_unknown" ); - d->presence_icons.append( "presence_offline" ); - d->presence_icons.append( "presence_connecting" ); - d->presence_icons.append( "presence_away" ); - d->presence_icons.append( "presence_online" ); - - //TQCString senderApp = "Kopete"; - //TQCString senderObjectId = "KIMIface"; - TQCString method = "contactPresenceChanged( TQString, TQCString, int )"; - //TQCString receiverObjectId = "KIMProxyIface"; - - // FIXME: make this work when the sender object id is set to KIMIFace - if ( !connectDCOPSignal( 0, 0, method, method, false ) ) - kdWarning() << "Couldn't connect DCOP signal. Won't receive any status notifications!" << endl; -} - -KIMProxy::~KIMProxy( ) -{ - //d->dc->setNotifications( false ); -} - -bool KIMProxy::initialize() -{ - if ( !m_initialized ) - { - m_initialized = true; // we should only do this once, as registeredToDCOP() will catch any new starts - // So there is no error from a failed query when using tdelibs 3.2, which don't have this servicetype - if ( KServiceType::serviceType( IM_SERVICE_TYPE ) ) - { - //kdDebug( 790 ) << k_funcinfo << endl; - TQCString dcopObjectId = "KIMIface"; - - // see what apps implementing our service type are out there - KService::List offers = KServiceType::offers( IM_SERVICE_TYPE ); - KService::List::iterator offer; - typedef TQValueList<TQCString> QCStringList; - QCStringList registeredApps = d->dc->registeredApplications(); - QCStringList::iterator app; - const QCStringList::iterator end = registeredApps.end(); - // for each registered app - for ( app = registeredApps.begin(); app != end; ++app ) - { - //kdDebug( 790 ) << " considering: " << *app << endl; - //for each offer - for ( offer = offers.begin(); offer != offers.end(); ++offer ) - { - TQCString dcopService = (*offer)->property("X-DCOP-ServiceName").toString().latin1(); - if ( !dcopService.isEmpty() ) - { - //kdDebug( 790 ) << " is it: " << dcopService << "?" << endl; - // get the application name ( minus any process ID ) - TQCString instanceName = (*app).left( dcopService.length() ); - // if the application implements the dcop service, add it - if ( instanceName == dcopService ) - { - m_apps_available = true; - //kdDebug( 790 ) << " app name: " << (*offer)->name() << ", has instance " << *app << ", dcopService: " << dcopService << endl; - if ( !m_im_client_stubs.find( dcopService ) ) - { - kdDebug( 790 ) << "App " << *app << ", dcopObjectId " << dcopObjectId << " found, using it for presence info." << endl; - m_im_client_stubs.insert( *app, new KIMIface_stub( d->dc, *app, dcopObjectId ) ); - pollApp( *app ); - } - } - } - } - } - } - } - return !m_im_client_stubs.isEmpty(); -} - -void KIMProxy::registeredToDCOP( const TQCString& appId ) -{ - //kdDebug( 790 ) << k_funcinfo << " appId '" << appId << "'" << endl; - // check that appId implements our service - // if the appId ends with a number, i.e. a pid like in foobar-12345, - if ( appId.isEmpty() ) - return; - - bool newApp = false; - // get an up to date list of offers in case a new app was installed - // and check each of the offers that implement the service type we're looking for, - // to see if any of them are the app that just registered - const KService::List offers = KServiceType::offers( IM_SERVICE_TYPE ); - KService::List::const_iterator it; - for ( it = offers.begin(); it != offers.end(); ++it ) - { - TQCString dcopObjectId = "KIMIface"; - TQCString dcopService = (*it)->property("X-DCOP-ServiceName").toString().latin1(); - if ( appId.left( dcopService.length() ) == dcopService ) - { - // if it's not already known, insert it - if ( !m_im_client_stubs.find( appId ) ) - { - newApp = true; - kdDebug( 790 ) << "App: " << appId << ", dcopService: " << dcopService << " started, using it for presence info."<< endl; - m_im_client_stubs.insert( appId, new KIMIface_stub( d->dc, appId, dcopObjectId ) ); - } - } - //else - // kdDebug( 790 ) << "App doesn't implement our ServiceType" << endl; - } - //if ( newApp ) - // emit sigPresenceInfoExpired(); -} - -void KIMProxy::unregisteredFromDCOP( const TQCString& appId ) -{ - //kdDebug( 790 ) << k_funcinfo << appId << endl; - if ( m_im_client_stubs.find( appId ) ) - { - kdDebug( 790 ) << appId << " quit, removing its presence info." << endl; - - PresenceStringMap::Iterator it = d->presence_map.begin(); - const PresenceStringMap::Iterator end = d->presence_map.end(); - for ( ; it != end; ++it ) - { - ContactPresenceListCurrent list = it.data(); - ContactPresenceListCurrent::iterator cpIt = list.begin(); - while( cpIt != list.end() ) - { - ContactPresenceListCurrent::iterator gone = cpIt++; - if ( (*gone).appId == appId ) - { - list.remove( gone ); - } - } - } - m_im_client_stubs.remove( appId ); - emit sigPresenceInfoExpired(); - } -} - -void KIMProxy::contactPresenceChanged( TQString uid, TQCString appId, int presence ) -{ - // update the presence map - //kdDebug( 790 ) << k_funcinfo << "uid: " << uid << " appId: " << appId << " presence " << presence << endl; - ContactPresenceListCurrent current; - current = d->presence_map[ uid ]; - //kdDebug( 790 ) << "current best presence from : " << current.best().appId << " is: " << current.best().presence << endl; - AppPresenceCurrent newPresence; - newPresence.appId = appId; - newPresence.presence = presence; - - if ( current.update( newPresence ) ) - { - d->presence_map.insert( uid, current ); - emit sigContactPresenceChanged( uid ); - } -} - -int KIMProxy::presenceNumeric( const TQString& uid ) -{ - AppPresenceCurrent ap; - ap.presence = 0; - if ( initialize() ) - { - ContactPresenceListCurrent presence = d->presence_map[ uid ]; - ap = presence.best(); - } - return ap.presence; -} - -TQString KIMProxy::presenceString( const TQString& uid ) -{ - AppPresenceCurrent ap; - ap.presence = 0; - if ( initialize() ) - { - ContactPresenceListCurrent presence = d->presence_map[ uid ]; - ap = presence.best(); - } - if ( ap.appId.isEmpty() ) - return TQString::null; - else - return d->presence_strings[ ap.presence ]; -} - -TQPixmap KIMProxy::presenceIcon( const TQString& uid ) -{ - AppPresenceCurrent ap; - ap.presence = 0; - if ( initialize() ) - { - ContactPresenceListCurrent presence = d->presence_map[ uid ]; - ap = presence.best(); - } - if ( ap.appId.isEmpty() ) - { - //kdDebug( 790 ) << k_funcinfo << "returning a null TQPixmap because we were asked for an icon for a uid we know nothing about" << endl; - return TQPixmap(); - } - else - { - //kdDebug( 790 ) << k_funcinfo << "returning this: " << d->presence_icons[ ap.presence ] << endl; - return SmallIcon( d->presence_icons[ ap.presence ]); - } -} - -TQStringList KIMProxy::allContacts() -{ - TQStringList value = d->presence_map.keys(); - return value; -} - -TQStringList KIMProxy::reachableContacts() -{ - TQStringList value; - - if ( initialize() ) - { - TQDictIterator<KIMIface_stub> it( m_im_client_stubs ); - for ( ; it.current(); ++it ) - { - value += it.current()->reachableContacts( ); - } - } - return value; -} - -TQStringList KIMProxy::onlineContacts() -{ - TQStringList value; - PresenceStringMap::iterator it = d->presence_map.begin(); - const PresenceStringMap::iterator end= d->presence_map.end(); - for ( ; it != end; ++it ) - if ( it.data().best().presence > 2 /*Better than Connecting, ie Away or Online*/ ) - value.append( it.key() ); - - return value; -} - -TQStringList KIMProxy::fileTransferContacts() -{ - TQStringList value; - - if ( initialize() ) - { - TQDictIterator<KIMIface_stub> it( m_im_client_stubs ); - for ( ; it.current(); ++it ) - { - value += it.current()->fileTransferContacts( ); - } - } - return value; -} - -bool KIMProxy::isPresent( const TQString& uid ) -{ - return ( !d->presence_map[ uid ].isEmpty() ); -} - -TQString KIMProxy::displayName( const TQString& uid ) -{ - TQString name; - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - name = s->displayName( uid ); - } - //kdDebug( 790 ) << k_funcinfo << name << endl; - return name; -} - -bool KIMProxy::canReceiveFiles( const TQString & uid ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - return s->canReceiveFiles( uid ); - } - return false; -} - -bool KIMProxy::canRespond( const TQString & uid ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - return s->canRespond( uid ); - } - return false; -} - -TQString KIMProxy::context( const TQString & uid ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - return s->context( uid ); - } - return TQString::null; -} - -void KIMProxy::chatWithContact( const TQString& uid ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - { - kapp->updateRemoteUserTimestamp( s->app() ); - s->chatWithContact( uid ); - } - } - return; -} - -void KIMProxy::messageContact( const TQString& uid, const TQString& message ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForUid( uid ) ) - { - kapp->updateRemoteUserTimestamp( s->app() ); - s->messageContact( uid, message ); - } - } - return; -} - -void KIMProxy::sendFile(const TQString &uid, const KURL &sourceURL, const TQString &altFileName, uint fileSize ) -{ - if ( initialize() ) - { - TQDictIterator<KIMIface_stub> it( m_im_client_stubs ); - for ( ; it.current(); ++it ) - { - if ( it.current()->canReceiveFiles( uid ) ) - { - kapp->updateRemoteUserTimestamp( it.current()->app() ); - it.current()->sendFile( uid, sourceURL, altFileName, fileSize ); - break; - } - } - } - return; -} - -bool KIMProxy::addContact( const TQString &contactId, const TQString &protocol ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForProtocol( protocol ) ) - return s->addContact( contactId, protocol ); - } - return false; -} - -TQString KIMProxy::locate( const TQString & contactId, const TQString & protocol ) -{ - if ( initialize() ) - { - if ( KIMIface_stub* s = stubForProtocol( protocol ) ) - return s->locate( contactId, protocol ); - } - return TQString::null; -} - -bool KIMProxy::imAppsAvailable() -{ - return ( !m_im_client_stubs.isEmpty() ); -} - -bool KIMProxy::startPreferredApp() -{ - TQString preferences = TQString("[X-DCOP-ServiceName] = '%1'").arg( preferredApp() ); - // start/find an instance of DCOP/InstantMessenger - TQString error; - TQCString dcopService; - // Get a preferred IM client. - // The app will notify itself to us using registeredToDCOP, so we don't need to record a stub for it here - // FIXME: error in preferences, see debug output - preferences = TQString::null; - int result = KDCOPServiceStarter::self()->findServiceFor( IM_SERVICE_TYPE, TQString::null, preferences, &error, &dcopService ); - - kdDebug( 790 ) << k_funcinfo << "error was: " << error << ", dcopService: " << dcopService << endl; - - return ( result == 0 ); -} - - -void KIMProxy::pollAll( const TQString &uid ) -{ -/* // We only need to call this function if we don't have any data at all - // otherwise, the data will be kept fresh by received presence change - // DCOP signals - if ( !d->presence_map.contains( uid ) ) - { - AppPresence *presence = new AppPresence(); - // record current presence from known clients - TQDictIterator<KIMIface_stub> it( m_im_client_stubs ); - for ( ; it.current(); ++it ) - { - presence->insert( it.currentKey().ascii(), it.current()->presenceStatus( uid ) ); // m_im_client_stubs has qstring keys... - } - d->presence_map.insert( uid, presence ); - }*/ -} - -void KIMProxy::pollApp( const TQCString & appId ) -{ - //kdDebug( 790 ) << k_funcinfo << endl; - KIMIface_stub * appStub = m_im_client_stubs[ appId ]; - TQStringList contacts = m_im_client_stubs[ appId ]->allContacts(); - TQStringList::iterator it = contacts.begin(); - TQStringList::iterator end = contacts.end(); - for ( ; it != end; ++it ) - { - ContactPresenceListCurrent current = d->presence_map[ *it ]; - AppPresenceCurrent ap; - ap.appId = appId; - ap.presence = appStub->presenceStatus( *it ); - current.append( ap ); - - d->presence_map.insert( *it, current ); - if ( current.update( ap ) ) - emit sigContactPresenceChanged( *it ); - //kdDebug( 790 ) << " uid: " << *it << " presence: " << ap.presence << endl; - } -} - -KIMIface_stub * KIMProxy::stubForUid( const TQString &uid ) -{ - // get best appPresence - AppPresenceCurrent ap = d->presence_map[ uid ].best(); - // look up the presence string from that app - return m_im_client_stubs.find( ap.appId ); -} - -KIMIface_stub * KIMProxy::stubForProtocol( const TQString &protocol) -{ - KIMIface_stub * app; - // see if the preferred client supports this protocol - TQString preferred = preferredApp(); - if ( ( app = m_im_client_stubs.find( preferred ) ) ) - { - if ( app->protocols().grep( protocol ).count() > 0 ) - return app; - } - // preferred doesn't do this protocol, try the first of the others that says it does - TQDictIterator<KIMIface_stub> it( m_im_client_stubs ); - for ( ; it.current(); ++it ) - { - if ( it.current()->protocols().grep( protocol ).count() > 0 ) - return it.current(); - } - return 0L; -} - -TQString KIMProxy::preferredApp() -{ - TDEConfig *store = new KSimpleConfig( IM_CLIENT_PREFERENCES_FILE ); - store->setGroup( IM_CLIENT_PREFERENCES_SECTION ); - TQString preferredApp = store->readEntry( IM_CLIENT_PREFERENCES_ENTRY ); - //kdDebug( 790 ) << k_funcinfo << "found preferred app: " << preferredApp << endl; - return preferredApp; -} - -#include "kimproxy.moc" |