From 0531d71e6cc5e1b1fbf57618d3e838af1562aa90 Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Tue, 24 Aug 2021 18:34:24 +0200 Subject: [PATCH] fix(@desktop/chat): Text formatting menu should not disappear when performing actions Qt's Menu closes the menu when action is triggered and to overcome this default behaviour added a custom event to be called when action is clicked. Fixed some formatting related bugs. fixes #2349 --- ui/shared/status/StatusChatInput.qml | 36 +++++++++++++------ .../StatusChatInputTextFormationAction.qml | 4 ++- ui/shared/status/StatusTextFormatMenu.qml | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/ui/shared/status/StatusChatInput.qml b/ui/shared/status/StatusChatInput.qml index 39163b8162..e943fdc3eb 100644 --- a/ui/shared/status/StatusChatInput.qml +++ b/ui/shared/status/StatusChatInput.qml @@ -213,25 +213,41 @@ Rectangle { function wrapSelection(wrapWith) { if (messageInputField.selectionStart - messageInputField.selectionEnd === 0) return + // calulate the new selection start and end positions + var newSelectionStart = messageInputField.selectionStart + wrapWith.length + var newSelectionEnd = messageInputField.selectionEnd - messageInputField.selectionStart + newSelectionStart + insertInTextInput(messageInputField.selectionStart, wrapWith); insertInTextInput(messageInputField.selectionEnd, wrapWith); - messageInputField.deselect() + messageInputField.select(newSelectionStart, newSelectionEnd) } + function unwrapSelection(unwrapWith, selectedTextWithFormationChars) { - if (messageInputField.selectionStart - messageInputField.selectionEnd === 0) return + if (messageInputField.selectionStart - messageInputField.selectionEnd === 0) return - selectedTextWithFormationChars = selectedTextWithFormationChars.trim() - // Check if the selectedTextWithFormationChars has formation chars and if so, calculate how many so we can adapt the start and end pos - const selectTextDiff = (selectedTextWithFormationChars.length - messageInputField.selectedText.length) / 2 + // calulate the new selection start and end positions + var newSelectionStart = messageInputField.selectionStart - unwrapWith.length + var newSelectionEnd = messageInputField.selectionEnd-messageInputField.selectionStart + newSelectionStart - const changedString = selectedTextWithFormationChars.replace(unwrapWith, '').replace(unwrapWith, '') + selectedTextWithFormationChars = selectedTextWithFormationChars.trim() + // Check if the selectedTextWithFormationChars has formation chars and if so, calculate how many so we can adapt the start and end pos + const selectTextDiff = (selectedTextWithFormationChars.length - messageInputField.selectedText.length) / 2 - messageInputField.remove(messageInputField.selectionStart - selectTextDiff, messageInputField.selectionEnd + selectTextDiff) + // Remove the deselected option from the before and after the selected text + const prefixChars = messageInputField.getText((messageInputField.selectionStart - selectTextDiff), messageInputField.selectionStart) + const updatedPrefixChars = prefixChars.replace(unwrapWith, '') + const postfixChars = messageInputField.getText(messageInputField.selectionEnd, (messageInputField.selectionEnd + selectTextDiff)) + const updatedPostfixChars = postfixChars.replace(unwrapWith, '') - insertInTextInput(messageInputField.selectionStart, changedString) + // Create updated selected string with pre and post formatting characters + const updatedSelectedStringWithFormatChars = updatedPrefixChars + messageInputField.selectedText + updatedPostfixChars - messageInputField.deselect() + messageInputField.remove(messageInputField.selectionStart - selectTextDiff, messageInputField.selectionEnd + selectTextDiff) + + insertInTextInput(messageInputField.selectionStart, updatedSelectedStringWithFormatChars) + + messageInputField.select(newSelectionStart, newSelectionEnd) } function getPlainText() { @@ -927,7 +943,7 @@ Rectangle { icon.name: "format-text-italic" //% "Italic" text: qsTrId("italic") - checked: textFormatMenu.surroundedBy("*") && !textFormatMenu.surroundedBy("**") + checked: (textFormatMenu.surroundedBy("*") && !textFormatMenu.surroundedBy("**")) || textFormatMenu.surroundedBy("***") } StatusChatInputTextFormationAction { wrapper: "~~" diff --git a/ui/shared/status/StatusChatInputTextFormationAction.qml b/ui/shared/status/StatusChatInputTextFormationAction.qml index de140539aa..dff1efff40 100644 --- a/ui/shared/status/StatusChatInputTextFormationAction.qml +++ b/ui/shared/status/StatusChatInputTextFormationAction.qml @@ -3,9 +3,11 @@ import QtQuick.Controls 2.13 Action { property string wrapper + // adding this signal due to a known limitation from Qt: Menu closes when Action is triggered + signal actionTriggered() icon.width: 12 icon.height: 16 - onTriggered: textFormatMenu.surroundedBy(wrapper) ? + onActionTriggered: checked ? unwrapSelection(wrapper, textFormatMenu.selectedTextWithFormationChars) : wrapSelection(wrapper) checked: textFormatMenu.surroundedBy(wrapper) diff --git a/ui/shared/status/StatusTextFormatMenu.qml b/ui/shared/status/StatusTextFormatMenu.qml index a99983fa3f..9728cbccd1 100644 --- a/ui/shared/status/StatusTextFormatMenu.qml +++ b/ui/shared/status/StatusTextFormatMenu.qml @@ -64,7 +64,7 @@ Menu { icon.name: menuItem.action.icon.name icon.width: menuItem.action.icon.width icon.height: menuItem.action.icon.height - onClicked: menuItem.action.trigger() + onClicked: menuItem.action.actionTriggered() highlighted: menuItem.action.checked StatusToolTip { visible: parent.hovered