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