From b1617b45606e2b81d60349ad6e27580591f4bece Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 29 Oct 2024 11:56:43 +0100 Subject: [PATCH] Refactoring around ChatEdit::checkDndEvent() It's ChatRoomWidget::checkDndEvent() now. --- client/chatedit.cpp | 31 +++----------------- client/chatedit.h | 1 - client/chatroomwidget.cpp | 62 ++++++++++++++++++++++++++------------- client/chatroomwidget.h | 10 ++++--- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/client/chatedit.cpp b/client/chatedit.cpp index 7ca11678..d2bc293e 100644 --- a/client/chatedit.cpp +++ b/client/chatedit.cpp @@ -105,29 +105,11 @@ bool ChatEdit::canInsertFromMimeData(const QMimeData* source) const return source->hasImage() || KChatEdit::canInsertFromMimeData(source); } -QString ChatEdit::checkDndEvent(QDropEvent* event) -{ - if (const auto* data = event->mimeData(); data->hasHtml()) { - const auto [cleanHtml, errorPos, errorString] = - HtmlFilter::fromLocalHtml(data->html()); - if (errorPos != -1) { - qCWarning(MSGINPUT) << "HTML validation failed at position" - << errorPos << "with error" << errorString; - event->ignore(); - return tr( - "Cannot insert HTML - it's either invalid or unsupported"); - } - } - event->setDropAction(Qt::CopyAction); - event->accept(); - return {}; -} - void ChatEdit::dragEnterEvent(QDragEnterEvent* event) { KChatEdit::dragEnterEvent(event); if (event->source() != this) - checkDndEvent(event); + chatRoomWidget->checkDndEvent(event); } void ChatEdit::alternatePaste() @@ -153,15 +135,10 @@ bool ChatEdit::acceptMimeData(const QMimeData* source) insertPlainText(document.toPlainText()); } else { // Before insertion, remove formatting unsupported in Matrix - const auto [cleanHtml, errorPos, errorString] = - HtmlFilter::fromLocalHtml(source->html()); - if (errorPos != -1) { - qCWarning(MSGINPUT) << "HTML insertion failed at pos" - << errorPos << "with error" << errorString; - chatRoomWidget->showStatusMessage( - tr("Could not insert HTML - it's either invalid or unsupported"), 5000); + const auto cleanHtml = chatRoomWidget->matrixHtmlFromMime(source); + if (cleanHtml.isEmpty()) return false; - } + insertHtml(cleanHtml); } ensureCursorVisible(); diff --git a/client/chatedit.h b/client/chatedit.h index efa45470..aee86d86 100644 --- a/client/chatedit.h +++ b/client/chatedit.h @@ -28,7 +28,6 @@ class ChatEdit : public KChatEdit void insertMention(QString author, QUrl url); bool acceptMimeData(const QMimeData* source); - QString checkDndEvent(QDropEvent* event); // NB: the following virtual functions are protected in QTextEdit but // ChatRoomWidget delegates to them diff --git a/client/chatroomwidget.cpp b/client/chatroomwidget.cpp index a0e97d9c..634178db 100644 --- a/client/chatroomwidget.cpp +++ b/client/chatroomwidget.cpp @@ -43,6 +43,8 @@ #include "htmlfilter.h" #include "logging_categories.h" +using namespace Qt::StringLiterals; + static auto DefaultPlaceholderText() { return ChatRoomWidget::tr( @@ -259,7 +261,7 @@ void ChatRoomWidget::setHudHtml(const QString& htmlCaption, m_hudCaption->setText(hudText); } -void ChatRoomWidget::showStatusMessage(const QString& message, int timeout) +void ChatRoomWidget::showStatusMessage(const QString& message, int timeout) const { mainWindow()->showStatusMessage(message, timeout); } @@ -722,9 +724,8 @@ void ChatRoomWidget::sendInput() error = NothingToSendMsg(); else if (text.startsWith('/') && !QStringView(text).mid(1).startsWith('/')) { - QRegularExpression cmdSplit( - "(\\w+)(?:\\s+(.*))?", - QRegularExpression::DotMatchesEverythingOption); + static QRegularExpression cmdSplit(u"(\\w+)(?:\\s+(.*))?"_s, + QRegularExpression::DotMatchesEverythingOption); const auto& blanksMatch = cmdSplit.match(text, 1); error = sendCommand(blanksMatch.capturedView(1), blanksMatch.captured(2)); @@ -741,23 +742,22 @@ void ChatRoomWidget::sendInput() m_chatEdit->saveInput(); } -ChatRoomWidget::completions_t -ChatRoomWidget::findCompletionMatches(const QString& pattern) const +ChatEdit::completions_t ChatRoomWidget::findCompletionMatches(const QString& pattern) const { - completions_t matches; - if (currentRoom()) { - const auto& members = currentRoom()->joinedMembers(); - for (const auto& m: members) { - using Quotient::Uri; - if (m.displayName() - .startsWith(pattern, Qt::CaseInsensitive) - || m.id().startsWith(pattern, Qt::CaseInsensitive)) - matches.push_back({ m.displayName(), Uri(m.id()).toUrl(Uri::MatrixToUri) }); - } - std::sort(matches.begin(), matches.end(), - [] (const auto& p1, const auto& p2) - { return p1.first.localeAwareCompare(p2.first) < 0; }); + if (!currentRoom()) + return {}; + + ChatEdit::completions_t matches; + const auto& members = currentRoom()->joinedMembers(); + for (const auto& m: members) { + using Quotient::Uri; + if (m.displayName().startsWith(pattern, Qt::CaseInsensitive) + || m.id().startsWith(pattern, Qt::CaseInsensitive)) + matches.emplace_back(m.displayName(), Uri(m.id()).toUrl(Uri::MatrixToUri)); } + std::ranges::sort(matches, [](const auto& p1, const auto& p2) { + return p1.first.localeAwareCompare(p2.first) < 0; + }); return matches; } @@ -822,7 +822,7 @@ void ChatRoomWidget::dragEnterEvent(QDragEnterEvent* event) event->ignore(); return; } - m_chatEdit->checkDndEvent(event); + checkDndEvent(event); } void ChatRoomWidget::dropEvent(QDropEvent* event) @@ -861,6 +861,28 @@ void ChatRoomWidget::dropEvent(QDropEvent* event) event->accept(); } +QString ChatRoomWidget::matrixHtmlFromMime(const QMimeData* data) const +{ + QUO_CHECK(data->hasHtml()); + const auto [cleanHtml, errorPos, errorString] = HtmlFilter::fromLocalHtml(data->html()); + if (errorPos != -1) { + qCWarning(MSGINPUT) << "HTML validation failed at position" << errorPos << "with error" + << errorString; + showStatusMessage(tr("Cannot insert HTML - it's either invalid or unsupported"), 5000); + } + return cleanHtml; +} + +void ChatRoomWidget::checkDndEvent(QDropEvent* event) const +{ + // `event` may originally come to m_chatEdit or be a QDragEnterEvent instead - all that is fine + if (const auto* data = event->mimeData(); data->hasHtml() && matrixHtmlFromMime(data).isEmpty()) + event->ignore(); + + event->setDropAction(Qt::CopyAction); + event->accept(); +} + int ChatRoomWidget::maximumChatEditHeight() const { return height() / 3; diff --git a/client/chatroomwidget.h b/client/chatroomwidget.h index 044bb050..534de6c0 100644 --- a/client/chatroomwidget.h +++ b/client/chatroomwidget.h @@ -30,13 +30,15 @@ class ChatRoomWidget : public QWidget { Q_OBJECT public: - using completions_t = ChatEdit::completions_t; - explicit ChatRoomWidget(MainWindow* parent = nullptr); TimelineWidget* timelineWidget() const; QuaternionRoom* currentRoom() const; - completions_t findCompletionMatches(const QString& pattern) const; + // Helpers for m_chatEdit + + ChatEdit::completions_t findCompletionMatches(const QString& pattern) const; + QString matrixHtmlFromMime(const QMimeData* data) const; + void checkDndEvent(QDropEvent* event) const; public slots: void setRoom(QuaternionRoom* newRoom); @@ -52,7 +54,7 @@ class ChatRoomWidget : public QWidget void setHudHtml(const QString& htmlCaption, const QStringList& plainTextNames = {}); - void showStatusMessage(const QString& message, int timeout = 0); + void showStatusMessage(const QString& message, int timeout = 0) const; void showCompletions(QStringList matches, int pos); void typingChanged();