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 <tdeemailsettings.h>
00045 #include <tdeapplication.h>
00046 #include <tdelocale.h>
00047 #include <kdebug.h>
00048 #include <tdeconfig.h>
00049 #include <kuser.h>
00050 #include <dcopclient.h>
00051
00052 #include <tqregexp.h>
00053
00054 #include <assert.h>
00055
00056 using namespace KPIM;
00057
00058 static TQCString newDCOPObjectName()
00059 {
00060 static int s_count = 0;
00061 TQCString name( "KPIM::IdentityManager" );
00062 if ( s_count++ ) {
00063 name += '-';
00064 name += TQCString().setNum( s_count );
00065 }
00066 return name;
00067 }
00068
00069 IdentityManager::IdentityManager( bool readonly, TQObject * parent, const char * name )
00070 : ConfigManager( parent, name ), DCOPObject( newDCOPObjectName() )
00071 {
00072 mReadOnly = readonly;
00073 mConfig = new TDEConfig( "emailidentities", readonly );
00074 readConfig(mConfig);
00075 if ( mIdentities.isEmpty() ) {
00076 kdDebug(5006) << "emailidentities is empty -> convert from kmailrc" << endl;
00077
00078
00079 TDEConfig 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(TQCString,TQCString)",
00095 "slotIdentitiesChanged(TQCString,TQCString)", 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 TQValueList<uint> seenUOIDs;
00112 for ( TQValueList<Identity>::ConstIterator it = mIdentities.begin() ;
00113 it != mIdentities.end() ; ++it )
00114 seenUOIDs << (*it).uoid();
00115
00116 TQValueList<uint> changedUOIDs;
00117
00118 for ( TQValueList<Identity>::ConstIterator it = mShadowIdentities.begin() ;
00119 it != mShadowIdentities.end() ; ++it ) {
00120 TQValueList<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 ( TQValueList<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 ( TQValueList<uint>::ConstIterator it = changedUOIDs.begin() ;
00150 it != changedUOIDs.end() ; ++it )
00151 emit changed( *it );
00152
00153 emit ConfigManager::changed();
00154
00155
00156
00157
00158 TQByteArray data; TQDataStream arg( data, IO_WriteOnly );
00159 arg << kapp->dcopClient()->appId();
00160 arg << DCOPObject::objId();
00161 kapp->dcopClient()->emitDCOPSignal( "KPIM::IdentityManager", "identitiesChanged(TQCString,TQCString)", 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 TQStringList IdentityManager::identities() const
00175 {
00176 TQStringList result;
00177 for ( ConstIterator it = mIdentities.begin() ;
00178 it != mIdentities.end() ; ++it )
00179 result << (*it).identityName();
00180 return result;
00181 }
00182
00183 TQStringList IdentityManager::shadowIdentities() const
00184 {
00185 TQStringList 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 TQStringList identities = groupList(mConfig);
00198 for ( TQStringList::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 TDEConfigGroup cg( mConfig, TQString::fromLatin1("Identity #%1").arg(i) );
00205 (*it).writeConfig( &cg );
00206 if ( (*it).isDefault() ) {
00207
00208 TDEConfigGroup 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).primaryEmailAddress() );
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(TDEConfigBase* config) {
00224 mIdentities.clear();
00225
00226 TQStringList identities = groupList(config);
00227 if ( identities.isEmpty() ) return;
00228
00229 TDEConfigGroup general( config, "General" );
00230 uint defaultIdentity = general.readUnsignedNumEntry( configKeyDefaultIdentity );
00231 bool haveDefault = false;
00232
00233 for ( TQStringList::Iterator group = identities.begin() ;
00234 group != identities.end() ; ++group ) {
00235 TDEConfigGroup 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 TQStringList IdentityManager::groupList(TDEConfigBase* config) const {
00253 return config->groupList().grep( TQRegExp("^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 TQString & 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 TQString & 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 TQString & addresses ) const
00306 {
00307 const TQStringList addressList = KPIM::splitEmailAddrList( addresses );
00308 for( TQStringList::ConstIterator addrIt = addressList.begin();
00309 addrIt != addressList.end(); ++addrIt ) {
00310 const TQString addr = KPIM::getEmailAddress( *addrIt ).lower();
00311 for ( ConstIterator it = begin() ; it != end() ; ++it ) {
00312 const Identity & id = *it;
00313 if ( id.matchesEmailAddress( addr ) ) {
00314 return id;
00315 }
00316 }
00317 }
00318 return Identity::null();
00319 }
00320
00321 bool IdentityManager::thatIsMe( const TQString & addressList ) const {
00322 return !identityForAddress( addressList ).isNull();
00323 }
00324
00325 Identity & IdentityManager::modifyIdentityForName( const TQString & name )
00326 {
00327 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00328 if ( (*it).identityName() == name ) return (*it);
00329 kdWarning( 5006 ) << "IdentityManager::identityForName() used as newFromScratch() replacement!"
00330 << "\n name == \"" << name << "\"" << endl;
00331 return newFromScratch( name );
00332 }
00333
00334 Identity & IdentityManager::modifyIdentityForUoid( uint uoid )
00335 {
00336 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00337 if ( (*it).uoid() == uoid ) return (*it);
00338 kdWarning( 5006 ) << "IdentityManager::identityForUoid() used as newFromScratch() replacement!"
00339 << "\n uoid == \"" << uoid << "\"" << endl;
00340 return newFromScratch( i18n("Unnamed") );
00341 }
00342
00343 const Identity & IdentityManager::defaultIdentity() const {
00344 for ( ConstIterator it = begin() ; it != end() ; ++it )
00345 if ( (*it).isDefault() ) return (*it);
00346 (mIdentities.isEmpty() ? kdFatal( 5006 ) : kdWarning( 5006 ) )
00347 << "IdentityManager: No default identity found!" << endl;
00348 return *begin();
00349 }
00350
00351 bool IdentityManager::setAsDefault( const TQString & name ) {
00352
00353 TQStringList names = shadowIdentities();
00354 if ( names.find( name ) == names.end() ) return false;
00355
00356 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00357 (*it).setIsDefault( (*it).identityName() == name );
00358
00359 sort();
00360 return true;
00361 }
00362
00363 bool IdentityManager::setAsDefault( uint uoid ) {
00364
00365 bool found = false;
00366 for ( ConstIterator it = mShadowIdentities.begin() ;
00367 it != mShadowIdentities.end() ; ++it )
00368 if ( (*it).uoid() == uoid ) {
00369 found = true;
00370 break;
00371 }
00372 if ( !found ) return false;
00373
00374
00375 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00376 (*it).setIsDefault( (*it).uoid() == uoid );
00377
00378 sort();
00379 return true;
00380 }
00381
00382 bool IdentityManager::removeIdentity( const TQString & name ) {
00383 for ( Iterator it = modifyBegin() ; it != modifyEnd() ; ++it )
00384 if ( (*it).identityName() == name ) {
00385 bool removedWasDefault = (*it).isDefault();
00386 mShadowIdentities.remove( it );
00387 if ( removedWasDefault )
00388 mShadowIdentities.first().setIsDefault( true );
00389 return true;
00390 }
00391 return false;
00392 }
00393
00394 Identity & IdentityManager::newFromScratch( const TQString & name ) {
00395 return newFromExisting( Identity( name ) );
00396 }
00397
00398 Identity & IdentityManager::newFromControlCenter( const TQString & name ) {
00399 KEMailSettings es;
00400 es.setProfile( es.defaultProfileName() );
00401
00402 return newFromExisting( Identity( name,
00403 es.getSetting( KEMailSettings::RealName ),
00404 es.getSetting( KEMailSettings::EmailAddress ),
00405 es.getSetting( KEMailSettings::Organization ),
00406 es.getSetting( KEMailSettings::ReplyToAddress )
00407 ) );
00408 }
00409
00410 Identity & IdentityManager::newFromExisting( const Identity & other,
00411 const TQString & name ) {
00412 mShadowIdentities << other;
00413 Identity & result = mShadowIdentities.last();
00414 result.setIsDefault( false );
00415 result.setUoid( newUoid() );
00416 if ( !name.isNull() )
00417 result.setIdentityName( name );
00418 return result;
00419 }
00420
00421 void IdentityManager::createDefaultIdentity() {
00422 TQString fullName, emailAddress;
00423 bool done = false;
00424
00425
00426 createDefaultIdentity( fullName, emailAddress );
00427
00428
00429 if ( fullName.isEmpty() && emailAddress.isEmpty() ) {
00430 KEMailSettings emailSettings;
00431 fullName = emailSettings.getSetting( KEMailSettings::RealName );
00432 emailAddress = emailSettings.getSetting( KEMailSettings::EmailAddress );
00433
00434 if ( !fullName.isEmpty() && !emailAddress.isEmpty() ) {
00435 newFromControlCenter( i18n("Default") );
00436 done = true;
00437 } else {
00438
00439 KUser user;
00440 if ( fullName.isEmpty() )
00441 fullName = user.fullName();
00442 if ( emailAddress.isEmpty() ) {
00443 emailAddress = user.loginName();
00444 if ( !emailAddress.isEmpty() ) {
00445 TDEConfigGroup general( mConfig, "General" );
00446 TQString defaultdomain = general.readEntry( "Default domain" );
00447 if( !defaultdomain.isEmpty() ) {
00448 emailAddress += '@' + defaultdomain;
00449 }
00450 else {
00451 emailAddress = TQString();
00452 }
00453 }
00454 }
00455 }
00456 }
00457
00458 if ( !done )
00459 mShadowIdentities << Identity( i18n("Default"), fullName, emailAddress );
00460
00461 mShadowIdentities.last().setIsDefault( true );
00462 mShadowIdentities.last().setUoid( newUoid() );
00463 if ( mReadOnly )
00464 mIdentities = mShadowIdentities;
00465 }
00466
00467 int IdentityManager::newUoid()
00468 {
00469 int uoid;
00470
00471
00472 TQValueList<uint> usedUOIDs;
00473 for ( TQValueList<Identity>::ConstIterator it = mIdentities.begin() ;
00474 it != mIdentities.end() ; ++it )
00475 usedUOIDs << (*it).uoid();
00476
00477 if ( hasPendingChanges() ) {
00478
00479
00480 for ( TQValueList<Identity>::ConstIterator it = mShadowIdentities.begin() ;
00481 it != mShadowIdentities.end() ; ++it ) {
00482 usedUOIDs << (*it).uoid();
00483 }
00484 }
00485
00486 usedUOIDs << 0;
00487
00488
00489 do {
00490 uoid = kapp->random();
00491 } while ( usedUOIDs.find( uoid ) != usedUOIDs.end() );
00492
00493 return uoid;
00494 }
00495
00496 TQStringList KPIM::IdentityManager::allEmails() const
00497 {
00498 TQStringList lst;
00499 for ( ConstIterator it = begin() ; it != end() ; ++it ) {
00500 lst << (*it).primaryEmailAddress();
00501 }
00502 return lst;
00503 }
00504
00505 void KPIM::IdentityManager::slotIdentitiesChanged( TQCString appId, TQCString objId )
00506 {
00507
00508
00509 if ( kapp->dcopClient()->appId() != appId || DCOPObject::objId() != objId ) {
00510 mConfig->reparseConfiguration();
00511 Q_ASSERT( !hasPendingChanges() );
00512 readConfig( mConfig );
00513 }
00514 }
00515
00516 #include "identitymanager.moc"