DebugConsole output: add text selection & copying

This commit is contained in:
miruka 2020-09-28 18:10:26 -04:00
parent 4cc4229728
commit 192112ab4e
2 changed files with 96 additions and 23 deletions

View File

@ -4,6 +4,7 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Window 2.12 import QtQuick.Window 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import Clipboard 0.1
import "Base" import "Base"
import "ShortcutBundles" import "ShortcutBundles"
@ -21,6 +22,9 @@ HDrawer {
property int maxHistoryLength: 4096 property int maxHistoryLength: 4096
property var textBeforeHistoryNavigation: null // null or string property var textBeforeHistoryNavigation: null // null or string
property int selectedOutputDelegateIndex: -1
property string selectedOutputText: ""
property string help: qsTr( property string help: qsTr(
`Javascript debugging console `Javascript debugging console
@ -44,7 +48,7 @@ HDrawer {
property bool doUselessThing: false property bool doUselessThing: false
property real baseGIFSpeed: 1.0 property real baseGIFSpeed: 1.0
readonly property alias commandsView: commandsView readonly property alias outputList: outputList
function toggle(targetItem=null, js="", addToHistory=false) { function toggle(targetItem=null, js="", addToHistory=false) {
if (debugConsole.visible) { if (debugConsole.visible) {
@ -101,7 +105,7 @@ HDrawer {
output = err.toString() output = err.toString()
} }
commandsView.model.insert(0, { input, output, error }) outputList.model.insert(0, { input, output, error })
} }
@ -116,7 +120,7 @@ HDrawer {
position: 0 position: 0
onTargetChanged: { onTargetChanged: {
commandsView.model.insert(0, { outputList.model.insert(0, {
input: "t = " + String(target), input: "t = " + String(target),
output: "", output: "",
error: false, error: false,
@ -158,7 +162,7 @@ HDrawer {
anchors.leftMargin: 1 anchors.leftMargin: 1
HListView { HListView {
id: commandsView id: outputList
spacing: theme.spacing spacing: theme.spacing
topMargin: theme.spacing topMargin: theme.spacing
bottomMargin: topMargin bottomMargin: topMargin
@ -172,35 +176,86 @@ HDrawer {
model: ListModel {} model: ListModel {}
delegate: HColumnLayout { delegate: HSelectableLabel {
width: commandsView.width - id: delegate
commandsView.leftMargin - commandsView.rightMargin width: outputList.width -
outputList.leftMargin - outputList.rightMargin
HLabel { text:
text: "> " + model.input.replace(/\n/g, "\n> ") `<div style="white-space: pre-wrap">` +
`<font color="${theme.chat.message.quote}">` +
utils.plain2Html(model.input) +
"</font>" +
(
model.output ?
"<br>" + utils.plain2Html(model.output) :
""
) +
"</div>"
textFormat: HSelectableLabel.RichText
wrapMode: HLabel.Wrap wrapMode: HLabel.Wrap
color: theme.chat.message.quote color: model.error ? theme.colors.errorText : theme.colors.text
font.family: theme.fontFamily.mono font.family: theme.fontFamily.mono
visible: Boolean(model.input)
Layout.fillWidth: true Layout.fillWidth: true
onSelectedTextChanged: if (selectedText) {
selectedOutputDelegateIndex = model.index
selectedOutputText = selectedText
} else if (selectedOutputDelegateIndex === model.index) {
selectedOutputDelegateIndex = -1
selectedOutputText = ""
} }
HLabel { Connections {
text: model.output target: debugConsole
wrapMode: HLabel.Wrap onSelectedOutputDelegateIndexChanged: {
color: model.error ? if (selectedOutputDelegateIndex !== model.index)
theme.colors.errorText : theme.colors.text delegate.deselect()
font.family: theme.fontFamily.mono }
visible: Boolean(model.output) }
Layout.fillWidth: true TapHandler {
acceptedButtons: Qt.RightButton
gesturePolicy: TapHandler.ReleaseWithinBounds
acceptedPointerTypes:
PointerDevice.GenericPointer | PointerDevice.Pen
onTapped: menu.popup()
}
TapHandler {
acceptedPointerTypes:
PointerDevice.Finger | PointerDevice.Pen
onLongPressed: menu.popup()
}
HMenu {
id: menu
implicitWidth: Math.min(window.width, 150)
z: 10000
HMenuItem {
icon.name: "copy-text"
text: qsTr("Copy")
onTriggered: {
if (delegate.selectedText) {
delegate.copy()
return
}
delegate.selectAll()
delegate.copy()
delegate.deselect()
}
}
} }
} }
FlickShortcuts { FlickShortcuts {
active: debugConsole.visible active: debugConsole.visible
flickable: commandsView flickable: outputList
} }
Rectangle { Rectangle {
@ -260,6 +315,17 @@ HDrawer {
Keys.onEscapePressed: debugConsole.close() Keys.onEscapePressed: debugConsole.close()
Keys.onPressed: ev => {
if (
ev.matches(StandardKey.Copy) &&
! inputArea.selectedText &&
selectedOutputText
) {
ev.accepted = true
Clipboard.text = selectedOutputText
}
}
Layout.fillWidth: true Layout.fillWidth: true
} }

View File

@ -196,6 +196,13 @@ QtObject {
} }
function plain2Html(text) {
// Escape html, convert `\n` into `<br>` tags and `\t` into four spaces
return escapeHtml(text).replace(/\n/g, "<br>")
.replace(/\t/g, "&nbsp;" * 4)
}
function htmlColorize(text, color) { function htmlColorize(text, color) {
return `<font color="${color}">${text}</font>` return `<font color="${color}">${text}</font>`
} }