File indexing completed on 2024-05-19 05:04:23

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 "messagelinewidget.h"
0008 #include "dialogs/createsoundmessagewizard.h"
0009 #include "dialogs/createvideomessagewizard.h"
0010 #include "messagemaximumsizedialog/messagemaximumsizedialog.h"
0011 #include "messagetextedit.h"
0012 #include "misc/emoticonmenuwidget.h"
0013 #include "ownuser/ownuserpreferences.h"
0014 #include "rocketchataccount.h"
0015 #include "ruqolaglobalconfig.h"
0016 #include "ruqolaserverconfig.h"
0017 #include "ruqolawidgets_debug.h"
0018 
0019 #include <KLocalizedString>
0020 #include <KMessageBox>
0021 #include <QMimeDatabase>
0022 
0023 #include <KIO/Global>
0024 #include <QClipboard>
0025 #include <QDir>
0026 #include <QGuiApplication>
0027 #include <QHBoxLayout>
0028 #include <QImageWriter>
0029 #include <QMenu>
0030 #include <QMimeData>
0031 #include <QScreen>
0032 #include <QTemporaryFile>
0033 #include <QToolButton>
0034 #include <QWidgetAction>
0035 
0036 MessageLineWidget::MessageLineWidget(QWidget *parent)
0037     : QWidget(parent)
0038     , mMessageTextEdit(new MessageTextEdit(this))
0039     , mSendFileButton(new QToolButton(this))
0040     , mEmoticonButton(new QToolButton(this))
0041     , mSendMessageButton(new QToolButton(this))
0042     , mVideoMessageButton(new QToolButton(this))
0043     , mSoundMessageButton(new QToolButton(this))
0044 {
0045     auto mainLayout = new QHBoxLayout(this);
0046     mainLayout->setObjectName(QStringLiteral("mainLayout"));
0047     mainLayout->setContentsMargins({});
0048     mainLayout->setSpacing(0);
0049 
0050     mMessageTextEdit->setObjectName(QStringLiteral("mMessageTextEdit"));
0051     mainLayout->addWidget(mMessageTextEdit);
0052     connect(mMessageTextEdit, &MessageTextEdit::sendMessage, this, &MessageLineWidget::slotSendMessage);
0053     connect(mMessageTextEdit, &MessageTextEdit::keyPressed, this, &MessageLineWidget::keyPressedInLineEdit);
0054     connect(mMessageTextEdit, &MessageTextEdit::textEditing, this, &MessageLineWidget::slotTextEditing);
0055     connect(mMessageTextEdit, &MessageTextEdit::textClicked, this, &MessageLineWidget::textEditClicked);
0056 
0057     mSendFileButton->setAutoRaise(true);
0058     mSendFileButton->setObjectName(QStringLiteral("mSendFileButton"));
0059     mainLayout->addWidget(mSendFileButton);
0060 #ifndef QT_NO_ACCESSIBILITY
0061     mSendFileButton->setAccessibleName(i18n("Attach File"));
0062 #endif
0063 
0064     mSendFileButton->setIcon(QIcon::fromTheme(QStringLiteral("document-send-symbolic")));
0065     connect(mSendFileButton, &QToolButton::clicked, this, &MessageLineWidget::slotSendFile);
0066 
0067     mVideoMessageButton->setAutoRaise(true);
0068     mVideoMessageButton->setObjectName(QStringLiteral("mVideoMessageButton"));
0069 #ifndef QT_NO_ACCESSIBILITY
0070     mVideoMessageButton->setAccessibleName(i18n("Video Message"));
0071 #endif
0072 
0073     mainLayout->addWidget(mVideoMessageButton);
0074     mVideoMessageButton->setIcon(QIcon::fromTheme(QStringLiteral("camera-video")));
0075     connect(mVideoMessageButton, &QToolButton::clicked, this, &MessageLineWidget::slotSendVideoMessage);
0076 
0077     mSoundMessageButton->setAutoRaise(true);
0078     mSoundMessageButton->setObjectName(QStringLiteral("mSoundMessageButton"));
0079 #ifndef QT_NO_ACCESSIBILITY
0080     mSoundMessageButton->setAccessibleName(i18n("Sound Message"));
0081 #endif
0082 
0083     mainLayout->addWidget(mSoundMessageButton);
0084     mSoundMessageButton->setIcon(QIcon::fromTheme(QStringLiteral("audio-input-microphone")));
0085     connect(mSoundMessageButton, &QToolButton::clicked, this, &MessageLineWidget::slotSendSoundMessage);
0086 
0087     mEmoticonButton->setAutoRaise(true);
0088     mEmoticonButton->setObjectName(QStringLiteral("mEmoticonButton"));
0089     mEmoticonButton->setIcon(QIcon::fromTheme(QStringLiteral("smiley-add")));
0090     mEmoticonButton->setPopupMode(QToolButton::InstantPopup);
0091 #ifndef QT_NO_ACCESSIBILITY
0092     mEmoticonButton->setAccessibleName(i18n("Add Emoticon"));
0093 #endif
0094     mainLayout->addWidget(mEmoticonButton);
0095 
0096     mSendMessageButton->setAutoRaise(true);
0097     mSendMessageButton->setObjectName(QStringLiteral("mSendMessageButton"));
0098     mSendMessageButton->setIcon(QIcon::fromTheme(QStringLiteral("mail-sent")));
0099 #ifndef QT_NO_ACCESSIBILITY
0100     mSendMessageButton->setAccessibleName(i18n("Send Message"));
0101 #endif
0102     mainLayout->addWidget(mSendMessageButton);
0103     mSendMessageButton->setEnabled(false);
0104     connect(mSendMessageButton, &QToolButton::clicked, this, [this]() {
0105         slotSendMessage(mMessageTextEdit->text());
0106         mMessageTextEdit->clear();
0107     });
0108 
0109     auto emoticonMenu = new QMenu(this);
0110     auto action = new QWidgetAction(emoticonMenu);
0111     mEmoticonMenuWidget = new EmoticonMenuWidget(this);
0112     action->setDefaultWidget(mEmoticonMenuWidget);
0113     emoticonMenu->addAction(action);
0114     mEmoticonButton->setMenu(emoticonMenu);
0115     connect(emoticonMenu, &QMenu::aboutToShow, mEmoticonMenuWidget, &EmoticonMenuWidget::forceLineEditFocus);
0116     connect(mEmoticonMenuWidget, &EmoticonMenuWidget::insertEmojiIdentifier, mMessageTextEdit, &MessageTextEdit::insertEmoji);
0117     connect(mMessageTextEdit, &MessageTextEdit::handleMimeData, this, &MessageLineWidget::handleMimeData);
0118 
0119     setFocusProxy(mMessageTextEdit);
0120 }
0121 
0122 MessageLineWidget::~MessageLineWidget() = default;
0123 
0124 void MessageLineWidget::slotSendMessage(const QString &msg)
0125 {
0126     if (!msg.isEmpty()) {
0127         if (mMessageIdBeingEdited.isEmpty() && mQuotePermalink.isEmpty()) {
0128             if (msg.startsWith(QLatin1Char('/'))) {
0129                 // a command ?
0130                 if (mCurrentRocketChatAccount->runCommand(msg, roomId(), mThreadMessageId)) {
0131                     setMode(MessageLineWidget::EditingMode::NewMessage);
0132                     return;
0133                 }
0134             }
0135             if (msg.size() > mCurrentRocketChatAccount->messageMaximumAllowedSize()) {
0136                 if (mCurrentRocketChatAccount->messageAllowConvertLongMessagesToAttachment()) {
0137                     if (KMessageBox::ButtonCode::PrimaryAction
0138                         == KMessageBox::questionTwoActions(this,
0139                                                            i18n("Do you want to convert this big text as attachment?"),
0140                                                            i18nc("@title:window", "Message Too Big"),
0141                                                            KStandardGuiItem::ok(),
0142                                                            KStandardGuiItem::cancel())) {
0143                         QPointer<MessageMaximumSizeDialog> dlg = new MessageMaximumSizeDialog(this);
0144                         if (dlg->exec()) {
0145                             QTemporaryFile tempFile(QDir::tempPath() + QStringLiteral("/XXXXXX.txt"));
0146                             tempFile.setAutoRemove(false);
0147                             if (tempFile.open()) {
0148                                 QTextStream stream(&tempFile);
0149                                 stream << msg;
0150                                 tempFile.close();
0151 
0152                                 QFile f(tempFile.fileName());
0153                                 if (!f.rename(dlg->fileName())) {
0154                                     qCWarning(RUQOLAWIDGETS_LOG) << "Rename file failed" << tempFile.fileName() << " dlg->fileName()" << dlg->fileName();
0155                                 }
0156                                 UploadFileDialog::UploadFileInfo uploadFileInfo;
0157                                 uploadFileInfo.description = dlg->description();
0158                                 uploadFileInfo.fileUrl = QUrl::fromLocalFile(f.fileName());
0159                                 uploadFileInfo.deleteTemporaryFile = true;
0160                                 sendFile(uploadFileInfo);
0161                             }
0162                         }
0163                         delete dlg;
0164                         // We need to send as file here.
0165                         return;
0166                     } else {
0167                         return;
0168                     }
0169                 } else {
0170                     return;
0171                 }
0172             }
0173             if (mThreadMessageId.isEmpty()) {
0174                 mCurrentRocketChatAccount->sendMessage(roomId(), msg);
0175             } else {
0176                 mCurrentRocketChatAccount->replyOnThread(roomId(), mThreadMessageId, msg);
0177                 if (!mReplyInThreadDialogBox) {
0178                     setThreadMessageId({});
0179                 }
0180             }
0181         } else if (!mMessageIdBeingEdited.isEmpty()) {
0182             // TODO check message size
0183             mCurrentRocketChatAccount->updateMessage(roomId(), mMessageIdBeingEdited, msg);
0184             clearMessageIdBeingEdited();
0185         } else if (!mQuotePermalink.isEmpty()) {
0186             const QString newMessage = QStringLiteral("[ ](%1) %2").arg(mQuotePermalink, msg);
0187             if (mThreadMessageId.isEmpty()) {
0188                 mCurrentRocketChatAccount->sendMessage(roomId(), newMessage);
0189             } else {
0190                 mCurrentRocketChatAccount->replyOnThread(roomId(), mThreadMessageId, newMessage);
0191                 if (!mReplyInThreadDialogBox) {
0192                     setThreadMessageId({});
0193                 }
0194             }
0195             setQuoteMessage({}, {});
0196             clearMessageIdBeingEdited();
0197         }
0198         setMode(MessageLineWidget::EditingMode::NewMessage);
0199     }
0200 }
0201 
0202 void MessageLineWidget::sendFile(const UploadFileDialog::UploadFileInfo &uploadFileInfo)
0203 {
0204     RocketChatRestApi::UploadFileJob::UploadFileInfo info;
0205     info.description = uploadFileInfo.description;
0206     info.messageText = QString();
0207     info.filenameUrl = uploadFileInfo.fileUrl;
0208     info.roomId = roomId();
0209     info.threadMessageId = mThreadMessageId;
0210     info.fileName = uploadFileInfo.fileName;
0211     info.deleteTemporaryFile = uploadFileInfo.deleteTemporaryFile;
0212 
0213     Q_EMIT createUploadJob(info);
0214 }
0215 
0216 void MessageLineWidget::setQuoteMessage(const QString &permalink, const QString &text)
0217 {
0218     clearMessageIdBeingEdited();
0219     mQuotePermalink = permalink;
0220     mQuoteText = text;
0221     Q_EMIT quoteMessageChanged(mQuotePermalink, text);
0222 }
0223 
0224 void MessageLineWidget::clearEditingMode()
0225 {
0226     // Remove old mark as editing
0227     MessagesModel *model = messageModel();
0228     const QModelIndex index = model->indexForMessage(mMessageIdBeingEdited);
0229     if (index.isValid()) {
0230         model->setData(index, false, MessagesModel::MessageInEditMode);
0231     }
0232 }
0233 
0234 QString MessageLineWidget::quoteText() const
0235 {
0236     return mQuoteText;
0237 }
0238 
0239 QString MessageLineWidget::quotePermalink() const
0240 {
0241     return mQuotePermalink;
0242 }
0243 
0244 void MessageLineWidget::clearMessageIdBeingEdited()
0245 {
0246     MessagesModel *model = messageModel();
0247     if (!mMessageIdBeingEdited.isEmpty()) {
0248         const QModelIndex index = model->indexForMessage(mMessageIdBeingEdited);
0249         if (index.isValid()) {
0250             model->setData(index, false, MessagesModel::MessageInEditMode);
0251         }
0252         mMessageIdBeingEdited.clear();
0253     }
0254     mQuotePermalink.clear();
0255     mQuoteText.clear();
0256     setText(QString());
0257     setMode(MessageLineWidget::EditingMode::NewMessage);
0258 }
0259 
0260 void MessageLineWidget::setEditMessage(const QString &messageId, const QString &text)
0261 {
0262     // Remove old mark as editing
0263     clearEditingMode();
0264     mMessageIdBeingEdited = messageId;
0265     if (!mMessageIdBeingEdited.isEmpty()) {
0266         MessagesModel *model = messageModel();
0267         const QModelIndex index = model->indexForMessage(mMessageIdBeingEdited);
0268         if (index.isValid()) {
0269             model->setData(index, true, MessagesModel::MessageInEditMode);
0270         }
0271     }
0272     setMode(messageId.isEmpty() ? MessageLineWidget::EditingMode::NewMessage : MessageLineWidget::EditingMode::EditMessage);
0273     setText(text);
0274     setFocus();
0275 }
0276 
0277 void MessageLineWidget::slotPublicSettingChanged()
0278 {
0279     mSendFileButton->setVisible(mCurrentRocketChatAccount->uploadFileEnabled());
0280     mSoundMessageButton->setVisible(mCurrentRocketChatAccount->audioRecorderEnabled());
0281     mVideoMessageButton->setVisible(mCurrentRocketChatAccount->videoRecorderEnabled());
0282 }
0283 
0284 void MessageLineWidget::slotOwnUserPreferencesChanged()
0285 {
0286     mEmoticonButton->setVisible(mCurrentRocketChatAccount->ownUserPreferences().useEmojis());
0287 }
0288 
0289 void MessageLineWidget::slotPrivateSettingsChanged()
0290 {
0291     mSoundMessageButton->setVisible(mCurrentRocketChatAccount->audioRecorderEnabled());
0292     mVideoMessageButton->setVisible(mCurrentRocketChatAccount->videoRecorderEnabled());
0293 }
0294 
0295 void MessageLineWidget::setCurrentRocketChatAccount(RocketChatAccount *account, bool threadMessageDialog)
0296 {
0297     if (mCurrentRocketChatAccount) {
0298         disconnect(mCurrentRocketChatAccount, &RocketChatAccount::privateSettingsChanged, this, &MessageLineWidget::slotPrivateSettingsChanged);
0299     }
0300     mCurrentRocketChatAccount = account;
0301     connect(mCurrentRocketChatAccount, &RocketChatAccount::privateSettingsChanged, this, &MessageLineWidget::slotPrivateSettingsChanged);
0302     mMessageTextEdit->setCurrentRocketChatAccount(account, threadMessageDialog);
0303     mEmoticonMenuWidget->setCurrentRocketChatAccount(account);
0304 }
0305 
0306 void MessageLineWidget::setText(const QString &text)
0307 {
0308     mMessageTextEdit->changeText(text, text.length());
0309 }
0310 
0311 QString MessageLineWidget::text() const
0312 {
0313     return mMessageTextEdit->text();
0314 }
0315 
0316 MessageTextEdit *MessageLineWidget::messageTextEdit() const
0317 {
0318     return mMessageTextEdit;
0319 }
0320 
0321 void MessageLineWidget::slotSendSoundMessage()
0322 {
0323     QPointer<CreateSoundMessageWizard> dlg = new CreateSoundMessageWizard(mCurrentRocketChatAccount, this);
0324     if (dlg->exec()) {
0325         const CreateSoundMessageWizard::CreateSoundMessageInfo info = dlg->soundMessageInfo();
0326         UploadFileDialog::UploadFileInfo result;
0327         result.description = info.mDescription;
0328         result.fileUrl = info.mFileUrl;
0329         result.fileName = info.mFileName;
0330         result.deleteTemporaryFile = true;
0331         sendFile(result);
0332     }
0333     delete dlg;
0334 }
0335 
0336 void MessageLineWidget::slotSendVideoMessage()
0337 {
0338     QPointer<CreateVideoMessageWizard> dlg = new CreateVideoMessageWizard(mCurrentRocketChatAccount, this);
0339     if (dlg->exec()) {
0340         const CreateVideoMessageWizard::CreateVideoMessageInfo info = dlg->videoMessageInfo();
0341         if (info.isValid()) {
0342             UploadFileDialog::UploadFileInfo result;
0343             result.description = info.mDescription;
0344             result.fileUrl = info.mFileUrl;
0345             result.deleteTemporaryFile = true;
0346             result.fileName = info.mFileName;
0347             sendFile(result);
0348         }
0349     }
0350     delete dlg;
0351 }
0352 
0353 void MessageLineWidget::slotSendFile()
0354 {
0355     QPointer<UploadFileDialog> dlg = new UploadFileDialog(this);
0356     QStringList whiteList = mCurrentRocketChatAccount->ruqolaServerConfig()->mediaWhiteList();
0357     const QStringList blackList = mCurrentRocketChatAccount->ruqolaServerConfig()->mediaBlackList();
0358     for (const auto &mediaType : blackList) {
0359         if (whiteList.contains(mediaType)) {
0360             whiteList.removeAll(mediaType);
0361         }
0362     }
0363     // Disable for the moment dlg->setAuthorizedMediaTypes(whiteList);
0364     // qDebug() << " whiteList " << whiteList << " blackList " << blackList;
0365     if (dlg->exec()) {
0366         const UploadFileDialog::UploadFileInfo result = dlg->fileInfo();
0367         if (result.fileUrl.isLocalFile()) {
0368             const QFileInfo info(result.fileUrl.toLocalFile());
0369             const qint64 maximumFileSize = mCurrentRocketChatAccount->ruqolaServerConfig()->fileMaxFileSize();
0370             if (info.size() > maximumFileSize) {
0371                 KMessageBox::error(this, i18n("File selected is too big (Maximum size %1)", KIO::convertSize(maximumFileSize)), i18n("File upload"));
0372                 delete dlg;
0373                 return;
0374             }
0375             auto invalidMedia = [this, dlg]() {
0376                 KMessageBox::error(this, i18n("Server doesn't authorized this file (invalid mimetype)"));
0377                 delete dlg;
0378             };
0379 
0380             QMimeDatabase mimeDatabase;
0381             const QString mimeTypeName = mimeDatabase.mimeTypeForFile(result.fileUrl.toLocalFile()).name();
0382 #if 0 // Disable for the moment "image/*" is not a valid MIME type for example
0383             qDebug() << " mimeTypeName" << mimeTypeName << " whiteList " << whiteList;
0384             if (!whiteList.isEmpty()) {
0385                 if (!whiteList.contains(mimeTypeName)) {
0386                     invalidMedia();
0387                     return;
0388                 }
0389             }
0390 #endif
0391             if (blackList.contains(mimeTypeName)) {
0392                 invalidMedia();
0393                 return;
0394             }
0395         }
0396 
0397         sendFile(result);
0398     }
0399     delete dlg;
0400 }
0401 
0402 QString MessageLineWidget::threadMessageId() const
0403 {
0404     return mThreadMessageId;
0405 }
0406 
0407 void MessageLineWidget::setThreadMessageId(const QString &threadMessageId, const QString &text, bool replyInDialogBox)
0408 {
0409     mReplyInThreadDialogBox = replyInDialogBox;
0410 
0411     if (mThreadMessageId == threadMessageId) {
0412         return;
0413     }
0414 
0415     mThreadMessageId = threadMessageId;
0416     Q_EMIT threadMessageIdChanged(mThreadMessageId, text);
0417 }
0418 
0419 MessageLineWidget::EditingMode MessageLineWidget::mode() const
0420 {
0421     return mMode;
0422 }
0423 
0424 void MessageLineWidget::setMode(EditingMode mode)
0425 {
0426     if (mMode != mode) {
0427         mMode = mode;
0428         switch (mMode) {
0429         case EditingMode::NewMessage:
0430             mSendMessageButton->setIcon(QIcon::fromTheme(QStringLiteral("mail-sent")));
0431             break;
0432         case EditingMode::EditMessage:
0433             mSendMessageButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-symbolic")));
0434             break;
0435         }
0436     }
0437 }
0438 
0439 void MessageLineWidget::slotTextEditing(bool clearNotification)
0440 {
0441     mSendMessageButton->setEnabled(!clearNotification);
0442     mCurrentRocketChatAccount->textEditing(roomId(), clearNotification);
0443 }
0444 
0445 QString MessageLineWidget::messageIdBeingEdited() const
0446 {
0447     return mMessageIdBeingEdited;
0448 }
0449 
0450 void MessageLineWidget::setMessageIdBeingEdited(const QString &messageIdBeingEdited)
0451 {
0452     mMessageIdBeingEdited = messageIdBeingEdited;
0453 }
0454 
0455 QString MessageLineWidget::roomId() const
0456 {
0457     return mMessageTextEdit->roomId();
0458 }
0459 
0460 void MessageLineWidget::setRoomId(const QString &roomId)
0461 {
0462     mMessageTextEdit->setRoomId(roomId);
0463 }
0464 
0465 bool MessageLineWidget::handleMimeData(const QMimeData *mimeData)
0466 {
0467     auto uploadFile = [this](const QUrl &url, const QPixmap &pix) {
0468         QPointer<UploadFileDialog> dlg = new UploadFileDialog(this);
0469         dlg->setFileUrl(url);
0470         dlg->setPixmap(pix);
0471         if (dlg->exec()) {
0472             const UploadFileDialog::UploadFileInfo uploadFileInfo = dlg->fileInfo();
0473             sendFile(uploadFileInfo);
0474         }
0475         delete dlg;
0476     };
0477     if (mimeData->hasUrls()) {
0478         const QList<QUrl> urls = mimeData->urls();
0479         for (const QUrl &url : urls) {
0480             if (url.isLocalFile()) {
0481                 uploadFile(url, QPixmap());
0482             }
0483         }
0484         return true;
0485     } else if (mimeData->hasImage()) {
0486         QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/XXXXXX.png"));
0487         if (tempFile.open()) {
0488             const auto image = mimeData->imageData().value<QImage>();
0489             QImageWriter writer(&tempFile, "PNG");
0490             if (writer.write(image)) {
0491                 const QUrl url = QUrl::fromLocalFile(tempFile.fileName());
0492                 tempFile.close();
0493                 const QSize pixmapAvatarSize = QSize(120, 120) * screen()->devicePixelRatio();
0494                 uploadFile(url, QPixmap::fromImage(image).scaled(pixmapAvatarSize, Qt::KeepAspectRatio));
0495                 return true;
0496             }
0497         }
0498     }
0499     return false;
0500 }
0501 
0502 MessagesModel *MessageLineWidget::messageModel() const
0503 {
0504     MessagesModel *model =
0505         mThreadMessageId.isEmpty() ? mCurrentRocketChatAccount->messageModelForRoom(roomId()) : mCurrentRocketChatAccount->threadMessageModel();
0506     Q_ASSERT(model);
0507     return model;
0508 }
0509 
0510 void MessageLineWidget::keyPressedInLineEdit(QKeyEvent *ev)
0511 {
0512     const int key = ev->key();
0513     if (key == Qt::Key_Escape) {
0514         if (!mMessageIdBeingEdited.isEmpty() || !mQuotePermalink.isEmpty()) {
0515             clearMessageIdBeingEdited();
0516             ev->accept();
0517         } else {
0518             Q_EMIT keyPressed(ev);
0519         }
0520     } else if (ev->matches(QKeySequence::Paste)) {
0521         const QMimeData *mimeData = qApp->clipboard()->mimeData();
0522         if (handleMimeData(mimeData)) {
0523             ev->accept();
0524         }
0525     } else if ((key == Qt::Key_Up || key == Qt::Key_Down) && ev->modifiers() & Qt::AltModifier) {
0526         MessagesModel *model = messageModel();
0527         auto isEditable = [this](const Message &msg) {
0528             return mCurrentRocketChatAccount->isMessageEditable(msg);
0529         };
0530         if (key == Qt::Key_Up) {
0531             const Message &msg = model->findLastMessageBefore(mMessageIdBeingEdited, isEditable);
0532             setEditMessage(msg.messageId(), msg.originalMessageOrAttachmentDescription());
0533         } else {
0534             const Message &msg = model->findNextMessageAfter(mMessageIdBeingEdited, isEditable);
0535             setEditMessage(msg.messageId(), msg.originalMessageOrAttachmentDescription());
0536         }
0537         ev->accept();
0538     } else {
0539         Q_EMIT keyPressed(ev);
0540     }
0541 }
0542 
0543 void MessageLineWidget::textEditClicked()
0544 {
0545     if (RuqolaGlobalConfig::self()->markAsReadOnTextClicked()) {
0546         mCurrentRocketChatAccount->markRoomAsRead(roomId());
0547     }
0548 }
0549 
0550 #include "moc_messagelinewidget.cpp"