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 }