25 #include <tqpixmapcache.h> 26 #include <dcopclient.h> 27 #include <kapplication.h> 28 #include <kdcopservicestarter.h> 30 #include <kmessagebox.h> 31 #include <ksimpleconfig.h> 32 #include <kiconloader.h> 34 #include <kservicetype.h> 36 #include "kimiface_stub.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 )";
206 if ( !connectDCOPSignal( 0, 0, method, method,
false ) )
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 );
324 emit sigPresenceInfoExpired();
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 );
342 emit sigContactPresenceChanged( uid );
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() );
452 if ( KIMIface_stub* s = stubForUid( uid ) )
453 name = s->displayName( uid );
463 if ( KIMIface_stub* s = stubForUid( uid ) )
464 return s->canReceiveFiles( uid );
473 if ( KIMIface_stub* s = stubForUid( uid ) )
474 return s->canRespond( uid );
483 if ( KIMIface_stub* s = stubForUid( uid ) )
484 return s->context( uid );
486 return TQString::null;
493 if ( KIMIface_stub* s = stubForUid( uid ) )
495 kapp->updateRemoteUserTimestamp( s->app() );
496 s->chatWithContact( uid );
506 if ( KIMIface_stub* s = stubForUid( 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 );
537 if ( KIMIface_stub* s = stubForProtocol( protocol ) )
538 return s->addContact( contactId, protocol );
547 if ( KIMIface_stub* s = stubForProtocol( 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 ) )
611 emit sigContactPresenceChanged( *it );
619 AppPresenceCurrent ap = d->presence_map[ uid ].best();
621 return m_im_client_stubs.find( ap.appId );
628 TQString preferred = preferredApp();
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 KConfig *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 "kimproxy.moc" KIMIface_stub * stubForProtocol(const TQString &protocol)
Get the app stub for this protocol.
TQPixmap presenceIcon(const TQString &uid)
Obtain the icon representing the IM presence for the specified contact.
bool canRespond(const TQString &uid)
Indicate if a given contact will be able to respond.
TQString context(const TQString &uid)
Obtain the given contact's current context (home, work, or any)
void sendFile(const TQString &uid, const KURL &sourceURL, const TQString &altFileName=TQString::null, uint fileSize=0)
Send a file to the contact.
KIMIface_stub * stubForUid(const TQString &uid)
Get the app stub best able to reach this uid.
bool canReceiveFiles(const TQString &uid)
Indicate if a given contact can receive files.
TQStringList fileTransferContacts()
Obtain a list of IM-contacts who may receive file transfers.
TQString locate(const TQString &contactId, const TQString &protocol)
Obtain the KABC UID corresponding to the given IM address.
bool isPresent(const TQString &uid)
Confirm if a given contact is known to the proxy.
bool imAppsAvailable()
Checks if there are any compatible instant messaging applications available.
TQString displayName(const TQString &uid)
Obtain the proxy's idea of the contact's display name.
TQString presenceString(const TQString &uid)
Obtain the IM presence as a i18ned string for the specified contact.
bool startPreferredApp()
Start the user's preferred IM application.
bool addContact(const TQString &contactId, const TQString &protocol)
Add a new contact given its protocol specific identifier.
void pollApp(const TQCString &appId)
Bootstrap our presence data for a newly registered app.
void pollAll(const TQString &uid)
Bootstrap our presence data by polling all known apps.
void contactPresenceChanged(TQString uid, TQCString appId, int presence)
Just exists to let the IDL compiler make the DCOP signal for this.
static KIMProxy * instance(DCOPClient *client)
Obtain an instance of KIMProxy.
TQStringList allContacts()
Obtain a list of IM-contacts known to IM-applications.
void registeredToDCOP(const TQCString &appId)
Updates the proxy's data after a new application registered with DCOP.
TQStringList reachableContacts()
Obtain a list of IM-contacts that are currently reachable.
bool initialize()
Get the proxy ready to connect.
void chatWithContact(const TQString &uid)
Start a chat session with the specified contact.
TQStringList onlineContacts()
Obtain a list of IM-contacts that are currently online.
void messageContact(const TQString &uid, const TQString &message)
Send a single message to the specified contact.
void unregisteredFromDCOP(const TQCString &appId)
Updates the proxy's data after an application unregistered with DCOP.
Provides access to instant messenger programs which implement KDE's instant messanger interface KIMIf...
int presenceNumeric(const TQString &uid)
Obtain the IM presence as a number for the specified contact.
TQString preferredApp()
Get the name of the user's IM application of choice.