diff --git a/kde/gui/ProcManagerWindow.qml b/kde/gui/ProcManagerWindow.qml index 8b43000..47ca36b 100644 --- a/kde/gui/ProcManagerWindow.qml +++ b/kde/gui/ProcManagerWindow.qml @@ -14,6 +14,7 @@ Window { property var procs: [] property string outputText: "" property int selectedPid: -1 + property bool outputVisible: true // Track the session we're displaying (synced from main window) property string currentSessionId: ollie.activeSessionId @@ -106,113 +107,123 @@ Window { } } - // Process list - ListView { - id: procList - Layout.fillWidth: true - Layout.preferredHeight: 180 - Layout.minimumHeight: 100 - model: procs - clip: true - - ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded } - - delegate: Rectangle { - width: procList.width - height: 44 - color: selectedPid === modelData.pid ? palette.highlight : (index % 2 ? palette.alternateBase : palette.base) - - MouseArea { - anchors.fill: parent - onClicked: selectedPid = modelData.pid - onDoubleClicked: { - selectedPid = modelData.pid - var out = ollie.procOutput(currentSessionId, currentAgentId, selectedPid) - outputText = out.length > 0 ? out : "(no output)" - } - } - - RowLayout { - anchors.fill: parent - anchors.margins: 8 - spacing: 12 - - // Status indicator - Rectangle { - width: 10 - height: 10 - radius: 5 - color: modelData.status === "running" ? "#4CAF50" : (modelData.exitCode === 0 ? "#9E9E9E" : "#F44336") - } - - // PID - Label { - text: modelData.pid - font.family: "monospace" - Layout.preferredWidth: 50 - } - - // Tool - Label { - text: modelData.tool - font.weight: Font.Medium - Layout.preferredWidth: 80 - elide: Text.ElideRight - } - - // Command - Label { - text: modelData.cmd - Layout.fillWidth: true - elide: Text.ElideMiddle - opacity: 0.8 - } - - // Runtime - Label { - text: formatRuntime(modelData.runtime) - font.family: "monospace" - Layout.preferredWidth: 55 - horizontalAlignment: Text.AlignRight - } - - // Exit code (if exited) - Label { - visible: modelData.status !== "running" - text: modelData.exitCode === 0 ? "✓" : "exit " + modelData.exitCode - font.family: "monospace" - color: modelData.exitCode === 0 ? "#4CAF50" : "#F44336" - Layout.preferredWidth: 45 - } - } - } - - Label { - anchors.centerIn: parent - visible: procs.length === 0 - text: currentSessionId ? "No background processes" : "No session selected" - opacity: 0.5 - } - } - - // Output pane (always visible) - GroupBox { + // Resizable split between process list and output + SplitView { Layout.fillWidth: true Layout.fillHeight: true - Layout.minimumHeight: 100 - title: selectedPid > 0 ? "Output (PID " + selectedPid + ")" : "Output" + orientation: Qt.Vertical - ScrollView { - anchors.fill: parent - TextArea { - id: outputArea - text: outputText - readOnly: true - font.family: "monospace" - font.pointSize: 11 - wrapMode: TextEdit.Wrap - selectByMouse: true - placeholderText: "Select a process and click View Output" + // Process list + ListView { + id: procList + SplitView.fillWidth: true + SplitView.minimumHeight: 80 + SplitView.preferredHeight: 180 + model: procs + clip: true + + ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded } + + delegate: Rectangle { + width: procList.width + height: 44 + color: selectedPid === modelData.pid ? palette.highlight : (index % 2 ? palette.alternateBase : palette.base) + + MouseArea { + anchors.fill: parent + onClicked: selectedPid = modelData.pid + onDoubleClicked: { + selectedPid = modelData.pid + var out = ollie.procOutput(currentSessionId, currentAgentId, selectedPid) + outputText = out.length > 0 ? out : "(no output)" + outputVisible = true + } + } + + RowLayout { + anchors.fill: parent + anchors.margins: 8 + spacing: 12 + + // Status indicator + Rectangle { + width: 10 + height: 10 + radius: 5 + color: modelData.status === "running" ? "#4CAF50" : (modelData.exitCode === 0 ? "#9E9E9E" : "#F44336") + } + + // PID + Label { + text: modelData.pid + font.family: "monospace" + Layout.preferredWidth: 50 + } + + // Tool + Label { + text: modelData.tool + font.weight: Font.Medium + Layout.preferredWidth: 80 + elide: Text.ElideRight + } + + // Command + Label { + text: modelData.cmd + Layout.fillWidth: true + elide: Text.ElideMiddle + opacity: 0.8 + } + + // Runtime + Label { + text: formatRuntime(modelData.runtime) + font.family: "monospace" + Layout.preferredWidth: 55 + horizontalAlignment: Text.AlignRight + } + + // Exit code (if exited) + Label { + visible: modelData.status !== "running" + text: modelData.exitCode === 0 ? "✓" : "exit " + modelData.exitCode + font.family: "monospace" + color: modelData.exitCode === 0 ? "#4CAF50" : "#F44336" + Layout.preferredWidth: 45 + } + } + } + + Label { + anchors.centerIn: parent + visible: procs.length === 0 + text: currentSessionId ? "No background processes" : "No session selected" + opacity: 0.5 + } + } + + // Output pane (toggle-able) + GroupBox { + id: outputPane + visible: outputVisible + SplitView.fillWidth: true + SplitView.fillHeight: true + SplitView.minimumHeight: 60 + title: selectedPid > 0 ? "Output (PID " + selectedPid + ")" : "Output" + + ScrollView { + anchors.fill: parent + TextArea { + id: outputArea + text: outputText + readOnly: true + font.family: "monospace" + font.pointSize: 11 + wrapMode: TextEdit.Wrap + selectByMouse: true + placeholderText: "Select a process and click View Output" + } } } } @@ -236,9 +247,16 @@ Window { outputText = "" var out = ollie.procOutput(currentSessionId, currentAgentId, selectedPid) outputText = out.length > 0 ? out : "(no output)" + outputVisible = true } } + Button { + text: outputVisible ? "Hide Output" : "Show Output" + icon.name: outputVisible ? "go-up" : "go-down" + onClicked: outputVisible = !outputVisible + } + Item { Layout.fillWidth: true } Button {