File indexing completed on 2024-05-19 05:17:27

0001 /*
0002     SPDX-FileCopyrightText: 2002 Marc Mutz <mutz@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // config keys:
0008 static const char configKeyDefaultIdentity[] = "Default Identity";
0009 
0010 #include "identitymanager.h"
0011 #include "identity.h" // for IdentityList::{export,import}Data
0012 
0013 #include <KEmailAddress> // for static helper functions
0014 
0015 #include "kidentitymanagementcore_debug.h"
0016 #include <KConfig>
0017 #include <KConfigGroup>
0018 #include <KEMailSettings> // for IdentityEntry::fromControlCenter()
0019 #include <KLocalizedString>
0020 #include <KSharedConfig>
0021 #include <kuser.h>
0022 
0023 #include <QDBusConnection>
0024 #include <QHostInfo>
0025 #include <QRandomGenerator>
0026 
0027 #include <QRegularExpression>
0028 #include <cassert>
0029 
0030 #include "identitymanageradaptor.h"
0031 
0032 namespace KIdentityManagementCore
0033 {
0034 static QString newDBusObjectName()
0035 {
0036     static int s_count = 0;
0037     QString name(QStringLiteral("/KIDENTITYMANAGER_IdentityManager"));
0038     if (s_count++) {
0039         name += QLatin1Char('_');
0040         name += QString::number(s_count);
0041     }
0042     return name;
0043 }
0044 
0045 /**
0046  *   Private class that helps to provide binary compatibility between releases.
0047  *   @internal
0048  */
0049 //@cond PRIVATE
0050 class IdentityManagerPrivate
0051 {
0052 public:
0053     IdentityManagerPrivate(KIdentityManagementCore::IdentityManager *);
0054     ~IdentityManagerPrivate();
0055     void writeConfig() const;
0056     void readConfig(KConfig *config);
0057     void createDefaultIdentity();
0058     [[nodiscard]] QStringList groupList(KConfig *config) const;
0059     void slotIdentitiesChanged(const QString &id);
0060     KConfig *mConfig = nullptr;
0061 
0062     QList<Identity> mIdentities;
0063     QList<Identity> shadowIdentities;
0064 
0065     // returns a new Unique Object Identifier
0066     [[nodiscard]] int newUoid();
0067 
0068     bool mReadOnly = true;
0069     KIdentityManagementCore::IdentityManager *const q;
0070 };
0071 
0072 IdentityManagerPrivate::IdentityManagerPrivate(KIdentityManagementCore::IdentityManager *manager)
0073     : q(manager)
0074 {
0075 }
0076 
0077 void IdentityManagerPrivate::writeConfig() const
0078 {
0079     const QStringList identities = groupList(mConfig);
0080     QStringList::const_iterator groupEnd = identities.constEnd();
0081     for (QStringList::const_iterator group = identities.constBegin(); group != groupEnd; ++group) {
0082         mConfig->deleteGroup(*group);
0083     }
0084     int i = 0;
0085     IdentityManager::ConstIterator end = mIdentities.constEnd();
0086     for (IdentityManager::ConstIterator it = mIdentities.constBegin(); it != end; ++it, ++i) {
0087         KConfigGroup cg(mConfig, QStringLiteral("Identity #%1").arg(i));
0088         (*it).writeConfig(cg);
0089         if ((*it).isDefault()) {
0090             // remember which one is default:
0091             KConfigGroup general(mConfig, QStringLiteral("General"));
0092             general.writeEntry(configKeyDefaultIdentity, (*it).uoid());
0093 
0094             // Also write the default identity to emailsettings
0095             KEMailSettings es;
0096             es.setSetting(KEMailSettings::RealName, (*it).fullName());
0097             es.setSetting(KEMailSettings::EmailAddress, (*it).primaryEmailAddress());
0098             es.setSetting(KEMailSettings::Organization, (*it).organization());
0099             es.setSetting(KEMailSettings::ReplyToAddress, (*it).replyToAddr());
0100         }
0101     }
0102     mConfig->sync();
0103 }
0104 
0105 void IdentityManagerPrivate::readConfig(KConfig *config)
0106 {
0107     mIdentities.clear();
0108 
0109     const QStringList identities = groupList(config);
0110     if (identities.isEmpty()) {
0111         return; // nothing to be done...
0112     }
0113 
0114     KConfigGroup general(config, QStringLiteral("General"));
0115     uint defaultIdentity = general.readEntry(configKeyDefaultIdentity, 0);
0116     bool haveDefault = false;
0117     QStringList::const_iterator groupEnd = identities.constEnd();
0118     for (QStringList::const_iterator group = identities.constBegin(); group != groupEnd; ++group) {
0119         KConfigGroup configGroup(config, *group);
0120         Identity identity;
0121         identity.readConfig(configGroup);
0122         // Don't load invalid identity
0123         if (!identity.isNull() && !identity.primaryEmailAddress().isEmpty()) {
0124             if (!haveDefault && identity.uoid() == defaultIdentity) {
0125                 haveDefault = true;
0126                 identity.setIsDefault(true);
0127             }
0128         }
0129         mIdentities << identity;
0130     }
0131     if (!haveDefault) {
0132         if (mIdentities.isEmpty()) {
0133             mIdentities << Identity();
0134         }
0135 
0136         qCDebug(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: There was no default identity."
0137                                          << "Marking first one as default.";
0138         mIdentities.first().setIsDefault(true);
0139     }
0140     std::sort(mIdentities.begin(), mIdentities.end());
0141 
0142     shadowIdentities = mIdentities;
0143 }
0144 
0145 void IdentityManagerPrivate::createDefaultIdentity()
0146 {
0147     QString fullName;
0148     QString emailAddress;
0149     bool done = false;
0150 
0151     // Check if the application has any settings
0152     q->createDefaultIdentity(fullName, emailAddress);
0153 
0154     // If not, then use the kcontrol settings
0155     if (fullName.isEmpty() && emailAddress.isEmpty()) {
0156         KEMailSettings emailSettings;
0157         fullName = emailSettings.getSetting(KEMailSettings::RealName);
0158         emailAddress = emailSettings.getSetting(KEMailSettings::EmailAddress);
0159 
0160         if (!fullName.isEmpty() && !emailAddress.isEmpty()) {
0161             q->newFromControlCenter(i18nc("use default address from control center", "Default"));
0162             done = true;
0163         } else {
0164             // If KEmailSettings doesn't have name and address, generate something from KUser
0165             KUser user;
0166             if (fullName.isEmpty()) {
0167                 fullName = user.property(KUser::FullName).toString();
0168             }
0169             if (emailAddress.isEmpty()) {
0170                 emailAddress = user.loginName();
0171                 if (!emailAddress.isEmpty()) {
0172                     KConfigGroup general(mConfig, QStringLiteral("General"));
0173                     QString defaultdomain = general.readEntry("Default domain");
0174                     if (!defaultdomain.isEmpty()) {
0175                         emailAddress += QLatin1Char('@') + defaultdomain;
0176                     } else {
0177                         emailAddress.clear();
0178                     }
0179                 }
0180             }
0181         }
0182     }
0183 
0184     if (!done) {
0185         // Default identity name
0186         QString name(i18nc("Default name for new email accounts/identities.", "Unnamed"));
0187 
0188         if (!emailAddress.isEmpty()) {
0189             // If we have an email address, create a default identity name from it
0190             QString idName = emailAddress;
0191             int pos = idName.indexOf(QLatin1Char('@'));
0192             if (pos != -1) {
0193                 name = idName.mid(pos + 1, -1);
0194             }
0195 
0196             // Make the name a bit more human friendly
0197             name.replace(QLatin1Char('.'), QLatin1Char(' '));
0198             pos = name.indexOf(QLatin1Char(' '));
0199             if (pos != 0) {
0200                 name[pos + 1] = name[pos + 1].toUpper();
0201             }
0202             name[0] = name[0].toUpper();
0203         } else if (!fullName.isEmpty()) {
0204             // If we have a full name, create a default identity name from it
0205             name = fullName;
0206         }
0207         shadowIdentities << Identity(name, fullName, emailAddress);
0208     }
0209 
0210     shadowIdentities.last().setIsDefault(true);
0211     shadowIdentities.last().setUoid(newUoid());
0212     if (mReadOnly) { // commit won't do it in readonly mode
0213         mIdentities = shadowIdentities;
0214     }
0215 }
0216 
0217 QStringList IdentityManagerPrivate::groupList(KConfig *config) const
0218 {
0219     return config->groupList().filter(QRegularExpression(QStringLiteral("^Identity #\\d+$")));
0220 }
0221 
0222 int IdentityManagerPrivate::newUoid()
0223 {
0224     int uoid;
0225 
0226     // determine the UOIDs of all saved identities
0227     QList<uint> usedUOIDs;
0228     usedUOIDs.reserve(mIdentities.count() + (q->hasPendingChanges() ? shadowIdentities.count() : 0));
0229     const QList<Identity>::ConstIterator end(mIdentities.constEnd());
0230     for (QList<Identity>::ConstIterator it = mIdentities.constBegin(); it != end; ++it) {
0231         usedUOIDs << (*it).uoid();
0232     }
0233 
0234     if (q->hasPendingChanges()) {
0235         // add UOIDs of all shadow identities. Yes, we will add a lot of duplicate
0236         // UOIDs, but avoiding duplicate UOIDs isn't worth the effort.
0237         const QList<Identity>::ConstIterator endShadow(shadowIdentities.constEnd());
0238         for (QList<Identity>::ConstIterator it = shadowIdentities.constBegin(); it != endShadow; ++it) {
0239             usedUOIDs << (*it).uoid();
0240         }
0241     }
0242 
0243     do {
0244         // 0 refers to the default identity, so accept 1 only as lowest value
0245         uoid = QRandomGenerator::global()->bounded(1, RAND_MAX);
0246     } while (usedUOIDs.contains(uoid));
0247 
0248     return uoid;
0249 }
0250 
0251 void IdentityManagerPrivate::slotIdentitiesChanged(const QString &id)
0252 {
0253     qCDebug(KIDENTITYMANAGEMENT_LOG) << " KIdentityManagementCore::IdentityManager::slotIdentitiesChanged :" << id;
0254     const QString ourIdentifier = QStringLiteral("%1/%2").arg(QDBusConnection::sessionBus().baseService(), q->property("uniqueDBusPath").toString());
0255     if (id != ourIdentifier) {
0256         mConfig->reparseConfiguration();
0257         Q_ASSERT(!q->hasPendingChanges());
0258         readConfig(mConfig);
0259         Q_EMIT q->needToReloadIdentitySettings();
0260         Q_EMIT q->changed();
0261         Q_EMIT q->identitiesWereChanged();
0262     }
0263 }
0264 
0265 Q_GLOBAL_STATIC(IdentityManager, s_self)
0266 
0267 IdentityManager *IdentityManager::self()
0268 {
0269     return s_self;
0270 }
0271 
0272 IdentityManager::IdentityManager(bool readonly, QObject *parent, const char *name)
0273     : QObject(parent)
0274     , d(new IdentityManagerPrivate(this))
0275 {
0276     setObjectName(QLatin1StringView(name));
0277     new IdentityManagerAdaptor(this);
0278     QDBusConnection dbus = QDBusConnection::sessionBus();
0279     const QString dbusPath = newDBusObjectName();
0280     setProperty("uniqueDBusPath", dbusPath);
0281     const QString dbusInterface = QStringLiteral("org.kde.pim.IdentityManager");
0282     dbus.registerObject(dbusPath, this);
0283     dbus.connect(QString(), QString(), dbusInterface, QStringLiteral("identitiesChanged"), this, SLOT(slotIdentitiesChanged(QString)));
0284 
0285     d->mReadOnly = readonly;
0286     d->mConfig = new KConfig(QStringLiteral("emailidentities"));
0287     if (!d->mConfig->isConfigWritable(true)) {
0288         qCWarning(KIDENTITYMANAGEMENT_LOG) << "impossible to write on this file";
0289     }
0290     d->readConfig(d->mConfig);
0291     // we need at least a default identity:
0292     if (d->mIdentities.isEmpty()) {
0293         qCDebug(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: No identity found. Creating default.";
0294         d->createDefaultIdentity();
0295         commit();
0296     }
0297 
0298     KSharedConfig::Ptr kmailConf(KSharedConfig::openConfig(QStringLiteral("kmail2rc")));
0299     if (!d->mReadOnly) {
0300         bool needCommit = false;
0301         if (kmailConf->hasGroup(QStringLiteral("Composer"))) {
0302             KConfigGroup composerGroup = kmailConf->group(QStringLiteral("Composer"));
0303             if (composerGroup.hasKey(QStringLiteral("pgp-auto-sign"))) {
0304                 const bool pgpAutoSign = composerGroup.readEntry(QStringLiteral("pgp-auto-sign"), false);
0305                 const QList<Identity>::iterator end = d->mIdentities.end();
0306                 for (QList<Identity>::iterator it = d->mIdentities.begin(); it != end; ++it) {
0307                     it->setPgpAutoSign(pgpAutoSign);
0308                 }
0309                 composerGroup.deleteEntry(QStringLiteral("pgp-auto-sign"));
0310                 composerGroup.sync();
0311                 needCommit = true;
0312             }
0313         }
0314         if (kmailConf->hasGroup(QStringLiteral("General"))) {
0315             KConfigGroup generalGroup = kmailConf->group(QStringLiteral("General"));
0316             if (generalGroup.hasKey(QStringLiteral("Default domain"))) {
0317                 QString defaultDomain = generalGroup.readEntry(QStringLiteral("Default domain"));
0318                 if (defaultDomain.isEmpty()) {
0319                     defaultDomain = QHostInfo::localHostName();
0320                 }
0321                 const QList<Identity>::iterator end = d->mIdentities.end();
0322                 for (QList<Identity>::iterator it = d->mIdentities.begin(); it != end; ++it) {
0323                     it->setDefaultDomainName(defaultDomain);
0324                 }
0325                 generalGroup.deleteEntry(QStringLiteral("Default domain"));
0326                 generalGroup.sync();
0327                 needCommit = true;
0328             }
0329         }
0330         if (needCommit) {
0331             commit();
0332         }
0333     }
0334 
0335     // Migration: people without settings in kemailsettings should get some
0336     if (KEMailSettings().getSetting(KEMailSettings::EmailAddress).isEmpty()) {
0337         d->writeConfig();
0338     }
0339 }
0340 
0341 IdentityManager::~IdentityManager()
0342 {
0343     if (hasPendingChanges()) {
0344         qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: There were uncommitted changes!";
0345     }
0346 }
0347 
0348 QString IdentityManager::makeUnique(const QString &name) const
0349 {
0350     int suffix = 1;
0351     QString result = name;
0352     while (identities().contains(result)) {
0353         result = i18nc(
0354             "%1: name; %2: number appended to it to make it unique "
0355             "among a list of names",
0356             "%1 #%2",
0357             name,
0358             suffix);
0359         ++suffix;
0360     }
0361     return result;
0362 }
0363 
0364 bool IdentityManager::isUnique(const QString &name) const
0365 {
0366     return !identities().contains(name);
0367 }
0368 
0369 void IdentityManager::commit()
0370 {
0371     // early out:
0372     if (!hasPendingChanges() || d->mReadOnly) {
0373         return;
0374     }
0375 
0376     QList<uint> seenUOIDs;
0377     seenUOIDs.reserve(d->mIdentities.count());
0378     const QList<Identity>::ConstIterator end = d->mIdentities.constEnd();
0379     for (QList<Identity>::ConstIterator it = d->mIdentities.constBegin(); it != end; ++it) {
0380         seenUOIDs << (*it).uoid();
0381     }
0382 
0383     QList<uint> changedUOIDs;
0384     // find added and changed identities:
0385     for (QList<Identity>::ConstIterator it = d->shadowIdentities.constBegin(); it != d->shadowIdentities.constEnd(); ++it) {
0386         const int index = seenUOIDs.indexOf((*it).uoid());
0387         if (index != -1) {
0388             uint uoid = seenUOIDs.at(index);
0389             const Identity &orig = identityForUoid(uoid); // look up in mIdentities
0390             if (*it != orig) {
0391                 // changed identity
0392                 qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting changed() for identity" << uoid;
0393                 Q_EMIT changed(*it);
0394                 Q_EMIT identityChanged(*it);
0395                 changedUOIDs << uoid;
0396             }
0397             seenUOIDs.removeAll(uoid);
0398         } else {
0399             // new identity
0400             qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting added() for identity" << (*it).uoid();
0401             Q_EMIT added(*it);
0402         }
0403     }
0404 
0405     // what's left are deleted identities:
0406     for (QList<uint>::ConstIterator it = seenUOIDs.constBegin(); it != seenUOIDs.constEnd(); ++it) {
0407         qCDebug(KIDENTITYMANAGEMENT_LOG) << "emitting deleted() for identity" << (*it);
0408         Q_EMIT deleted(*it);
0409     }
0410 
0411     d->mIdentities = d->shadowIdentities;
0412     d->writeConfig();
0413 
0414     // now that mIdentities has all the new info, we can Q_EMIT the added/changed
0415     // signals that ship a uoid. This is because the slots might use
0416     // identityForUoid(uoid)...
0417     QList<uint>::ConstIterator changedEnd(changedUOIDs.constEnd());
0418     for (QList<uint>::ConstIterator it = changedUOIDs.constBegin(); it != changedEnd; ++it) {
0419         Q_EMIT changed(*it);
0420     }
0421 
0422     Q_EMIT changed(); // normal signal
0423     Q_EMIT identitiesWereChanged(); // normal signal
0424 
0425     // DBus signal for other IdentityManager instances
0426     const QString ourIdentifier = QStringLiteral("%1/%2").arg(QDBusConnection::sessionBus().baseService(), property("uniqueDBusPath").toString());
0427     Q_EMIT identitiesChanged(ourIdentifier);
0428 }
0429 
0430 void IdentityManager::rollback()
0431 {
0432     d->shadowIdentities = d->mIdentities;
0433 }
0434 
0435 void IdentityManager::saveIdentity(const Identity &ident)
0436 {
0437     const auto existing = std::find_if(modifyBegin(), modifyEnd(), [ident](const auto &existingIdentity) {
0438         return existingIdentity.uoid() == ident.uoid();
0439     });
0440 
0441     if (existing != modifyEnd()) {
0442         d->shadowIdentities.replace(existing - modifyBegin(), ident);
0443     } else {
0444         d->shadowIdentities << ident;
0445     }
0446 
0447     commit();
0448 }
0449 
0450 bool IdentityManager::hasPendingChanges() const
0451 {
0452     return d->mIdentities != d->shadowIdentities;
0453 }
0454 
0455 QStringList IdentityManager::identities() const
0456 {
0457     QStringList result;
0458     result.reserve(d->mIdentities.count());
0459     ConstIterator end = d->mIdentities.constEnd();
0460     for (ConstIterator it = d->mIdentities.constBegin(); it != end; ++it) {
0461         result << (*it).identityName();
0462     }
0463     return result;
0464 }
0465 
0466 QStringList IdentityManager::shadowIdentities() const
0467 {
0468     QStringList result;
0469     result.reserve(d->shadowIdentities.count());
0470     ConstIterator end = d->shadowIdentities.constEnd();
0471     for (ConstIterator it = d->shadowIdentities.constBegin(); it != end; ++it) {
0472         result << (*it).identityName();
0473     }
0474     return result;
0475 }
0476 
0477 void IdentityManager::sort()
0478 {
0479     std::sort(d->shadowIdentities.begin(), d->shadowIdentities.end());
0480 }
0481 
0482 IdentityManager::ConstIterator IdentityManager::begin() const
0483 {
0484     return d->mIdentities.constBegin();
0485 }
0486 
0487 IdentityManager::ConstIterator IdentityManager::end() const
0488 {
0489     return d->mIdentities.constEnd();
0490 }
0491 
0492 IdentityManager::Iterator IdentityManager::modifyBegin()
0493 {
0494     return d->shadowIdentities.begin();
0495 }
0496 
0497 IdentityManager::Iterator IdentityManager::modifyEnd()
0498 {
0499     return d->shadowIdentities.end();
0500 }
0501 
0502 const Identity &IdentityManager::identityForUoid(uint uoid) const
0503 {
0504     for (ConstIterator it = begin(); it != end(); ++it) {
0505         if ((*it).uoid() == uoid) {
0506             return *it;
0507         }
0508     }
0509     return Identity::null();
0510 }
0511 
0512 const Identity &IdentityManager::identityForUoidOrDefault(uint uoid) const
0513 {
0514     const Identity &ident = identityForUoid(uoid);
0515     if (ident.isNull()) {
0516         return defaultIdentity();
0517     } else {
0518         return ident;
0519     }
0520 }
0521 
0522 const Identity &IdentityManager::identityForAddress(const QString &addresses) const
0523 {
0524     const QStringList addressList = KEmailAddress::splitAddressList(addresses);
0525     for (const QString &fullAddress : addressList) {
0526         const QString addrSpec = KEmailAddress::extractEmailAddress(fullAddress).toLower();
0527         for (ConstIterator it = begin(); it != end(); ++it) {
0528             const Identity &identity = *it;
0529             if (identity.matchesEmailAddress(addrSpec)) {
0530                 return identity;
0531             }
0532         }
0533     }
0534     return Identity::null();
0535 }
0536 
0537 bool IdentityManager::thatIsMe(const QString &addressList) const
0538 {
0539     return !identityForAddress(addressList).isNull();
0540 }
0541 
0542 Identity &IdentityManager::modifyIdentityForName(const QString &name)
0543 {
0544     for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) {
0545         if ((*it).identityName() == name) {
0546             return *it;
0547         }
0548     }
0549 
0550     qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager::modifyIdentityForName() used as"
0551                                        << "newFromScratch() replacement!" << Qt::endl
0552                                        << "  name == \"" << name << "\"";
0553     return newFromScratch(name);
0554 }
0555 
0556 Identity &IdentityManager::modifyIdentityForUoid(uint uoid)
0557 {
0558     for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) {
0559         if ((*it).uoid() == uoid) {
0560             return *it;
0561         }
0562     }
0563 
0564     qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager::identityForUoid() used as"
0565                                        << "newFromScratch() replacement!" << Qt::endl
0566                                        << "  uoid == \"" << uoid << "\"";
0567     return newFromScratch(i18n("Unnamed"));
0568 }
0569 
0570 const Identity &IdentityManager::defaultIdentity() const
0571 {
0572     for (ConstIterator it = begin(); it != end(); ++it) {
0573         if ((*it).isDefault()) {
0574             return *it;
0575         }
0576     }
0577 
0578     if (d->mIdentities.isEmpty()) {
0579         qCritical() << "IdentityManager: No default identity found!";
0580     } else {
0581         qCWarning(KIDENTITYMANAGEMENT_LOG) << "IdentityManager: No default identity found!";
0582     }
0583     return *begin();
0584 }
0585 
0586 bool IdentityManager::setAsDefault(uint uoid)
0587 {
0588     // First, check if the identity actually exists:
0589     bool found = false;
0590     ConstIterator end(d->shadowIdentities.constEnd());
0591     for (ConstIterator it = d->shadowIdentities.constBegin(); it != end; ++it) {
0592         if ((*it).uoid() == uoid) {
0593             found = true;
0594             break;
0595         }
0596     }
0597 
0598     if (!found) {
0599         return false;
0600     }
0601 
0602     // Then, change the default as requested:
0603     for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) {
0604         (*it).setIsDefault((*it).uoid() == uoid);
0605     }
0606 
0607     // and re-sort:
0608     sort();
0609     return true;
0610 }
0611 
0612 bool IdentityManager::removeIdentity(const QString &name)
0613 {
0614     if (d->shadowIdentities.size() <= 1) {
0615         return false;
0616     }
0617 
0618     for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) {
0619         if ((*it).identityName() == name) {
0620             bool removedWasDefault = (*it).isDefault();
0621             d->shadowIdentities.erase(it);
0622             if (removedWasDefault && !d->shadowIdentities.isEmpty()) {
0623                 d->shadowIdentities.first().setIsDefault(true);
0624             }
0625             return true;
0626         }
0627     }
0628     return false;
0629 }
0630 
0631 bool IdentityManager::removeIdentityForced(const QString &name)
0632 {
0633     for (Iterator it = modifyBegin(); it != modifyEnd(); ++it) {
0634         if ((*it).identityName() == name) {
0635             bool removedWasDefault = (*it).isDefault();
0636             d->shadowIdentities.erase(it);
0637             if (removedWasDefault && !d->shadowIdentities.isEmpty()) {
0638                 d->shadowIdentities.first().setIsDefault(true);
0639             }
0640             return true;
0641         }
0642     }
0643     return false;
0644 }
0645 
0646 Identity &IdentityManager::newFromScratch(const QString &name)
0647 {
0648     return newFromExisting(Identity(name));
0649 }
0650 
0651 Identity &IdentityManager::newFromControlCenter(const QString &name)
0652 {
0653     KEMailSettings es;
0654     es.setProfile(es.defaultProfileName());
0655 
0656     return newFromExisting(Identity(name,
0657                                     es.getSetting(KEMailSettings::RealName),
0658                                     es.getSetting(KEMailSettings::EmailAddress),
0659                                     es.getSetting(KEMailSettings::Organization),
0660                                     es.getSetting(KEMailSettings::ReplyToAddress)));
0661 }
0662 
0663 Identity &IdentityManager::newFromExisting(const Identity &other, const QString &name)
0664 {
0665     d->shadowIdentities << other;
0666     Identity &result = d->shadowIdentities.last();
0667     result.setIsDefault(false); // we don't want two default identities!
0668     result.setUoid(d->newUoid()); // we don't want two identities w/ same UOID
0669     if (!name.isNull()) {
0670         result.setIdentityName(name);
0671     }
0672     return result;
0673 }
0674 
0675 QStringList KIdentityManagementCore::IdentityManager::allEmails() const
0676 {
0677     QStringList lst;
0678     for (ConstIterator it = begin(); it != end(); ++it) {
0679         lst << (*it).primaryEmailAddress();
0680         if (!(*it).emailAliases().isEmpty()) {
0681             lst << (*it).emailAliases();
0682         }
0683     }
0684     return lst;
0685 }
0686 
0687 void IdentityManager::createDefaultIdentity(QString &, QString &)
0688 {
0689 }
0690 
0691 void KIdentityManagementCore::IdentityManager::slotRollback()
0692 {
0693     rollback();
0694 }
0695 
0696 IdentityManagerPrivate::~IdentityManagerPrivate()
0697 {
0698     delete mConfig;
0699 }
0700 }
0701 #include "moc_identitymanager.cpp"