From d1acb97fe2d702e8603e5582c20d0c5aac11699e Mon Sep 17 00:00:00 2001 From: James Graham Date: Sun, 22 Feb 2026 19:17:42 +0000 Subject: [PATCH] - Make sure that when adding characters before/after a link that it doesn't take the link style - Make sure that when double clicking a link with a space the whole text is selected - Make sure that shift selection with arrows works - Make sure that ctrl left right (word jump) moves across the whole link even if multiple words --- autotests/actionstest.cpp | 1 - autotests/chatkeyhelpertesthelper.h | 6 +- src/libneochat/blockcache.h | 30 ++ src/libneochat/chatkeyhelper.cpp | 302 +++++++++++++----- src/libneochat/chatkeyhelper.h | 27 +- src/libneochat/chattextitemhelper.cpp | 15 +- src/libneochat/chattextitemhelper.h | 22 +- .../models/chatbarmessagecontentmodel.cpp | 2 +- 8 files changed, 313 insertions(+), 92 deletions(-) diff --git a/autotests/actionstest.cpp b/autotests/actionstest.cpp index 5137b6107..294c45e31 100644 --- a/autotests/actionstest.cpp +++ b/autotests/actionstest.cpp @@ -93,7 +93,6 @@ void ActionsTest::testActions() auto cache = new ChatBarCache(this); cache->cache() += Block::CacheItem{.type = MessageComponentType::Text, .content = QTextDocumentFragment::fromMarkdown(command)}; auto result = ActionsModel::handleAction(room, cache); - qWarning() << result << resultText; QCOMPARE(resultText, std::get>(result)); QCOMPARE(type, std::get>(result)); } diff --git a/autotests/chatkeyhelpertesthelper.h b/autotests/chatkeyhelpertesthelper.h index 68d6259e1..fba7ac3f2 100644 --- a/autotests/chatkeyhelpertesthelper.h +++ b/autotests/chatkeyhelpertesthelper.h @@ -30,14 +30,14 @@ public: ChatTextItemHelper *textItem() const { - return m_keyHelper->textItem; + return m_keyHelper->textItem(); } void setTextItem(ChatTextItemHelper *textItem) { - if (textItem == m_keyHelper->textItem) { + if (textItem == m_keyHelper->textItem()) { return; } - m_keyHelper->textItem = textItem; + m_keyHelper->setTextItem(textItem); Q_EMIT textItemChanged(); } diff --git a/src/libneochat/blockcache.h b/src/libneochat/blockcache.h index b229806ff..a0a2eb59c 100644 --- a/src/libneochat/blockcache.h +++ b/src/libneochat/blockcache.h @@ -11,13 +11,35 @@ namespace Block { +/** + * @struct CacheItem + * + * A structure to define an item stored in a Block::Cache. + * + * @sa Block::Cache + */ struct CacheItem { MessageComponentType::Type type = MessageComponentType::Other; QTextDocumentFragment content; + /** + * @brief Return the contents of the CacheItem as a single string. + */ QString toString() const; }; +/** + * @class Cache + * + * A class to cache the contents of a ChatBarMessageContentModel. + * + * We can't store the actual content items as the QTextDocuments are attached to + * text items that may be deleted by the QML engine. Instead we get the contents + * as a QTextDocumentFragment in a Block::CacheItem which can be used to reconstruct the + * model later. + * + * @sa ChatBarMessageContentModel, QTextDocumentFragment, QTextDocument, Block::CacheItem + */ class Cache : private QList { public: @@ -26,8 +48,16 @@ public: using QList::clear; using QList::append, QList::operator+=, QList::operator<<; + /** + * @brief Fill the cache from a list of MessageComponents. + * + * @sa MessageComponent + */ void fill(QList components); + /** + * @brief Return the contents of the Cache as a single string. + */ QString toString() const; }; } diff --git a/src/libneochat/chatkeyhelper.cpp b/src/libneochat/chatkeyhelper.cpp index 49c26cd16..c6756bcfe 100644 --- a/src/libneochat/chatkeyhelper.cpp +++ b/src/libneochat/chatkeyhelper.cpp @@ -7,12 +7,34 @@ #include "clipboard.h" #include "neochatroom.h" #include "richformat.h" +#include ChatKeyHelper::ChatKeyHelper(QObject *parent) : QObject(parent) { } +ChatTextItemHelper *ChatKeyHelper::textItem() const +{ + return m_textItem; +} + +void ChatKeyHelper::setTextItem(ChatTextItemHelper *textItem) +{ + if (textItem == m_textItem) { + return; + } + + if (m_textItem) { + m_textItem->disconnect(this); + } + m_textItem = textItem; + if (m_textItem) { + connect(m_textItem, &ChatTextItemHelper::contentsChange, this, &ChatKeyHelper::checkLinkFormat); + connect(m_textItem, &ChatTextItemHelper::selectedTextChanged, this, &ChatKeyHelper::checkMouseSelection); + } +} + bool ChatKeyHelper::handleKey(Qt::Key key, Qt::KeyboardModifiers modifiers) { switch (key) { @@ -23,9 +45,9 @@ bool ChatKeyHelper::handleKey(Qt::Key key, Qt::KeyboardModifiers modifiers) case Qt::Key_Down: return down(); case Qt::Key_Left: - return left(); + return left(modifiers); case Qt::Key_Right: - return right(); + return right(modifiers); case Qt::Key_Tab: return tab(); case Qt::Key_Delete: @@ -45,10 +67,6 @@ bool ChatKeyHelper::handleKey(Qt::Key key, Qt::KeyboardModifiers modifiers) bool ChatKeyHelper::vKey(Qt::KeyboardModifiers modifiers) { - if (!textItem) { - return false; - } - if (modifiers.testFlag(Qt::ControlModifier)) { return pasteImage(); } @@ -57,12 +75,12 @@ bool ChatKeyHelper::vKey(Qt::KeyboardModifiers modifiers) bool ChatKeyHelper::up(Qt::KeyboardModifiers modifiers) { - if (!textItem) { + if (!m_textItem) { return false; } if (modifiers.testFlag(Qt::ControlModifier)) { - const auto room = textItem->room(); + const auto room = m_textItem->room(); if (!room) { return false; } @@ -70,12 +88,12 @@ bool ChatKeyHelper::up(Qt::KeyboardModifiers modifiers) return true; } - if (textItem->isCompleting) { + if (m_textItem->isCompleting) { Q_EMIT unhandledUp(true); return true; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } @@ -88,15 +106,15 @@ bool ChatKeyHelper::up(Qt::KeyboardModifiers modifiers) bool ChatKeyHelper::down() { - if (!textItem) { + if (!m_textItem) { return false; } - if (textItem->isCompleting) { + if (m_textItem->isCompleting) { Q_EMIT unhandledDown(true); return true; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } @@ -108,46 +126,54 @@ bool ChatKeyHelper::down() return false; } -bool ChatKeyHelper::left() +bool ChatKeyHelper::left(Qt::KeyboardModifiers modifiers) { - if (!textItem) { + if (!m_textItem) { return false; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } - return selectLink(cursor, true); + bool ctrlLeft = nextWordLeft(cursor, modifiers); + if (ctrlLeft) { + return true; + } + return selectLeft(cursor, modifiers); } -bool ChatKeyHelper::right() +bool ChatKeyHelper::right(Qt::KeyboardModifiers modifiers) { - if (!textItem) { + if (!m_textItem) { return false; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } - return selectLink(cursor, false); + bool ctrlRight = nextWordRight(cursor, modifiers); + if (ctrlRight) { + return true; + } + return selectRight(cursor, modifiers); } bool ChatKeyHelper::tab() { - if (!textItem) { + if (!m_textItem) { return false; } - if (textItem->isCompleting) { + if (m_textItem->isCompleting) { Q_EMIT unhandledTab(true); return true; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } - if (cursor.currentList() && textItem->canIndentListMoreAtCursor()) { - textItem->indentListMoreAtCursor(); + if (cursor.currentList() && m_textItem->canIndentListMoreAtCursor()) { + m_textItem->indentListMoreAtCursor(); return true; } return false; @@ -155,45 +181,45 @@ bool ChatKeyHelper::tab() bool ChatKeyHelper::deleteChar() { - if (!textItem) { + if (!m_textItem) { return false; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull() || cursor.hasSelection()) { return false; } - if (cursor.position() >= textItem->document()->characterCount() - textItem->fixedEndChars().length() - 1) { + if (cursor.position() >= m_textItem->document()->characterCount() - m_textItem->fixedEndChars().length() - 1) { Q_EMIT unhandledDelete(); return true; } - return selectLink(cursor, false); + return selectRight(cursor); } bool ChatKeyHelper::backspace() { - if (!textItem) { + if (!m_textItem) { return false; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } - if (cursor.position() <= textItem->fixedStartChars().length()) { - if (cursor.currentList() && textItem->canIndentListLessAtCursor()) { - textItem->indentListLessAtCursor(); + if (cursor.position() <= m_textItem->fixedStartChars().length()) { + if (cursor.currentList() && m_textItem->canIndentListLessAtCursor()) { + m_textItem->indentListLessAtCursor(); return true; } Q_EMIT unhandledBackspace(); return true; } - return selectLink(cursor, true); + return selectLeft(cursor); } bool ChatKeyHelper::insertReturn(Qt::KeyboardModifiers modifiers) { - if (!textItem) { + if (!m_textItem) { return false; } @@ -203,7 +229,7 @@ bool ChatKeyHelper::insertReturn(Qt::KeyboardModifiers modifiers) return true; } - if (!shiftPressed && textItem->isCompleting) { + if (!shiftPressed && m_textItem->isCompleting) { Q_EMIT unhandledReturn(true); return true; } @@ -213,7 +239,7 @@ bool ChatKeyHelper::insertReturn(Qt::KeyboardModifiers modifiers) return true; } - QTextCursor cursor = textItem->textCursor(); + QTextCursor cursor = m_textItem->textCursor(); if (cursor.isNull()) { return false; } @@ -233,10 +259,10 @@ bool ChatKeyHelper::insertReturn(Qt::KeyboardModifiers modifiers) bool ChatKeyHelper::cancel() { - if (!textItem) { + if (!m_textItem) { return false; } - if (textItem->isCompleting) { + if (m_textItem->isCompleting) { Q_EMIT closeCompletion(); return true; } @@ -245,7 +271,7 @@ bool ChatKeyHelper::cancel() bool ChatKeyHelper::pasteImage() { - if (!textItem) { + if (!m_textItem) { return false; } const auto savePath = Clipboard().saveImage(); @@ -255,50 +281,47 @@ bool ChatKeyHelper::pasteImage() return false; } -bool ChatKeyHelper::selectLink(QTextCursor &cursor, bool back) +bool ChatKeyHelper::selectLeft(QTextCursor &cursor, Qt::KeyboardModifiers modifiers) { - if (cursor.hasSelection() || (!cursor.charFormat().isAnchor() && back) || (!back && cursor.atBlockEnd())) { + if ((cursor.hasSelection() || !cursor.charFormat().isAnchor()) && !modifiers.testFlag(Qt::ShiftModifier)) { return false; } - // If we are on the very right and going right we need to exit. - if (!back) { - const auto startPos = cursor.position(); - cursor.movePosition(QTextCursor::NextCharacter); - if (cursor.charFormat().isAnchor()) { - cursor.setPosition(startPos); - } else { - return false; - } - } + // We need to rearrange the selection from right to left. + const auto selectionStart = cursor.selectionStart(); + cursor.setPosition(cursor.selectionEnd()); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, cursor.position() - selectionStart); - // Figure out if we're on the left side of a link. - // note a cusor on the leftmost of a link will not have the anchor set in char format. - bool onLeft = false; - if (!cursor.charFormat().isAnchor() && !back) { - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); - if (cursor.charFormat().isAnchor()) { - onLeft = true; - } else { - return false; - } + if (!cursor.charFormat().isAnchor()) { + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + m_textItem->setSelection(cursor.selectionEnd(), cursor.selectionStart()); + return true; } const auto hRef = cursor.charFormat().anchorHref(); auto currentCharFormat = cursor.charFormat(); - - // If not on the left figure out where it is. - if (!onLeft) { - const auto startPos = cursor.position(); - while (currentCharFormat.isAnchor() && currentCharFormat.anchorHref() == hRef && cursor.position() > 0) { - cursor.movePosition(QTextCursor::PreviousCharacter); - currentCharFormat = cursor.charFormat(); - } - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, startPos - cursor.position()); + while (currentCharFormat.isAnchor() && currentCharFormat.anchorHref() == hRef && cursor.position() > 0) { + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + currentCharFormat = cursor.charFormat(); } - // Then select everything to right. - // We do it this way so it works when you start in the middle. - currentCharFormat = cursor.charFormat(); + + m_textItem->setSelection(cursor.selectionEnd(), cursor.selectionStart()); + return true; +} + +bool ChatKeyHelper::selectRight(QTextCursor &cursor, Qt::KeyboardModifiers modifiers) +{ + if ((cursor.hasSelection() && !modifiers.testFlag(Qt::ShiftModifier)) || cursor.atBlockEnd()) { + return false; + } + + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + if (!cursor.charFormat().isAnchor()) { + return false; + } + + const auto hRef = cursor.charFormat().anchorHref(); + auto currentCharFormat = cursor.charFormat(); while (currentCharFormat.isAnchor() && currentCharFormat.anchorHref() == hRef && cursor.position() < cursor.block().length() - 1) { cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); currentCharFormat = cursor.charFormat(); @@ -307,8 +330,133 @@ bool ChatKeyHelper::selectLink(QTextCursor &cursor, bool back) cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); } - textItem->setSelection(cursor); + m_textItem->setSelection(cursor.selectionStart(), cursor.selectionEnd()); return true; } +bool ChatKeyHelper::nextWordLeft(QTextCursor &cursor, Qt::KeyboardModifiers modifiers) +{ + if (!modifiers.testFlag(Qt::ControlModifier)) { + return false; + } + + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + // Cross any whitespace. + while (cursor.selectedText() == u' ') { + cursor.setPosition(cursor.selectionStart()); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + } + if (!cursor.charFormat().isAnchor()) { + return false; + } + // Cross link. + while (cursor.charFormat().isAnchor()) { + cursor.setPosition(cursor.selectionStart()); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + } + + m_textItem->setCursorPosition(cursor.selectionStart()); + return true; +} + +bool ChatKeyHelper::nextWordRight(QTextCursor &cursor, Qt::KeyboardModifiers modifiers) +{ + if (!modifiers.testFlag(Qt::ControlModifier)) { + return false; + } + + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + // Cross any whitespace. + while (cursor.selectedText() == u' ') { + cursor.setPosition(cursor.selectionEnd()); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + } + if (!cursor.charFormat().isAnchor()) { + return false; + } + // Cross link. + while (cursor.charFormat().isAnchor()) { + cursor.setPosition(cursor.selectionEnd()); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + } + m_textItem->setCursorPosition(cursor.selectionEnd()); + return true; +} + +void ChatKeyHelper::checkMouseSelection() +{ + if (!m_textItem) { + return; + } + QTextCursor cursor = m_textItem->textCursor(); + if (cursor.isNull()) { + return; + } + if (!cursor.hasSelection()) { + return; + } + bool selectingLink = false; + cursor.beginEditBlock(); + cursor.setPosition(m_textItem->selectionStart()); + if (cursor.charFormat().isAnchor()) { + selectingLink = true; + } + if (!selectingLink) { + cursor.movePosition(QTextCursor::NextCharacter); + if (cursor.charFormat().isAnchor()) { + selectingLink = true; + } + } + if (!selectingLink) { + cursor.setPosition(m_textItem->selectionEnd()); + if (cursor.charFormat().isAnchor()) { + selectingLink = true; + } + } + if (!selectingLink) { + return; + } + // Wind all the way to the left of the link. + cursor.setPosition(m_textItem->selectionStart()); + const auto hRef = cursor.charFormat().anchorHref(); + auto currentCharFormat = cursor.charFormat(); + while (currentCharFormat.isAnchor() && currentCharFormat.anchorHref() == hRef && cursor.position() > 0) { + cursor.movePosition(QTextCursor::PreviousCharacter); + currentCharFormat = cursor.charFormat(); + } + cursor.endEditBlock(); + selectRight(cursor); +} + +void ChatKeyHelper::checkLinkFormat(int position, int charsRemoved, int charsAdded) +{ + if (!m_textItem || charsRemoved > charsAdded || charsAdded - charsRemoved != 1) { + return; + } + QTextCursor cursor = m_textItem->textCursor(); + if (cursor.isNull()) { + return; + } + + bool nextToLink = false; + cursor.setPosition(position); + if (cursor.charFormat().isAnchor()) { + nextToLink = true; + } + // Note 2 because a cursor on the left of a link will not show it in the format. + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, 2); + if (cursor.charFormat().isAnchor()) { + nextToLink = true; + } + if (!nextToLink) { + return; + } + + cursor.beginEditBlock(); + cursor.setPosition(position); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + cursor.setCharFormat({}); + cursor.endEditBlock(); +} + #include "moc_chatkeyhelper.cpp" diff --git a/src/libneochat/chatkeyhelper.h b/src/libneochat/chatkeyhelper.h index 5b8e80325..68a10809c 100644 --- a/src/libneochat/chatkeyhelper.h +++ b/src/libneochat/chatkeyhelper.h @@ -32,7 +32,14 @@ public: * * @sa ChatTextItemHelper */ - QPointer textItem; + ChatTextItemHelper *textItem() const; + + /** + * @brief Set the ChatTextItemHelper that ChatKeyHelper is handling key presses for. + * + * @sa ChatTextItemHelper + */ + void setTextItem(ChatTextItemHelper *textItem); /** * @brief handle the given key and modifiers. @@ -115,15 +122,17 @@ Q_SIGNALS: void imagePasted(const QString &filePath); private: + QPointer m_textItem; + bool vKey(Qt::KeyboardModifiers modifiers); bool up(Qt::KeyboardModifiers modifiers); bool down(); - bool left(); + bool left(Qt::KeyboardModifiers modifiers); - bool right(); + bool right(Qt::KeyboardModifiers modifiers); bool tab(); @@ -137,5 +146,15 @@ private: bool pasteImage(); - bool selectLink(QTextCursor &cursor, bool back); + bool selectLeft(QTextCursor &cursor, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + + bool selectRight(QTextCursor &cursor, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + + bool nextWordLeft(QTextCursor &cursor, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + + bool nextWordRight(QTextCursor &cursor, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + + void checkMouseSelection(); + + void checkLinkFormat(int position, int charsRemoved, int charsAdded); }; diff --git a/src/libneochat/chattextitemhelper.cpp b/src/libneochat/chattextitemhelper.cpp index ceaeb0760..cd0fe8d2c 100644 --- a/src/libneochat/chattextitemhelper.cpp +++ b/src/libneochat/chattextitemhelper.cpp @@ -82,6 +82,7 @@ void ChatTextItemHelper::setTextItem(QQuickItem *textItem) if (m_textItem) { connect(m_textItem, SIGNAL(cursorPositionChanged()), this, SLOT(itemCursorPositionChanged())); + connect(m_textItem, SIGNAL(selectedTextChanged()), this, SLOT(itemSelectedTextChanged())); connect(m_textItem, SIGNAL(textFormatChanged(QQuickTextEdit::TextFormat)), this, SLOT(itemTextFormatChanged())); if (const auto doc = document()) { connect(doc, &QTextDocument::contentsChanged, this, &ChatTextItemHelper::contentsChanged); @@ -387,12 +388,13 @@ void ChatTextItemHelper::setCursorPosition(int pos) m_textItem->setProperty("cursorPosition", pos); } -void ChatTextItemHelper::setSelection(const QTextCursor &cursor) +void ChatTextItemHelper::setSelection(int selectionStart, int selectionEnd) { if (!m_textItem) { return; } - metaObject()->invokeMethod(m_textItem, "select", Qt::DirectConnection, cursor.selectionStart(), cursor.selectionEnd()); + m_selectionJustChanged = true; + metaObject()->invokeMethod(m_textItem, "select", Qt::DirectConnection, selectionStart, selectionEnd); } void ChatTextItemHelper::setCursorVisible(bool visible) @@ -448,6 +450,15 @@ void ChatTextItemHelper::itemCursorPositionChanged() Q_EMIT listChanged(); } +void ChatTextItemHelper::itemSelectedTextChanged() +{ + if (m_selectionJustChanged) { + m_selectionJustChanged = false; + return; + } + Q_EMIT selectedTextChanged(); +} + void ChatTextItemHelper::mergeFormatOnCursor(RichFormat::Format format, QTextCursor cursor) { if (cursor.isNull()) { diff --git a/src/libneochat/chattextitemhelper.h b/src/libneochat/chattextitemhelper.h index 12a25870f..cdc9ac85b 100644 --- a/src/libneochat/chattextitemhelper.h +++ b/src/libneochat/chattextitemhelper.h @@ -182,6 +182,16 @@ public: */ QRect cursorRectangle() const; + /** + * @brief The start position of any text selection in the underlying text item. + */ + int selectionStart() const; + + /** + * @brief The end position of any text selection in the underlying text item. + */ + int selectionEnd() const; + /** * @brief Set the cursor position of the underlying text item to the given value. */ @@ -190,7 +200,7 @@ public: /** * @brief Set the selection of the underlying text item to the given cursor. */ - void setSelection(const QTextCursor &cursor); + void setSelection(int selectionStart, int selectionEnd); /** * @brief Set the cursor visibility of the underlying text item to the given value. @@ -312,11 +322,17 @@ Q_SIGNALS: */ void cursorPositionChanged(bool fromContentsChange); + /** + * @brief Emitted when the selected text of the underlying text item is changed. + */ + void selectedTextChanged(); + private: QPointer m_textItem; QPointer m_highlighter; bool m_contentsJustChanged = false; + bool m_selectionJustChanged = false; QString m_fixedStartChars = {}; QString m_fixedEndChars = {}; @@ -326,9 +342,6 @@ private: std::optional lineLength(int lineNumber) const; - int selectionStart() const; - int selectionEnd() const; - void mergeTextFormatOnCursor(RichFormat::Format format, QTextCursor cursor); void mergeStyleFormatOnCursor(RichFormat::Format format, QTextCursor cursor); void mergeListFormatOnCursor(RichFormat::Format format, const QTextCursor &cursor); @@ -339,4 +352,5 @@ private: private Q_SLOTS: void itemTextFormatChanged(); void itemCursorPositionChanged(); + void itemSelectedTextChanged(); }; diff --git a/src/messagecontent/models/chatbarmessagecontentmodel.cpp b/src/messagecontent/models/chatbarmessagecontentmodel.cpp index 1443950a1..8dcb5ab48 100644 --- a/src/messagecontent/models/chatbarmessagecontentmodel.cpp +++ b/src/messagecontent/models/chatbarmessagecontentmodel.cpp @@ -38,7 +38,7 @@ ChatBarMessageContentModel::ChatBarMessageContentModel(QObject *parent) }); connect(this, &ChatBarMessageContentModel::focusRowChanged, this, [this]() { m_markdownHelper->setTextItem(focusedTextItem()); - m_keyHelper->textItem = focusedTextItem(); + m_keyHelper->setTextItem(focusedTextItem()); }); connect(this, &ChatBarMessageContentModel::roomChanged, this, [this]() { for (const auto &component : m_components) {