File indexing completed on 2024-12-15 04:54:42
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 <QColor> 0012 #include <QRect> 0013 #include <QStyledItemDelegate> 0014 0015 #include "core/item.h" 0016 #include "core/theme.h" 0017 0018 class QAbstractItemView; 0019 0020 namespace MessageList 0021 { 0022 namespace Core 0023 { 0024 class Item; 0025 0026 /** 0027 * The ThemeDelegate paints the message list view message and group items by 0028 * using the supplied Theme. 0029 */ 0030 class ThemeDelegate : public QStyledItemDelegate 0031 { 0032 Q_OBJECT 0033 0034 public: 0035 explicit ThemeDelegate(QAbstractItemView *parent); 0036 ~ThemeDelegate() override; 0037 /** 0038 * Called when the global fonts change (from systemsettings) 0039 */ 0040 void generalFontChanged(); 0041 0042 private: 0043 const Theme *mTheme = nullptr; ///< Shallow pointer to the current theme 0044 QAbstractItemView *const mItemView; 0045 0046 QColor mGroupHeaderBackgroundColor; // cache 0047 0048 // hitTest results 0049 QModelIndex mHitIndex; 0050 Item *mHitItem = nullptr; 0051 QRect mHitItemRect; 0052 const Theme::Column *mHitColumn = nullptr; 0053 const Theme::Row *mHitRow = nullptr; 0054 int mHitRowIndex; 0055 bool mHitRowIsMessageRow; 0056 QRect mHitRowRect; 0057 bool mHitContentItemRight; 0058 const Theme::ContentItem *mHitContentItem = nullptr; 0059 QRect mHitContentItemRect; 0060 0061 mutable QSize mCachedMessageItemSizeHint; 0062 mutable QSize mCachedGroupHeaderItemSizeHint; 0063 0064 public: 0065 const Theme *theme() const; 0066 void setTheme(const Theme *theme); 0067 0068 /** 0069 * Returns a heuristic sizeHint() for the specified item type and column. 0070 * The hint is based on the contents of the theme (and not of any message or group header). 0071 */ 0072 QSize sizeHintForItemTypeAndColumn(Item::Type type, int column, const Item *item = nullptr) const; 0073 0074 /** 0075 * Performs a hit test on the specified viewport point. 0076 * Returns true if the point hit something and false otherwise. 0077 * When the hit test is successful then the hitIndex(), hitItem(), hitColumn(), hitRow(), and hitContentItem() 0078 * function will return information about the item that was effectively hit. 0079 * If exact is set to true then hitTest() will return true only if the viewportPoint 0080 * is exactly over an item. If exact is set to false then the hitTest() function 0081 * will do its best to find the closest object to be actually "hit": this is useful, 0082 * for example, in drag and drop operations. 0083 */ 0084 bool hitTest(const QPoint &viewportPoint, bool exact = true); 0085 0086 /** 0087 * Returns the model index that was reported as hit by the previous call to hitTest(). 0088 * The result of this function is valid only if hitTest() returned true and only 0089 * within the same calling function. 0090 */ 0091 const QModelIndex &hitIndex() const; 0092 0093 /** 0094 * Returns the Item that was reported as hit by the previous call to hitTest(). 0095 * The result of this function is valid only if hitTest() returned true and only 0096 * within the same calling function. 0097 */ 0098 Item *hitItem() const; 0099 0100 /** 0101 * Returns the visual rectangle of the item that was reported as hit by the previous call to hitTest(). 0102 * The result of this function is valid only if hitTest() returned true and only 0103 * within the same calling function. Please note that this rectangle refers 0104 * to a specific item column (and not all of the columns). 0105 */ 0106 QRect hitItemRect() const; 0107 0108 /** 0109 * Returns the theme column that was reported as hit by the previous call to hitTest(). 0110 * The result of this function is valid only if hitTest() returned true and only 0111 * within the same calling function. 0112 */ 0113 const Theme::Column *hitColumn() const; 0114 0115 /** 0116 * Returns the index of the theme column that was reported as hit by the previous call to hitTest(). 0117 * The result of this function is valid only if hitTest() returned true and only 0118 * within the same calling function. 0119 * This is the same as hitIndex().column(). 0120 */ 0121 int hitColumnIndex() const; 0122 0123 /** 0124 * Returns the theme row that was reported as hit by the previous call to hitTest(). 0125 * The result of this function is valid only if hitTest() returned true and only 0126 * within the same calling function. This function may also return a null row 0127 * when hitTest() returned true. This means that the item was globally hit 0128 * but no row was exactly hit (the user probably hit the margin instead). 0129 */ 0130 const Theme::Row *hitRow() const; 0131 0132 /** 0133 * Returns the index of the theme row that was reported as hit by the previous call to hitTest(). 0134 * The result of this function is valid only if hitRow() returns a non null value. 0135 */ 0136 int hitRowIndex() const; 0137 0138 /** 0139 * Returns the rectangle of the row that was reported as hit by the previous call to hitTest(). 0140 * The result of this function is valid only if hitTest() returned true and only 0141 * within the same calling function. The result of this function is also invalid 0142 * if hitRow() returns 0. 0143 */ 0144 QRect hitRowRect() const; 0145 0146 /** 0147 * Returns true if the hitRow() is a message row, false otherwise. 0148 * The result of this function has a meaning only if hitRow() returns a non zero result. 0149 */ 0150 bool hitRowIsMessageRow() const; 0151 0152 /** 0153 * Returns the theme content item that was reported as hit by the previous call to hitTest(). 0154 * The result of this function is valid only if hitTest() returned true and only 0155 * within the same calling function. This function may also return a null content item 0156 * when hitTest() returned true. This means that the item was globally hit 0157 * but no content item was exactly hit (the user might have clicked inside a blank unused space instead). 0158 */ 0159 const Theme::ContentItem *hitContentItem() const; 0160 0161 /** 0162 * Returns true if the hit theme content item was a right item and false otherwise. 0163 * The result of this function is valid only if hitContentItem() returns true. 0164 */ 0165 bool hitContentItemRight() const; 0166 0167 /** 0168 * Returns the bounding rect of the content item that was reported as hit by the previous call to hitTest(). 0169 * The result of this function is valid only if hitTest() returned true and only 0170 * within the same calling function. The result of this function is to be considered 0171 * invalid also when hitContentItem() returns 0. 0172 */ 0173 QRect hitContentItemRect() const; 0174 0175 protected: 0176 /** 0177 * Returns the Item for the specified model index. Pure virtual: must be reimplemented 0178 * by derived classes. 0179 */ 0180 virtual Item *itemFromIndex(const QModelIndex &index) const = 0; 0181 0182 /** 0183 * Reimplemented from QStyledItemDelegate 0184 */ 0185 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; 0186 0187 /** 0188 * Reimplemented from QStyledItemDelegate 0189 */ 0190 QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; 0191 }; 0192 } // namespace Core 0193 } // namespace MessageList