1 /*
2    SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
3 
4    SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "libruqolawidgets_private_export.h"
10 #include "utils.h"
11 
12 #include "misc/pixmapcache.h"
13 
14 #include <QFont>
15 #include <QItemDelegate>
16 #include <QScopedPointer>
17 
18 class QListView;
19 class RocketChatAccount;
20 class Message;
21 class MessageDelegateHelperBase;
22 class MessageDelegateHelperText;
23 class MessageAttachmentDelegateHelperImage;
24 class MessageAttachmentDelegateHelperFile;
25 class MessageDelegateHelperReactions;
26 class MessageAttachmentDelegateHelperVideo;
27 class MessageAttachmentDelegateHelperSound;
28 class MessageAttachmentDelegateHelperText;
29 class MessageAttachment;
30 class AvatarCacheManager;
31 class LIBRUQOLAWIDGETS_TESTS_EXPORT MessageListDelegate : public QItemDelegate
32 {
33     Q_OBJECT
34 
35 public:
36     explicit MessageListDelegate(QListView *view);
37     ~MessageListDelegate() override;
38 
39     void setRocketChatAccount(RocketChatAccount *rcAccount);
40 
41     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
42     QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
43     bool mouseEvent(QEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index);
44     bool maybeStartDrag(QMouseEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index);
45 
46     bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override;
47 
48     void drawDate(QPainter *painter, const QModelIndex &index, const QStyleOptionViewItem &option, bool drawLastSeenLine) const;
49 
50     void setShowThreadContext(bool b);
51 
52     Q_REQUIRED_RESULT bool hasSelection() const;
53     Q_REQUIRED_RESULT QString selectedText() const;
54 
55     void selectAll(const QStyleOptionViewItem &option, const QModelIndex &index);
56     void clearTextDocumentCache();
57 
58     void clearSelection();
59 
60 private:
61     Q_REQUIRED_RESULT bool showIgnoreMessages(const QModelIndex &index) const;
62     Q_REQUIRED_RESULT QPixmap makeAvatarPixmap(const QWidget *widget, const QModelIndex &index, int maxHeight) const;
63 
64     struct Layout {
65         // Sender
66         QString senderText;
67         QFont senderFont;
68         QRectF senderRect;
69 
70         // Avatar pixmap
71         QPixmap avatarPixmap;
72         QPointF avatarPos;
73 
74         // Roles icon
75         QRect rolesIconRect;
76 
77         // Edited icon
78         QRect editedIconRect;
79 
80         // Favorite icon
81         QRect favoriteIconRect;
82 
83         // Pinned icon
84         QRect pinIconRect;
85 
86         // Translated icon
87         QRect translatedIconRect;
88 
89         // Show Ignore Message icon
90         QRect showIgnoredMessageIconRect;
91 
92         // add-reaction button and timestamp
93         QRect addReactionRect;
94         QString timeStampText;
95         QPoint timeStampPos;
96         QRect timeStampRect;
97 
98         QRect usableRect; // rect for everything except the date header (at the top) and the sender (on the left)
99 
100         // Text message
101         QRect textRect;
102         qreal baseLine; // used to draw sender/timestamp
103 
104         // Attachments
105         QRect attachmentsRect;
106         QVector<QRect> attachmentsRectList;
107 
108         // Reactions
109         qreal reactionsY = 0;
110         qreal reactionsHeight = 0;
111 
112         // Replies
113         qreal repliesY = 0;
114         qreal repliesHeight = 0;
115 
116         // Discussions
117         qreal discussionsHeight = 0;
118 
119         // Last See
120         qreal displayLastSeenMessageY = 0;
121 
122         // showIgnoreMessage
123         bool showIgnoreMessage = false;
124     };
125     Layout doLayout(const QStyleOptionViewItem &option, const QModelIndex &index) const;
126     void drawLastSeenLine(QPainter *painter, qint64 displayLastSeenY, const QStyleOptionViewItem &option) const;
127 
128     /// @note Ownership is not transferred
129     MessageDelegateHelperBase *attachmentsHelper(const MessageAttachment &msgAttach) const;
130 
131     friend class MessageListDelegateTest;
132 
133     const QIcon mEditedIcon;
134     const QIcon mRolesIcon;
135     const QIcon mAddReactionIcon;
136     const QIcon mFavoriteIcon;
137     const QIcon mPinIcon;
138     const QIcon mTranslatedIcon;
139     QColor mEditColorMode;
140     QColor mOpenDiscussionColorMode;
141     QColor mReplyThreadColorMode;
142     RocketChatAccount *mRocketChatAccount = nullptr;
143     QListView *const mListView;
144 
145     QScopedPointer<MessageDelegateHelperText> mHelperText;
146     QScopedPointer<MessageAttachmentDelegateHelperImage> mHelperAttachmentImage;
147     QScopedPointer<MessageAttachmentDelegateHelperFile> mHelperAttachmentFile;
148     QScopedPointer<MessageDelegateHelperReactions> mHelperReactions;
149     QScopedPointer<MessageAttachmentDelegateHelperVideo> mHelperAttachmentVideo;
150     QScopedPointer<MessageAttachmentDelegateHelperSound> mHelperAttachmentSound;
151     QScopedPointer<MessageAttachmentDelegateHelperText> mHelperAttachmentText;
152     AvatarCacheManager *const mAvatarCacheManager;
153 };
154