plasmoid: inline session rename, cwd folder dialog, fix rename signal bug
- Double-click session name in list to rename inline (RET to confirm, ESC to cancel) - Double-click cwd heading to open folder picker and change working directory - Add setConfig() to QML D-Bus client - Fix capi.go: chat/state callbacks used stale sessID after rename - Makefile: kf5 target uses trap to always restore CMakeLists.txt
This commit is contained in:
parent
28ce943e45
commit
9701d8f67c
26
Makefile
26
Makefile
|
|
@ -21,11 +21,11 @@ daemon: lib
|
|||
|
||||
# Step 2b: Build using KF5/Qt5 (for Plasma 5.27)
|
||||
kf5: lib
|
||||
cp CMakeLists.txt CMakeLists.txt.kf6.bak
|
||||
cp CMakeLists-kf5.txt CMakeLists.txt
|
||||
cmake -B $(BUILD_DIR) -S . --fresh
|
||||
cmake --build $(BUILD_DIR)
|
||||
mv CMakeLists.txt.kf6.bak CMakeLists.txt
|
||||
@cp CMakeLists.txt CMakeLists.txt.kf6.bak && \
|
||||
trap 'mv -f CMakeLists.txt.kf6.bak CMakeLists.txt' EXIT && \
|
||||
cp CMakeLists-kf5.txt CMakeLists.txt && \
|
||||
cmake -B $(BUILD_DIR) -S . --fresh && \
|
||||
cmake --build $(BUILD_DIR)
|
||||
|
||||
# Install the KF5 build
|
||||
kf5-install: kf5
|
||||
|
|
@ -46,15 +46,13 @@ kf5-install: kf5
|
|||
/usr/lib/x86_64-linux-gnu/qt5/qml/org/ollie/private/
|
||||
sudo install -m644 plasmoid/plugin/qmldir \
|
||||
/usr/lib/x86_64-linux-gnu/qt5/qml/org/ollie/private/
|
||||
# Plasmoid package (swap metadata + QML for Plasma 5)
|
||||
cp plasmoid/metadata.json plasmoid/metadata.json.kf6.bak
|
||||
cp plasmoid/contents/ui/main.qml plasmoid/contents/ui/main.qml.kf6.bak
|
||||
cp plasmoid/metadata-kf5.json plasmoid/metadata.json
|
||||
cp plasmoid/contents/ui/main-kf5.qml plasmoid/contents/ui/main.qml
|
||||
kpackagetool5 -t Plasma/Applet -u plasmoid/ 2>/dev/null || \
|
||||
kpackagetool5 -t Plasma/Applet -i plasmoid/
|
||||
mv plasmoid/metadata.json.kf6.bak plasmoid/metadata.json
|
||||
mv plasmoid/contents/ui/main.qml.kf6.bak plasmoid/contents/ui/main.qml
|
||||
# Plasmoid package (use temp copy to avoid clobbering source tree ownership)
|
||||
cp -a plasmoid /tmp/ollie-plasmoid-kf5
|
||||
cp plasmoid/metadata-kf5.json /tmp/ollie-plasmoid-kf5/metadata.json
|
||||
cp plasmoid/contents/ui/main-kf5.qml /tmp/ollie-plasmoid-kf5/contents/ui/main.qml
|
||||
kpackagetool5 -t Plasma/Applet -u /tmp/ollie-plasmoid-kf5/ 2>/dev/null || \
|
||||
kpackagetool5 -t Plasma/Applet -i /tmp/ollie-plasmoid-kf5/
|
||||
$(RM) -r /tmp/ollie-plasmoid-kf5
|
||||
# Dolphin service menus + helpers
|
||||
mkdir -p ~/.local/share/kio/servicemenus
|
||||
install -m755 dolphin/ollie-actions.desktop ~/.local/share/kio/servicemenus/
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ func ollie_create_session(cwdC *C.char, backendC *C.char, modelC *C.char, agentC
|
|||
sess.logMu.Unlock()
|
||||
|
||||
if chatCB != nil {
|
||||
cID := C.CString(sessID)
|
||||
cID := C.CString(sess.id)
|
||||
cText := C.CString(text)
|
||||
C.ollie_chat_cb_invoke(chatCB, cID, C.int64_t(offset), cText, C.int(len(text)))
|
||||
C.free(unsafe.Pointer(cID))
|
||||
|
|
@ -225,7 +225,7 @@ func ollie_create_session(cwdC *C.char, backendC *C.char, modelC *C.char, agentC
|
|||
}
|
||||
current = next
|
||||
if stateCB != nil {
|
||||
cID := C.CString(sessID)
|
||||
cID := C.CString(sess.id)
|
||||
cState := C.CString(current)
|
||||
C.ollie_state_cb_invoke(stateCB, cID, cState)
|
||||
C.free(unsafe.Pointer(cID))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Dialogs 1.3
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
|
|
@ -13,6 +14,17 @@ Item {
|
|||
|
||||
readonly property var dbus: Ollie.OllieDBusClient
|
||||
|
||||
FileDialog {
|
||||
id: folderDialog
|
||||
title: "Choose working directory"
|
||||
selectFolder: true
|
||||
folder: dbus.activeCwd ? "file://" + dbus.activeCwd : shortcuts.home
|
||||
onAccepted: {
|
||||
var path = fileUrl.toString().replace("file://", "")
|
||||
dbus.setConfig(dbus.activeSessionId, "cwd", path)
|
||||
}
|
||||
}
|
||||
|
||||
Plasmoid.status: dbus.sessions.length > 0
|
||||
? PlasmaCore.Types.ActiveStatus
|
||||
: PlasmaCore.Types.PassiveStatus
|
||||
|
|
@ -90,6 +102,15 @@ Item {
|
|||
text: dbus.activeCwd || "Ollie"
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideMiddle
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: {
|
||||
if (dbus.activeSessionId !== "") {
|
||||
folderDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
|
|
@ -111,9 +132,12 @@ Item {
|
|||
model: dbus.sessions
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: sessionDelegate
|
||||
width: sessionList.width
|
||||
highlighted: modelData.id === dbus.activeSessionId
|
||||
|
||||
property bool renaming: false
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 6
|
||||
|
||||
|
|
@ -131,27 +155,60 @@ Item {
|
|||
}
|
||||
|
||||
Label {
|
||||
id: sessionLabel
|
||||
text: modelData.id
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.family: "monospace"
|
||||
font.pixelSize: 11
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: inlineRenameField
|
||||
Layout.fillWidth: true
|
||||
font.family: "monospace"
|
||||
font.pixelSize: 11
|
||||
visible: sessionDelegate.renaming
|
||||
onAccepted: {
|
||||
var newName = text.trim()
|
||||
if (newName !== "" && newName !== modelData.id) {
|
||||
dbus.renameSession(modelData.id, newName)
|
||||
}
|
||||
sessionDelegate.renaming = false
|
||||
}
|
||||
Keys.onEscapePressed: sessionDelegate.renaming = false
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
text = modelData.id
|
||||
selectAll()
|
||||
forceActiveFocus()
|
||||
}
|
||||
}
|
||||
onActiveFocusChanged: {
|
||||
if (!activeFocus && sessionDelegate.renaming) {
|
||||
sessionDelegate.renaming = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: modelData.agent
|
||||
opacity: 0.7
|
||||
font.pixelSize: 11
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
icon.name: "process-stop"
|
||||
implicitWidth: 22; implicitHeight: 22
|
||||
onClicked: dbus.killSession(modelData.id)
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: dbus.activeSessionId = modelData.id
|
||||
onDoubleClicked: sessionDelegate.renaming = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
import org.kde.plasma.plasmoid
|
||||
import org.kde.plasma.components as PlasmaComponents
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
|
|
@ -13,6 +14,16 @@ PlasmoidItem {
|
|||
// Convenience alias
|
||||
readonly property var dbus: Ollie.OllieDBusClient
|
||||
|
||||
FolderDialog {
|
||||
id: folderDialog
|
||||
title: "Choose working directory"
|
||||
currentFolder: dbus.activeCwd ? "file://" + dbus.activeCwd : StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
||||
onAccepted: {
|
||||
let path = selectedFolder.toString().replace("file://", "")
|
||||
dbus.setConfig(dbus.activeSessionId, "cwd", path)
|
||||
}
|
||||
}
|
||||
|
||||
preferredRepresentation: compactRepresentation
|
||||
|
||||
toolTipMainText: "Ollie"
|
||||
|
|
@ -88,6 +99,15 @@ PlasmoidItem {
|
|||
text: dbus.activeCwd || "Ollie"
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideMiddle
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: {
|
||||
if (dbus.activeSessionId !== "") {
|
||||
folderDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
|
|
@ -109,9 +129,12 @@ PlasmoidItem {
|
|||
model: dbus.sessions
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: sessionDelegate
|
||||
width: sessionList.width
|
||||
highlighted: modelData.id === dbus.activeSessionId
|
||||
|
||||
property bool renaming: false
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 6
|
||||
|
||||
|
|
@ -129,27 +152,60 @@ PlasmoidItem {
|
|||
}
|
||||
|
||||
Label {
|
||||
id: sessionLabel
|
||||
text: modelData.id
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.family: "monospace"
|
||||
font.pixelSize: 11
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: inlineRenameField
|
||||
Layout.fillWidth: true
|
||||
font.family: "monospace"
|
||||
font.pixelSize: 11
|
||||
visible: sessionDelegate.renaming
|
||||
onAccepted: {
|
||||
let newName = text.trim()
|
||||
if (newName !== "" && newName !== modelData.id) {
|
||||
dbus.renameSession(modelData.id, newName)
|
||||
}
|
||||
sessionDelegate.renaming = false
|
||||
}
|
||||
Keys.onEscapePressed: sessionDelegate.renaming = false
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
text = modelData.id
|
||||
selectAll()
|
||||
forceActiveFocus()
|
||||
}
|
||||
}
|
||||
onActiveFocusChanged: {
|
||||
if (!activeFocus && sessionDelegate.renaming) {
|
||||
sessionDelegate.renaming = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: modelData.agent
|
||||
opacity: 0.7
|
||||
font.pixelSize: 11
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
icon.name: "process-stop"
|
||||
implicitWidth: 22; implicitHeight: 22
|
||||
onClicked: dbus.killSession(modelData.id)
|
||||
visible: !sessionDelegate.renaming
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: dbus.activeSessionId = modelData.id
|
||||
onDoubleClicked: sessionDelegate.renaming = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,6 +183,33 @@ bool OllieDBusClient::killSession(const QString &sessionId)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::renameSession(const QString &sessionId, const QString &newName)
|
||||
{
|
||||
QDBusReply<bool> reply = m_iface->call("RenameSession", sessionId, newName);
|
||||
if (reply.isValid() && reply.value()) {
|
||||
if (sessionId == m_activeSessionId) {
|
||||
m_activeSessionId = newName;
|
||||
emit activeSessionIdChanged();
|
||||
}
|
||||
refreshSessions();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::setConfig(const QString &sessionId, const QString &key, const QString &value)
|
||||
{
|
||||
QDBusReply<bool> reply = m_iface->call("SetConfig", sessionId, key, value);
|
||||
if (reply.isValid() && reply.value()) {
|
||||
if (sessionId == m_activeSessionId && key == "cwd") {
|
||||
m_activeCwd = value;
|
||||
emit activeCwdChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::submit(const QString &sessionId, const QString &prompt)
|
||||
{
|
||||
QDBusReply<bool> reply = m_iface->call("Submit", sessionId, prompt);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ public:
|
|||
Q_INVOKABLE void fetchChat();
|
||||
Q_INVOKABLE QString createSession(const QString &cwd);
|
||||
Q_INVOKABLE bool killSession(const QString &sessionId);
|
||||
Q_INVOKABLE bool renameSession(const QString &sessionId, const QString &newName);
|
||||
Q_INVOKABLE bool setConfig(const QString &sessionId, const QString &key, const QString &value);
|
||||
Q_INVOKABLE bool submit(const QString &sessionId, const QString &prompt);
|
||||
Q_INVOKABLE bool interrupt(const QString &sessionId);
|
||||
|
||||
|
|
|
|||
Reference in New Issue