00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kopeteprotocol.h"
00021
00022 #include <kdebug.h>
00023 #include <kaction.h>
00024 #include <klocale.h>
00025 #include <kjob.h>
00026
00027 #include "kopeteaccountmanager.h"
00028 #include "kopeteaccount.h"
00029 #include "kopetecontact.h"
00030 #include "kopeteglobal.h"
00031 #include "kopeteproperty.h"
00032 #include "kopetemetacontact.h"
00033
00034 namespace Kopete
00035 {
00036
00037 class Protocol::Private
00038 {
00039 public:
00040 bool unloading;
00041 Protocol::Capabilities capabilities;
00042
00043
00044
00045
00046 PropertyTmpl mStickLastSeen;
00047 PropertyTmpl mStickFullName;
00048
00049 Kopete::OnlineStatus accountNotConnectedStatus;
00050 };
00051
00052 Protocol::Protocol( const KComponentData &instance, QObject *parent )
00053 : Plugin( instance, parent )
00054 {
00055 d = new Private;
00056 d->mStickLastSeen = Global::Properties::self()->lastSeen();
00057 d->mStickFullName = Global::Properties::self()->fullName();
00058 d->unloading = false;
00059 d->accountNotConnectedStatus = Kopete::OnlineStatus( Kopete::OnlineStatus::Unknown, 0, this, Kopete::OnlineStatus::AccountOffline, QStringList(QString::fromLatin1( "account_offline_overlay" )), i18n( "Account Offline" ) );
00060 }
00061
00062 Protocol::~Protocol()
00063 {
00064
00065 foreach( Account *a , AccountManager::self()->accounts() )
00066 {
00067 if( a->protocol() == this )
00068 {
00069 kWarning( 14010 ) << "Deleting protocol with existing accounts! Did the account unloading go wrong? account: "
00070 << a->accountId() << endl;
00071
00072 delete a;
00073 }
00074 }
00075 delete d;
00076 }
00077
00078 Protocol::Capabilities Protocol::capabilities() const
00079 {
00080 return d->capabilities;
00081 }
00082
00083 void Protocol::setCapabilities( Protocol::Capabilities capabilities )
00084 {
00085 d->capabilities = capabilities;
00086 }
00087
00088
00089 Kopete::OnlineStatus Protocol::accountOfflineStatus() const
00090 {
00091 return d->accountNotConnectedStatus;
00092 }
00093
00094 void Protocol::slotAccountOnlineStatusChanged( Contact *self )
00095 {
00096 if ( !self || !self->account() || self->account()->isConnected())
00097 return;
00098
00099 disconnect( self, 0, this, 0 );
00100
00101 connect( self->account(), SIGNAL(destroyed( )),
00102 this, SLOT( slotAccountDestroyed( ) ) );
00103
00104 self->account()->deleteLater();
00105 }
00106
00107 void Protocol::slotAccountDestroyed( )
00108 {
00109 foreach( Account *a , AccountManager::self()->accounts() )
00110 {
00111 if( a->protocol() == this )
00112 {
00113
00114 return;
00115 }
00116 }
00117
00118
00119
00120
00121
00122 emit( readyForUnload() );
00123 }
00124
00125 void Protocol::aboutToUnload()
00126 {
00127
00128 d->unloading = true;
00129
00130 int accountcountcount=0;
00131
00132 foreach( Account *a , AccountManager::self()->accounts() )
00133 {
00134 if( a->protocol() == this )
00135 {
00136 accountcountcount++;
00137
00138 if ( a->myself() && a->myself()->isOnline() )
00139 {
00140 kDebug( 14010 ) << a->accountId() <<
00141 " is still connected, disconnecting..." << endl;
00142
00143 QObject::connect( a->myself(),
00144 SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus &, const Kopete::OnlineStatus & ) ),
00145 this, SLOT( slotAccountOnlineStatusChanged( Kopete::Contact * ) ) );
00146 a->disconnect();
00147 }
00148 else
00149 {
00150
00151 kDebug( 14010 ) << a->accountId() <<
00152 " is already disconnected, deleting..." << endl;
00153
00154 QObject::connect( a, SIGNAL( destroyed( ) ),
00155 this, SLOT( slotAccountDestroyed( ) ) );
00156 a->deleteLater();
00157 }
00158 }
00159 }
00160
00161 if( accountcountcount > 0 )
00162 {
00163
00164 emit readyForUnload();
00165 }
00166 }
00167
00168
00169
00170 void Protocol::slotMetaContactAboutToSave( MetaContact *metaContact )
00171 {
00172 QMap<QString, QString> serializedData, sd;
00173 QMap<QString, QString> addressBookData, ad;
00174 QMap<QString, QString>::Iterator it;
00175
00176
00177
00178 QListIterator<Contact *> cit(metaContact->contacts());
00179 while ( cit.hasNext() )
00180 {
00181 Contact *c = cit.next();
00182 if( c->protocol()->pluginId() != pluginId() )
00183 continue;
00184
00185 sd.clear();
00186 ad.clear();
00187
00188
00189
00190 sd[ QString::fromLatin1( "contactId" ) ] = c->contactId();
00191
00192 sd[ QString::fromLatin1( "displayName" ) ] = c->property(Global::Properties::self()->nickName()).value().toString();
00193 if(c->account())
00194 sd[ QString::fromLatin1( "accountId" ) ] = c->account()->accountId();
00195
00196
00197 QString index = c->protocol()->addressBookIndexField();
00198 if( !index.isEmpty() )
00199 ad[ index ] = c->contactId();
00200
00201 c->serializeProperties( sd );
00202 c->serialize( sd, ad );
00203
00204
00205 for( it = sd.begin(); it != sd.end(); ++it )
00206 {
00207
00208
00209
00210
00211
00212
00213 if( serializedData.contains( it.key() ) )
00214 serializedData[ it.key() ] = serializedData[ it.key() ] + QChar( 0xE000 ) + it.value();
00215 else
00216 serializedData[ it.key() ] = it.value();
00217 }
00218
00219 for( it = ad.begin(); it != ad.end(); ++it )
00220 {
00221 if( addressBookData.contains( it.key() ) )
00222 addressBookData[ it.key() ] = addressBookData[ it.key() ] + QChar( 0xE000 ) + it.value();
00223 else
00224 addressBookData[ it.key() ] = it.value();
00225 }
00226 }
00227
00228
00229
00230 metaContact->setPluginData( this, serializedData );
00231
00232 for( it = addressBookData.begin(); it != addressBookData.end(); ++it )
00233 {
00234
00235
00236
00237
00238
00239
00240
00241
00242 if( it.key().startsWith( QString::fromLatin1( "messaging/" ) ) )
00243 {
00244 metaContact->setAddressBookField( this, it.key(), QString::fromLatin1( "All" ), it.value() );
00245
00246 }
00247 else
00248 metaContact->setAddressBookField( this, QString::fromLatin1( "kopete" ), it.key(), it.value() );
00249 }
00250 }
00251
00252 void Protocol::deserialize( MetaContact *metaContact, const QMap<QString, QString> &data )
00253 {
00254
00255
00256
00257 QMap<QString, QStringList> serializedData;
00258 QMap<QString, QStringList::Iterator> serializedDataIterators;
00259 QMap<QString, QString>::ConstIterator it;
00260 for( it = data.begin(); it != data.end(); ++it )
00261 {
00262 serializedData[ it.key() ] = it.value().split( QChar( 0xE000 ), QString::KeepEmptyParts );
00263 serializedDataIterators[ it.key() ] = serializedData[ it.key() ].begin();
00264 }
00265
00266 int count = serializedData[QString::fromLatin1("contactId")].count();
00267
00268
00269 for( int i = 0; i < count ; i++ )
00270 {
00271 QMap<QString, QString> sd;
00272 #ifdef __GNUC__
00273 #warning write this properly
00274 #endif
00275 #if 0
00276 QMap<QString, QStringList::Iterator>::Iterator serializedDataIt;
00277 for( serializedDataIt = serializedDataIterators.begin(); serializedDataIt != serializedDataIterators.end(); ++serializedDataIt )
00278 {
00279 sd[ serializedDataIt.key() ] = *( serializedDataIt.data() );
00280 ++( serializedDataIt.data() );
00281 }
00282
00283 #else
00284 QMap<QString, QStringList>::Iterator serializedDataIt;
00285 QMap<QString, QStringList>::Iterator serializedDataItEnd = serializedData.end();
00286 for( serializedDataIt = serializedData.begin(); serializedDataIt != serializedDataItEnd; ++serializedDataIt )
00287 {
00288 QStringList sl=serializedDataIt.value();
00289 if(sl.count()>i)
00290 sd[ serializedDataIt.key() ] = sl[i];
00291 }
00292
00293
00294 #endif
00295
00296 const QString& accountId=sd[ QString::fromLatin1( "accountId" ) ];
00297
00298
00299
00300 if(accountId == sd[ QString::fromLatin1( "contactId" ) ] )
00301 {
00302 kDebug( 14010 ) << "Myself contact was on the contactlist.xml for account " << accountId << ". Ignore it";
00303 continue;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 QMap<QString, QString> ad;
00316
00317
00318 #if 0
00319 QStringList kabcFields = addressBookFields();
00320 for( QStringList::Iterator fieldIt = kabcFields.begin(); fieldIt != kabcFields.end(); ++fieldIt )
00321 {
00322
00323
00324
00325
00326 if( ( *fieldIt ).startsWith( QString::fromLatin1( "messaging/" ) ) )
00327 ad[ *fieldIt ] = metaContact->addressBookField( this, *fieldIt, QString::fromLatin1( "All" ) );
00328 else
00329 ad[ *fieldIt ] = metaContact->addressBookField( this, QString::fromLatin1( "kopete" ), *fieldIt );
00330 }
00331
00332
00333
00334
00335 if( accountId.isNull() )
00336 {
00337 Q3Dict<Account> accounts = AccountManager::self()->accounts( this );
00338 if ( accounts.count() > 0 )
00339 {
00340 sd[ QString::fromLatin1( "accountId" ) ] = Q3DictIterator<Account>( accounts ).currentKey();
00341 }
00342 else
00343 {
00344 kWarning( 14010 ) <<
00345 "No account available and account not set in " \
00346 "contactlist.xml either!" << endl
00347 << "Not deserializing this contact." << endl;
00348 return;
00349 }
00350 }
00351 #endif
00352
00353
00354 Contact *c = deserializeContact( metaContact, sd, ad );
00355 if (c)
00356 c->deserializeProperties( sd );
00357 }
00358 }
00359
00360 Contact *Protocol::deserializeContact(
00361 MetaContact * metaContact,
00362 const QMap<QString, QString> & serializedData,
00363 const QMap<QString, QString> & addressBookData )
00364 {
00365 Q_UNUSED( metaContact )
00366 Q_UNUSED( serializedData )
00367 Q_UNUSED( addressBookData )
00368
00369 return 0;
00370 }
00371
00372 KJob *Protocol::createProtocolTask(const QString &taskType)
00373 {
00374
00375 Q_UNUSED( taskType )
00376 return 0;
00377 }
00378
00379 bool Protocol::validatePassword( const QString & password ) const
00380 {
00381 Q_UNUSED( password )
00382 return true;
00383 }
00384
00385 }
00386
00387 #include "kopeteprotocol.moc"
00388