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 QString IdentityManager::makeUnique( const QString &name ) const
00101 {
00102 int suffix = 1;
00103 QString result = name;
00104 while ( identities().contains( result ) ) {
00105 result = i18nc( "%1: name; %2: number appended to it to make it unique "
00106 "among a list of names", "%1 #%2",
00107 name, suffix );
00108 suffix++;
00109 }
00110 return result;
00111 }
00112
00113 bool IdentityManager::isUnique( const QString &name ) const
00114 {
00115 return !identities().contains( name );
00116 }
00117
00118 void IdentityManager::commit()
00119 {
00120
00121 if ( !hasPendingChanges() || mReadOnly ) {
00122 return;
00123 }
00124
00125 QList<uint> seenUOIDs;
00126 for ( QList<Identity>::ConstIterator it = mIdentities.constBegin();
00127 it != mIdentities.constEnd(); ++it ) {
00128 seenUOIDs << (*it).uoid();
00129 }
00130
00131 QList<uint> changedUOIDs;
00132
00133 for ( QList<Identity>::ConstIterator it = mShadowIdentities.constBegin();
00134 it != mShadowIdentities.constEnd(); ++it ) {
00135 int index = seenUOIDs.indexOf( (*it).uoid() );
00136 if ( index != -1 ) {
00137 uint uoid = seenUOIDs.at( index );
00138 const Identity &orig = identityForUoid( uoid );
00139 if ( *it != orig ) {
00140
00141 kDebug( 5325 ) << "emitting changed() for identity" << uoid;
00142 emit changed(*it);
00143 changedUOIDs << uoid;
00144 }
00145 seenUOIDs.removeAll( uoid );
00146 } else {
00147
00148 kDebug( 5325 ) << "emitting added() for identity" << (*it).uoid();
00149 emit added(*it);
00150 }
00151 }
00152
00153
00154 for ( QList<uint>::ConstIterator it = seenUOIDs.constBegin();
00155 it != seenUOIDs.constEnd(); ++it ) {
00156 kDebug( 5325 ) << "emitting deleted() for identity" << (*it);
00157 emit deleted(*it);
00158 }
00159
00160 mIdentities = mShadowIdentities;
00161 writeConfig();
00162
00163
00164
00165
00166 for ( QList<uint>::ConstIterator it = changedUOIDs.constBegin();
00167 it != changedUOIDs.constEnd(); ++it )
00168 emit changed(*it);
00169
00170 emit changed();
00171
00172
00173 emit identitiesChanged( QDBusConnection::sessionBus().baseService() );
00174 }
00175
00176 void IdentityManager::rollback()
00177 {
00178 mShadowIdentities = mIdentities;
00179 }
00180
00181 bool IdentityManager::hasPendingChanges() const
00182 {
00183 return mIdentities != mShadowIdentities;
00184 }
00185
00186 QStringList IdentityManager::identities() const
00187 {
00188 QStringList result;
00189 for ( ConstIterator it = mIdentities.begin();
00190 it != mIdentities.end(); ++it )
00191 result << (*it).identityName();
00192 return result;
00193 }
00194
00195 QStringList IdentityManager::shadowIdentities() const
00196 {
00197 QStringList result;
00198 for ( ConstIterator it = mShadowIdentities.begin();
00199 it != mShadowIdentities.end(); ++it )
00200 result << (*it).identityName();
00201 return result;
00202 }
00203
00204 void IdentityManager::sort()
00205 {
00206 qSort( mShadowIdentities );
00207 }
00208
00209 void IdentityManager::writeConfig() const
00210 {
00211 const QStringList identities = groupList( mConfig );
00212 for ( QStringList::const_iterator group = identities.begin();
00213 group != identities.end(); ++group )
00214 mConfig->deleteGroup( *group );
00215 int i = 0;
00216 for ( ConstIterator it = mIdentities.begin();
00217 it != mIdentities.end(); ++it, ++i ) {
00218 KConfigGroup cg( mConfig, QString::fromLatin1( "Identity #%1" ).arg( i ) );
00219 (*it).writeConfig( cg );
00220 if ( (*it).isDefault() ) {
00221
00222 KConfigGroup general( mConfig, "General" );
00223 general.writeEntry( configKeyDefaultIdentity, (*it).uoid() );
00224
00225
00226 KEMailSettings es;
00227 es.setSetting( KEMailSettings::RealName, (*it).fullName() );
00228 es.setSetting( KEMailSettings::EmailAddress, (*it).emailAddr() );
00229 es.setSetting( KEMailSettings::Organization, (*it).organization() );
00230 es.setSetting( KEMailSettings::ReplyToAddress, (*it).replyToAddr() );
00231 }
00232 }
00233 mConfig->sync();
00234
00235 }
00236
00237 void IdentityManager::readConfig( KConfig *config )
00238 {
00239 mIdentities.clear();
00240
00241 const QStringList identities = groupList( config );
00242 if ( identities.isEmpty() ) {
00243 return;
00244 }
00245
00246 KConfigGroup general( config, "General" );
00247 uint defaultIdentity = general.readEntry( configKeyDefaultIdentity, 0 );
00248 bool haveDefault = false;
00249
00250 for ( QStringList::const_iterator group = identities.begin();
00251 group != identities.end(); ++group ) {
00252 KConfigGroup configGroup( config, *group );
00253 mIdentities << Identity();
00254 mIdentities.last().readConfig( configGroup );
00255 if ( !haveDefault && mIdentities.last().uoid() == defaultIdentity ) {
00256 haveDefault = true;
00257 mIdentities.last().setIsDefault( true );
00258 }
00259 }
00260 if ( !haveDefault ) {
00261 kWarning( 5325 ) << "IdentityManager: There was no default identity."
00262 << "Marking first one as default.";
00263 mIdentities.first().setIsDefault( true );
00264 }
00265 qSort( mIdentities );
00266
00267 mShadowIdentities = mIdentities;
00268 }
00269
00270 QStringList IdentityManager::groupList( KConfig *config ) const
00271 {
00272 return config->groupList().filter( QRegExp( "^Identity #\\d+$" ) );
00273 }
00274
00275 IdentityManager::ConstIterator IdentityManager::begin() const
00276 {
00277 return mIdentities.begin();
00278 }
00279
00280 IdentityManager::ConstIterator IdentityManager::end() const
00281 {
00282 return mIdentities.end();
00283 }
00284
00285 IdentityManager::Iterator IdentityManager::modifyBegin()
00286 {
00287 return mShadowIdentities.begin();
00288 }
00289
00290 IdentityManager::Iterator IdentityManager::modifyEnd()
00291 {
00292 return mShadowIdentities.end();
00293 }
00294
00295 const Identity &IdentityManager::identityForUoid( uint uoid ) const
00296 {
00297 for ( ConstIterator it = begin(); it != end(); ++it ) {
00298 if ( (*it).uoid() == uoid ) {
00299 return (*it);
00300 }
00301 }
00302 return Identity::null();
00303 }
00304
00305 const Identity &IdentityManager::identityForUoidOrDefault( uint uoid ) const
00306 {
00307 const Identity &ident = identityForUoid( uoid );
00308 if ( ident.isNull() ) {
00309 return defaultIdentity();
00310 } else {
00311 return ident;
00312 }
00313 }
00314
00315 const Identity &IdentityManager::identityForAddress(
00316 const QString &addresses ) const
00317 {
00318 QStringList addressList = KPIMUtils::splitAddressList( addresses );
00319 for ( ConstIterator it = begin(); it != end(); ++it ) {
00320 for ( QStringList::ConstIterator addrIt = addressList.constBegin();
00321 addrIt != addressList.constEnd(); ++addrIt ) {
00322 if ( (*it).emailAddr().toLower() == KPIMUtils::extractEmailAddress( *addrIt ).toLower() ) {
00323 return (*it);
00324 }
00325 }
00326 }
00327 return Identity::null();
00328 }
00329
00330 bool IdentityManager::thatIsMe( const QString &addressList ) const
00331 {
00332 return !identityForAddress( addressList ).isNull();
00333 }
00334
00335 Identity &IdentityManager::modifyIdentityForName( const QString &name )
00336 {
00337 for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) {
00338 if ( (*it).identityName() == name ) {
00339 return (*it);
00340 }
00341 }
00342
00343 kWarning( 5325 ) << "IdentityManager::modifyIdentityForName() used as"
00344 << "newFromScratch() replacement!"
00345 << endl << " name == \"" << name << "\"";
00346 return newFromScratch( name );
00347 }
00348
00349 Identity &IdentityManager::modifyIdentityForUoid( uint uoid )
00350 {
00351 for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) {
00352 if ( (*it).uoid() == uoid ) {
00353 return (*it);
00354 }
00355 }
00356
00357 kWarning( 5325 ) << "IdentityManager::identityForUoid() used as"
00358 << "newFromScratch() replacement!"
00359 << endl << " uoid == \"" << uoid << "\"";
00360 return newFromScratch( i18n( "Unnamed" ) );
00361 }
00362
00363 const Identity &IdentityManager::defaultIdentity() const
00364 {
00365 for ( ConstIterator it = begin(); it != end(); ++it ) {
00366 if ( (*it).isDefault() ) {
00367 return (*it);
00368 }
00369 }
00370
00371 if ( mIdentities.isEmpty() )
00372 kFatal( 5325 ) << "IdentityManager: No default identity found!";
00373 else
00374 kWarning( 5325 ) << "IdentityManager: No default identity found!";
00375 return *begin();
00376 }
00377
00378 bool IdentityManager::setAsDefault( uint uoid )
00379 {
00380
00381 bool found = false;
00382 for ( ConstIterator it = mShadowIdentities.constBegin();
00383 it != mShadowIdentities.constEnd(); ++it )
00384 if ( (*it).uoid() == uoid ) {
00385 found = true;
00386 break;
00387 }
00388
00389 if ( !found ) {
00390 return false;
00391 }
00392
00393
00394 for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) {
00395 (*it).setIsDefault( (*it).uoid() == uoid );
00396 }
00397
00398
00399 sort();
00400 return true;
00401 }
00402
00403 bool IdentityManager::removeIdentity( const QString &name )
00404 {
00405 if ( mShadowIdentities.size() <= 1 )
00406 return false;
00407
00408 for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) {
00409 if ( (*it).identityName() == name ) {
00410 bool removedWasDefault = (*it).isDefault();
00411 mShadowIdentities.erase( it );
00412 if ( removedWasDefault ) {
00413 mShadowIdentities.first().setIsDefault( true );
00414 }
00415 return true;
00416 }
00417 }
00418 return false;
00419 }
00420
00421 Identity &IdentityManager::newFromScratch( const QString &name )
00422 {
00423 return newFromExisting( Identity( name ) );
00424 }
00425
00426 Identity &IdentityManager::newFromControlCenter( const QString &name )
00427 {
00428 KEMailSettings es;
00429 es.setProfile( es.defaultProfileName() );
00430
00431 return
00432 newFromExisting( Identity( name,
00433 es.getSetting( KEMailSettings::RealName ),
00434 es.getSetting( KEMailSettings::EmailAddress ),
00435 es.getSetting( KEMailSettings::Organization ),
00436 es.getSetting( KEMailSettings::ReplyToAddress ) ) );
00437 }
00438
00439 Identity &IdentityManager::newFromExisting( const Identity &other,
00440 const QString &name )
00441 {
00442 mShadowIdentities << other;
00443 Identity &result = mShadowIdentities.last();
00444 result.setIsDefault( false );
00445 result.setUoid( newUoid() );
00446 if ( !name.isNull() ) {
00447 result.setIdentityName( name );
00448 }
00449 return result;
00450 }
00451
00452 void IdentityManager::createDefaultIdentity()
00453 {
00454 QString fullName, emailAddress;
00455 bool done = false;
00456
00457
00458 createDefaultIdentity( fullName, emailAddress );
00459
00460
00461 if ( fullName.isEmpty() && emailAddress.isEmpty() ) {
00462 KEMailSettings emailSettings;
00463 fullName = emailSettings.getSetting( KEMailSettings::RealName );
00464 emailAddress = emailSettings.getSetting( KEMailSettings::EmailAddress );
00465
00466 if ( !fullName.isEmpty() && !emailAddress.isEmpty() ) {
00467 newFromControlCenter( i18nc( "use default address from control center",
00468 "Default" ) );
00469 done = true;
00470 } else {
00471
00472 KUser user;
00473 if ( fullName.isEmpty() ) {
00474 fullName = user.property( KUser::FullName ).toString();
00475 }
00476 if ( emailAddress.isEmpty() ) {
00477 emailAddress = user.loginName();
00478 if ( !emailAddress.isEmpty() ) {
00479 KConfigGroup general( mConfig, "General" );
00480 QString defaultdomain = general.readEntry( "Default domain" );
00481 if ( !defaultdomain.isEmpty() ) {
00482 emailAddress += '@' + defaultdomain;
00483 } else {
00484 emailAddress.clear();
00485 }
00486 }
00487 }
00488 }
00489 }
00490
00491 if ( !done ) {
00492
00493 QString name( i18nc( "Default name for new email accounts/identities.", "Unnamed" ) );
00494
00495 if ( !emailAddress.isEmpty() ) {
00496
00497 QString idName = emailAddress;
00498 int pos = idName.indexOf( '@' );
00499 if ( pos != -1 ) {
00500 name = idName.mid( pos + 1, -1 );
00501 }
00502
00503
00504 name.replace( '.', ' ' );
00505 pos = name.indexOf( ' ' );
00506 if ( pos != 0 ) {
00507 name[pos + 1] = name[pos + 1].toUpper();
00508 }
00509 name[0] = name[0].toUpper();
00510 } else if ( !fullName.isEmpty() ) {
00511
00512 name = fullName;
00513 }
00514 mShadowIdentities << Identity( name, fullName, emailAddress );
00515 }
00516
00517 mShadowIdentities.last().setIsDefault( true );
00518 mShadowIdentities.last().setUoid( newUoid() );
00519 if ( mReadOnly ) {
00520 mIdentities = mShadowIdentities;
00521 }
00522 }
00523
00524 int IdentityManager::newUoid()
00525 {
00526 int uoid;
00527
00528
00529 QList<uint> usedUOIDs;
00530 for ( QList<Identity>::ConstIterator it = mIdentities.constBegin();
00531 it != mIdentities.constEnd(); ++it )
00532 usedUOIDs << (*it).uoid();
00533
00534 if ( hasPendingChanges() ) {
00535
00536
00537 for ( QList<Identity>::ConstIterator it = mShadowIdentities.constBegin();
00538 it != mShadowIdentities.constEnd(); ++it ) {
00539 usedUOIDs << (*it).uoid();
00540 }
00541 }
00542
00543 usedUOIDs << 0;
00544
00545
00546 do {
00547 uoid = KRandom::random();
00548 } while ( usedUOIDs.indexOf( uoid ) != -1 );
00549
00550 return uoid;
00551 }
00552
00553 QStringList KPIMIdentities::IdentityManager::allEmails() const
00554 {
00555 QStringList lst;
00556 for ( ConstIterator it = begin(); it != end(); ++it ) {
00557 lst << (*it).emailAddr();
00558 }
00559 return lst;
00560 }
00561
00562 void KPIMIdentities::IdentityManager::slotRollback()
00563 {
00564 rollback();
00565 }
00566
00567 void KPIMIdentities::IdentityManager::slotIdentitiesChanged( const QString &id )
00568 {
00569 kDebug( 5325 ) <<" KPIMIdentities::IdentityManager::slotIdentitiesChanged :" << id;
00570 if ( id != QDBusConnection::sessionBus().baseService() ) {
00571 mConfig->reparseConfiguration();
00572 Q_ASSERT( !hasPendingChanges() );
00573 readConfig( mConfig );
00574 emit changed();
00575 }
00576 }
00577
00578 #include "identitymanager.moc"