File indexing completed on 2024-12-01 04:37:00
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"