Warning, file /frameworks/kpeople/src/metacontact.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2013 David Edmundson <davidedmundson@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "global.h"
0008 #include "kpeople_debug.h"
0009 #include "metacontact_p.h"
0010 
0011 #include <QSharedData>
0012 
0013 namespace KPeople
0014 {
0015 class MetaContactData : public QSharedData
0016 {
0017 public:
0018     QString personUri;
0019     QStringList contactUris;
0020     AbstractContact::List contacts;
0021     AbstractContact::Ptr personAddressee;
0022 };
0023 }
0024 
0025 // TODO: It feels like MetaContact and MetaContactProxy should be merged,
0026 // still, not today.
0027 
0028 class MetaContactProxy : public KPeople::AbstractContact
0029 {
0030 public:
0031     MetaContactProxy(const AbstractContact::List &contacts)
0032         : m_contacts(contacts)
0033     {
0034     }
0035 
0036     QVariant customProperty(const QString &key) const override
0037     {
0038         if (key.startsWith(QLatin1String("all-"))) {
0039             QVariantList ret;
0040             for (const AbstractContact::Ptr &contact : std::as_const(m_contacts)) {
0041                 QVariant val = contact->customProperty(key);
0042                 Q_ASSERT(val.canConvert<QVariantList>() || val.isNull());
0043 
0044                 if (!val.isNull()) {
0045                     ret.append(val.toList());
0046                 }
0047             }
0048             return ret;
0049         } else {
0050             for (const AbstractContact::Ptr &contact : std::as_const(m_contacts)) {
0051                 QVariant val = contact->customProperty(key);
0052                 if (val.isValid()) {
0053                     return val;
0054                 }
0055             }
0056             return QVariant();
0057         }
0058     }
0059 
0060     const AbstractContact::List m_contacts;
0061 };
0062 
0063 using namespace KPeople;
0064 
0065 MetaContact::MetaContact()
0066     : d(new MetaContactData)
0067 {
0068     reload();
0069 }
0070 
0071 MetaContact::MetaContact(const QString &personUri, const QMap<QString, AbstractContact::Ptr> &contacts)
0072     : d(new MetaContactData)
0073 {
0074     d->personUri = personUri;
0075 
0076     QMap<QString, AbstractContact::Ptr>::const_iterator it = contacts.constBegin();
0077     while (it != contacts.constEnd()) {
0078         insertContactInternal(it.key(), it.value());
0079         it++;
0080     }
0081     reload();
0082 }
0083 
0084 MetaContact::MetaContact(const QString &contactUri, const AbstractContact::Ptr &contact)
0085     : d(new MetaContactData)
0086 {
0087     d->personUri = contactUri;
0088     insertContactInternal(contactUri, contact);
0089     reload();
0090 }
0091 
0092 MetaContact::MetaContact(const MetaContact &other)
0093     : d(other.d)
0094 {
0095 }
0096 
0097 MetaContact &MetaContact::operator=(const MetaContact &other)
0098 {
0099     if (this != &other) {
0100         d = other.d;
0101     }
0102 
0103     return *this;
0104 }
0105 
0106 MetaContact::~MetaContact()
0107 {
0108 }
0109 
0110 QString MetaContact::id() const
0111 {
0112     return d->personUri;
0113 }
0114 
0115 bool MetaContact::isValid() const
0116 {
0117     return !d->contacts.isEmpty();
0118 }
0119 
0120 QStringList MetaContact::contactUris() const
0121 {
0122     return d->contactUris;
0123 }
0124 
0125 AbstractContact::Ptr MetaContact::contact(const QString &contactUri)
0126 {
0127     int index = d->contactUris.indexOf(contactUri);
0128     if (index >= 0) {
0129         return d->contacts[index];
0130     } else {
0131         return AbstractContact::Ptr();
0132     }
0133 }
0134 
0135 AbstractContact::List MetaContact::contacts() const
0136 {
0137     return d->contacts;
0138 }
0139 
0140 const AbstractContact::Ptr &MetaContact::personAddressee() const
0141 {
0142     Q_ASSERT(d->personAddressee);
0143     return d->personAddressee;
0144 }
0145 
0146 int MetaContact::insertContact(const QString &contactUri, const AbstractContact::Ptr &contact)
0147 {
0148     int index = insertContactInternal(contactUri, contact);
0149     if (index >= 0) {
0150         reload();
0151     } else {
0152         qCWarning(KPEOPLE_LOG) << "Inserting an already-present contact" << contactUri;
0153     }
0154     return index;
0155 }
0156 
0157 int MetaContact::insertContactInternal(const QString &contactUri, const AbstractContact::Ptr &contact)
0158 {
0159     if (d->contactUris.contains(contactUri)) {
0160         // if item is already listed, do nothing.
0161         return -1;
0162     } else {
0163         // TODO if from the local address book - prepend to give higher priority.
0164         int index = d->contacts.size();
0165         d->contacts.append(contact);
0166         d->contactUris.append(contactUri);
0167         return index;
0168     }
0169 }
0170 
0171 int MetaContact::updateContact(const QString &contactUri, const AbstractContact::Ptr &contact)
0172 {
0173     const int index = d->contactUris.indexOf(contactUri);
0174     Q_ASSERT(index < 0 || d->contacts[index] == contact);
0175     if (index < 0) {
0176         qCWarning(KPEOPLE_LOG) << "contact not part of the metacontact";
0177     }
0178     return index;
0179 }
0180 
0181 int MetaContact::removeContact(const QString &contactUri)
0182 {
0183     const int index = d->contactUris.indexOf(contactUri);
0184     if (index >= 0) {
0185         d->contacts.removeAt(index);
0186         d->contactUris.removeAt(index);
0187         reload();
0188     }
0189     return index;
0190 }
0191 
0192 void MetaContact::reload()
0193 {
0194     // always favour the first item
0195 
0196     // Optimization, if only one contact re-use that one
0197     d->personAddressee = (d->contacts.size() == 1) ? d->contacts.first() : AbstractContact::Ptr(new MetaContactProxy(d->contacts));
0198     Q_ASSERT(d->personAddressee);
0199 }