kmail Library API Documentation

identitymanager.cpp

00001 /* -*- mode: C++; c-file-style: "gnu" -*- 00002 identitymanager.cpp 00003 00004 This file is part of KMail, the KDE mail client. 00005 Copyright (c) 2002 Marc Mutz <mutz@kde.org> 00006 00007 KMail is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License, version 2, as 00009 published by the Free Software Foundation. 00010 00011 KMail is distributed in the hope that it will be useful, but 00012 WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 In addition, as a special exception, the copyright holders give 00021 permission to link the code of this program with any edition of 00022 the Qt library by Trolltech AS, Norway (or with modified versions 00023 of Qt that use the same license as Qt), and distribute linked 00024 combinations including the two. You must obey the GNU General 00025 Public License in all respects for all of the code used other than 00026 Qt. If you modify this file, you may extend this exception to 00027 your version of the file, but you are not obligated to do so. If 00028 you do not wish to do so, delete this exception statement from 00029 your version. 00030 */ 00031 00032 // config keys: 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 "kmidentity.h" // for IdentityList::{export,import}Data 00042 #ifndef KMAIL_TESTING 00043 #include "kmkernel.h" 00044 #endif 00045 #include "kmmessage.h" // for static KMMessage helper functions 00046 00047 #include <kemailsettings.h> // for IdentityEntry::fromControlCenter() 00048 #include <kapplication.h> 00049 #include <klocale.h> 00050 #include <kdebug.h> 00051 #include <kconfig.h> 00052 #if KDE_IS_VERSION( 3, 1, 92 ) 00053 #include <kuser.h> 00054 #else 00055 #include <pwd.h> // for struct pw; 00056 #include <unistd.h> // for getuid 00057 #endif 00058 00059 #include <qregexp.h> 00060 00061 #include <assert.h> 00062 00063 IdentityManager::IdentityManager( QObject * parent, const char * name ) 00064 : ConfigManager( parent, name ) 00065 { 00066 readConfig(); 00067 mShadowIdentities = mIdentities; 00068 // we need at least a default identity: 00069 if ( mIdentities.isEmpty() ) { 00070 kdDebug( 5006 ) << "IdentityManager: No identity found. Creating default." << endl; 00071 createDefaultIdentity(); 00072 commit(); 00073 } 00074 } 00075 00076 IdentityManager::~IdentityManager() 00077 { 00078 kdWarning( hasPendingChanges(), 5006 ) 00079 << "IdentityManager: There were uncommitted changes!" << endl; 00080 } 00081 00082 void IdentityManager::commit() 00083 { 00084 // early out: 00085 if ( !hasPendingChanges() ) return; 00086 00087 QValueList<uint> seenUOIDs; 00088 for ( QValueList<KMIdentity>::ConstIterator it = mIdentities.begin() ; 00089 it != mIdentities.end() ; ++it ) 00090 seenUOIDs << (*it).uoid(); 00091 00092 // find added and changed identities: 00093 for ( QValueList<KMIdentity>::ConstIterator it = mShadowIdentities.begin() ; 00094 it != mShadowIdentities.end() ; ++it ) { 00095 QValueList<uint>::Iterator uoid = seenUOIDs.find( (*it).uoid() ); 00096 if ( uoid != seenUOIDs.end() ) { 00097 const KMIdentity & orig = identityForUoid( *uoid ); 00098 if ( *it != orig ) { 00099 // changed identity 00100 kdDebug( 5006 ) << "emitting changed() for identity " << *uoid << endl; 00101 emit changed( *it ); 00102 emit changed( *uoid ); 00103 } 00104 seenUOIDs.remove( uoid ); 00105 } else { 00106 // new identity 00107 kdDebug( 5006 ) << "emitting added() for identity " << (*it).uoid() << endl; 00108 emit added( *it ); 00109 } 00110 } 00111 00112 // what's left are deleted identities: 00113 for ( QValueList<uint>::ConstIterator it = seenUOIDs.begin() ; 00114 it != seenUOIDs.end() ; ++it ) { 00115 kdDebug( 5006 ) << "emitting deleted() for identity " << (*it) << endl; 00116 emit deleted( *it ); 00117 } 00118 00119 mIdentities = mShadowIdentities; 00120 writeConfig(); 00121 emit ConfigManager::changed(); 00122 } 00123 00124 void IdentityManager::rollback() 00125 { 00126 mShadowIdentities = mIdentities; 00127 } 00128 00129 bool IdentityManager::hasPendingChanges() const 00130 { 00131 return mIdentities != mShadowIdentities; 00132 } 00133 00134 QStringList IdentityManager::identities() const 00135 { 00136 QStringList result; 00137 for ( ConstIterator it = mIdentities.begin() ; 00138 it != mIdentities.end() ; ++it ) 00139 result << (*it).identityName(); 00140 return result; 00141 } 00142 00143 QStringList IdentityManager::shadowIdentities() const 00144 { 00145 QStringList result; 00146 for ( ConstIterator it = mShadowIdentities.begin() ; 00147 it != mShadowIdentities.end() ; ++it ) 00148 result << (*it).identityName(); 00149 return result; 00150 } 00151 00152 // hmm, anyone can explain why I need to explicitly instantate qHeapSort? 00153 //template void qHeapSort( QValueList<KMIdentity> & ); 00154 00155 void IdentityManager::sort() { 00156 qHeapSort( mShadowIdentities ); 00157 } 00158 00159 void IdentityManager::writeConfig() const { 00160 QStringList identities = groupList(); 00161 KConfig * config = KMKernel::config(); 00162 for ( QStringList::Iterator group = identities.begin() ; 00163 group != identities.end() ; ++group ) 00164 config->deleteGroup( *group ); 00165 int i = 0; 00166 for ( ConstIterator it = mIdentities.begin() ; 00167 it != mIdentities.end() ; ++it, ++i ) { 00168 KConfigGroup cg( config, QString::fromLatin1("Identity #%1").arg(i) ); 00169 (*it).writeConfig( &cg ); 00170 if ( (*it).isDefault() ) { 00171 // remember which one is default: 00172 KConfigGroup general( config, "General" ); 00173 general.writeEntry( configKeyDefaultIdentity, (*it).uoid() ); 00174 } 00175 } 00176 #ifndef KMAIL_TESTING 00177 kmkernel->slotRequestConfigSync(); 00178 #else 00179 config->sync(); 00180 #endif 00181 } 00182 00183 void IdentityManager::readConfig() { 00184 mIdentities.clear(); 00185 00186 QStringList identities = groupList(); 00187 if ( identities.isEmpty() ) return; // nothing to be done... 00188 00189 KConfigGroup general( KMKernel::config(), "General" ); 00190 uint defaultIdentity = general.readUnsignedNumEntry( configKeyDefaultIdentity ); 00191 bool haveDefault = false; 00192 00193 for ( QStringList::Iterator group = identities.begin() ; 00194 group != identities.end() ; ++group ) { 00195 KConfigGroup config( KMKernel::config(), *group ); 00196 mIdentities << KMIdentity(); 00197 mIdentities.last().readConfig( &config ); 00198 if ( !haveDefault && mIdentities.last().uoid() == defaultIdentity ) { 00199 haveDefault = true; 00200 mIdentities.last().setIsDefault( true ); 00201 } 00202 } 00203 if ( !haveDefault ) { 00204 kdWarning( 5006 ) << "IdentityManager: There was no default identity. Marking first one as default." << endl; 00205 mIdentities.first().setIsDefault( true ); 00206 } 00207 qHeapSort( mIdentities ); 00208 } 00209 00210 QStringList IdentityManager::groupList() const { 00211 return KMKernel::config()->groupList().grep( QRegExp("^Identity #\\d+$") ); 00212 } 00213 00214 IdentityManager::ConstIterator IdentityManager::begin() const { 00215 return mIdentities.begin(); 00216 } 00217 00218 IdentityManager::ConstIterator IdentityManager::end() const { 00219 return mIdentities.end(); 00220 } 00221 00222 IdentityManager::Iterator IdentityManager::begin() { 00223 return mShadowIdentities.begin(); 00224 } 00225 00226 IdentityManager::Iterator IdentityManager::end() { 00227 return mShadowIdentities.end(); 00228 } 00229 00230 const KMIdentity & IdentityManager::identityForName( const QString & name ) const 00231 { 00232 kdWarning( 5006 ) 00233 << "deprecated method IdentityManager::identityForName() called!" << endl; 00234 for ( ConstIterator it = begin() ; it != end() ; ++it ) 00235 if ( (*it).identityName() == name ) return (*it); 00236 return KMIdentity::null; 00237 } 00238 00239 const KMIdentity & IdentityManager::identityForUoid( uint uoid ) const { 00240 for ( ConstIterator it = begin() ; it != end() ; ++it ) 00241 if ( (*it).uoid() == uoid ) return (*it); 00242 return KMIdentity::null; 00243 } 00244 00245 const KMIdentity & IdentityManager::identityForNameOrDefault( const QString & name ) const 00246 { 00247 const KMIdentity & ident = identityForName( name ); 00248 if ( ident.isNull() ) 00249 return defaultIdentity(); 00250 else 00251 return ident; 00252 } 00253 00254 const KMIdentity & IdentityManager::identityForUoidOrDefault( uint uoid ) const 00255 { 00256 const KMIdentity & ident = identityForUoid( uoid ); 00257 if ( ident.isNull() ) 00258 return defaultIdentity(); 00259 else 00260 return ident; 00261 } 00262 00263 const KMIdentity & IdentityManager::identityForAddress( const QString & addresses ) const 00264 { 00265 QStringList addressList = KMMessage::splitEmailAddrList( addresses ); 00266 for ( ConstIterator it = begin() ; it != end() ; ++it ) { 00267 for( QStringList::ConstIterator addrIt = addressList.begin(); 00268 addrIt != addressList.end(); ++addrIt ) { 00269 // I use QString::utf8() instead of QString::latin1() because I want 00270 // a QCString and not a char*. It doesn't matter because emailAddr() 00271 // returns a 7-bit string. 00272 if( (*it).emailAddr().utf8().lower() == 00273 KMMessage::getEmailAddr( *addrIt ).lower() ) 00274 return (*it); 00275 } 00276 } 00277 return KMIdentity::null; 00278 } 00279 00280 bool IdentityManager::thatIsMe( const QString & addressList ) const { 00281 return !identityForAddress( addressList ).isNull(); 00282 } 00283 00284 KMIdentity & IdentityManager::identityForName( const QString & name ) 00285 { 00286 for ( Iterator it = begin() ; it != end() ; ++it ) 00287 if ( (*it).identityName() == name ) return (*it); 00288 kdWarning( 5006 ) << "IdentityManager::identityForName() used as newFromScratch() replacement!" 00289 << "\n name == \"" << name << "\"" << endl; 00290 return newFromScratch( name ); 00291 } 00292 00293 KMIdentity & IdentityManager::identityForUoid( uint uoid ) 00294 { 00295 for ( Iterator it = begin() ; it != end() ; ++it ) 00296 if ( (*it).uoid() == uoid ) return (*it); 00297 kdWarning( 5006 ) << "IdentityManager::identityForUoid() used as newFromScratch() replacement!" 00298 << "\n uoid == \"" << uoid << "\"" << endl; 00299 return newFromScratch( i18n("Unnamed") ); 00300 } 00301 00302 const KMIdentity & IdentityManager::defaultIdentity() const { 00303 for ( ConstIterator it = begin() ; it != end() ; ++it ) 00304 if ( (*it).isDefault() ) return (*it); 00305 (mIdentities.isEmpty() ? kdFatal( 5006 ) : kdWarning( 5006 ) ) 00306 << "IdentityManager: No default identity found!" << endl; 00307 return *begin(); 00308 } 00309 00310 bool IdentityManager::setAsDefault( const QString & name ) { 00311 // First, check if the identity actually exists: 00312 QStringList names = shadowIdentities(); 00313 if ( names.find( name ) == names.end() ) return false; 00314 // Then, change the default as requested: 00315 for ( Iterator it = begin() ; it != end() ; ++it ) 00316 (*it).setIsDefault( (*it).identityName() == name ); 00317 // and re-sort: 00318 sort(); 00319 return true; 00320 } 00321 00322 bool IdentityManager::setAsDefault( uint uoid ) { 00323 // First, check if the identity actually exists: 00324 bool found = false; 00325 for ( ConstIterator it = mShadowIdentities.begin() ; 00326 it != mShadowIdentities.end() ; ++it ) 00327 if ( (*it).uoid() == uoid ) { 00328 found = true; 00329 break; 00330 } 00331 if ( !found ) return false; 00332 00333 // Then, change the default as requested: 00334 for ( Iterator it = begin() ; it != end() ; ++it ) 00335 (*it).setIsDefault( (*it).uoid() == uoid ); 00336 // and re-sort: 00337 sort(); 00338 return true; 00339 } 00340 00341 bool IdentityManager::removeIdentity( const QString & name ) { 00342 for ( Iterator it = begin() ; it != end() ; ++it ) 00343 if ( (*it).identityName() == name ) { 00344 bool removedWasDefault = (*it).isDefault(); 00345 mShadowIdentities.remove( it ); 00346 if ( removedWasDefault ) 00347 mShadowIdentities.first().setIsDefault( true ); 00348 return true; 00349 } 00350 return false; 00351 } 00352 00353 KMIdentity & IdentityManager::newFromScratch( const QString & name ) { 00354 return newFromExisting( KMIdentity( name ) ); 00355 } 00356 00357 KMIdentity & IdentityManager::newFromControlCenter( const QString & name ) { 00358 KEMailSettings es; 00359 es.setProfile( es.defaultProfileName() ); 00360 00361 return newFromExisting( KMIdentity( name, 00362 es.getSetting( KEMailSettings::RealName ), 00363 es.getSetting( KEMailSettings::EmailAddress ), 00364 es.getSetting( KEMailSettings::Organization ), 00365 es.getSetting( KEMailSettings::ReplyToAddress ) 00366 ) ); 00367 } 00368 00369 KMIdentity & IdentityManager::newFromExisting( const KMIdentity & other, 00370 const QString & name ) { 00371 mShadowIdentities << other; 00372 KMIdentity & result = mShadowIdentities.last(); 00373 result.setIsDefault( false ); // we don't want two default identities! 00374 result.setUoid( newUoid() ); // we don't want two identies w/ same UOID 00375 if ( !name.isNull() ) 00376 result.setIdentityName( name ); 00377 return result; 00378 } 00379 00380 void IdentityManager::createDefaultIdentity() { 00381 #if KDE_IS_VERSION( 3, 1, 92 ) 00382 KUser user; 00383 QString fullName = user.fullName(); 00384 00385 QString emailAddress = user.loginName(); 00386 if ( !emailAddress.isEmpty() ) { 00387 KConfigGroup general( KMKernel::config(), "General" ); 00388 QString defaultdomain = general.readEntry( "Default domain" ); 00389 if( !defaultdomain.isEmpty() ) { 00390 emailAddress += '@' + defaultdomain; 00391 } 00392 else { 00393 emailAddress = QString::null; 00394 } 00395 } 00396 #else 00397 QString fullName, emailAddress; 00398 if ( const struct passwd * pw = getpwuid( getuid() ) ) { 00399 // extract possible full name from /etc/passwd 00400 fullName = QString::fromLocal8Bit( pw->pw_gecos ); 00401 const int i = fullName.find(','); 00402 if ( i > 0 ) fullName.truncate( i ); 00403 } 00404 #endif 00405 mShadowIdentities << KMIdentity( i18n("Default"), fullName, emailAddress ); 00406 mShadowIdentities.last().setIsDefault( true ); 00407 mShadowIdentities.last().setUoid( newUoid() ); 00408 } 00409 00410 int IdentityManager::newUoid() 00411 { 00412 int uoid; 00413 00414 // determine the UOIDs of all saved identities 00415 QValueList<uint> usedUOIDs; 00416 for ( QValueList<KMIdentity>::ConstIterator it = mIdentities.begin() ; 00417 it != mIdentities.end() ; ++it ) 00418 usedUOIDs << (*it).uoid(); 00419 00420 if ( hasPendingChanges() ) { 00421 // add UOIDs of all shadow identities. Yes, we will add a lot of duplicate 00422 // UOIDs, but avoiding duplicate UOIDs isn't worth the effort. 00423 for ( QValueList<KMIdentity>::ConstIterator it = mShadowIdentities.begin() ; 00424 it != mShadowIdentities.end() ; ++it ) { 00425 usedUOIDs << (*it).uoid(); 00426 } 00427 } 00428 00429 usedUOIDs << 0; // no UOID must be 0 because this value always refers to the 00430 // default identity 00431 00432 do { 00433 uoid = kapp->random(); 00434 } while ( usedUOIDs.find( uoid ) != usedUOIDs.end() ); 00435 00436 return uoid; 00437 } 00438 00439 #include "identitymanager.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:58 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003