File indexing completed on 2024-05-19 05:14:36

0001 /*
0002   This file is part of KAddressBook.
0003 
0004   SPDX-FileCopyrightText: 2020 Konrad Czapla <kondzio89dev@gmail.com>
0005 
0006   SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #pragma once
0010 
0011 #include <Akonadi/EntityTreeModel>
0012 #include <KContacts/ContactGroup>
0013 #include <QIdentityProxyModel>
0014 #include <QObject>
0015 
0016 namespace Akonadi
0017 {
0018 class Item;
0019 class Monitor;
0020 }
0021 
0022 namespace KContacts
0023 {
0024 class Addressee;
0025 class ContactGroup;
0026 }
0027 class ContactInfoProxyModel : public QIdentityProxyModel
0028 {
0029     Q_OBJECT
0030 public:
0031     enum Roles {
0032         PictureRole = Akonadi::EntityTreeModel::UserRole,
0033         InitialsRole,
0034         DescriptionRole,
0035     };
0036 
0037     explicit ContactInfoProxyModel(QObject *parent = nullptr);
0038     QVariant data(const QModelIndex &index, int role) const override;
0039 
0040 private:
0041     class ContactCacheData
0042     {
0043     public:
0044         using List = QList<ContactCacheData>;
0045         using ListIterator = ContactCacheData::List::iterator;
0046         using ConstListIterator = ContactCacheData::List::ConstIterator;
0047 
0048         ContactCacheData() = default;
0049         ~ContactCacheData() = default;
0050         ContactCacheData(const ContactCacheData &) = default;
0051 
0052         ContactCacheData(const KContacts::ContactGroup::ContactReference &other)
0053             : mUid(other.uid())
0054             , mGid(other.gid())
0055         {
0056         }
0057 
0058         ContactCacheData(const Akonadi::Item &other)
0059             : mUid(QString::number(other.id()))
0060             , mGid(other.gid())
0061         {
0062         }
0063 
0064         [[nodiscard]] bool setData(const Akonadi::Item &item);
0065 
0066         friend bool operator==(const ContactCacheData &lhs, const ContactCacheData &rhs);
0067 
0068         [[nodiscard]] QString uid() const
0069         {
0070             return mUid;
0071         }
0072         [[nodiscard]] QString gid() const
0073         {
0074             return mGid;
0075         }
0076         [[nodiscard]] QString name() const
0077         {
0078             return mName;
0079         }
0080         [[nodiscard]] QString email() const
0081         {
0082             return mEmail;
0083         }
0084 
0085     private:
0086         [[nodiscard]] bool validateItem(const Akonadi::Item &item) const;
0087         QString mUid;
0088         QString mGid;
0089         QString mName;
0090         QString mEmail;
0091     };
0092 
0093     [[nodiscard]] QString getInitials(const KContacts::Addressee &contact) const;
0094     [[nodiscard]] QString getInitials(const Akonadi::Item::Id groupItemId, const KContacts::ContactGroup &groupContacts) const;
0095     [[nodiscard]] QString getDescription(const KContacts::Addressee &contact) const;
0096     [[nodiscard]] QString getDescription(const Akonadi::Item::Id groupItemId, const KContacts::ContactGroup &groupContacts) const;
0097     [[nodiscard]] QStringList getIdsContactGroup(const KContacts::ContactGroup &group) const;
0098     [[nodiscard]] QStringList getIdsCacheContactGroup(const Akonadi::Item::Id groupItemId) const;
0099     [[nodiscard]] bool isCacheItemToFetch(const Akonadi::Item::Id groupItemId, const KContacts::ContactGroup &group) const;
0100     [[nodiscard]] ContactCacheData::ListIterator findCacheItem(const Akonadi::Item::Id groupItemId, const ContactCacheData &cacheContact);
0101     [[nodiscard]] ContactCacheData::ConstListIterator findCacheItem(const Akonadi::Item::Id groupItemId, const ContactCacheData &cacheContact) const;
0102     [[nodiscard]] QMap<const char *, QVariant> buildFetchProperties(const Akonadi::Item::Id groupItemId) const;
0103 
0104     void resolveGroup(const Akonadi::Item::Id groupItemId, const KContacts::ContactGroup &groupContacts) const;
0105     void fetchItems(const Akonadi::Item::List &items, const QMap<const char *, QVariant> &properties) const;
0106 
0107     void slotFetchJobFinished(KJob *job);
0108     void slotItemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers);
0109     void slotRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
0110 
0111     friend bool operator==(const ContactCacheData &lhs, const ContactCacheData &rhs);
0112     using Cache = QMap<Akonadi::Item::Id, ContactCacheData::List>;
0113     mutable Cache mGroupsCache;
0114     mutable QList<Akonadi::Item::Id> mPendingGroupItems;
0115     const QList<int> mKrole{PictureRole, InitialsRole, DescriptionRole};
0116     Akonadi::Monitor *const mMonitor;
0117 };