1 | /* |
2 | Copyright (c) 2002 Marc Mutz <mutz@kde.org> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | // config keys: |
21 | static const char configKeyDefaultIdentity[] = "Default Identity" ; |
22 | |
23 | #include "identitymanager.h" |
24 | #include "identity.h" // for IdentityList::{export,import}Data |
25 | |
26 | #include <kpimutils/email.h> // for static helper functions |
27 | |
28 | #include <kemailsettings.h> // for IdentityEntry::fromControlCenter() |
29 | #include <klocale.h> |
30 | #include <klocalizedstring.h> |
31 | #include <kglobal.h> |
32 | #include <kdebug.h> |
33 | #include <kconfig.h> |
34 | #include <kuser.h> |
35 | #include <kconfiggroup.h> |
36 | |
37 | #include <QList> |
38 | #include <QRegExp> |
39 | #include <QtDBus/QtDBus> |
40 | #include <QHostInfo> |
41 | |
42 | #include <assert.h> |
43 | #include <krandom.h> |
44 | |
45 | #include "identitymanageradaptor.h" |
46 | |
47 | using namespace KPIMIdentities; |
48 | |
49 | static QString newDBusObjectName() |
50 | { |
51 | static int s_count = 0; |
52 | QString name( QLatin1String("/KPIMIDENTITIES_IdentityManager" ) ); |
53 | if ( s_count++ ) { |
54 | name += QLatin1Char('_'); |
55 | name += QString::number( s_count ); |
56 | } |
57 | return name; |
58 | } |
59 | |
60 | IdentityManager::IdentityManager( bool readonly, QObject *parent, |
61 | const char *name ) |
62 | : QObject( parent ) |
63 | { |
64 | setObjectName( QLatin1String(name) ); |
65 | KGlobal::locale()->insertCatalog( QLatin1String("libkpimidentities" ) ); |
66 | new IdentityManagerAdaptor( this ); |
67 | QDBusConnection dbus = QDBusConnection::sessionBus(); |
68 | const QString dbusPath = newDBusObjectName(); |
69 | setProperty( "uniqueDBusPath" , dbusPath ); |
70 | const QString dbusInterface = QLatin1String("org.kde.pim.IdentityManager" ); |
71 | dbus.registerObject( dbusPath, this ); |
72 | dbus.connect( QString(), QString(), dbusInterface, QLatin1String("identitiesChanged" ), this, |
73 | SLOT(slotIdentitiesChanged(QString)) ); |
74 | |
75 | mReadOnly = readonly; |
76 | mConfig = new KConfig( QLatin1String("emailidentities" ) ); |
77 | readConfig( mConfig ); |
78 | if ( mIdentities.isEmpty() ) { |
79 | kDebug( 5325 ) << "emailidentities is empty -> convert from kmailrc" ; |
80 | // No emailidentities file, or an empty one due to broken conversion |
81 | // (kconf_update bug in kdelibs <= 3.2.2) |
82 | // => convert it, i.e. read settings from kmailrc |
83 | KConfig kmailConf( QLatin1String("kmailrc" ) ); |
84 | readConfig( &kmailConf ); |
85 | } |
86 | // we need at least a default identity: |
87 | if ( mIdentities.isEmpty() ) { |
88 | kDebug( 5325 ) << "IdentityManager: No identity found. Creating default." ; |
89 | createDefaultIdentity(); |
90 | commit(); |
91 | } |
92 | |
93 | KConfig kmailConf( QLatin1String("kmail2rc" ) ); |
94 | if (!mReadOnly) { |
95 | bool needCommit = false; |
96 | if (kmailConf.hasGroup(QLatin1String("Composer" ))) { |
97 | KConfigGroup composerGroup = kmailConf.group(QLatin1String("Composer" )); |
98 | if (composerGroup.hasKey(QLatin1String("pgp-auto-sign" ))) { |
99 | const bool pgpAutoSign = composerGroup.readEntry(QLatin1String("pgp-auto-sign" ), false); |
100 | QList<Identity>::iterator end = mIdentities.end(); |
101 | for ( QList<Identity>::iterator it = mIdentities.begin(); it != end; ++it ) { |
102 | it->setPgpAutoSign(pgpAutoSign); |
103 | } |
104 | composerGroup.deleteEntry(QLatin1String("pgp-auto-sign" )); |
105 | composerGroup.sync(); |
106 | needCommit = true; |
107 | } |
108 | } |
109 | if (kmailConf.hasGroup(QLatin1String("General" ))) { |
110 | KConfigGroup generalGroup = kmailConf.group(QLatin1String("General" )); |
111 | if (generalGroup.hasKey(QLatin1String("Default domain" ))) { |
112 | QString defaultDomain = generalGroup.readEntry(QLatin1String("Default domain" )); |
113 | if (defaultDomain.isEmpty()) { |
114 | defaultDomain = QHostInfo::localHostName(); |
115 | } |
116 | QList<Identity>::iterator end = mIdentities.end(); |
117 | for ( QList<Identity>::iterator it = mIdentities.begin(); it != end; ++it ) { |
118 | it->setDefaultDomainName(defaultDomain); |
119 | } |
120 | generalGroup.deleteEntry(QLatin1String("Default domain" )); |
121 | generalGroup.sync(); |
122 | needCommit = true; |
123 | } |
124 | } |
125 | if (needCommit) |
126 | commit(); |
127 | } |
128 | |
129 | // Migration: people without settings in kemailsettings should get some |
130 | if ( KEMailSettings().getSetting( KEMailSettings::EmailAddress ).isEmpty() ) { |
131 | writeConfig(); |
132 | } |
133 | } |
134 | |
135 | IdentityManager::~IdentityManager() |
136 | { |
137 | kWarning( hasPendingChanges(), 5325 ) |
138 | << "IdentityManager: There were uncommitted changes!" ; |
139 | delete mConfig; |
140 | } |
141 | |
142 | QString IdentityManager::makeUnique( const QString &name ) const |
143 | { |
144 | int suffix = 1; |
145 | QString result = name; |
146 | while ( identities().contains( result ) ) { |
147 | result = i18nc( "%1: name; %2: number appended to it to make it unique " |
148 | "among a list of names" , "%1 #%2" , |
149 | name, suffix ); |
150 | suffix++; |
151 | } |
152 | return result; |
153 | } |
154 | |
155 | bool IdentityManager::isUnique( const QString &name ) const |
156 | { |
157 | return !identities().contains( name ); |
158 | } |
159 | |
160 | void IdentityManager::commit() |
161 | { |
162 | // early out: |
163 | if ( !hasPendingChanges() || mReadOnly ) { |
164 | return; |
165 | } |
166 | |
167 | QList<uint> seenUOIDs; |
168 | QList<Identity>::ConstIterator end = mIdentities.constEnd(); |
169 | for ( QList<Identity>::ConstIterator it = mIdentities.constBegin(); |
170 | it != end; ++it ) { |
171 | seenUOIDs << ( *it ).uoid(); |
172 | } |
173 | |
174 | QList<uint> changedUOIDs; |
175 | // find added and changed identities: |
176 | for ( QList<Identity>::ConstIterator it = mShadowIdentities.constBegin(); |
177 | it != mShadowIdentities.constEnd(); ++it ) { |
178 | int index = seenUOIDs.indexOf( ( *it ).uoid() ); |
179 | if ( index != -1 ) { |
180 | uint uoid = seenUOIDs.at( index ); |
181 | const Identity &orig = identityForUoid( uoid ); // look up in mIdentities |
182 | if ( *it != orig ) { |
183 | // changed identity |
184 | kDebug( 5325 ) << "emitting changed() for identity" << uoid; |
185 | emit changed( *it ); |
186 | changedUOIDs << uoid; |
187 | } |
188 | seenUOIDs.removeAll( uoid ); |
189 | } else { |
190 | // new identity |
191 | kDebug( 5325 ) << "emitting added() for identity" << ( *it ).uoid(); |
192 | emit added( *it ); |
193 | } |
194 | } |
195 | |
196 | // what's left are deleted identities: |
197 | for ( QList<uint>::ConstIterator it = seenUOIDs.constBegin(); |
198 | it != seenUOIDs.constEnd(); ++it ) { |
199 | kDebug( 5325 ) << "emitting deleted() for identity" << ( *it ); |
200 | emit deleted( *it ); |
201 | } |
202 | |
203 | mIdentities = mShadowIdentities; |
204 | writeConfig(); |
205 | |
206 | // now that mIdentities has all the new info, we can emit the added/changed |
207 | // signals that ship a uoid. This is because the slots might use |
208 | // identityForUoid(uoid)... |
209 | QList<uint>::ConstIterator changedEnd( changedUOIDs.constEnd() ); |
210 | for ( QList<uint>::ConstIterator it = changedUOIDs.constBegin(); |
211 | it != changedEnd; ++it ) { |
212 | emit changed( *it ); |
213 | } |
214 | |
215 | emit changed(); // normal signal |
216 | |
217 | // DBus signal for other IdentityManager instances |
218 | const QString ourIdentifier = QString::fromLatin1( "%1/%2" ). |
219 | arg( QDBusConnection::sessionBus().baseService() ). |
220 | arg( property( "uniqueDBusPath" ).toString() ); |
221 | emit identitiesChanged( ourIdentifier ); |
222 | } |
223 | |
224 | void IdentityManager::rollback() |
225 | { |
226 | mShadowIdentities = mIdentities; |
227 | } |
228 | |
229 | bool IdentityManager::hasPendingChanges() const |
230 | { |
231 | return mIdentities != mShadowIdentities; |
232 | } |
233 | |
234 | QStringList IdentityManager::identities() const |
235 | { |
236 | QStringList result; |
237 | ConstIterator end = mIdentities.constEnd(); |
238 | for ( ConstIterator it = mIdentities.constBegin(); |
239 | it != end; ++it ) { |
240 | result << ( *it ).identityName(); |
241 | } |
242 | return result; |
243 | } |
244 | |
245 | QStringList IdentityManager::shadowIdentities() const |
246 | { |
247 | QStringList result; |
248 | ConstIterator end = mShadowIdentities.constEnd(); |
249 | for ( ConstIterator it = mShadowIdentities.constBegin(); |
250 | it != end; ++it ) { |
251 | result << ( *it ).identityName(); |
252 | } |
253 | return result; |
254 | } |
255 | |
256 | void IdentityManager::sort() |
257 | { |
258 | qSort( mShadowIdentities ); |
259 | } |
260 | |
261 | void IdentityManager::writeConfig() const |
262 | { |
263 | const QStringList identities = groupList( mConfig ); |
264 | QStringList::const_iterator groupEnd = identities.constEnd(); |
265 | for ( QStringList::const_iterator group = identities.constBegin(); |
266 | group != groupEnd; ++group ) { |
267 | mConfig->deleteGroup( *group ); |
268 | } |
269 | int i = 0; |
270 | ConstIterator end = mIdentities.constEnd(); |
271 | for ( ConstIterator it = mIdentities.constBegin(); |
272 | it != end; ++it, ++i ) { |
273 | KConfigGroup cg( mConfig, QString::fromLatin1( "Identity #%1" ).arg( i ) ); |
274 | ( *it ).writeConfig( cg ); |
275 | if ( ( *it ).isDefault() ) { |
276 | // remember which one is default: |
277 | KConfigGroup general( mConfig, "General" ); |
278 | general.writeEntry( configKeyDefaultIdentity, ( *it ).uoid() ); |
279 | |
280 | // Also write the default identity to emailsettings |
281 | KEMailSettings es; |
282 | es.setSetting( KEMailSettings::RealName, ( *it ).fullName() ); |
283 | es.setSetting( KEMailSettings::EmailAddress, ( *it ).primaryEmailAddress() ); |
284 | es.setSetting( KEMailSettings::Organization, ( *it ).organization() ); |
285 | es.setSetting( KEMailSettings::ReplyToAddress, ( *it ).replyToAddr() ); |
286 | } |
287 | } |
288 | mConfig->sync(); |
289 | |
290 | } |
291 | |
292 | void IdentityManager::readConfig( KConfig *config ) |
293 | { |
294 | mIdentities.clear(); |
295 | |
296 | const QStringList identities = groupList( config ); |
297 | if ( identities.isEmpty() ) { |
298 | return; // nothing to be done... |
299 | } |
300 | |
301 | KConfigGroup general( config, "General" ); |
302 | uint defaultIdentity = general.readEntry( configKeyDefaultIdentity, 0 ); |
303 | bool haveDefault = false; |
304 | QStringList::const_iterator groupEnd = identities.constEnd(); |
305 | for ( QStringList::const_iterator group = identities.constBegin(); |
306 | group != groupEnd; ++group ) { |
307 | KConfigGroup configGroup( config, *group ); |
308 | mIdentities << Identity(); |
309 | mIdentities.last().readConfig( configGroup ); |
310 | if ( !haveDefault && mIdentities.last().uoid() == defaultIdentity ) { |
311 | haveDefault = true; |
312 | mIdentities.last().setIsDefault( true ); |
313 | } |
314 | } |
315 | |
316 | if ( !haveDefault ) { |
317 | kWarning( 5325 ) << "IdentityManager: There was no default identity." |
318 | << "Marking first one as default." ; |
319 | mIdentities.first().setIsDefault( true ); |
320 | } |
321 | qSort( mIdentities ); |
322 | |
323 | mShadowIdentities = mIdentities; |
324 | } |
325 | |
326 | QStringList IdentityManager::groupList( KConfig *config ) const |
327 | { |
328 | return config->groupList().filter( QRegExp( QLatin1String("^Identity #\\d+$" ) ) ); |
329 | } |
330 | |
331 | IdentityManager::ConstIterator IdentityManager::begin() const |
332 | { |
333 | return mIdentities.begin(); |
334 | } |
335 | |
336 | IdentityManager::ConstIterator IdentityManager::end() const |
337 | { |
338 | return mIdentities.end(); |
339 | } |
340 | |
341 | IdentityManager::Iterator IdentityManager::modifyBegin() |
342 | { |
343 | return mShadowIdentities.begin(); |
344 | } |
345 | |
346 | IdentityManager::Iterator IdentityManager::modifyEnd() |
347 | { |
348 | return mShadowIdentities.end(); |
349 | } |
350 | |
351 | const Identity &IdentityManager::identityForUoid( uint uoid ) const |
352 | { |
353 | for ( ConstIterator it = begin(); it != end(); ++it ) { |
354 | if ( ( *it ).uoid() == uoid ) { |
355 | return ( *it ); |
356 | } |
357 | } |
358 | return Identity::null(); |
359 | } |
360 | |
361 | const Identity &IdentityManager::identityForUoidOrDefault( uint uoid ) const |
362 | { |
363 | const Identity &ident = identityForUoid( uoid ); |
364 | if ( ident.isNull() ) { |
365 | return defaultIdentity(); |
366 | } else { |
367 | return ident; |
368 | } |
369 | } |
370 | |
371 | const Identity &IdentityManager::identityForAddress( |
372 | const QString &addresses ) const |
373 | { |
374 | const QStringList addressList = KPIMUtils::splitAddressList( addresses ); |
375 | foreach ( const QString &fullAddress, addressList ) { |
376 | const QString addrSpec = KPIMUtils::extractEmailAddress( fullAddress ).toLower(); |
377 | for ( ConstIterator it = begin(); it != end(); ++it ) { |
378 | const Identity &identity = *it; |
379 | if ( identity.matchesEmailAddress( addrSpec ) ) { |
380 | return identity; |
381 | } |
382 | } |
383 | } |
384 | return Identity::null(); |
385 | } |
386 | |
387 | bool IdentityManager::thatIsMe( const QString &addressList ) const |
388 | { |
389 | return !identityForAddress( addressList ).isNull(); |
390 | } |
391 | |
392 | Identity &IdentityManager::modifyIdentityForName( const QString &name ) |
393 | { |
394 | for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) { |
395 | if ( ( *it ).identityName() == name ) { |
396 | return ( *it ); |
397 | } |
398 | } |
399 | |
400 | kWarning( 5325 ) << "IdentityManager::modifyIdentityForName() used as" |
401 | << "newFromScratch() replacement!" |
402 | << endl << " name == \"" << name << "\"" ; |
403 | return newFromScratch( name ); |
404 | } |
405 | |
406 | Identity &IdentityManager::modifyIdentityForUoid( uint uoid ) |
407 | { |
408 | for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) { |
409 | if ( ( *it ).uoid() == uoid ) { |
410 | return ( *it ); |
411 | } |
412 | } |
413 | |
414 | kWarning( 5325 ) << "IdentityManager::identityForUoid() used as" |
415 | << "newFromScratch() replacement!" |
416 | << endl << " uoid == \"" << uoid << "\"" ; |
417 | return newFromScratch( i18n( "Unnamed" ) ); |
418 | } |
419 | |
420 | const Identity &IdentityManager::defaultIdentity() const |
421 | { |
422 | for ( ConstIterator it = begin(); it != end(); ++it ) { |
423 | if ( ( *it ).isDefault() ) { |
424 | return ( *it ); |
425 | } |
426 | } |
427 | |
428 | if ( mIdentities.isEmpty() ) { |
429 | kFatal( 5325 ) << "IdentityManager: No default identity found!" ; |
430 | } else { |
431 | kWarning( 5325 ) << "IdentityManager: No default identity found!" ; |
432 | } |
433 | return *begin(); |
434 | } |
435 | |
436 | bool IdentityManager::setAsDefault( uint uoid ) |
437 | { |
438 | // First, check if the identity actually exists: |
439 | bool found = false; |
440 | for ( ConstIterator it = mShadowIdentities.constBegin(); |
441 | it != mShadowIdentities.constEnd(); ++it ) { |
442 | if ( ( *it ).uoid() == uoid ) { |
443 | found = true; |
444 | break; |
445 | } |
446 | } |
447 | |
448 | if ( !found ) { |
449 | return false; |
450 | } |
451 | |
452 | // Then, change the default as requested: |
453 | for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) { |
454 | ( *it ).setIsDefault( ( *it ).uoid() == uoid ); |
455 | } |
456 | |
457 | // and re-sort: |
458 | sort(); |
459 | return true; |
460 | } |
461 | |
462 | bool IdentityManager::removeIdentity( const QString &name ) |
463 | { |
464 | if ( mShadowIdentities.size() <= 1 ) { |
465 | return false; |
466 | } |
467 | |
468 | for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) { |
469 | if ( ( *it ).identityName() == name ) { |
470 | bool removedWasDefault = ( *it ).isDefault(); |
471 | mShadowIdentities.erase( it ); |
472 | if ( removedWasDefault && !mShadowIdentities.isEmpty() ) { |
473 | mShadowIdentities.first().setIsDefault( true ); |
474 | } |
475 | return true; |
476 | } |
477 | } |
478 | return false; |
479 | } |
480 | |
481 | bool IdentityManager::removeIdentityForced( const QString &name ) |
482 | { |
483 | for ( Iterator it = modifyBegin(); it != modifyEnd(); ++it ) { |
484 | if ( ( *it ).identityName() == name ) { |
485 | bool removedWasDefault = ( *it ).isDefault(); |
486 | mShadowIdentities.erase( it ); |
487 | if ( removedWasDefault && !mShadowIdentities.isEmpty() ) { |
488 | mShadowIdentities.first().setIsDefault( true ); |
489 | } |
490 | return true; |
491 | } |
492 | } |
493 | return false; |
494 | } |
495 | |
496 | Identity &IdentityManager::newFromScratch( const QString &name ) |
497 | { |
498 | return newFromExisting( Identity( name ) ); |
499 | } |
500 | |
501 | Identity &IdentityManager::newFromControlCenter( const QString &name ) |
502 | { |
503 | KEMailSettings es; |
504 | es.setProfile( es.defaultProfileName() ); |
505 | |
506 | return |
507 | newFromExisting( Identity( name, |
508 | es.getSetting( KEMailSettings::RealName ), |
509 | es.getSetting( KEMailSettings::EmailAddress ), |
510 | es.getSetting( KEMailSettings::Organization ), |
511 | es.getSetting( KEMailSettings::ReplyToAddress ) ) ); |
512 | } |
513 | |
514 | Identity &IdentityManager::newFromExisting( const Identity &other, const QString &name ) |
515 | { |
516 | mShadowIdentities << other; |
517 | Identity &result = mShadowIdentities.last(); |
518 | result.setIsDefault( false ); // we don't want two default identities! |
519 | result.setUoid( newUoid() ); // we don't want two identies w/ same UOID |
520 | if ( !name.isNull() ) { |
521 | result.setIdentityName( name ); |
522 | } |
523 | return result; |
524 | } |
525 | |
526 | void IdentityManager::createDefaultIdentity() |
527 | { |
528 | QString fullName, emailAddress; |
529 | bool done = false; |
530 | |
531 | // Check if the application has any settings |
532 | createDefaultIdentity( fullName, emailAddress ); |
533 | |
534 | // If not, then use the kcontrol settings |
535 | if ( fullName.isEmpty() && emailAddress.isEmpty() ) { |
536 | KEMailSettings emailSettings; |
537 | fullName = emailSettings.getSetting( KEMailSettings::RealName ); |
538 | emailAddress = emailSettings.getSetting( KEMailSettings::EmailAddress ); |
539 | |
540 | if ( !fullName.isEmpty() && !emailAddress.isEmpty() ) { |
541 | newFromControlCenter( i18nc( "use default address from control center" , |
542 | "Default" ) ); |
543 | done = true; |
544 | } else { |
545 | // If KEmailSettings doesn't have name and address, generate something from KUser |
546 | KUser user; |
547 | if ( fullName.isEmpty() ) { |
548 | fullName = user.property( KUser::FullName ).toString(); |
549 | } |
550 | if ( emailAddress.isEmpty() ) { |
551 | emailAddress = user.loginName(); |
552 | if ( !emailAddress.isEmpty() ) { |
553 | KConfigGroup general( mConfig, "General" ); |
554 | QString defaultdomain = general.readEntry( "Default domain" ); |
555 | if ( !defaultdomain.isEmpty() ) { |
556 | emailAddress += QLatin1Char('@') + defaultdomain; |
557 | } else { |
558 | emailAddress.clear(); |
559 | } |
560 | } |
561 | } |
562 | } |
563 | } |
564 | |
565 | if ( !done ) { |
566 | // Default identity name |
567 | QString name( i18nc( "Default name for new email accounts/identities." , "Unnamed" ) ); |
568 | |
569 | if ( !emailAddress.isEmpty() ) { |
570 | // If we have an email address, create a default identity name from it |
571 | QString idName = emailAddress; |
572 | int pos = idName.indexOf( QLatin1Char('@') ); |
573 | if ( pos != -1 ) { |
574 | name = idName.mid( pos + 1, -1 ); |
575 | } |
576 | |
577 | // Make the name a bit more human friendly |
578 | name.replace( QLatin1Char('.'), QLatin1Char(' ') ); |
579 | pos = name.indexOf( QLatin1Char(' ') ); |
580 | if ( pos != 0 ) { |
581 | name[pos + 1] = name[pos + 1].toUpper(); |
582 | } |
583 | name[0] = name[0].toUpper(); |
584 | } else if ( !fullName.isEmpty() ) { |
585 | // If we have a full name, create a default identity name from it |
586 | name = fullName; |
587 | } |
588 | mShadowIdentities << Identity( name, fullName, emailAddress ); |
589 | } |
590 | |
591 | mShadowIdentities.last().setIsDefault( true ); |
592 | mShadowIdentities.last().setUoid( newUoid() ); |
593 | if ( mReadOnly ) { // commit won't do it in readonly mode |
594 | mIdentities = mShadowIdentities; |
595 | } |
596 | } |
597 | |
598 | int IdentityManager::newUoid() |
599 | { |
600 | int uoid; |
601 | |
602 | // determine the UOIDs of all saved identities |
603 | QList<uint> usedUOIDs; |
604 | QList<Identity>::ConstIterator end( mIdentities.constEnd() ); |
605 | for ( QList<Identity>::ConstIterator it = mIdentities.constBegin(); |
606 | it != end; ++it ) { |
607 | usedUOIDs << ( *it ).uoid(); |
608 | } |
609 | |
610 | if ( hasPendingChanges() ) { |
611 | // add UOIDs of all shadow identities. Yes, we will add a lot of duplicate |
612 | // UOIDs, but avoiding duplicate UOIDs isn't worth the effort. |
613 | QList<Identity>::ConstIterator endShadow( mShadowIdentities.constEnd() ); |
614 | for ( QList<Identity>::ConstIterator it = mShadowIdentities.constBegin(); |
615 | it != endShadow; ++it ) { |
616 | usedUOIDs << ( *it ).uoid(); |
617 | } |
618 | } |
619 | |
620 | usedUOIDs << 0; // no UOID must be 0 because this value always refers to the |
621 | // default identity |
622 | |
623 | do { |
624 | uoid = KRandom::random(); |
625 | } while ( usedUOIDs.indexOf( uoid ) != -1 ); |
626 | |
627 | return uoid; |
628 | } |
629 | |
630 | QStringList KPIMIdentities::IdentityManager::allEmails() const |
631 | { |
632 | QStringList lst; |
633 | for ( ConstIterator it = begin(); it != end(); ++it ) { |
634 | lst << ( *it ).primaryEmailAddress(); |
635 | if ( !( *it ).emailAliases().isEmpty() ) { |
636 | lst << ( *it ).emailAliases(); |
637 | } |
638 | } |
639 | return lst; |
640 | } |
641 | |
642 | void KPIMIdentities::IdentityManager::slotRollback() |
643 | { |
644 | rollback(); |
645 | } |
646 | |
647 | void KPIMIdentities::IdentityManager::slotIdentitiesChanged( const QString &id ) |
648 | { |
649 | kDebug( 5325 ) << " KPIMIdentities::IdentityManager::slotIdentitiesChanged :" << id; |
650 | const QString ourIdentifier = QString::fromLatin1( "%1/%2" ). |
651 | arg( QDBusConnection::sessionBus().baseService() ). |
652 | arg( property( "uniqueDBusPath" ).toString() ); |
653 | if ( id != ourIdentifier ) { |
654 | mConfig->reparseConfiguration(); |
655 | Q_ASSERT( !hasPendingChanges() ); |
656 | readConfig( mConfig ); |
657 | emit changed(); |
658 | } |
659 | } |
660 | |
661 | |