145 lines
5.2 KiB
QML
145 lines
5.2 KiB
QML
|
|
import QtQuick
|
||
|
|
import QtQuick.Controls
|
||
|
|
import QtQuick.Layouts
|
||
|
|
|
||
|
|
// Панель одного документа: шапка (заголовок, режим, действия) + текст.
|
||
|
|
// Режимы: редактирование (TextArea) / просмотр (read-only TextArea).
|
||
|
|
Item {
|
||
|
|
id: pane
|
||
|
|
|
||
|
|
property int docIndex: -1
|
||
|
|
property bool editMode: true
|
||
|
|
property bool canOpenBeside: false // кнопка «открыть рядом» (заглавная панель)
|
||
|
|
property bool closable: false // кнопка «закрыть панель» (вторая панель)
|
||
|
|
|
||
|
|
signal openBeside()
|
||
|
|
signal closePane()
|
||
|
|
|
||
|
|
function refreshHeader() {
|
||
|
|
const title = documentManager.titleAt(pane.docIndex)
|
||
|
|
headerTitle.text = title + (documentManager.isDirty(pane.docIndex) ? " •" : "")
|
||
|
|
}
|
||
|
|
|
||
|
|
ColumnLayout {
|
||
|
|
anchors.fill: parent
|
||
|
|
spacing: 0
|
||
|
|
|
||
|
|
Rectangle {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
implicitHeight: 30
|
||
|
|
color: "whitesmoke"
|
||
|
|
|
||
|
|
RowLayout {
|
||
|
|
anchors.fill: parent
|
||
|
|
anchors.leftMargin: 8
|
||
|
|
anchors.rightMargin: 4
|
||
|
|
spacing: 6
|
||
|
|
|
||
|
|
Label {
|
||
|
|
id: headerTitle
|
||
|
|
Layout.fillWidth: true
|
||
|
|
elide: Text.ElideMiddle
|
||
|
|
color: "#444"
|
||
|
|
text: ""
|
||
|
|
}
|
||
|
|
|
||
|
|
// Переключатель режимов
|
||
|
|
ToolButton {
|
||
|
|
text: "✎"
|
||
|
|
checkable: true
|
||
|
|
checked: pane.editMode
|
||
|
|
ToolTip.visible: hovered
|
||
|
|
ToolTip.text: qsTr("Режим редактирования (Ctrl+E)")
|
||
|
|
onClicked: { pane.editMode = true; editBtn.checked = true; viewBtn.checked = false }
|
||
|
|
}
|
||
|
|
ToolButton {
|
||
|
|
id: viewBtn
|
||
|
|
text: "👁"
|
||
|
|
checkable: true
|
||
|
|
checked: !pane.editMode
|
||
|
|
ToolTip.visible: hovered
|
||
|
|
ToolTip.text: qsTr("Режим просмотра (Ctrl+E)")
|
||
|
|
onClicked: { pane.editMode = false; editBtn.checked = false; viewBtn.checked = true }
|
||
|
|
}
|
||
|
|
|
||
|
|
ToolButton {
|
||
|
|
id: editBtn
|
||
|
|
visible: false
|
||
|
|
checkable: true
|
||
|
|
checked: true
|
||
|
|
onClicked: { pane.editMode = true; viewBtn.checked = false }
|
||
|
|
}
|
||
|
|
|
||
|
|
ToolButton {
|
||
|
|
text: "\u25B8\u25CB\u25C0" // «открыть рядом» (две панели)
|
||
|
|
visible: pane.canOpenBeside && !documentManager.sideBySide
|
||
|
|
ToolTip.visible: hovered
|
||
|
|
ToolTip.text: qsTr("Открыть рядом (две панели)")
|
||
|
|
onClicked: pane.openBeside()
|
||
|
|
}
|
||
|
|
|
||
|
|
ToolButton {
|
||
|
|
text: "\u2715"
|
||
|
|
visible: pane.closable
|
||
|
|
ToolTip.visible: hovered
|
||
|
|
ToolTip.text: qsTr("Закрыть вторую панель")
|
||
|
|
onClicked: pane.closePane()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Rectangle {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
Layout.fillHeight: true
|
||
|
|
color: "white"
|
||
|
|
|
||
|
|
TextArea {
|
||
|
|
id: editor
|
||
|
|
anchors.fill: parent
|
||
|
|
visible: pane.editMode
|
||
|
|
text: documentManager.contentAt(pane.docIndex)
|
||
|
|
onTextEdited: documentManager.updateContent(pane.docIndex, text)
|
||
|
|
selectByMouse: true
|
||
|
|
font.family: "Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
||
|
|
font.pixelSize: 14
|
||
|
|
wrapMode: TextEdit.NoWrap
|
||
|
|
padding: 10
|
||
|
|
placeholderText: qsTr("Документ не выбран")
|
||
|
|
}
|
||
|
|
|
||
|
|
TextArea {
|
||
|
|
id: viewer
|
||
|
|
anchors.fill: parent
|
||
|
|
visible: !pane.editMode
|
||
|
|
text: documentManager.contentAt(pane.docIndex)
|
||
|
|
readOnly: true
|
||
|
|
selectByMouse: true
|
||
|
|
font.family: "Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
||
|
|
font.pixelSize: 14
|
||
|
|
wrapMode: TextEdit.Wrap
|
||
|
|
padding: 12
|
||
|
|
placeholderText: qsTr("Документ не выбран")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Свежий заголовок при смене признака «изменено»
|
||
|
|
Connections {
|
||
|
|
target: documentManager
|
||
|
|
function onDirtyFlagChanged(i) {
|
||
|
|
if (i === pane.docIndex)
|
||
|
|
pane.refreshHeader()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// Просмотр обновляется при изменении контента (например, при правке в соседней панели)
|
||
|
|
Connections {
|
||
|
|
target: documentManager
|
||
|
|
function onContentChanged(i) {
|
||
|
|
if (i === pane.docIndex && !pane.editMode)
|
||
|
|
viewer.text = documentManager.contentAt(i)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
onDocIndexChanged: pane.refreshHeader()
|
||
|
|
Component.onCompleted: pane.refreshHeader()
|
||
|
|
}
|