ollie/kde/gui/NewSessionDialog.qml

270 lines
8.9 KiB
QML

// NewSessionDialog.qml — Dialog for creating or editing a session
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Dialog {
id: root
title: editMode ? "Session Settings" : "New Session"
width: 520
modal: false
x: (parent ? (parent.width - width) / 2 : 0)
y: (parent ? (parent.height - height) / 2 : 0)
property bool dragging: false
// Mode: false = create, true = edit existing session
property bool editMode: false
property string editSessionName: ""
// Keep the non-modal dialog visually separate from the application behind it.
background: Item {
// A dark offset layer reads as a shadow instead of a bright outline.
Rectangle {
x: 4
y: 6
width: parent.width
height: parent.height
color: Qt.rgba(0, 0, 0, 0.28)
radius: 4
}
Rectangle {
anchors.fill: parent
color: theme.windowColor
border.color: theme.dialogOutlineColor
border.width: 3
radius: 4
Rectangle {
anchors.fill: parent
anchors.margins: 3
color: "transparent"
border.color: theme.lightColor
border.width: 1
radius: 3
}
}
}
header: Rectangle {
implicitHeight: 36
color: theme.buttonColor
Text {
anchors.centerIn: parent
text: root.title
color: theme.buttonTextColor
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.SizeAllCursor
property point pressPosition
onPressed: pressPosition = Qt.point(mouse.x, mouse.y)
onPositionChanged: if (pressed) {
root.x += mouse.x - pressPosition.x
root.y += mouse.y - pressPosition.y
}
}
}
signal sessionCreated()
// Open in edit mode for a given session.
function openForSession(sessionName) {
editMode = true
editSessionName = sessionName
open()
}
contentItem: ColumnLayout {
spacing: 16
Layout.margins: 16
Label {
id: errorLabel
Layout.fillWidth: true
visible: text !== ""
color: "red"
wrapMode: Text.Wrap
}
RowLayout {
Layout.fillWidth: true
Label { text: "Name:"; Layout.preferredWidth: 80 }
TextField {
id: nameField
Layout.fillWidth: true
placeholderText: "(auto-generated)"
enabled: !root.editMode
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Directory:"; Layout.preferredWidth: 80 }
TextField {
id: cwdField
Layout.fillWidth: true
placeholderText: "/path/to/project"
}
Button {
text: "Browse..."
onClicked: {
var folder = theme.chooseFolder("Select Working Directory", cwdField.text || "")
if (folder !== "")
cwdField.text = folder
}
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Remote:"; Layout.preferredWidth: 80 }
TextField {
id: remoteField
Layout.fillWidth: true
placeholderText: "user@host (optional)"
enabled: !root.editMode
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Workflow:"; Layout.preferredWidth: 80 }
ComboBox {
id: workflowCombo
Layout.fillWidth: true
enabled: ollie.workflowsLoaded
model: ollie.availableWorkflows
currentIndex: {
var idx = ollie.availableWorkflows.indexOf("none")
return idx >= 0 ? idx : 0
}
onCurrentTextChanged: {
variantCombo.model = ollie.variantsForWorkflow(currentText)
variantCombo.currentIndex = 0
}
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Variant:"; Layout.preferredWidth: 80 }
ComboBox {
id: variantCombo
Layout.fillWidth: true
enabled: ollie.workflowsLoaded
model: ollie.variantsForWorkflow(workflowCombo.currentText)
}
}
RowLayout {
Layout.fillWidth: true
visible: !root.editMode
CheckBox {
id: yoloCheckBox
text: "YOLO (DANGEROUS: disables\ntool sandboxing)"
Layout.fillWidth: true
}
}
Component.onCompleted: {
if (!ollie.workflowsLoaded) ollie.loadWorkflows()
}
}
footer: RowLayout {
Layout.fillWidth: true
Item { Layout.fillWidth: true }
Button {
id: okButton
text: root.editMode ? "Save" : "OK"
onClicked: {
errorLabel.text = ""
if (root.editMode) {
// Edit mode: write changed values back.
var cfg = root._originalConfig
var newCwd = cwdField.text.trim()
var newWorkflow = workflowCombo.currentText
var newVariant = variantCombo.currentText
if (newCwd !== cfg.cwd && newCwd !== "") {
var err = ollie.updateSessionConfig(root.editSessionName, "cwd", newCwd)
if (err) { errorLabel.text = err; return }
}
if (newWorkflow !== cfg.workflow) {
var err2 = ollie.updateSessionConfig(root.editSessionName, "workflow", newWorkflow)
if (err2) { errorLabel.text = err2; return }
}
if (newVariant !== cfg.variant) {
var varVal = newVariant === "default" ? "" : newVariant
var err3 = ollie.updateSessionConfig(root.editSessionName, "variant", varVal)
if (err3) { errorLabel.text = err3; return }
}
root.close()
} else {
// Create mode.
var name = nameField.text.trim()
var remote = remoteField.text.trim()
var cwd = cwdField.text.trim()
var workflow = workflowCombo.currentText
var variant = variantCombo.currentText
var err4 = ollie.createSession(name, remote, cwd, workflow, variant, yoloCheckBox.checked)
if (err4 === "") {
ollie.refreshSessions()
root.sessionCreated()
root.close()
} else {
errorLabel.text = err4
}
}
}
}
Button {
text: "Cancel"
onClicked: root.close()
}
}
// Do not request keyboard focus while opening. Clicking a field still focuses it.
focus: false
// Store original config when opened in edit mode for diffing on save.
property var _originalConfig: ({})
onOpened: {
errorLabel.text = ""
if (!ollie.workflowsLoaded) ollie.loadWorkflows()
if (editMode && editSessionName !== "") {
// Read current session config and populate fields.
var cfg = ollie.readSessionConfig(editSessionName)
_originalConfig = cfg
nameField.text = cfg.name || editSessionName
cwdField.text = cfg.cwd || ""
remoteField.text = cfg.remote || ""
var wfIdx = ollie.availableWorkflows.indexOf(cfg.workflow || "none")
workflowCombo.currentIndex = wfIdx >= 0 ? wfIdx : 0
// Populate variant after workflow is set.
var variants = ollie.variantsForWorkflow(workflowCombo.currentText)
variantCombo.model = variants
var vIdx = variants.indexOf(cfg.variant || "default")
variantCombo.currentIndex = vIdx >= 0 ? vIdx : 0
yoloCheckBox.checked = cfg.yolo === "true"
} else {
// Create mode: reset all fields.
editMode = false
editSessionName = ""
_originalConfig = {}
nameField.text = ""
cwdField.text = ""
remoteField.text = ""
yoloCheckBox.checked = false
var idx = ollie.availableWorkflows.indexOf("none")
workflowCombo.currentIndex = idx >= 0 ? idx : 0
variantCombo.currentIndex = 0
}
}
}