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 }