Fix copying multi-line selected rich text

For rich text (rendered HTML) fields and areas, the selectedText
property for some reason contains "\u2028" or "\u2029"
characters that look like newlines in Qt programs but are just
invisible anywhere else. Translate them to normal "\n".
This commit is contained in:
miruka 2020-10-31 02:59:56 -04:00
parent da75568428
commit 7564b40c3e
7 changed files with 27 additions and 12 deletions

View File

@ -9,6 +9,11 @@ TextEdit {
property bool enableLinkActivation: true property bool enableLinkActivation: true
// For rich text, selectedText returns some weird invisible characters
// instead of real newlines
readonly property string selectedPlainText:
selectedText.replace(/[\u2028\u2029]/g, "\n")
function selectWordAt(position) { function selectWordAt(position) {
label.cursorPosition = positionAt(position.x, position.y) label.cursorPosition = positionAt(position.x, position.y)
label.selectWord() label.selectWord()

View File

@ -30,6 +30,11 @@ TextArea {
property string previousDefaultText: "" // private property string previousDefaultText: "" // private
// For rich text, selectedText returns some weird invisible characters
// instead of real newlines
readonly property string selectedPlainText:
selectedText.replace(/[\u2028\u2029]/g, "\n")
property bool enableCustomImagePaste: false property bool enableCustomImagePaste: false
signal customImagePaste() signal customImagePaste()

View File

@ -50,14 +50,14 @@ HMenu {
HMenuItem { HMenuItem {
icon.name: "cut-text" icon.name: "cut-text"
text: qsTr("Cut") text: qsTr("Cut")
enabled: control.selectedText enabled: control.selectedPlainText
onTriggered: control.cut() onTriggered: control.cut()
} }
HMenuItem { HMenuItem {
icon.name: "copy-text" icon.name: "copy-text"
text: qsTr("Copy") text: qsTr("Copy")
enabled: control.selectedText enabled: control.selectedPlainText
onTriggered: control.copy() onTriggered: control.copy()
} }

View File

@ -30,6 +30,11 @@ TextField {
property string previousDefaultText: "" // private property string previousDefaultText: "" // private
// For rich text, selectedText returns some weird invisible characters
// instead of real newlines
readonly property string selectedPlainText:
selectedText.replace(/[\u2028\u2029]/g, "\n")
function reset() { function reset() {
clear() clear()
text = Qt.binding(() => defaultText || "") text = Qt.binding(() => defaultText || "")

View File

@ -208,9 +208,9 @@ HDrawer {
Layout.fillWidth: true Layout.fillWidth: true
onSelectedTextChanged: if (selectedText) { onSelectedTextChanged: if (selectedPlainText) {
selectedOutputDelegateIndex = model.index selectedOutputDelegateIndex = model.index
selectedOutputText = selectedText selectedOutputText = selectedPlainText
} else if (selectedOutputDelegateIndex === model.index) { } else if (selectedOutputDelegateIndex === model.index) {
selectedOutputDelegateIndex = -1 selectedOutputDelegateIndex = -1
selectedOutputText = "" selectedOutputText = ""
@ -249,7 +249,7 @@ HDrawer {
icon.name: "copy-text" icon.name: "copy-text"
text: qsTr("Copy") text: qsTr("Copy")
onTriggered: { onTriggered: {
if (delegate.selectedText) { if (delegate.selectedPlainText) {
delegate.copy() delegate.copy()
return return
} }
@ -337,7 +337,7 @@ HDrawer {
Keys.onPressed: ev => { Keys.onPressed: ev => {
if ( if (
ev.matches(StandardKey.Copy) && ev.matches(StandardKey.Copy) &&
! inputArea.selectedText && ! inputArea.selectedPlainText &&
selectedOutputText selectedOutputText
) { ) {
ev.accepted = true ev.accepted = true

View File

@ -225,7 +225,7 @@ HTextArea {
if (ev.text && autoCompletionOpen) acceptAutoCompletion() if (ev.text && autoCompletionOpen) acceptAutoCompletion()
if (ev.matches(StandardKey.Copy) && if (ev.matches(StandardKey.Copy) &&
! area.selectedText && ! area.selectedPlainText &&
eventList && eventList &&
(eventList.selectedCount || eventList.currentIndex !== -1)) (eventList.selectedCount || eventList.currentIndex !== -1))
{ {
@ -237,7 +237,7 @@ HTextArea {
// FIXME: buggy // FIXME: buggy
// if (ev.modifiers === Qt.NoModifier && // if (ev.modifiers === Qt.NoModifier &&
// ev.key === Qt.Key_Backspace && // ev.key === Qt.Key_Backspace &&
// ! area.selectedText) // ! area.selectedPlainText)
// { // {
// ev.accepted = true // ev.accepted = true
// area.remove( // area.remove(

View File

@ -82,7 +82,7 @@ HRowLayout {
window.settings.maxMessageCharactersPerLine window.settings.maxMessageCharactersPerLine
) )
readonly property alias selectedText: contentLabel.selectedText readonly property alias selectedText: contentLabel.selectedPlainText
spacing: theme.chat.message.horizontalSpacing spacing: theme.chat.message.horizontalSpacing
@ -182,9 +182,9 @@ HRowLayout {
Layout.maximumWidth: eventContent.maxMessageWidth Layout.maximumWidth: eventContent.maxMessageWidth
Layout.fillWidth: true Layout.fillWidth: true
onSelectedTextChanged: if (selectedText) { onSelectedTextChanged: if (selectedPlainText) {
eventList.delegateWithSelectedText = model.id eventList.delegateWithSelectedText = model.id
eventList.selectedText = selectedText eventList.selectedText = selectedPlainText
} else if (eventList.delegateWithSelectedText === model.id) { } else if (eventList.delegateWithSelectedText === model.id) {
eventList.delegateWithSelectedText = "" eventList.delegateWithSelectedText = ""
eventList.selectedText = "" eventList.selectedText = ""
@ -274,7 +274,7 @@ HRowLayout {
radius: theme.chat.message.radius radius: theme.chat.message.radius
z: -100 z: -100
color: eventDelegate.checked && color: eventDelegate.checked &&
! contentLabel.selectedText && ! contentLabel.selectedPlainText &&
! mousePointHandler.active && ! mousePointHandler.active &&
! mouseShiftPointHandler.active ? ! mouseShiftPointHandler.active ?
theme.chat.message.checkedBackground : theme.chat.message.checkedBackground :