25 #include <tqpixmapcache.h>
26 #include <dcopclient.h>
27 #include <tdeapplication.h>
28 #include <kdcopservicestarter.h>
30 #include <tdemessagebox.h>
31 #include <ksimpleconfig.h>
32 #include <kiconloader.h>
34 #include <kservicetype.h>
36 #include "kimiface_stub.h"
38 #include "tdeimproxy.h"
40 static KStaticDeleter<KIMProxy> _staticDeleter;
42 KIMProxy * KIMProxy::s_instance = 0L;
44 struct AppPresenceCurrent
50 class ContactPresenceListCurrent :
public TQValueList<AppPresenceCurrent>
54 bool update(
const AppPresenceCurrent );
55 AppPresenceCurrent best();
59 struct KIMProxy::Private
63 TQStringList presence_strings;
65 TQStringList presence_icons;
67 PresenceStringMap presence_map;
70 bool ContactPresenceListCurrent::update( AppPresenceCurrent ap )
78 bool bestChanged =
false;
79 AppPresenceCurrent best;
81 ContactPresenceListCurrent::iterator it = begin();
82 const ContactPresenceListCurrent::iterator itEnd = end();
83 ContactPresenceListCurrent::iterator existing = itEnd;
87 if ( (*it).presence > best.presence )
89 if ( (*it).appId == ap.appId )
94 if ( ap.presence > best.presence ||
95 best.appId == ap.appId )
98 if ( existing != itEnd )
106 AppPresenceCurrent ContactPresenceListCurrent::best()
108 AppPresenceCurrent best;
110 ContactPresenceListCurrent::iterator it = begin();
111 const ContactPresenceListCurrent::iterator itEnd = end();
112 while ( it != itEnd )
114 if ( (*it).presence > best.presence )
119 if ( best.presence == -1 )
171 _staticDeleter.setObject( s_instance,
new KIMProxy( client ) );
178 KIMProxy::KIMProxy(
DCOPClient* dc ) :
DCOPObject(
"KIMProxyIface" ), TQObject(), d( new Private )
180 m_im_client_stubs.setAutoDelete(
true );
183 m_initialized =
false;
184 connect( d->dc, TQT_SIGNAL( applicationRemoved(
const TQCString& ) ) ,
this, TQT_SLOT(
unregisteredFromDCOP(
const TQCString& ) ) );
185 connect( d->dc, TQT_SIGNAL( applicationRegistered(
const TQCString& ) ) ,
this, TQT_SLOT(
registeredToDCOP(
const TQCString& ) ) );
186 d->dc->setNotifications(
true );
188 d->presence_strings.append(
"Unknown" );
189 d->presence_strings.append(
"Offline" );
190 d->presence_strings.append(
"Connecting" );
191 d->presence_strings.append(
"Away" );
192 d->presence_strings.append(
"Online" );
194 d->presence_icons.append(
"presence_unknown" );
195 d->presence_icons.append(
"presence_offline" );
196 d->presence_icons.append(
"presence_connecting" );
197 d->presence_icons.append(
"presence_away" );
198 d->presence_icons.append(
"presence_online" );
202 TQCString method =
"contactPresenceChanged( TQString, TQCString, int )";
207 kdWarning() <<
"Couldn't connect DCOP signal. Won't receive any status notifications!" << endl;
210 KIMProxy::~KIMProxy( )
217 if ( !m_initialized )
219 m_initialized =
true;
221 if ( KServiceType::serviceType( IM_SERVICE_TYPE ) )
224 TQCString dcopObjectId =
"KIMIface";
227 KService::List offers = KServiceType::offers( IM_SERVICE_TYPE );
228 KService::List::iterator offer;
229 typedef TQValueList<TQCString> QCStringList;
230 QCStringList registeredApps = d->dc->registeredApplications();
231 QCStringList::iterator app;
232 const QCStringList::iterator end = registeredApps.end();
234 for ( app = registeredApps.begin(); app != end; ++app )
238 for ( offer = offers.begin(); offer != offers.end(); ++offer )
240 TQCString dcopService = (*offer)->property(
"X-DCOP-ServiceName").toString().latin1();
241 if ( !dcopService.isEmpty() )
245 TQCString instanceName = (*app).left( dcopService.length() );
247 if ( instanceName == dcopService )
249 m_apps_available =
true;
251 if ( !m_im_client_stubs.find( dcopService ) )
253 kdDebug( 790 ) <<
"App " << *app <<
", dcopObjectId " << dcopObjectId <<
" found, using it for presence info." << endl;
254 m_im_client_stubs.insert( *app,
new KIMIface_stub( d->dc, *app, dcopObjectId ) );
263 return !m_im_client_stubs.isEmpty();
271 if ( appId.isEmpty() )
278 const KService::List offers = KServiceType::offers( IM_SERVICE_TYPE );
279 KService::List::const_iterator it;
280 for ( it = offers.begin(); it != offers.end(); ++it )
282 TQCString dcopObjectId =
"KIMIface";
283 TQCString dcopService = (*it)->property(
"X-DCOP-ServiceName").toString().latin1();
284 if ( appId.left( dcopService.length() ) == dcopService )
287 if ( !m_im_client_stubs.find( appId ) )
290 kdDebug( 790 ) <<
"App: " << appId <<
", dcopService: " << dcopService <<
" started, using it for presence info."<< endl;
291 m_im_client_stubs.insert( appId,
new KIMIface_stub( d->dc, appId, dcopObjectId ) );
304 if ( m_im_client_stubs.find( appId ) )
306 kdDebug( 790 ) << appId <<
" quit, removing its presence info." << endl;
308 PresenceStringMap::Iterator it = d->presence_map.begin();
309 const PresenceStringMap::Iterator end = d->presence_map.end();
310 for ( ; it != end; ++it )
312 ContactPresenceListCurrent list = it.data();
313 ContactPresenceListCurrent::iterator cpIt = list.begin();
314 while( cpIt != list.end() )
316 ContactPresenceListCurrent::iterator gone = cpIt++;
317 if ( (*gone).appId == appId )
323 m_im_client_stubs.remove( appId );
332 ContactPresenceListCurrent current;
333 current = d->presence_map[ uid ];
335 AppPresenceCurrent newPresence;
336 newPresence.appId = appId;
337 newPresence.presence = presence;
339 if ( current.update( newPresence ) )
341 d->presence_map.insert( uid, current );
348 AppPresenceCurrent ap;
352 ContactPresenceListCurrent presence = d->presence_map[ uid ];
353 ap = presence.best();
360 AppPresenceCurrent ap;
364 ContactPresenceListCurrent presence = d->presence_map[ uid ];
365 ap = presence.best();
367 if ( ap.appId.isEmpty() )
368 return TQString::null;
370 return d->presence_strings[ ap.presence ];
375 AppPresenceCurrent ap;
379 ContactPresenceListCurrent presence = d->presence_map[ uid ];
380 ap = presence.best();
382 if ( ap.appId.isEmpty() )
390 return SmallIcon( d->presence_icons[ ap.presence ]);
396 TQStringList value = d->presence_map.keys();
406 TQDictIterator<KIMIface_stub> it( m_im_client_stubs );
407 for ( ; it.current(); ++it )
409 value += it.current()->reachableContacts( );
418 PresenceStringMap::iterator it = d->presence_map.begin();
419 const PresenceStringMap::iterator end= d->presence_map.end();
420 for ( ; it != end; ++it )
421 if ( it.data().best().presence > 2 )
422 value.append( it.key() );
433 TQDictIterator<KIMIface_stub> it( m_im_client_stubs );
434 for ( ; it.current(); ++it )
436 value += it.current()->fileTransferContacts( );
444 return ( !d->presence_map[ uid ].isEmpty() );
453 name = s->displayName( uid );
464 return s->canReceiveFiles( uid );
474 return s->canRespond( uid );
484 return s->context( uid );
486 return TQString::null;
495 kapp->updateRemoteUserTimestamp( s->app() );
496 s->chatWithContact( uid );
508 kapp->updateRemoteUserTimestamp( s->app() );
509 s->messageContact( uid, message );
515 void KIMProxy::sendFile(
const TQString &uid,
const KURL &sourceURL,
const TQString &altFileName, uint fileSize )
519 TQDictIterator<KIMIface_stub> it( m_im_client_stubs );
520 for ( ; it.current(); ++it )
522 if ( it.current()->canReceiveFiles( uid ) )
524 kapp->updateRemoteUserTimestamp( it.current()->app() );
525 it.current()->sendFile( uid, sourceURL, altFileName, fileSize );
538 return s->addContact( contactId, protocol );
548 return s->locate( contactId, protocol );
550 return TQString::null;
555 return ( !m_im_client_stubs.isEmpty() );
560 TQString preferences = TQString(
"[X-DCOP-ServiceName] = '%1'").arg(
preferredApp() );
563 TQCString dcopService;
567 preferences = TQString::null;
568 int result = KDCOPServiceStarter::self()->findServiceFor( IM_SERVICE_TYPE, TQString::null, preferences, &error, &dcopService );
570 kdDebug( 790 ) << k_funcinfo <<
"error was: " << error <<
", dcopService: " << dcopService << endl;
572 return ( result == 0 );
597 KIMIface_stub * appStub = m_im_client_stubs[ appId ];
598 TQStringList contacts = m_im_client_stubs[ appId ]->allContacts();
599 TQStringList::iterator it = contacts.begin();
600 TQStringList::iterator end = contacts.end();
601 for ( ; it != end; ++it )
603 ContactPresenceListCurrent current = d->presence_map[ *it ];
604 AppPresenceCurrent ap;
606 ap.presence = appStub->presenceStatus( *it );
607 current.append( ap );
609 d->presence_map.insert( *it, current );
610 if ( current.update( ap ) )
619 AppPresenceCurrent ap = d->presence_map[ uid ].best();
621 return m_im_client_stubs.find( ap.appId );
629 if ( ( app = m_im_client_stubs.find( preferred ) ) )
631 if ( app->protocols().grep( protocol ).count() > 0 )
635 TQDictIterator<KIMIface_stub> it( m_im_client_stubs );
636 for ( ; it.current(); ++it )
638 if ( it.current()->protocols().grep( protocol ).count() > 0 )
646 TDEConfig *store =
new KSimpleConfig( IM_CLIENT_PREFERENCES_FILE );
647 store->setGroup( IM_CLIENT_PREFERENCES_SECTION );
648 TQString
preferredApp = store->readEntry( IM_CLIENT_PREFERENCES_ENTRY );
653 #include "tdeimproxy.moc"