История: diff прямо в Просмотре версии + код не в одну строку
- Подсветка: highlight() отдаёт <br/> вместо сырых \n (RichText их схлопывал — код был одной строкой); plainToRich для fallback-путей - MdParser.parseBlocksWithDiff(old,new): поблочный LCS-diff с fence-aware разбивкой, change same/del/add, изменённые блоки в цветном div (красный/зелёный как в diff), codeId для копирования сохранены - MarkdownView.compareMarkdown: при задании рендерит версию с подсветкой отличий - История: Просмотр версии сравнивается со свежим содержимым с диска (workdirContent), легенда на обеих вкладках - Тесты: <br/>, порядок del/add, тинты, identical без подсветки
This commit is contained in:
@@ -30,6 +30,7 @@ Dialog {
|
||||
property string selectedHash: ""
|
||||
property string diffHtml: ""
|
||||
property string versionContent: ""
|
||||
property string currentContent: ""
|
||||
property bool busy: false
|
||||
|
||||
function fileDirOf(p) {
|
||||
@@ -59,6 +60,8 @@ Dialog {
|
||||
function reload() {
|
||||
if (vaultPath.length===0 || filePath.length===0) {
|
||||
historyModel = []
|
||||
versionContent = ""
|
||||
currentContent = ""
|
||||
diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Файл не выбран") + "</p>"
|
||||
return
|
||||
}
|
||||
@@ -75,6 +78,7 @@ Dialog {
|
||||
selectedIndex = -1
|
||||
selectedHash = ""
|
||||
versionContent = ""
|
||||
currentContent = ""
|
||||
const hasFile = filePath.length>0
|
||||
if (hasFile) {
|
||||
const st = gitManager.fileGitStatus(vaultPath, filePath)
|
||||
@@ -94,12 +98,16 @@ Dialog {
|
||||
if (selectedHash.length===0) {
|
||||
diffHtml = ""
|
||||
versionContent = ""
|
||||
currentContent = ""
|
||||
return
|
||||
}
|
||||
// свежее содержимое с диска — diff всегда актуален, даже если файл правили при открытом диалоге
|
||||
currentContent = gitManager.workdirContent(filePath)
|
||||
const html = gitManager.fileDiffHtml(vaultPath, filePath, selectedHash)
|
||||
if (html.length===0) diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Нет изменений") + "</p>"
|
||||
else diffHtml = html
|
||||
// содержимое версии — сырой markdown, отрисуется через MarkdownView как в «Просмотре»
|
||||
// содержимое версии — сырой markdown, отрисуется через MarkdownView как в «Просмотре»,
|
||||
// с подсветкой отличий от текущего файла прямо там
|
||||
versionContent = gitManager.fileContentAt(vaultPath, filePath, selectedHash)
|
||||
}
|
||||
|
||||
@@ -342,6 +350,7 @@ Dialog {
|
||||
id: versionPreview
|
||||
width: parent.width
|
||||
markdown: root.versionContent
|
||||
compareMarkdown: root.currentContent
|
||||
vaultRoot: root.vaultPath
|
||||
fileDir: root.fileDirOf(root.filePath)
|
||||
emptyText: qsTr("Нет версии для просмотра")
|
||||
@@ -352,18 +361,18 @@ Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
// Легенда — только для вкладки «Изменения»
|
||||
// Легенда — цвета отличий от текущего файла (обе вкладки)
|
||||
Row {
|
||||
visible: tabBar.currentIndex === 0
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: tabBar.currentIndex === 0 ? implicitHeight : 0
|
||||
Layout.margins: 6
|
||||
spacing: 12
|
||||
Row { spacing: 4; Rectangle { width:12; height:12; color:"#e6ffec"; border.color:"#1a7f37"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("добавлено"); color: Theme.textMuted; font.pixelSize:10 } }
|
||||
Row { spacing: 4; Rectangle { width:12; height:12; color:"#ffebe9"; border.color:"#cf222e"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("удалено"); color: Theme.textMuted; font.pixelSize:10 } }
|
||||
Row { spacing: 4; Rectangle { width:12; height:12; color:"#ddf4ff"; border.color:"#0969da"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("заголовок"); color: Theme.textMuted; font.pixelSize:10 } }
|
||||
Row { visible: tabBar.currentIndex === 0; spacing: 4; Rectangle { width:12; height:12; color:"#ddf4ff"; border.color:"#0969da"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("заголовок"); color: Theme.textMuted; font.pixelSize:10 } }
|
||||
Label {
|
||||
text: qsTr("Сравнение выбранной версии с текущим файлом")
|
||||
text: tabBar.currentIndex === 0
|
||||
? qsTr("Сравнение выбранной версии с текущим файлом")
|
||||
: qsTr("Версия с подсветкой отличий от текущего файла")
|
||||
color: Theme.textFaint
|
||||
font.pixelSize: 10
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -9,6 +9,9 @@ Item {
|
||||
property string vaultRoot: ""
|
||||
property string fileDir: ""
|
||||
property string emptyText: qsTr("Пустой файл — начните писать в режиме редактирования")
|
||||
// Если задан — markdown считается старой версией и подсвечиваются отличия от него
|
||||
// (блоки del — только в markdown, add — только в compareMarkdown)
|
||||
property string compareMarkdown: ""
|
||||
implicitHeight: column.implicitHeight + 24
|
||||
|
||||
signal linkActivated(string href)
|
||||
@@ -17,7 +20,9 @@ Item {
|
||||
function update() {
|
||||
// Триггерим пересборку блоков
|
||||
blocksModel.clear()
|
||||
const blocks = mdParser.parseBlocks(markdown, vaultRoot, fileDir)
|
||||
const blocks = compareMarkdown.length > 0
|
||||
? mdParser.parseBlocksWithDiff(markdown, compareMarkdown, vaultRoot, fileDir)
|
||||
: mdParser.parseBlocks(markdown, vaultRoot, fileDir)
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
blocksModel.append(blocks[i])
|
||||
}
|
||||
@@ -26,6 +31,7 @@ Item {
|
||||
}
|
||||
|
||||
onMarkdownChanged: update()
|
||||
onCompareMarkdownChanged: update()
|
||||
onVaultRootChanged: update()
|
||||
onFileDirChanged: update()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user