日志 支持选中拷贝正则

main
COT001\DEV 2026-04-22 14:31:19 +08:00
parent ea161f0573
commit 74d8d46b47
1 changed files with 107 additions and 30 deletions

View File

@ -72,8 +72,45 @@ Rectangle {
onLogDirectoryChanged: { refreshFileList() } onLogDirectoryChanged: { refreshFileList() }
ListModel{ ListModel { id: logModel }
id: logModel
property string regexPattern: ""
function applyRegexFilter() {
// plain + html
var plainLines = []
var htmlLines = []
for (var i = 0; i < logModel.count; i++) {
var item = logModel.get(i)
var plain = "["+item.time+"] ["+item.level+"] ["+item.tag+"] "+item.message
plainLines.push(plain)
htmlLines.push('<span style="color:'+item.color+'">'+plain.replace(/&/g,"&amp;").replace(/</g,"&lt;")+'</span>')
}
if (!regexPattern) {
logTextArea.text = htmlLines.join("<br/>")
return
}
try {
var re = new RegExp(regexPattern, "gim")
var fullText = plainLines.join("\n")
var resultHtml = []
var match
while ((match = re.exec(fullText)) !== null) {
//
var matchedLines = match[0].split("\n")
matchedLines.forEach(function(ml) {
//
var idx = plainLines.indexOf(ml)
var color = idx >= 0 ? logModel.get(idx).color : "#000"
resultHtml.push('<span style="color:'+color+'">'+ml.replace(/&/g,"&amp;").replace(/</g,"&lt;")+'</span>')
})
}
logTextArea.text = resultHtml.join("<br/>")
} catch(e) {
logTextArea.text = htmlLines.join("<br/>")
}
} }
Rectangle { Rectangle {
id: bar id: bar
@ -241,11 +278,13 @@ Rectangle {
} }
}) })
tagFilter.model = ["ALL"].concat(Array.from(allTags)) tagFilter.model = ["ALL"].concat(Array.from(allTags))
applyRegexFilter()
} catch(e) { } catch(e) {
console.error("Error in updateLogDisplay:", e) console.error("Error in updateLogDisplay:", e)
} }
} }
Rectangle { Rectangle {
id: logViewContainer
anchors.top: bar.bottom anchors.top: bar.bottom
anchors.left: fileSystemViewContainer.right anchors.left: fileSystemViewContainer.right
anchors.right: parent.right anchors.right: parent.right
@ -256,36 +295,74 @@ Rectangle {
anchors.rightMargin: 23 anchors.rightMargin: 23
radius: 9 radius: 9
clip: true clip: true
// Log display
ListView { //
anchors.fill: parent Rectangle {
id: searchBar
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 8
height: 32
radius: 6
color: "#f0f0f0"
border.color: regexError ? "red" : "#cccccc"
border.width: 1
property bool regexError: false
Row {
anchors.fill: parent
anchors.leftMargin: 8
anchors.rightMargin: 8
spacing: 6
Text {
anchors.verticalCenter: parent.verticalCenter
text: "正则:"
font.pixelSize: 13
color: "#555"
}
TextInput {
id: regexInput
anchors.verticalCenter: parent.verticalCenter
width: parent.width - 50
font.pixelSize: 13
onTextChanged: {
try {
if (text) new RegExp(text)
searchBar.regexError = false
} catch(e) {
searchBar.regexError = true
}
if (!searchBar.regexError) {
regexPattern = text
applyRegexFilter()
}
}
}
}
}
ScrollView {
anchors.top: searchBar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 10 anchors.margins: 10
boundsBehavior: Flickable.StopAtBounds anchors.topMargin: 6
model: logModel TextArea {
ScrollBar.vertical: ScrollBar{} id: logTextArea
delegate: Item { readOnly: true
selectByMouse: true
height: 20 textFormat: TextEdit.RichText
Row { wrapMode: TextEdit.NoWrap
spacing: 5 font.pixelSize: 13
Text { font.family: "Courier New"
text: "["+model.time+"]" background: null
color: "gray" Keys.onPressed: function(event) {
if (event.matches(StandardKey.Copy)) {
} logTextArea.copy()
event.accepted = true
Text {
text: "["+model.level+"]"
color: model.color
}
Text {
text: "["+model.tag+"]"
color: model.color
}
Text {
text: model.message
color: model.color
} }
} }
} }