1 /*
2 SPDX-FileCopyrightText: 2020-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "messageattachmentdelegatehelpervideo.h"
8 #include "common/delegatepaintutil.h"
9 #include "common/delegateutil.h"
10 #include "dialogs/showvideodialog.h"
11 #include "rocketchataccount.h"
12 #include "ruqola.h"
13 #include "ruqolawidgets_debug.h"
14
15 #include <KLocalizedString>
16
17 #include <KMessageBox>
18 #include <QAbstractItemView>
19 #include <QMouseEvent>
20 #include <QPainter>
21 #include <QPointer>
22 #include <QStyleOptionViewItem>
23
MessageAttachmentDelegateHelperVideo()24 MessageAttachmentDelegateHelperVideo::MessageAttachmentDelegateHelperVideo()
25 : mDownloadIcon(QIcon::fromTheme(QStringLiteral("cloud-download")))
26 , mVisibilityIcon(QIcon::fromTheme(QStringLiteral("visibility")))
27 {
28 }
29
30 MessageAttachmentDelegateHelperVideo::~MessageAttachmentDelegateHelperVideo() = default;
31
draw(const MessageAttachment & msgAttach,QPainter * painter,QRect messageRect,const QModelIndex & index,const QStyleOptionViewItem & option) const32 void MessageAttachmentDelegateHelperVideo::draw(const MessageAttachment &msgAttach,
33 QPainter *painter,
34 QRect messageRect,
35 const QModelIndex &index,
36 const QStyleOptionViewItem &option) const
37 {
38 Q_UNUSED(index)
39 const VideoLayout layout = layoutVideo(msgAttach, option, messageRect.width());
40 // Draw title and buttons
41 painter->drawText(messageRect.x(), messageRect.y() + option.fontMetrics.ascent(), layout.title);
42
43 mVisibilityIcon.paint(painter, layout.showButtonRect.translated(messageRect.topLeft()));
44 mDownloadIcon.paint(painter, layout.downloadButtonRect.translated(messageRect.topLeft()));
45
46 const int nextY = messageRect.y() + layout.titleSize.height() + DelegatePaintUtil::margin();
47
48 drawDescription(msgAttach, messageRect, painter, nextY);
49 }
50
sizeHint(const MessageAttachment & msgAttach,const QModelIndex & index,int maxWidth,const QStyleOptionViewItem & option) const51 QSize MessageAttachmentDelegateHelperVideo::sizeHint(const MessageAttachment &msgAttach,
52 const QModelIndex &index,
53 int maxWidth,
54 const QStyleOptionViewItem &option) const
55 {
56 Q_UNUSED(index)
57 const VideoLayout layout = layoutVideo(msgAttach, option, maxWidth);
58 int height = layout.titleSize.height() + DelegatePaintUtil::margin();
59 int descriptionWidth = 0;
60 if (!layout.description.isEmpty()) {
61 descriptionWidth = layout.descriptionSize.width();
62 height += layout.descriptionSize.height() + DelegatePaintUtil::margin();
63 }
64 return {qMax(qMax(0, layout.titleSize.width()), descriptionWidth), height};
65 }
66
handleMouseEvent(const MessageAttachment & msgAttach,QMouseEvent * mouseEvent,QRect attachmentsRect,const QStyleOptionViewItem & option,const QModelIndex & index)67 bool MessageAttachmentDelegateHelperVideo::handleMouseEvent(const MessageAttachment &msgAttach,
68 QMouseEvent *mouseEvent,
69 QRect attachmentsRect,
70 const QStyleOptionViewItem &option,
71 const QModelIndex &index)
72 {
73 if (mouseEvent->type() == QEvent::MouseButtonRelease) {
74 const QPoint pos = mouseEvent->pos();
75
76 VideoLayout layout = layoutVideo(msgAttach, option, attachmentsRect.width());
77 if (layout.downloadButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) {
78 auto *parentWidget = const_cast<QWidget *>(option.widget);
79 DelegateUtil::saveFile(parentWidget, layout.videoPath, i18n("Save Image"));
80 return true;
81 } else if (attachmentsRect.contains(pos) || layout.showButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) {
82 auto *parentWidget = const_cast<QWidget *>(option.widget);
83 ShowVideoDialog dlg(parentWidget);
84 dlg.setVideoUrl(QUrl::fromLocalFile(layout.videoPath));
85 dlg.exec();
86 return true;
87 }
88 }
89
90 return MessageDelegateHelperBase::handleMouseEvent(msgAttach, mouseEvent, attachmentsRect, option, index);
91 }
92
93 MessageAttachmentDelegateHelperVideo::VideoLayout
layoutVideo(const MessageAttachment & msgAttach,const QStyleOptionViewItem & option,int attachmentsWidth) const94 MessageAttachmentDelegateHelperVideo::layoutVideo(const MessageAttachment &msgAttach, const QStyleOptionViewItem &option, int attachmentsWidth) const
95 {
96 VideoLayout layout;
97 const QUrl url = Ruqola::self()->rocketChatAccount()->attachmentUrlFromLocalCache(msgAttach.link());
98 // or we could do layout.attachment = msgAttach; if we need many fields from it
99 layout.title = msgAttach.title();
100 layout.description = msgAttach.description();
101 layout.titleSize = option.fontMetrics.size(Qt::TextSingleLine, layout.title);
102 layout.descriptionSize = documentDescriptionForIndexSize(msgAttach, attachmentsWidth);
103 const int iconSize = option.widget->style()->pixelMetric(QStyle::PM_ButtonIconSize);
104 layout.showButtonRect = QRect(layout.titleSize.width() + DelegatePaintUtil::margin(), 0, iconSize, iconSize);
105 layout.downloadButtonRect = layout.showButtonRect.translated(iconSize + DelegatePaintUtil::margin(), 0);
106 if (url.isLocalFile()) {
107 layout.videoPath = url.toLocalFile();
108 }
109 return layout;
110 }
111