File indexing completed on 2024-12-15 04:54:37
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 <QList> 0012 #include <QString> 0013 0014 #include <ctime> // for time_t 0015 0016 #include <KMime/Headers> 0017 0018 #include <Akonadi/MessageStatus> 0019 0020 #include "core/model.h" 0021 #include "messagelist_export.h" 0022 0023 namespace MessageList 0024 { 0025 namespace Core 0026 { 0027 class ItemPrivate; 0028 0029 /** 0030 * A single item of the MessageList tree managed by MessageList::Model. 0031 * 0032 * This class stores basic information needed in all the subclasses which 0033 * at the moment of writing are MessageItem and GroupHeaderItem. 0034 */ 0035 class MESSAGELIST_EXPORT Item 0036 { 0037 friend class Model; 0038 friend class ModelPrivate; 0039 0040 public: 0041 /** 0042 * The type of the Item. 0043 */ 0044 enum Type { 0045 GroupHeader, ///< This item is a GroupHeaderItem 0046 Message, ///< This item is a MessageItem 0047 InvisibleRoot ///< This item is just Item and it's the only InvisibleRoot per Model. 0048 }; 0049 0050 /** 0051 * Specifies the initial expand status for the item that should be applied 0052 * when it's attached to the viewable tree. Needed as a workaround for 0053 * QTreeView limitations in handling item expansion. 0054 */ 0055 enum InitialExpandStatus { 0056 ExpandNeeded, ///< Must expand when this item becomes viewable 0057 NoExpandNeeded, ///< No expand needed at all 0058 ExpandExecuted ///< Item already expanded 0059 }; 0060 0061 protected: 0062 /** 0063 * Creates an Item. Only derived classes and MessageList::Model should access this. 0064 */ 0065 Item(Type type); 0066 Item(Type type, ItemPrivate *dd); 0067 0068 public: 0069 /** 0070 * Destroys the Item. Should be protected just like the constructor but the QList<> 0071 * helpers need to access it, so it's public actually. 0072 */ 0073 virtual ~Item(); 0074 0075 /** 0076 * Returns the type of this item. The Type can be set only in the constructor. 0077 */ 0078 [[nodiscard]] Type type() const; 0079 0080 /** 0081 * The initial expand status we have to honor when attaching to the viewable root. 0082 */ 0083 [[nodiscard]] InitialExpandStatus initialExpandStatus() const; 0084 0085 /** 0086 * Set the initial expand status we have to honor when attaching to the viewable root. 0087 */ 0088 void setInitialExpandStatus(InitialExpandStatus initialExpandStatus); 0089 0090 /** 0091 * Is this item attached to the viewable root ? 0092 */ 0093 [[nodiscard]] bool isViewable() const; 0094 0095 /** 0096 * Return true if Item pointed by it is an ancestor of this item (that is, 0097 * if it is its parent, parent of its parent, parent of its parent of its parent etc... 0098 */ 0099 [[nodiscard]] bool hasAncestor(const Item *it) const; 0100 0101 /** 0102 * Makes this item viewable, that is, notifies its existence to any listener 0103 * attached to the "rowsInserted()" signal, most notably QTreeView. 0104 * 0105 * This will also make all the children viewable. 0106 */ 0107 void setViewable(Model *model, bool bViewable); 0108 0109 /** 0110 * Return the list of child items. May be null. 0111 */ 0112 [[nodiscard]] QList<Item *> *childItems() const; 0113 0114 /** 0115 * Returns the child item at position idx or 0 if idx is out of the allowable range. 0116 */ 0117 [[nodiscard]] Item *childItem(int idx) const; 0118 0119 /** 0120 * Returns the first child item, if any. 0121 */ 0122 [[nodiscard]] Item *firstChildItem() const; 0123 0124 /** 0125 * Returns the item that is visually below the specified child if this item. 0126 * Note that the returned item may belong to a completely different subtree. 0127 */ 0128 [[nodiscard]] Item *itemBelowChild(Item *child); 0129 0130 /** 0131 * Returns the item that is visually above the specified child if this item. 0132 * Note that the returned item may belong to a completely different subtree. 0133 */ 0134 [[nodiscard]] Item *itemAboveChild(Item *child); 0135 0136 /** 0137 * Returns the deepest item in the subtree originating at this item. 0138 */ 0139 [[nodiscard]] Item *deepestItem(); 0140 0141 /** 0142 * Returns the item that is visually below this item in the tree. 0143 * Note that the returned item may belong to a completely different subtree. 0144 */ 0145 [[nodiscard]] Item *itemBelow(); 0146 0147 /** 0148 * Returns the item that is visually above this item in the tree. 0149 * Note that the returned item may belong to a completely different subtree. 0150 */ 0151 [[nodiscard]] Item *itemAbove(); 0152 0153 /** 0154 * Debug helper. Dumps the structure of this subtree. 0155 */ 0156 void dump(const QString &prefix); 0157 0158 /** 0159 * Returns the number of children of this Item. 0160 */ 0161 [[nodiscard]] int childItemCount() const; 0162 0163 /** 0164 * Convenience function that returns true if this item has children. 0165 */ 0166 [[nodiscard]] bool hasChildren() const; 0167 0168 /** 0169 * A structure used with MessageList::Item::childItemStats(). 0170 * Contains counts of total and unread messages in a subtree. 0171 */ 0172 class ChildItemStats 0173 { 0174 public: 0175 unsigned int mTotalChildCount; // total 0176 unsigned int mUnreadChildCount; // unread only 0177 public: 0178 ChildItemStats() 0179 : mTotalChildCount(0) 0180 , mUnreadChildCount(0) 0181 { 0182 } 0183 }; 0184 0185 /** 0186 * Gathers statistics about child items. 0187 * For performance purposes assumes that this item has children. 0188 * You MUST check it before calling it. 0189 */ 0190 void childItemStats(ChildItemStats &stats) const; 0191 0192 /** 0193 * Returns the actual index of the child Item item or -1 if 0194 * item is not a child of this Item. 0195 */ 0196 int indexOfChildItem(Item *item) const; 0197 0198 /** 0199 * Sets the cached guess for the index of this item in the parent's child list. 0200 * 0201 * This is used to speed up the index lookup with the following algorithm: 0202 * Ask the parent if this item is at the position specified by index guess (this costs ~O(1)). 0203 * If the position matches we have finished, if it doesn't then perform 0204 * a linear search via indexOfChildItem() (which costs ~O(n)). 0205 */ 0206 void setIndexGuess(int index); 0207 0208 /** 0209 * Returns the parent Item in the tree, or 0 if this item isn't attached to the tree. 0210 * Please note that even if this item has a non-zero parent, it can be still non viewable. 0211 * That is: the topmost parent of this item may be not attached to the viewable root. 0212 */ 0213 [[nodiscard]] Item *parent() const; 0214 0215 /** 0216 * Sets the parent for this item. You should also take care of inserting 0217 * this item in the parent's child list. 0218 */ 0219 void setParent(Item *pParent); 0220 0221 /** 0222 * Returns the topmost parent item that is not a Root item (that is, is a Message or GroupHeader). 0223 */ 0224 [[nodiscard]] Item *topmostNonRoot(); 0225 0226 /** 0227 * Returns the status associated to this Item. 0228 */ 0229 const Akonadi::MessageStatus &status() const; 0230 0231 /** 0232 * Sets the status associated to this Item. 0233 */ 0234 void setStatus(Akonadi::MessageStatus status); 0235 0236 /** 0237 * Returns a string describing the status e.g: "Read, Forwarded, Important" 0238 */ 0239 [[nodiscard]] QString statusDescription() const; 0240 0241 /** 0242 * Returns the size of this item (size of the Message, mainly) 0243 */ 0244 size_t size() const; 0245 0246 /** 0247 * Sets the size of this item (size of the Message, mainly) 0248 */ 0249 void setSize(size_t size); 0250 0251 /** 0252 * A string with a text rappresentation of size(). This is computed on-the-fly 0253 * and not cached. 0254 */ 0255 [[nodiscard]] QString formattedSize() const; 0256 0257 /** 0258 * Returns the date of this item 0259 */ 0260 time_t date() const; 0261 0262 /** 0263 * Sets the date of this item 0264 */ 0265 void setDate(time_t date); 0266 0267 /** 0268 * A string with a text rappresentation of date() obtained via Manager. This is computed on-the-fly 0269 * and not cached. 0270 */ 0271 [[nodiscard]] QString formattedDate() const; 0272 0273 /** 0274 * Returns the maximum date in the subtree originating from this item. 0275 * This is kept up-to-date by MessageList::Model. 0276 */ 0277 time_t maxDate() const; 0278 0279 /** 0280 * Sets the maximum date in the subtree originating from this item. 0281 */ 0282 void setMaxDate(time_t date); 0283 0284 /** 0285 * A string with a text rappresentation of maxDate() obtained via Manager. This is computed on-the-fly 0286 * and not cached. 0287 */ 0288 [[nodiscard]] QString formattedMaxDate() const; 0289 0290 /** 0291 * Recompute the maximum date from the current children list. 0292 * Return true if the current max date changed and false otherwise. 0293 */ 0294 bool recomputeMaxDate(); 0295 0296 /** 0297 * Returns the sender associated to this item. 0298 */ 0299 [[nodiscard]] const QString &sender() const; 0300 0301 /** 0302 * Sets the sender associated to this item. 0303 */ 0304 void setSender(const QString &sender); 0305 0306 /** 0307 * Display sender. 0308 */ 0309 [[nodiscard]] QString displaySender() const; 0310 0311 /** 0312 * Returns the receiver associated to this item. 0313 */ 0314 const QString &receiver() const; 0315 0316 /** 0317 * Sets the sender associated to this item. 0318 */ 0319 void setReceiver(const QString &receiver); 0320 0321 /** 0322 * Display receiver. 0323 */ 0324 [[nodiscard]] QString displayReceiver() const; 0325 0326 /** 0327 * Returns the sender or the receiver, depending on the underlying StorageModel settings. 0328 */ 0329 const QString &senderOrReceiver() const; 0330 0331 /** 0332 * Display sender or receiver. 0333 */ 0334 [[nodiscard]] QString displaySenderOrReceiver() const; 0335 0336 /** 0337 * Returns whether sender or receiver is supposed to be displayed. 0338 */ 0339 bool useReceiver() const; 0340 0341 /** 0342 * Returns the subject associated to this Item. 0343 */ 0344 const QString &subject() const; 0345 0346 /** 0347 * Sets the subject associated to this Item. 0348 */ 0349 void setSubject(const QString &subject); 0350 0351 /** 0352 * Returns the folder associated to this Item. 0353 */ 0354 const QString &folder() const; 0355 0356 /** 0357 * Sets the folder associated to this Item. 0358 */ 0359 void setFolder(const QString &folder); 0360 0361 /** 0362 * This is meant to be called right after the constructor. 0363 * It sets up several items at once (so even if not inlined it's still a single call) 0364 * and it skips some calls that can be avoided at constructor time. 0365 */ 0366 void initialSetup(time_t date, size_t size, const QString &sender, const QString &receiver, bool useReceiver); 0367 0368 void setItemId(qint64 id); 0369 [[nodiscard]] qint64 itemId() const; 0370 0371 void setParentCollectionId(qint64 id); 0372 [[nodiscard]] qint64 parentCollectionId() const; 0373 0374 /** 0375 * This is meant to be called right after the constructor for MessageItem objects. 0376 * It sets up several items at once (so even if not inlined it's still a single call). 0377 */ 0378 void setSubjectAndStatus(const QString &subject, Akonadi::MessageStatus status); 0379 0380 /** 0381 * Appends an Item to this item's child list. 0382 * The Model is used for beginInsertRows()/endInsertRows() calls. 0383 */ 0384 int appendChildItem(Model *model, Item *child); 0385 0386 /** 0387 * Appends a child item without inserting it via the model. 0388 * This is useful in ThemeEditor which doesn't use a custom model for the items. 0389 * You shouldn't need to use this function... 0390 */ 0391 void rawAppendChildItem(Item *child); 0392 0393 /** 0394 * Removes a child from this item's child list without deleting it. 0395 * The Model is used for beginRemoveRows()/endRemoveRows() calls. 0396 */ 0397 void takeChildItem(Model *model, Item *child); 0398 0399 /** 0400 * Kills all the child items without emitting any signal, recursively. 0401 * It should be used only when MessageList::Model is reset() afterwards. 0402 */ 0403 void killAllChildItems(); 0404 0405 protected: 0406 ItemPrivate *const d_ptr; 0407 Q_DECLARE_PRIVATE(Item) 0408 }; 0409 } // namespace Core 0410 } // namespace MessageList