File indexing completed on 2024-12-01 04:37:02
0001 /* 0002 SPDX-FileCopyrightText: 2021-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "roomwidgetbase.h" 0008 #include "dialogs/createnewdiscussiondialog.h" 0009 #include "messagelinewidget.h" 0010 #include "messagetextedit.h" 0011 #include "readonlylineeditwidget.h" 0012 #include "rocketchataccount.h" 0013 #include "room.h" 0014 #include "roomquotemessagewidget.h" 0015 #include "roomreplythreadwidget.h" 0016 #include "roomutil.h" 0017 #include "uploadfilemanager.h" 0018 #include "uploadfileprogressstatuslistwidget.h" 0019 0020 #include <QKeyEvent> 0021 #include <QStackedWidget> 0022 #include <QVBoxLayout> 0023 0024 RoomWidgetBase::RoomWidgetBase(MessageListView::Mode mode, QWidget *parent) 0025 : QWidget(parent) 0026 , mUploadFileProgressStatusListWidget(new UploadFileProgressStatusListWidget(this)) 0027 , mMessageListView(new MessageListView(nullptr, mode, this)) 0028 , mRoomReplyThreadWidget(new RoomReplyThreadWidget(this)) 0029 , mRoomQuoteMessageWidget(new RoomQuoteMessageWidget(this)) 0030 , mStackedWidget(new QStackedWidget(this)) 0031 , mMessageLineWidget(new MessageLineWidget(this)) 0032 , mReadOnlyLineEditWidget(new ReadOnlyLineEditWidget(this)) 0033 , mMainLayout(new QVBoxLayout(this)) 0034 { 0035 mMainLayout->setObjectName(QStringLiteral("mainLayout")); 0036 mMainLayout->setContentsMargins({}); 0037 mMainLayout->setSpacing(0); 0038 0039 mUploadFileProgressStatusListWidget->setObjectName(QStringLiteral("mUploadFileProgressStatusListWidget")); 0040 mUploadFileProgressStatusListWidget->setVisible(false); 0041 mMainLayout->addWidget(mUploadFileProgressStatusListWidget); 0042 connect(mUploadFileProgressStatusListWidget, &UploadFileProgressStatusListWidget::cancelUpload, this, &RoomWidgetBase::slotCancelUpload); 0043 0044 mMessageListView->setObjectName(QStringLiteral("mMessageListView")); 0045 mMessageListView->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::TopEdge | Qt::BottomEdge})); 0046 mMainLayout->addWidget(mMessageListView, 1); 0047 0048 mRoomReplyThreadWidget->setObjectName(QStringLiteral("mRoomReplyThreadWidget")); 0049 mRoomReplyThreadWidget->setVisible(false); 0050 0051 connect(mRoomReplyThreadWidget, &RoomReplyThreadWidget::cancelReplyingInThread, this, [this] { 0052 mMessageLineWidget->setThreadMessageId({}); 0053 }); 0054 0055 mRoomQuoteMessageWidget->setObjectName(QStringLiteral("mRoomQuoteMessageWidget")); 0056 mRoomQuoteMessageWidget->setVisible(false); 0057 0058 connect(mRoomQuoteMessageWidget, &RoomQuoteMessageWidget::cancelQuoteMessage, this, [this] { 0059 mMessageLineWidget->setQuoteMessage({}, QString()); 0060 }); 0061 0062 mMainLayout->addWidget(mRoomReplyThreadWidget); 0063 mMainLayout->addWidget(mRoomQuoteMessageWidget); 0064 0065 mStackedWidget->setObjectName(QStringLiteral("mStackedWidget")); 0066 mMainLayout->addWidget(mStackedWidget); 0067 0068 mMessageLineWidget->setObjectName(QStringLiteral("mMessageLineWidget")); 0069 mMessageLineWidget->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::TopEdge})); 0070 mStackedWidget->addWidget(mMessageLineWidget); 0071 0072 mReadOnlyLineEditWidget->setObjectName(QStringLiteral("mReadOnlyLineEditWidget")); 0073 mStackedWidget->addWidget(mReadOnlyLineEditWidget); 0074 0075 mStackedWidget->setCurrentWidget(mMessageLineWidget); 0076 0077 connect(mMessageLineWidget, &MessageLineWidget::keyPressed, this, &RoomWidgetBase::keyPressedInLineEdit); 0078 if (mode == MessageListView::Mode::Editing) { 0079 connect(mMessageLineWidget, &MessageLineWidget::threadMessageIdChanged, this, &RoomWidgetBase::slotShowThreadMessage); 0080 } 0081 connect(mMessageLineWidget, &MessageLineWidget::quoteMessageChanged, this, &RoomWidgetBase::slotShowQuoteMessage); 0082 connect(mMessageLineWidget, &MessageLineWidget::createUploadJob, this, &RoomWidgetBase::slotSendFile); 0083 0084 connect(mMessageListView, &MessageListView::editMessageRequested, mMessageLineWidget, &MessageLineWidget::setEditMessage); 0085 connect(mMessageListView, &MessageListView::quoteMessageRequested, mMessageLineWidget, &MessageLineWidget::setQuoteMessage); 0086 connect(mMessageListView, &MessageListView::createNewDiscussion, this, &RoomWidgetBase::createNewDiscussion); 0087 connect(mMessageListView, &MessageListView::createPrivateConversation, this, &RoomWidgetBase::slotCreatePrivateDiscussion); 0088 connect(mMessageListView, &MessageListView::loadHistoryRequested, this, &RoomWidgetBase::loadHistory); 0089 connect(mMessageListView, &MessageListView::replyInThreadRequested, mMessageLineWidget, [this](const QString &messageId, const QString &text) { 0090 mMessageLineWidget->setThreadMessageId(messageId, text, false); 0091 }); 0092 0093 connect(mMessageListView, &MessageListView::textToSpeech, this, &RoomWidgetBase::textToSpeech); 0094 0095 connect(mMessageListView, &MessageListView::errorMessage, this, &RoomWidgetBase::errorMessage); 0096 connect(mMessageListView, &MessageListView::successMessage, this, &RoomWidgetBase::successMessage); 0097 setAcceptDrops(true); 0098 } 0099 0100 RoomWidgetBase::~RoomWidgetBase() = default; 0101 0102 void RoomWidgetBase::slotSendFile(const RocketChatRestApi::UploadFileJob::UploadFileInfo &uploadFileInfo) 0103 { 0104 const int identifier = mCurrentRocketChatAccount->uploadFileManager()->addUpload(uploadFileInfo); 0105 if (identifier != -1) { 0106 mUploadFileProgressStatusListWidget->addProgressStatusWidget(identifier); 0107 } 0108 } 0109 0110 void RoomWidgetBase::slotShowThreadMessage(const QString &threadMessageId, const QString &text) 0111 { 0112 mRoomReplyThreadWidget->setMessageText(text); 0113 mRoomReplyThreadWidget->setVisible(!threadMessageId.isEmpty()); 0114 } 0115 0116 void RoomWidgetBase::slotCancelUpload(int identifier) 0117 { 0118 mCurrentRocketChatAccount->uploadFileManager()->cancelJob(identifier); 0119 } 0120 0121 MessageListView *RoomWidgetBase::messageListView() const 0122 { 0123 return mMessageListView; 0124 } 0125 0126 MessageLineWidget *RoomWidgetBase::messageLineWidget() const 0127 { 0128 return mMessageLineWidget; 0129 } 0130 0131 void RoomWidgetBase::slotShowQuoteMessage(const QString &permalink, const QString &text) 0132 { 0133 mRoomQuoteMessageWidget->setMessageText(text); 0134 mRoomQuoteMessageWidget->setVisible(!permalink.isEmpty()); 0135 } 0136 0137 void RoomWidgetBase::slotCreateNewDiscussion(const QString &messageId, const QString &originalMessage, const QString &channelName) 0138 { 0139 CreateNewDiscussionDialog dlg(mCurrentRocketChatAccount, this); 0140 dlg.setDiscussionName(originalMessage); 0141 dlg.setChannelInfo(channelName, mRoomId); 0142 dlg.setMessageId(messageId); 0143 dlg.exec(); 0144 } 0145 0146 void RoomWidgetBase::closeQuoteAndThreadInfo() 0147 { 0148 mRoomReplyThreadWidget->setVisible(false); 0149 mRoomQuoteMessageWidget->setVisible(false); 0150 } 0151 0152 void RoomWidgetBase::slotCreatePrivateDiscussion(const QString &userName) 0153 { 0154 Q_EMIT mCurrentRocketChatAccount->openLinkRequested(RoomUtil::generateUserLink(userName)); 0155 } 0156 0157 void RoomWidgetBase::keyPressedInLineEdit(QKeyEvent *ev) 0158 { 0159 const int key = ev->key(); 0160 if (key == Qt::Key_Escape) { 0161 if (mRoomReplyThreadWidget->isVisible()) { 0162 Q_EMIT mRoomReplyThreadWidget->cancelReplyingInThread(); 0163 } else if (mRoomQuoteMessageWidget->isVisible()) { 0164 Q_EMIT mRoomQuoteMessageWidget->cancelQuoteMessage(); 0165 } else { 0166 slotClearNotification(); 0167 } 0168 ev->accept(); 0169 } else if (ev->matches(QKeySequence::Copy) && mMessageLineWidget->messageTextEdit()->textCursor().selectedText().isEmpty()) { 0170 mMessageListView->copyMessageToClipboard(); 0171 ev->accept(); 0172 } else { 0173 mMessageListView->handleKeyPressEvent(ev); 0174 } 0175 } 0176 0177 void RoomWidgetBase::slotUploadProgress(const RocketChatRestApi::UploadFileJob::UploadStatusInfo &info, int jobIdentifier, const QString &accountName) 0178 { 0179 mUploadFileProgressStatusListWidget->uploadProgress(info, jobIdentifier, accountName); 0180 } 0181 0182 QString RoomWidgetBase::roomId() const 0183 { 0184 return mRoomId; 0185 } 0186 0187 void RoomWidgetBase::setRoomId(const QString &roomId) 0188 { 0189 mRoomId = roomId; 0190 } 0191 0192 void RoomWidgetBase::setCurrentRocketChatAccount(RocketChatAccount *account) 0193 { 0194 if (mCurrentRocketChatAccount) { 0195 disconnect(mCurrentRocketChatAccount, &RocketChatAccount::publicSettingChanged, mMessageLineWidget, &MessageLineWidget::slotPublicSettingChanged); 0196 disconnect(mCurrentRocketChatAccount->uploadFileManager(), &UploadFileManager::uploadProgress, this, &RoomWidgetBase::slotUploadProgress); 0197 disconnect(mCurrentRocketChatAccount, 0198 &RocketChatAccount::ownUserPreferencesChanged, 0199 mMessageLineWidget, 0200 &MessageLineWidget::slotOwnUserPreferencesChanged); 0201 // hide it when we switch account. 0202 mUploadFileProgressStatusListWidget->setVisible(false); 0203 } 0204 0205 mCurrentRocketChatAccount = account; 0206 connect(mCurrentRocketChatAccount, &RocketChatAccount::publicSettingChanged, mMessageLineWidget, &MessageLineWidget::slotPublicSettingChanged); 0207 connect(mCurrentRocketChatAccount->uploadFileManager(), &UploadFileManager::uploadProgress, this, &RoomWidgetBase::slotUploadProgress); 0208 connect(mCurrentRocketChatAccount, &RocketChatAccount::ownUserPreferencesChanged, mMessageLineWidget, &MessageLineWidget::slotOwnUserPreferencesChanged); 0209 mMessageListView->setCurrentRocketChatAccount(account); 0210 mMessageLineWidget->setCurrentRocketChatAccount(account, false); 0211 // When we switch we need to update it. 0212 mMessageLineWidget->slotPublicSettingChanged(); 0213 mMessageLineWidget->slotOwnUserPreferencesChanged(); 0214 mRoomId.clear(); // Clear it otherwise if we switch between two account with same roomId (as "GENERAL") we will see incorrect room. 0215 } 0216 0217 void RoomWidgetBase::slotClearNotification() 0218 { 0219 if (!mRoomId.isEmpty()) { 0220 auto room = mCurrentRocketChatAccount->room(mRoomId); 0221 if (room && ((room->unread() > 0) || room->alert())) { 0222 mCurrentRocketChatAccount->markRoomAsRead(mRoomId); 0223 } 0224 } 0225 } 0226 0227 void RoomWidgetBase::updateListView() 0228 { 0229 mMessageListView->clearTextDocumentCache(); 0230 mMessageListView->viewport()->update(); 0231 } 0232 0233 void RoomWidgetBase::updateRoomReadOnly(Room *room) 0234 { 0235 if (room->roomMessageInfo().isEmpty()) { 0236 mStackedWidget->setCurrentWidget(mMessageLineWidget); 0237 } else { 0238 mStackedWidget->setCurrentWidget(mReadOnlyLineEditWidget); 0239 mReadOnlyLineEditWidget->setMessage(room->roomMessageInfo()); 0240 } 0241 } 0242 0243 #include "moc_roomwidgetbase.cpp"