194 lines
5.9 KiB
QML
194 lines
5.9 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import Quickshell
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: widget
|
|
|
|
readonly property var currentTab: {
|
|
const tabs = NotepadStorageService.tabs || [];
|
|
const index = NotepadStorageService.currentTabIndex;
|
|
return (index >= 0 && index < tabs.length) ? tabs[index] : null;
|
|
}
|
|
// DMS only writes back temporary (scratch) tabs automatically; a tab backed
|
|
// by a real file is shown read-only so edits here cannot clobber it.
|
|
readonly property bool editable: currentTab !== null && currentTab.isTemporary === true
|
|
property bool contentLoaded: false
|
|
property int loadedTabId: -1
|
|
property bool applyingRemote: false
|
|
property bool dirty: false
|
|
|
|
function loadContent() {
|
|
if (!widget.currentTab)
|
|
return;
|
|
|
|
const tabId = widget.currentTab.id;
|
|
widget.contentLoaded = false;
|
|
NotepadStorageService.loadTabContent(NotepadStorageService.currentTabIndex, content => {
|
|
const buffer = NotepadStorageService.getSessionBuffer(tabId);
|
|
widget.applyingRemote = true;
|
|
editor.text = (buffer !== undefined) ? buffer.content : content;
|
|
widget.applyingRemote = false;
|
|
widget.loadedTabId = tabId;
|
|
widget.contentLoaded = true;
|
|
widget.dirty = false;
|
|
});
|
|
}
|
|
|
|
function save() {
|
|
if (!widget.contentLoaded || !widget.editable || widget.loadedTabId < 0)
|
|
return;
|
|
|
|
NotepadStorageService.setSessionBuffer(widget.loadedTabId, editor.text, editor.text);
|
|
NotepadStorageService.saveTabContent(NotepadStorageService.currentTabIndex, editor.text);
|
|
widget.dirty = false;
|
|
}
|
|
|
|
Ref {
|
|
service: NotepadStorageService
|
|
}
|
|
|
|
Component.onCompleted: widget.loadContent()
|
|
Component.onDestruction: {
|
|
if (widget.dirty)
|
|
widget.save();
|
|
}
|
|
|
|
Connections {
|
|
target: NotepadStorageService
|
|
|
|
function onCurrentTabIndexChanged() {
|
|
widget.loadContent();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: saveTimer
|
|
|
|
interval: 900
|
|
repeat: false
|
|
onTriggered: widget.save()
|
|
}
|
|
|
|
Rectangle {
|
|
id: editorFrame
|
|
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: footer.top
|
|
anchors.bottomMargin: Theme.spacingXS
|
|
radius: Theme.cornerRadius
|
|
color: Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency)
|
|
border.color: editor.activeFocus ? Theme.primary : Theme.outlineLight
|
|
border.width: editor.activeFocus ? 1 : Theme.layerOutlineWidth
|
|
clip: true
|
|
|
|
DankFlickable {
|
|
id: editorFlick
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: Theme.spacingS
|
|
contentWidth: width
|
|
contentHeight: editor.implicitHeight
|
|
clip: true
|
|
|
|
TextArea {
|
|
id: editor
|
|
|
|
width: editorFlick.width
|
|
readOnly: !widget.editable
|
|
wrapMode: TextArea.Wrap
|
|
selectByMouse: true
|
|
placeholderText: widget.editable ? "Notes, seeds, codes…" : "Open the DMS notepad to edit this tab"
|
|
color: Theme.surfaceText
|
|
placeholderTextColor: Theme.surfaceVariantText
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
font.family: Theme.monoFontFamily
|
|
background: null
|
|
|
|
onTextChanged: {
|
|
if (widget.applyingRemote || !widget.contentLoaded || !widget.editable)
|
|
return;
|
|
|
|
widget.dirty = true;
|
|
saveTimer.restart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: footer
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
height: 26
|
|
|
|
StyledText {
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.right: openButton.left
|
|
anchors.rightMargin: Theme.spacingS
|
|
text: {
|
|
if (!widget.currentTab)
|
|
return "No notepad tab";
|
|
if (!widget.editable)
|
|
return widget.currentTab.title + " · read-only here";
|
|
return widget.currentTab.title + (widget.dirty ? " · saving…" : " · saved");
|
|
}
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Rectangle {
|
|
id: openButton
|
|
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: openRow.width + Theme.spacingM * 2
|
|
height: 24
|
|
radius: Theme.cornerRadius
|
|
color: openArea.containsMouse ? Theme.surfaceHover : "transparent"
|
|
|
|
Row {
|
|
id: openRow
|
|
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
name: "open_in_new"
|
|
size: Theme.fontSizeMedium
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
|
|
StyledText {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: "Full notepad"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: openArea
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
widget.save();
|
|
Quickshell.execDetached(["dms", "ipc", "call", "notepad", "toggle"]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|