File indexing completed on 2024-12-15 04:54:38
0001 /****************************************************************************** 0002 * 0003 * SPDX-FileCopyrightText: 2008 Szymon Tomasz Stefanek <pragma@kvirc.net> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 * 0007 *******************************************************************************/ 0008 0009 #pragma once 0010 0011 #include "item_p.h" 0012 #include "messageitem.h" 0013 #include <Akonadi/Item> 0014 #include <Akonadi/Monitor> 0015 #include <Akonadi/Tag> 0016 #include <KJob> 0017 #include <PimCommonAkonadi/AnnotationDialog> 0018 #include <QCache> 0019 0020 namespace MessageList 0021 { 0022 namespace Core 0023 { 0024 class MessageItemPrivate : public ItemPrivate 0025 { 0026 public: 0027 explicit MessageItemPrivate(MessageItem *qq); 0028 ~MessageItemPrivate() override; 0029 0030 /** 0031 * Linear search in the list of tags. The lists of tags 0032 * associated to a message are supposed to be very short (c'mon.. you won't add more than a couple of tags to a single msg). 0033 * so a linear search is better than a hash lookup in most cases. 0034 */ 0035 const MessageItem::Tag *findTagInternal(const QString &szTagId) const; 0036 0037 /// Returns the list of tags. This is calculated on demand and cached in mTagList 0038 QList<MessageItem::Tag *> getTagList() const; 0039 0040 bool tagListInitialized() const; 0041 0042 /// Returns the tag with the highest priority, or 0 if there are no tags 0043 const MessageItem::Tag *bestTag() const; 0044 0045 /// Deletes the internal list of tags 0046 void invalidateTagCache(); 0047 0048 /// Deletes the cache of the annotation 0049 void invalidateAnnotationCache(); 0050 0051 // This creates mTagList and fills it with useful data 0052 void fillTagList(const Akonadi::Tag::List &taglist); 0053 0054 QByteArray mMessageIdMD5; ///< always set 0055 QByteArray mInReplyToIdMD5; ///< set only if we're doing threading 0056 QByteArray mReferencesIdMD5; ///< set only if we're doing threading 0057 QByteArray mStrippedSubjectMD5; ///< set only if we're doing threading 0058 Akonadi::Item mAkonadiItem; 0059 MessageItem::ThreadingStatus mThreadingStatus : 4; 0060 MessageItem::EncryptionState mEncryptionState : 4; 0061 MessageItem::SignatureState mSignatureState : 4; 0062 0063 bool mAboutToBeRemoved : 1; ///< Set to true when this item is going to be deleted and shouldn't be selectable 0064 bool mSubjectIsPrefixed : 1; ///< set only if we're doing subject based threading 0065 0066 private: 0067 // List of all tags. If this is 0, it means we have not yet calculated this list. It is calculated 0068 // on demand when needed. 0069 mutable QList<MessageItem::Tag *> *mTagList; 0070 }; 0071 0072 class FakeItemPrivate : public MessageItemPrivate 0073 { 0074 public: 0075 explicit FakeItemPrivate(FakeItem *qq); 0076 QList<MessageItem::Tag *> mFakeTags; 0077 }; 0078 0079 /** 0080 * A tag cache 0081 */ 0082 class TagCache : public QObject 0083 { 0084 Q_OBJECT 0085 public: 0086 TagCache(); 0087 void retrieveTags(const Akonadi::Tag::List &tags, MessageItemPrivate *m); 0088 void cancelRequest(MessageItemPrivate *m); 0089 0090 private Q_SLOTS: 0091 void onTagAdded(const Akonadi::Tag &); 0092 void onTagChanged(const Akonadi::Tag &); 0093 void onTagRemoved(const Akonadi::Tag &); 0094 void onTagsFetched(KJob *); 0095 0096 private: 0097 QHash<KJob *, MessageItemPrivate *> mRequests; 0098 QCache<Akonadi::Tag::Id, Akonadi::Tag> mCache; 0099 Akonadi::Monitor *mMonitor = nullptr; 0100 }; 0101 } 0102 }