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 "messageattachmentdelegatehelpersound.h"
0008 #include "common/delegatepaintutil.h"
0009 #include "common/delegateutil.h"
0010 #include "dialogs/playsounddialog.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 MessageAttachmentDelegateHelperSound::MessageAttachmentDelegateHelperSound(RocketChatAccount *account, QListView *view, TextSelectionImpl *textSelectionImpl)
0023     : MessageAttachmentDelegateHelperBase(account, view, textSelectionImpl)
0024     , mPlayerVolumeIcon(QIcon::fromTheme(QStringLiteral("player-volume")))
0025     , mDownloadIcon(QIcon::fromTheme(QStringLiteral("cloud-download")))
0026 {
0027 }
0028 
0029 MessageAttachmentDelegateHelperSound::~MessageAttachmentDelegateHelperSound() = default;
0030 
0031 void MessageAttachmentDelegateHelperSound::draw(const MessageAttachment &msgAttach,
0032                                                 QPainter *painter,
0033                                                 QRect messageRect,
0034                                                 const QModelIndex &index,
0035                                                 const QStyleOptionViewItem &option) const
0036 {
0037     const SoundLayout layout = layoutSound(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     mPlayerVolumeIcon.paint(painter, layout.playerVolumeButtonRect.translated(messageRect.topLeft()));
0042     mDownloadIcon.paint(painter, layout.downloadButtonRect.translated(messageRect.topLeft()));
0043 
0044     const int nextY = messageRect.y() + layout.titleSize.height() + DelegatePaintUtil::margin();
0045     drawDescription(msgAttach, messageRect, painter, nextY, index, option);
0046 }
0047 
0048 QSize MessageAttachmentDelegateHelperSound::sizeHint(const MessageAttachment &msgAttach,
0049                                                      const QModelIndex &index,
0050                                                      int maxWidth,
0051                                                      const QStyleOptionViewItem &option) const
0052 {
0053     Q_UNUSED(index)
0054     const SoundLayout layout = layoutSound(msgAttach, option, maxWidth);
0055     int height = layout.titleSize.height() + DelegatePaintUtil::margin();
0056     int descriptionWidth = 0;
0057     if (layout.hasDescription) {
0058         descriptionWidth = layout.descriptionSize.width();
0059         height += layout.descriptionSize.height() + DelegatePaintUtil::margin();
0060     }
0061     return {qMax(qMax(0, layout.titleSize.width()), descriptionWidth), height};
0062 }
0063 
0064 QPoint MessageAttachmentDelegateHelperSound::adaptMousePosition(const QPoint &pos,
0065                                                                 const MessageAttachment &msgAttach,
0066                                                                 QRect attachmentsRect,
0067                                                                 const QStyleOptionViewItem &option)
0068 {
0069     const SoundLayout layout = layoutSound(msgAttach, option, attachmentsRect.width());
0070     const QPoint relativePos = pos - attachmentsRect.topLeft() - QPoint(0, layout.titleSize.height() + DelegatePaintUtil::margin());
0071     return relativePos;
0072 }
0073 
0074 bool MessageAttachmentDelegateHelperSound::handleMouseEvent(const MessageAttachment &msgAttach,
0075                                                             QMouseEvent *mouseEvent,
0076                                                             QRect attachmentsRect,
0077                                                             const QStyleOptionViewItem &option,
0078                                                             const QModelIndex &index)
0079 {
0080     const QEvent::Type eventType = mouseEvent->type();
0081     switch (eventType) {
0082     case QEvent::MouseButtonRelease: {
0083         const QPoint pos = mouseEvent->pos();
0084 
0085         const SoundLayout layout = layoutSound(msgAttach, option, attachmentsRect.width());
0086         if (layout.downloadButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) {
0087             MessageAttachmentDownloadAndSaveJob::MessageAttachmentDownloadJobInfo info;
0088             info.attachmentType = MessageAttachmentDownloadAndSaveJob::AttachmentType::Sound;
0089             info.actionType = MessageAttachmentDownloadAndSaveJob::ActionType::DownloadAndSave;
0090             info.needToDownloadAttachment = !mRocketChatAccount->attachmentIsInLocalCache(layout.audioPath);
0091             info.parentWidget = const_cast<QWidget *>(option.widget);
0092             info.attachmentPath = layout.audioPath;
0093             auto job = new MessageAttachmentDownloadAndSaveJob(this);
0094             job->setRocketChatAccount(mRocketChatAccount);
0095             job->setInfo(std::move(info));
0096             job->start();
0097             return true;
0098         } else if (QRect(attachmentsRect.topLeft(), layout.titleSize).contains(pos)
0099                    || layout.playerVolumeButtonRect.translated(attachmentsRect.topLeft()).contains(pos)) {
0100             auto parentWidget = const_cast<QWidget *>(option.widget);
0101             PlaySoundDialog dlg(mRocketChatAccount, parentWidget);
0102             dlg.setAudioPath(layout.audioPath);
0103             dlg.exec();
0104             return true;
0105         }
0106         break;
0107     }
0108     default:
0109         break;
0110     }
0111 
0112     return MessageAttachmentDelegateHelperBase::handleMouseEvent(msgAttach, mouseEvent, attachmentsRect, option, index);
0113 }
0114 
0115 MessageAttachmentDelegateHelperSound::SoundLayout
0116 MessageAttachmentDelegateHelperSound::layoutSound(const MessageAttachment &msgAttach, const QStyleOptionViewItem &option, int attachmentsWidth) const
0117 {
0118     SoundLayout layout;
0119     // or we could do layout.attachment = msgAttach; if we need many fields from it
0120     layout.title = msgAttach.title();
0121     layout.hasDescription = msgAttach.hasDescription();
0122     layout.titleSize = option.fontMetrics.size(Qt::TextSingleLine, layout.title);
0123     layout.descriptionSize = documentDescriptionForIndexSize(convertAttachmentToDocumentDescriptionInfo(msgAttach, attachmentsWidth));
0124     const int iconSize = option.widget->style()->pixelMetric(QStyle::PM_ButtonIconSize);
0125     layout.playerVolumeButtonRect = QRect(layout.titleSize.width() + DelegatePaintUtil::margin(), 0, iconSize, iconSize);
0126     layout.downloadButtonRect = layout.playerVolumeButtonRect.translated(iconSize + DelegatePaintUtil::margin(), 0);
0127     layout.audioPath = msgAttach.link();
0128     return layout;
0129 }