fdf59f5b39
- Frontmatter: шапка --- ключ: значение (источник правды свойств) - VaultSettings: .flora/settings.json (журнал, sqlEnabled, sqlMaxRows) - Database: files/tags/file_tags/links/properties, только SELECT/WITH на read-only соединении (mode=ro + query_only + зонд), лимит строк - MdParser: ~sql-блоки таблицей (parseBlocks + Renderer), шапка скрыта в просмотре - Окно: per-window Database/VaultSettings, sync при сохранении, дебаунс reindex - QML: VaultSettingsDialog, FilePropertiesDialog, меню, автообновление ~sql - FileStore.journalDir, DocumentManager.reloadDocument - Тест flora_db_test (23/23 зелёных)
164 lines
6.1 KiB
QML
164 lines
6.1 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import Flora
|
|
|
|
// Настройки одного хранилища: лежат в <vault>/.flora/settings.json,
|
|
// в git не попадают (как и сама база). Применяются живьём через vaultSettings.
|
|
Dialog {
|
|
id: root
|
|
|
|
title: qsTr("Настройки хранилища")
|
|
modal: true
|
|
width: 560
|
|
height: 640
|
|
anchors.centerIn: parent
|
|
closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside
|
|
standardButtons: Dialog.NoButton
|
|
background: Rectangle { color: Theme.surface; border.color: Theme.borderStrong; radius: 10 }
|
|
|
|
footer: RowLayout {
|
|
spacing: 8
|
|
Item { Layout.fillWidth: true }
|
|
Button {
|
|
text: qsTr("Отмена")
|
|
onClicked: {
|
|
// откатить живьём применённое (сеттеры уже ушли в базу через changed)
|
|
vaultSettings.open(fileStore.vault)
|
|
root.reject()
|
|
}
|
|
}
|
|
Button {
|
|
text: qsTr("Сохранить")
|
|
highlighted: true
|
|
onClicked: root.saveSettings()
|
|
}
|
|
}
|
|
|
|
onOpened: {
|
|
journalField.text = vaultSettings.journalDir
|
|
sqlCheck.checked = vaultSettings.sqlEnabled
|
|
maxRowsSpin.value = vaultSettings.sqlMaxRows
|
|
root.refreshStats()
|
|
statusLabel.text = ""
|
|
}
|
|
|
|
function saveSettings() {
|
|
vaultSettings.journalDir = journalField.text
|
|
vaultSettings.sqlEnabled = sqlCheck.checked
|
|
vaultSettings.sqlMaxRows = maxRowsSpin.value
|
|
// Флаги уже ушли в базу живьём (сигнал changed); здесь только persist
|
|
if (!vaultSettings.save()) {
|
|
statusLabel.text = qsTr("Не удалось записать .flora/settings.json")
|
|
return
|
|
}
|
|
root.accept()
|
|
}
|
|
|
|
function refreshStats() {
|
|
const s = vaultDatabase.stats()
|
|
statFiles.text = s.files
|
|
statTags.text = s.tags
|
|
statLinks.text = s.links
|
|
statProps.text = s.properties
|
|
const kb = Math.round(s.dbSize / 1024)
|
|
statDb.text = kb < 1024 ? kb + " КБ" : (kb / 1024).toFixed(1) + " МБ"
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
|
|
Label {
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.Wrap
|
|
color: Theme.textSecondary
|
|
font.pixelSize: 11
|
|
text: fileStore.ready ? fileStore.vault : qsTr("Хранилище не открыто")
|
|
elide: Text.ElideMiddle
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("Заметки дня")
|
|
background: Rectangle { color: Theme.bgAlt; border.color: Theme.border; radius: 8 }
|
|
label: Label { text: parent.title; color: Theme.text; font.bold: true; leftPadding: 6 }
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 8
|
|
Label { text: qsTr("Папка:"); color: Theme.textSecondary }
|
|
TextField {
|
|
id: journalField
|
|
Layout.fillWidth: true
|
|
placeholderText: qsTr("Журнал")
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("SQL-блоки (~sql)")
|
|
background: Rectangle { color: Theme.bgAlt; border.color: Theme.border; radius: 8 }
|
|
label: Label { text: parent.title; color: Theme.text; font.bold: true; leftPadding: 6 }
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 8
|
|
spacing: 6
|
|
CheckBox {
|
|
id: sqlCheck
|
|
text: qsTr("Выполнять ~sql-запросы в просмотре")
|
|
}
|
|
RowLayout {
|
|
Label { text: qsTr("Строк в результате:"); color: Theme.textSecondary }
|
|
SpinBox { id: maxRowsSpin; from: 5; to: 500; stepSize: 5; editable: true }
|
|
}
|
|
Label {
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.Wrap
|
|
color: Theme.textFaint
|
|
font.pixelSize: 11
|
|
text: qsTr("Таблицы: files(path,title,mtime,size), tags(name), file_tags, links, properties(file_id,key,value). Только чтение (SELECT / WITH).")
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("База хранилища")
|
|
background: Rectangle { color: Theme.bgAlt; border.color: Theme.border; radius: 8 }
|
|
label: Label { text: parent.title; color: Theme.text; font.bold: true; leftPadding: 6 }
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 8
|
|
spacing: 4
|
|
GridLayout {
|
|
columns: 2
|
|
columnSpacing: 12
|
|
Label { text: qsTr("Файлов:"); color: Theme.textSecondary }
|
|
Label { id: statFiles; color: Theme.text }
|
|
Label { text: qsTr("Тегов:"); color: Theme.textSecondary }
|
|
Label { id: statTags; color: Theme.text }
|
|
Label { text: qsTr("Связей:"); color: Theme.textSecondary }
|
|
Label { id: statLinks; color: Theme.text }
|
|
Label { text: qsTr("Свойств:"); color: Theme.textSecondary }
|
|
Label { id: statProps; color: Theme.text }
|
|
Label { text: qsTr("База:"); color: Theme.textSecondary }
|
|
Label { id: statDb; color: Theme.text }
|
|
}
|
|
Button {
|
|
text: qsTr("Обновить статистику")
|
|
onClicked: root.refreshStats()
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
id: statusLabel
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.Wrap
|
|
color: "#e5484d"
|
|
font.pixelSize: 11
|
|
}
|
|
}
|
|
}
|