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"
44struct AppPresenceCurrent
50class ContactPresenceListCurrent :
public TQValueList<AppPresenceCurrent>
54 bool update(
const AppPresenceCurrent );
55 AppPresenceCurrent best();
59struct KIMProxy::Private
63 TQStringList presence_strings;
65 TQStringList presence_icons;
67 PresenceStringMap presence_map;
70bool 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 )
106AppPresenceCurrent 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 ) );
178KIMProxy::KIMProxy(
DCOPClient* dc ) :
DCOPObject(
"KIMProxyIface" ), TQObject(), d( new Private )
180 m_im_client_stubs.setAutoDelete(
true );
183 m_initialized =
false;
184 connect( d->dc, TQ_SIGNAL( applicationRemoved(
const TQCString& ) ) ,
this, TQ_SLOT(
unregisteredFromDCOP(
const TQCString& ) ) );
185 connect( d->dc, TQ_SIGNAL( applicationRegistered(
const TQCString& ) ) ,
this, TQ_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;
210KIMProxy::~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 );
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 )
647 store->
setGroup( IM_CLIENT_PREFERENCES_SECTION );
653#include "tdeimproxy.moc"
bool connectDCOPSignal(const TQCString &sender, const TQCString &senderObj, const TQCString &signal, const TQCString &slot, bool Volatile)
Provides access to instant messenger programs which implement KDE's instant messanger interface KIMIf...
KIMIface_stub * stubForProtocol(const TQString &protocol)
Get the app stub for this protocol.
void sigContactPresenceChanged(const TQString &uid)
Indicates that the specified IM-contact's presence changed.
TQPixmap presenceIcon(const TQString &uid)
Obtain the icon representing the IM presence for the specified contact.
TQStringList onlineContacts()
Obtain a list of IM-contacts that are currently online.
bool canReceiveFiles(const TQString &uid)
Indicate if a given contact can receive files.
void unregisteredFromDCOP(const TQCString &appId)
Updates the proxy's data after an application unregistered with DCOP.
void sigPresenceInfoExpired()
Indicates that presence information obtained earlier on might not be valid any longer.
void chatWithContact(const TQString &uid)
Start a chat session with the specified contact.
TQStringList allContacts()
Obtain a list of IM-contacts known to IM-applications.
bool initialize()
Get the proxy ready to connect.
int presenceNumeric(const TQString &uid)
Obtain the IM presence as a number for the specified contact.
bool isPresent(const TQString &uid)
Confirm if a given contact is known to the proxy.
void messageContact(const TQString &uid, const TQString &message)
Send a single message to the specified contact.
TQStringList fileTransferContacts()
Obtain a list of IM-contacts who may receive file transfers.
TQString displayName(const TQString &uid)
Obtain the proxy's idea of the contact's display name.
bool startPreferredApp()
Start the user's preferred IM application.
bool imAppsAvailable()
Checks if there are any compatible instant messaging applications available.
bool canRespond(const TQString &uid)
Indicate if a given contact will be able to respond.
void registeredToDCOP(const TQCString &appId)
Updates the proxy's data after a new application registered with DCOP.
void contactPresenceChanged(TQString uid, TQCString appId, int presence)
Just exists to let the IDL compiler make the DCOP signal for this.
TQStringList reachableContacts()
Obtain a list of IM-contacts that are currently reachable.
void pollAll(const TQString &uid)
Bootstrap our presence data by polling all known apps.
TQString locate(const TQString &contactId, const TQString &protocol)
Obtain the KABC UID corresponding to the given IM address.
TQString context(const TQString &uid)
Obtain the given contact's current context (home, work, or any)
KIMIface_stub * stubForUid(const TQString &uid)
Get the app stub best able to reach this uid.
void sendFile(const TQString &uid, const KURL &sourceURL, const TQString &altFileName=TQString::null, uint fileSize=0)
Send a file to the contact.
bool addContact(const TQString &contactId, const TQString &protocol)
Add a new contact given its protocol specific identifier.
static KIMProxy * instance(DCOPClient *client)
Obtain an instance of KIMProxy.
void pollApp(const TQCString &appId)
Bootstrap our presence data for a newly registered app.
TQString preferredApp()
Get the name of the user's IM application of choice.
TQString presenceString(const TQString &uid)
Obtain the IM presence as a i18ned string for the specified contact.
TQString readEntry(const TQString &pKey, const TQString &aDefault=TQString::null) const
void setGroup(const TQString &group)
TQString toString() const
kdbgstream kdWarning(int area=0)
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)
const TDEShortcut & end()