00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 static const char configKeyDefaultIdentity[] = "Default Identity";
00034
00035 #ifdef HAVE_CONFIG_H
00036 #include <config.h>
00037 #endif
00038
00039 #include "identitymanager.h"
00040
00041 #include "identity.h"
00042 #include <libemailfunctions/email.h>
00043
00044 #include <kemailsettings.h>
00045 #include <kapplication.h>
00046 #include <klocale.h>
00047 #include <kdebug.h>
00048 #include <kconfig.h>
00049 #include <kuser.h>
00050 #include <dcopclient.h>
00051
00052 #include <qregexp.h>
00053
00054 #include <assert.h>
00055
00056 using namespace KPIM;
00057
00058 static QCString newDCOPObjectName()
00059 {
00060 static int s_count = 0;
00061 QCString name( "KPIM::IdentityManager" );
00062 if ( s_count++ ) {
00063 name += '-';
00064 name += QCString().setNum( s_count );
00065 }
00066 return name;
00067 }
00068
00069 IdentityManager::IdentityManager( bool readonly, QObject * parent, const char * name )
00070 : ConfigManager( parent, name ), DCOPObject( newDCOPObjectName() )
00071 {
00072 mReadOnly = readonly;
00073 mConfig = new KConfig( "emailidentities", readonly );
00074 readConfig(mConfig);
00075 if ( mIdentities.isEmpty() ) {
00076 kdDebug(5006) << "emailidentities is empty -> convert from kmailrc" << endl;
00077
00078
00079 KConfig kmailConf( "kmailrc", true );
00080 readConfig( &kmailConf );
00081 }
00082
00083 if ( mIdentities.isEmpty() ) {
00084 kdDebug( 5006 ) << "IdentityManager: No identity found. Creating default." << endl;
00085 createDefaultIdentity();
00086 commit();
00087 }
00088
00089 if ( KEMailSettings().getSetting( KEMailSettings::EmailAddress ).isEmpty() ) {
00090 writeConfig();
00091 }
00092
00093
00094 if ( !connectDCOPSignal( 0, "KPIM::IdentityManager", "identitiesChanged(QCString,QCString)",
00095 "slotIdentitiesChanged(QCString,QCString)", false ) )
00096 kdError(5650) << "IdentityManager: connection to identitiesChanged failed" << endl;
00097 }
00098
00099 IdentityManager::~IdentityManager()
00100 {
00101 kdWarning( hasPendingChanges(), 5006 )
00102 << "IdentityManager: There were uncommitted changes!" << endl;
00103 delete mConfig;
00104 }
00105
00106 void IdentityManager::commit()
00107 {
00108
00109 if ( !hasPendingChanges() || mReadOnly ) return;
00110
00111 QValueList<uint> seenUOIDs;
00112 for ( QValueList<Identity>::ConstIterator it = mIdentities.begin() ;
00113 it != mIdentities.end() ; ++it )
00114 seenUOIDs << (*it).uoid();
00115
00116 QValueList<uint> changedUOIDs;
00117
00118 for ( QValueList<Identity>::ConstIterator it = mShadowIdentities.begin() ;
00119 it != mShadowIdentities.end() ; ++it ) {
00120 QValueList<uint>::Iterator uoid = seenUOIDs.find( (*it).uoid() );
00121 if ( uoid != seenUOIDs.end() ) {
00122 const Identity & orig = identityForUoid( *uoid );
00123 if ( *it != orig ) {
00124
00125 kdDebug( 5006 ) << "emitting changed() for identity " << *uoid << endl;
00126 emit changed( *it );
00127 changedUOIDs << *uoid;
00128 }
00129 seenUOIDs.remove( uoid );
00130 } else {
00131
00132 kdDebug( 5006 ) << "emitting added() for identity " << (*it).uoid() << endl;
00133 emit added( *it );
00134 }
00135 }
00136
00137
00138 for ( QValueList<uint>::ConstIterator it = seenUOIDs.begin() ;
00139 it != seenUOIDs.end() ; ++it ) {
00140 kdDebug( 5006 ) << "emitting deleted() for identity " << (*it) << endl;
00141 emit deleted( *it );
00142 }
00143
00144 mIdentities = mShadowIdentities;
00145 writeConfig();
00146
00147
00148
00149 for ( QValueList<uint>::ConstIterator it = changedUOIDs.begin() ;
00150 it != changedUOIDs.end() ; ++it )
00151 emit changed( *it );
00152
00153 emit ConfigManager::changed();
00154
00155
00156
00157
00158 QByteArray data; QDataStream arg( data, IO_WriteOnly );
00159 arg << kapp->dcopClient()->appId();
00160 arg << DCOPObject::objId();
00161 kapp->dcopClient()->emitDCOPSignal( "KPIM::IdentityManager", "identitiesChanged(QCString,QCString)", data );
00162 }
00163
00164 void IdentityManager::rollback()
00165 {
00166 mShadowIdentities = mIdentities;
00167 }
00168
00169 bool IdentityManager::hasPendingChanges() const
00170 {
00171 return mIdentities != mShadowIdentities;
00172 }
00173
00174 QStringList IdentityManager::identities() const
00175 {
00176 QStringList result;
00177 for ( ConstIterator it = mIdentities.begin() ;
00178 it != mIdentities.end() ; ++it )
00179 result << (*it).identityName();
00180 return result;
00181 }
00182
00183 QStringList IdentityManager::shadowIdentities() const
00184 {
00185 QStringList result;
00186 for ( ConstIterator it = mShadowIdentities.begin() ;
00187 it != mShadowIdentities.end() ; ++it )
00188 result << (*it).identityName();
00189 return result;
00190 }
00191
00192 void IdentityManager::sort() {
00193 qHeapSort( mShadowIdentities );
00194 }
00195
00196 void IdentityManager::writeConfig() const {
00197 QStringList identities = groupList(mConfig);
00198 for ( QStringList::Iterator group = identities.begin() ;
00199 group != identities.end() ; ++group )
00200 mConfig->deleteGroup( *group );
00201 int i = 0;
00202 for ( ConstIterator it = mIdentities.begin() ;
00203 it != mIdentities.end() ; ++it, ++i ) {
00204 KConfigGroup cg( mConfig, QString::fromLatin1("Identity #%1").arg(i) );
00205 (*it).writeConfig( &cg );
00206 if ( (*it).isDefault() ) {
00207
00208 KConfigGroup general( mConfig, "General" );
00209 general.writeEntry( configKeyDefaultIdentity, (*it).uoid() );
00210
00211
00212 KEMailSettings es;
00213 es.setSetting( KEMailSettings::RealName, (*it).fullName() );
00214 es.setSetting( KEMailSettings::EmailAddress, (*it).emailAddr() );
00215 es.setSetting( KEMailSettings::Organization, (*it).organization() );
00216 es.setSetting( KEMailSettings::ReplyToAddress, (*it).replyToAddr() );
00217 }
00218 }
00219 mConfig->sync();
00220
00221 }
00222
00223 void IdentityManager::readConfig(KConfigBase* config) {
00224 mIdentities.clear();
00225
00226 QStringList identities = groupList(config);
00227 if ( identities.isEmpty() ) return;
00228
00229 KConfigGroup general( config, "General" );
00230 uint defaultIdentity = general.readUnsignedNumEntry( configKeyDefaultIdentity );
00231 bool haveDefault = false;
00232
00233 for ( QStringList::Iterator group = identities.begin() ;
00234 group != identities.end() ; ++group ) {
00235 KConfigGroup configGroup( config, *group );
00236 mIdentities << Identity();
00237 mIdentities.last().readConfig( &configGroup );
00238 if ( !haveDefault && mIdentities.last().uoid() == defaultIdentity ) {
00239 haveDefault = true;
00240 mIdentities.last().setIsDefault( true );
00241 }
00242 }
00243 if ( !haveDefault ) {
00244 kdWarning( 5006 ) << "IdentityManager: There was no default identity. Marking first one as default." << endl;
00245 mIdentities.first().setIsDefault( true );
00246 }
00247 qHeapSort( mIdentities );
00248
00249 mShadowIdentities = mIdentities;
00250 }
00251
00252 QStringList IdentityManager::groupList(KConfigBase* config) const {
00253 return config->groupList().grep( QRegExp("^Identity #\\d+$") );
00254 }
00255
00256 IdentityManager::ConstIterator IdentityManager::begin() const {
00257 return mIdentities.begin();
00258 }
00259
00260 IdentityManager::ConstIterator IdentityManager::end() const {
00261 return mIdentities.end();
00262 }
00263
00264 IdentityManager::Iterator IdentityManager::modifyBegin() {
00265 return mShadowIdentities.begin();
00266 }
00267
00268 IdentityManager::Iterator IdentityManager::modifyEnd() {
00269 return mShadowIdentities.end();
00270 }
00271
00272 const Identity & IdentityManager::identityForName( const QString & name ) const
00273 {
00274 kdWarning( 5006 )
00275 << "deprecated method IdentityManager::identityForName() called!" << endl;
00276 for ( ConstIterator it = begin() ; it != end() ; ++it )
00277 if ( (*it).identityName() == name ) return (*it);
00278 return Identity::null();
00279 }
00280
00281 const Identity & IdentityManager::identityForUoid( uint uoid ) const {
00282 for ( ConstIterator it = begin() ; it != end() ; ++it )
00283 if ( (*it).uoid() == uoid ) return (*it);
00284 return Identity::null();
00285 }
00286
00287 const Identity & IdentityManager::identityForNameOrDefault( const QString & name ) const
00288 {
00289 const Identity & ident = identityForName( name );
00290 if ( ident.isNull() )
00291 return defaultIdentity();
00292 else
00293 return ident;
00294 }
00295
00296 const Identity & IdentityManager::identityForUoidOrDefault( uint uoid ) const
00297 {
00298 const Identity & ident = identityForUoid( uoid );
00299 if ( ident.isNull() )
00300 return defaultIdentity();
00301 else
00302 return ident;
00303 }
00304
00305 const Identity & IdentityManager::identityForAddress( const QString & addresses ) const
00306 {
00307 QStringList addressList = KPIM::splitEmailAddrList( addresses );
00308 for ( ConstIterator it = begin() ; it != end() ; ++it ) {
00309 for( QStringList::ConstIterator addrIt = addressList.begin();
00310 addrIt != addressList.end(); ++addrIt ) {
00311
00312
00313
00314 if( (*it).emailAddr().lower() ==
00315 KPIM::getEmailAddress( *addrIt ).lower() ) {
00316 return (*it);
00317 }
00318 }
00319 }
00320 return Identity::null();
00321 }
00322
00323 bool IdentityManager::thatIsMe( const QString & addressList ) const {
00324 return !identityForAddress( addressList ).isNull();
00325 }
00326
00327 Identity & IdentityManager::modifyIdentityForName( const QString & name )
00328 {
00329 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00330 if ( (*it).identityName() == name ) return (*it);
00331 kdWarning( 5006 ) << "IdentityManager::identityForName() used as newFromScratch() replacement!"
00332 << "\n name == \"" << name << "\"" << endl;
00333 return newFromScratch( name );
00334 }
00335
00336 Identity & IdentityManager::modifyIdentityForUoid( uint uoid )
00337 {
00338 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00339 if ( (*it).uoid() == uoid ) return (*it);
00340 kdWarning( 5006 ) << "IdentityManager::identityForUoid() used as newFromScratch() replacement!"
00341 << "\n uoid == \"" << uoid << "\"" << endl;
00342 return newFromScratch( i18n("Unnamed") );
00343 }
00344
00345 const Identity & IdentityManager::defaultIdentity() const {
00346 for ( ConstIterator it = begin() ; it != end() ; ++it )
00347 if ( (*it).isDefault() ) return (*it);
00348 (mIdentities.isEmpty() ? kdFatal( 5006 ) : kdWarning( 5006 ) )
00349 << "IdentityManager: No default identity found!" << endl;
00350 return *begin();
00351 }
00352
00353 bool IdentityManager::setAsDefault( const QString & name ) {
00354
00355 QStringList names = shadowIdentities();
00356 if ( names.find( name ) == names.end() ) return false;
00357
00358 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00359 (*it).setIsDefault( (*it).identityName() == name );
00360
00361 sort();
00362 return true;
00363 }
00364
00365 bool IdentityManager::setAsDefault( uint uoid ) {
00366
00367 bool found = false;
00368 for ( ConstIterator it = mShadowIdentities.begin() ;
00369 it != mShadowIdentities.end() ; ++it )
00370 if ( (*it).uoid() == uoid ) {
00371 found = true;
00372 break;
00373 }
00374 if ( !found ) return false;
00375
00376
00377 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00378 (*it).setIsDefault( (*it).uoid() == uoid );
00379
00380 sort();
00381 return true;
00382 }
00383
00384 bool IdentityManager::removeIdentity( const QString & name ) {
00385 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00386 if ( (*it).identityName() == name ) {
00387 bool removedWasDefault = (*it).isDefault();
00388 mShadowIdentities.remove( it );
00389 if ( removedWasDefault )
00390 mShadowIdentities.first().setIsDefault( true );
00391 return true;
00392 }
00393 return false;
00394 }
00395
00396 Identity & IdentityManager::newFromScratch( const QString & name ) {
00397 return newFromExisting( Identity( name ) );
00398 }
00399
00400 Identity & IdentityManager::newFromControlCenter( const QString & name ) {
00401 KEMailSettings es;
00402 es.setProfile( es.defaultProfileName() );
00403
00404 return newFromExisting( Identity( name,
00405 es.getSetting( KEMailSettings::RealName ),
00406 es.getSetting( KEMailSettings::EmailAddress ),
00407 es.getSetting( KEMailSettings::Organization ),
00408 es.getSetting( KEMailSettings::ReplyToAddress )
00409 ) );
00410 }
00411
00412 Identity & IdentityManager::newFromExisting( const Identity & other,
00413 const QString & name ) {
00414 mShadowIdentities << other;
00415 Identity & result = mShadowIdentities.last();
00416 result.setIsDefault( false );
00417 result.setUoid( newUoid() );
00418 if ( !name.isNull() )
00419 result.setIdentityName( name );
00420 return result;
00421 }
00422
00423 void IdentityManager::createDefaultIdentity() {
00424 QString fullName, emailAddress;
00425 bool done = false;
00426
00427
00428 createDefaultIdentity( fullName, emailAddress );
00429
00430
00431 if ( fullName.isEmpty() && emailAddress.isEmpty() ) {
00432 KEMailSettings emailSettings;
00433 fullName = emailSettings.getSetting( KEMailSettings::RealName );
00434 emailAddress = emailSettings.getSetting( KEMailSettings::EmailAddress );
00435
00436 if ( !fullName.isEmpty() && !emailAddress.isEmpty() ) {
00437 newFromControlCenter( i18n("Default") );
00438 done = true;
00439 } else {
00440
00441 KUser user;
00442 if ( fullName.isEmpty() )
00443 fullName = user.fullName();
00444 if ( emailAddress.isEmpty() ) {
00445 emailAddress = user.loginName();
00446 if ( !emailAddress.isEmpty() ) {
00447 KConfigGroup general( mConfig, "General" );
00448 QString defaultdomain = general.readEntry( "Default domain" );
00449 if( !defaultdomain.isEmpty() ) {
00450 emailAddress += '@' + defaultdomain;
00451 }
00452 else {
00453 emailAddress = QString::null;
00454 }
00455 }
00456 }
00457 }
00458 }
00459
00460 if ( !done )
00461 mShadowIdentities << Identity( i18n("Default"), fullName, emailAddress );
00462
00463 mShadowIdentities.last().setIsDefault( true );
00464 mShadowIdentities.last().setUoid( newUoid() );
00465 if ( mReadOnly )
00466 mIdentities = mShadowIdentities;
00467 }
00468
00469 int IdentityManager::newUoid()
00470 {
00471 int uoid;
00472
00473
00474 QValueList<uint> usedUOIDs;
00475 for ( QValueList<Identity>::ConstIterator it = mIdentities.begin() ;
00476 it != mIdentities.end() ; ++it )
00477 usedUOIDs << (*it).uoid();
00478
00479 if ( hasPendingChanges() ) {
00480
00481
00482 for ( QValueList<Identity>::ConstIterator it = mShadowIdentities.begin() ;
00483 it != mShadowIdentities.end() ; ++it ) {
00484 usedUOIDs << (*it).uoid();
00485 }
00486 }
00487
00488 usedUOIDs << 0;
00489
00490
00491 do {
00492 uoid = kapp->random();
00493 } while ( usedUOIDs.find( uoid ) != usedUOIDs.end() );
00494
00495 return uoid;
00496 }
00497
00498 QStringList KPIM::IdentityManager::allEmails() const
00499 {
00500 QStringList lst;
00501 for ( ConstIterator it = begin() ; it != end() ; ++it ) {
00502 lst << (*it).emailAddr();
00503 }
00504 return lst;
00505 }
00506
00507 void KPIM::IdentityManager::slotIdentitiesChanged( QCString appId, QCString objId )
00508 {
00509
00510
00511 if ( kapp->dcopClient()->appId() != appId || DCOPObject::objId() != objId ) {
00512 mConfig->reparseConfiguration();
00513 Q_ASSERT( !hasPendingChanges() );
00514 readConfig( mConfig );
00515 }
00516 }
00517
00518 #include "identitymanager.moc"