File indexing completed on 2024-12-22 04:46:05
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "messageattachmentdelegatehelpervideo.h" 0008 #include "common/delegatepaintutil.h" 0009 #include "common/delegateutil.h" 0010 #include "dialogs/showvideodialog.h" 0011 #include "misc/messageattachmentdownloadandsavejob.h" 0012 #include "rocketchataccount.h" 0013 0014 #include <KLocalizedString> 0015 0016 #include <QAbstractItemView> 0017 #include <QAbstractTextDocumentLayout> 0018 #include <QMouseEvent> 0019 #include <QPainter> 0020 #include <QStyleOptionViewItem> 0021 0022 MessageAttachmentDelegateHelperVideo::MessageAttachmentDelegateHelperVideo(RocketChatAccount *account, QListView *view, TextSelectionImpl *textSelectionImpl) 0023 : MessageAttachmentDelegateHelperBase(account, view, textSelectionImpl) 0024 , mDownloadIcon(QIcon::fromTheme(QStringLiteral("cloud-download"))) 0025 , mVisibilityIcon(QIcon::fromTheme(QStringLiteral("visibility"))) 0026 { 0027 } 0028 0029 MessageAttachmentDelegateHelperVideo::~MessageAttachmentDelegateHelperVideo() = default; 0030 0031 void MessageAttachmentDelegateHelperVideo::draw(const MessageAttachment &msgAttach, 0032 QPainter *painter, 0033 QRect messageRect, 0034 const QModelIndex &index, 0035 const QStyleOptionViewItem &option) const 0036 { 0037 const VideoLayout layout = layoutVideo(msgAttach, option, messageRect.width()); 0038 // drawTitle(msgAttach, painter, ); 0039 // Draw title and buttons 0040 painter->drawText(messageRect.x(), messageRect.y() + option.fontMetrics.ascent(), layout.title); 0041 0042 mVisibilityIcon.paint(painter, layout.showButtonRect.translated(messageRect.topLeft())); 0043 mDownloadIcon.paint(painter, layout.downloadButtonRect.translated(messageRect.topLeft())); 0044 0045 const int nextY = messageRect.y() + layout.titleSize.height() + DelegatePaintUtil::margin(); 0046 0047 drawDescription(msgAttach, messageRect, painter, nextY, index, option); 0048 } 0049 0050 QSize MessageAttachmentDelegateHelperVideo::sizeHint(const MessageAttachment &msgAttach, 0051 const QModelIndex &index, 0052 int maxWidth, 0053 const QStyleOptionViewItem &option) const 0054 { 0055 Q_UNUSED(index) 0056 const VideoLayout layout = layoutVideo(msgAttach, option, maxWidth); 0057 int height = layout.titleSize.height() + DelegatePaintUtil::margin(); 0058 int descriptionWidth = 0; 0059 if (layout.hasDescription) { 0060 descriptionWidth = layout.descriptionSize.width(); 0061 height += layout.descriptionSize.height() + DelegatePaintUtil::margin(); 0062 } 0063 return {qMax(qMax(0, layout.titleSize.width()), descriptionWidth), height}; 0064 } 0065 0066 bool MessageAttachmentDelegateHelperVideo::handleMouseEvent(const MessageAttachment &msgAttach, 0067 QMouseEvent *mouseEvent, 0068 QRect attachmentsRect, 0069 const QStyleOptionViewItem &option, 0070 const QModelIndex &index) 0071 { 0072 const QEvent::Type eventType = mouseEvent->type(); 0073 switch (eventType) { 0074 case QEvent::MouseButtonRelease: { 0075 const QPoint pos = mouseEvent->pos(); 0076 0077 const VideoLayout layout = layoutVideo(msgAttach, option, attachmentsRect.width()); 0078 if (layout.downloadButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) { 0079 MessageAttachmentDownloadAndSaveJob::MessageAttachmentDownloadJobInfo info; 0080 info.attachmentType = MessageAttachmentDownloadAndSaveJob::AttachmentType::Video; 0081 info.actionType = MessageAttachmentDownloadAndSaveJob::ActionType::DownloadAndSave; 0082 info.needToDownloadAttachment = !mRocketChatAccount->attachmentIsInLocalCache(layout.videoPath); 0083 info.parentWidget = const_cast<QWidget *>(option.widget); 0084 info.attachmentPath = layout.videoPath; 0085 auto job = new MessageAttachmentDownloadAndSaveJob(this); 0086 job->setRocketChatAccount(mRocketChatAccount); 0087 job->setInfo(std::move(info)); 0088 job->start(); 0089 return true; 0090 } else if (QRect(attachmentsRect.topLeft(), layout.titleSize).contains(pos) 0091 || layout.showButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) { 0092 auto parentWidget = const_cast<QWidget *>(option.widget); 0093 ShowVideoDialog dlg(mRocketChatAccount, parentWidget); 0094 dlg.setVideoPath(layout.videoPath); 0095 dlg.exec(); 0096 return true; 0097 } 0098 break; 0099 } 0100 default: 0101 break; 0102 } 0103 0104 return MessageAttachmentDelegateHelperBase::handleMouseEvent(msgAttach, mouseEvent, attachmentsRect, option, index); 0105 } 0106 0107 MessageAttachmentDelegateHelperVideo::VideoLayout 0108 MessageAttachmentDelegateHelperVideo::layoutVideo(const MessageAttachment &msgAttach, const QStyleOptionViewItem &option, int attachmentsWidth) const 0109 { 0110 VideoLayout layout; 0111 // or we could do layout.attachment = msgAttach; if we need many fields from it 0112 layout.title = msgAttach.title(); 0113 layout.hasDescription = msgAttach.hasDescription(); 0114 layout.titleSize = option.fontMetrics.size(Qt::TextSingleLine, layout.title); 0115 layout.descriptionSize = documentDescriptionForIndexSize(convertAttachmentToDocumentDescriptionInfo(msgAttach, attachmentsWidth)); 0116 const int iconSize = option.widget->style()->pixelMetric(QStyle::PM_ButtonIconSize); 0117 layout.showButtonRect = QRect(layout.titleSize.width() + DelegatePaintUtil::margin(), 0, iconSize, iconSize); 0118 layout.downloadButtonRect = layout.showButtonRect.translated(iconSize + DelegatePaintUtil::margin(), 0); 0119 layout.videoPath = msgAttach.link(); 0120 return layout; 0121 } 0122 0123 QPoint MessageAttachmentDelegateHelperVideo::adaptMousePosition(const QPoint &pos, 0124 const MessageAttachment &msgAttach, 0125 QRect attachmentsRect, 0126 const QStyleOptionViewItem &option) 0127 { 0128 const VideoLayout layout = layoutVideo(msgAttach, option, attachmentsRect.width()); 0129 const QPoint relativePos = pos - attachmentsRect.topLeft() - QPoint(0, layout.titleSize.height() + DelegatePaintUtil::margin()); 0130 return relativePos; 0131 }