File indexing completed on 2019-12-31 11:46:54

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