// 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 } } }