Compare commits

...

4 commits

Author SHA1 Message Date
Nicolas Fella
cbd0eda348 Explictly specify signal handler args 2024-06-06 02:33:34 +02:00
Nicolas Fella
632bf8e450 Port runcommand config to Kirigami.Dialog
It works better out of the box
2024-06-06 02:32:16 +02:00
Nicolas Fella
811101352f Port runcommand config to ItemDelegate 2024-06-06 02:30:05 +02:00
Nicolas Fella
6366ceb530 [app] Fixup plugin config pages
Depending on the content we want to use Page or ScrollablePage

The runcommand config should be a scrollablepage, but isn't right now

The code even (incompletely) works around that

To address this make the individual config files add their page instead of an additional wrapper page
2024-06-06 02:27:40 +02:00
9 changed files with 299 additions and 286 deletions

View file

@ -40,7 +40,6 @@ ecm_target_qml_sources(kdeconnect-app SOURCES
qml/volume.qml qml/volume.qml
qml/MprisSlider.qml qml/MprisSlider.qml
qml/PluginSettings.qml qml/PluginSettings.qml
qml/PluginInfoPage.qml
qml/Settings.qml qml/Settings.qml
) )

View file

@ -1,31 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import org.kde.kirigami as Kirigami
Kirigami.Page {
id: root
property string configFile
property string device
actions: loader.item && loader.item.action ? [loader.item.action] : []
onConfigFileChanged: loader.setSource(configFile, {
device: root.device
})
Loader {
anchors.fill: parent
id: loader
Component.onCompleted: setSource(configFile, {
device: root.device
})
}
}

View file

@ -63,17 +63,14 @@ Kirigami.ScrollablePage {
// https://bugreports.qt.io/browse/QTBUG-123123 // https://bugreports.qt.io/browse/QTBUG-123123
Accessible.name: i18nd("kdeconnect-app", "Configure plugin") Accessible.name: i18nd("kdeconnect-app", "Configure plugin")
onTriggered: { onTriggered: {
if (pageStack.lastItem.toString().startsWith("PluginInfoPage")) { if (!pageStack.lastItem.toString().startsWith("PluginSettings")) {
pageStack.lastItem.configFile = configSource; pageStack.pop()
pageStack.lastItem.title = name;
pageStack.goForward();
} else {
pageStack.push(Qt.resolvedUrl("PluginInfoPage.qml"), {
title: name,
configFile: configSource,
device: root.device,
});
} }
pageStack.push(configSource, {
title: name,
device: root.device,
});
} }
} }
] ]

View file

@ -10,31 +10,36 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
Kirigami.FormLayout { Kirigami.Page {
property string device property string device
KdeConnectPluginConfig { Kirigami.FormLayout {
id: config
deviceId: device
pluginName: "kdeconnect_clipboard"
}
Component.onCompleted: { anchors.fill: parent
autoShare.checked = config.getBool("autoShare", config.getBool("sendUnknown", true))
password.checked = config.getBool("sendPassword", true)
}
QQC2.CheckBox { KdeConnectPluginConfig {
id: autoShare id: config
text: i18n("Automatically share the clipboard from this device") deviceId: device
onClicked: config.set("autoShare", checked) pluginName: "kdeconnect_clipboard"
} }
QQC2.CheckBox { Component.onCompleted: {
id: password autoShare.checked = config.getBool("autoShare", config.getBool("sendUnknown", true))
text: i18n("Including passwords (as marked by password managers)") password.checked = config.getBool("sendPassword", true)
onClicked: config.set("sendPassword", checked) }
}
QQC2.CheckBox {
id: autoShare
text: i18n("Automatically share the clipboard from this device")
onClicked: config.set("autoShare", checked)
}
QQC2.CheckBox {
id: password
text: i18n("Including passwords (as marked by password managers)")
onClicked: config.set("sendPassword", checked)
}
}
} }

View file

@ -11,46 +11,52 @@ import org.kde.kirigami 2.20 as Kirigami
import Qt.labs.platform 1.1 import Qt.labs.platform 1.1
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
Kirigami.FormLayout { Kirigami.Page {
property string device property string device
property var action: Kirigami.Action { actions: [
icon.name: "dialog-ok" Kirigami.Action {
text: i18n("Apply") icon.name: "dialog-ok"
onTriggered: config.set("ringtone", path.text) text: i18n("Apply")
} onTriggered: config.set("ringtone", path.text)
FileDialog {
id: fileDialog
currentFile: path.text
onAccepted: {
path.text = currentFile.toString().replace("file://", "")
} }
} ]
KdeConnectPluginConfig { Kirigami.FormLayout {
id: config
deviceId: device
pluginName: "kdeconnect_findthisdevice"
onConfigChanged: { anchors.fill: parent
path.text = getString("ringtone", StandardPaths.writableLocation(StandardPaths.DownloadsLocation).toString().replace("file://", ""))
}
}
RowLayout { FileDialog {
Kirigami.FormData.label: i18n("Sound to play:") id: fileDialog
currentFile: path.text
QQC2.TextField { onAccepted: {
id: path path.text = currentFile.toString().replace("file://", "")
}
} }
QQC2.Button { KdeConnectPluginConfig {
icon.name: "document-open" id: config
onClicked: fileDialog.open() deviceId: device
pluginName: "kdeconnect_findthisdevice"
onConfigChanged: {
path.text = getString("ringtone", StandardPaths.writableLocation(StandardPaths.DownloadsLocation).toString().replace("file://", ""))
}
}
RowLayout {
Kirigami.FormData.label: i18n("Sound to play:")
QQC2.TextField {
id: path
}
QQC2.Button {
icon.name: "document-open"
onClicked: fileDialog.open()
}
} }
} }
} }

View file

@ -10,48 +10,54 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
Kirigami.FormLayout { Kirigami.Page {
property string device property string device
KdeConnectPluginConfig { Kirigami.FormLayout {
id: config
deviceId: device
pluginName: "kdeconnect_pausemusic"
}
Component.onCompleted: { anchors.fill: parent
talking.checked = config.getBool("conditionTalking", false)
mute.checked = config.getBool("actionMute", false)
pause.checked = config.getBool("actionPause", true)
resume.checked = config.getBool("actionResume", true)
}
QQC2.RadioButton { KdeConnectPluginConfig {
text: i18n("Pause as soon as phone rings") id: config
checked: !talking.checked deviceId: device
} pluginName: "kdeconnect_pausemusic"
}
QQC2.RadioButton { Component.onCompleted: {
id: talking talking.checked = config.getBool("conditionTalking", false)
onCheckedChanged: config.set("conditionTalking", checked) mute.checked = config.getBool("actionMute", false)
text: i18n("Pause only while talking") pause.checked = config.getBool("actionPause", true)
} resume.checked = config.getBool("actionResume", true)
}
QQC2.CheckBox { QQC2.RadioButton {
id: pause text: i18n("Pause as soon as phone rings")
text: i18n("Pause media players") checked: !talking.checked
onClicked: config.set("actionPause", checked) }
}
QQC2.CheckBox { QQC2.RadioButton {
id: mute id: talking
text: i18n("Mute system sound") onCheckedChanged: config.set("conditionTalking", checked)
onClicked: config.set("actionMute", checked) text: i18n("Pause only while talking")
} }
QQC2.CheckBox { QQC2.CheckBox {
id: resume id: pause
text: i18n("Resume automatically when call ends") text: i18n("Pause media players")
onClicked: config.set("actionResume", checked) onClicked: config.set("actionPause", checked)
}
QQC2.CheckBox {
id: mute
text: i18n("Mute system sound")
onClicked: config.set("actionMute", checked)
}
QQC2.CheckBox {
id: resume
text: i18n("Resume automatically when call ends")
onClicked: config.set("actionResume", checked)
}
} }
} }

View file

@ -3,118 +3,137 @@
* *
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/ */
pragma ComponentBehavior: Bound
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Layouts
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
ListView { Kirigami.ScrollablePage {
id: view id: root
Component.onCompleted: {
root.leftPadding = 0
root.rightPadding = 0
root.topPadding = 0
root.bottomPadding = 0
}
property string device property string device
property var action: Kirigami.Action { actions: [
icon.name: "list-add" Kirigami.Action {
text: i18n("Add command") icon.name: "list-add"
onTriggered: addDialog.open() text: i18n("Add command")
} onTriggered: addDialog.open()
}
]
model: CommandsModel { ListView {
id: commandModel id: view
deviceId: device
}
delegate: Kirigami.SwipeListItem { model: CommandsModel {
width: parent.width id: commandModel
enabled: true deviceId: device
contentItem: QQC2.Label {
text: i18n("%1 <br> <i>%2</i>", name, command)
} }
actions: Kirigami.Action { delegate: QQC2.ItemDelegate {
text: i18n("Delete") id: commandDelegate
icon.name: "delete"
onTriggered: commandModel.removeCommand(index)
}
}
Kirigami.PlaceholderMessage { required property string name
icon.name: 'utilities-terminal' required property string command
anchors.centerIn: parent required property int index
visible: view.count === 0
width: parent.width - Kirigami.Units.gridUnit * 4
text: i18n("No Commands")
explanation: i18n("Add commands to run them remotely from other devices")
helpfulAction: view.action
}
QQC2.Dialog { text: name
id: addDialog width: ListView.view.width
title: "Add command"
standardButtons: QQC2.Dialog.Save | QQC2.Dialog.Cancel contentItem: RowLayout {
Kirigami.TitleSubtitle {
Kirigami.FormLayout { title: commandDelegate.text
QQC2.TextField { subtitle: commandDelegate.command
id: nameField Layout.fillWidth: true
Kirigami.FormData.label: i18n("Name:")
}
QQC2.TextField {
id: commandField
Kirigami.FormData.label: i18n("Command:")
}
QQC2.ComboBox {
Kirigami.FormData.label: i18n("Sample commands:")
textRole: "name"
model: ListModel {
id: sampleCommands
ListElement {
name: "Sample command"
command: ""
}
ListElement {
name: "Suspend"
command: "systemctl suspend"
}
ListElement {
name: "Maximum Brightness"
command: "qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.setBrightness `qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.brightnessMax`"
}
ListElement {
name: "Lock Screen"
command: "loginctl lock-session"
}
ListElement {
name: "Unlock Screen"
command: "loginctl unlock-session"
}
ListElement {
name: "Close All Vaults"
command: "qdbus org.kde.kded5 /modules/plasmavault closeAllVaults"
}
ListElement {
name: "Forcefully Close All Vaults"
command: "qdbus org.kde.kded5 /modules/plasmavault forceCloseAllVaults"
}
} }
onActivated: {
if (index > 0) { QQC2.ToolButton {
nameField.text = sampleCommands.get(index).name text: i18n("Delete")
commandField.text = sampleCommands.get(index).command icon.name: "delete"
} onClicked: commandModel.removeCommand(commandDelegate.index)
display: QQC2.ToolButton.IconOnly
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered || activeFocus
} }
} }
} }
onAccepted: commandModel.addCommand(nameField.text, commandField.text) Kirigami.PlaceholderMessage {
icon.name: 'utilities-terminal'
anchors.centerIn: parent
visible: view.count === 0
width: parent.width - Kirigami.Units.gridUnit * 4
text: i18n("No Commands")
explanation: i18n("Add commands to run them remotely from other devices")
helpfulAction: root.actions[0]
}
Kirigami.Dialog {
id: addDialog
title: "Add command"
standardButtons: QQC2.Dialog.Save | QQC2.Dialog.Cancel
horizontalPadding: Kirigami.Units.largeSpacing
Kirigami.FormLayout {
QQC2.TextField {
id: nameField
Kirigami.FormData.label: i18n("Name:")
}
QQC2.TextField {
id: commandField
Kirigami.FormData.label: i18n("Command:")
}
QQC2.ComboBox {
Kirigami.FormData.label: i18n("Sample commands:")
textRole: "name"
model: ListModel {
id: sampleCommands
ListElement {
name: "Sample command"
command: ""
}
ListElement {
name: "Suspend"
command: "systemctl suspend"
}
ListElement {
name: "Maximum Brightness"
command: "qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.setBrightness `qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.brightnessMax`"
}
ListElement {
name: "Lock Screen"
command: "loginctl lock-session"
}
ListElement {
name: "Unlock Screen"
command: "loginctl unlock-session"
}
ListElement {
name: "Close All Vaults"
command: "qdbus org.kde.kded5 /modules/plasmavault closeAllVaults"
}
ListElement {
name: "Forcefully Close All Vaults"
command: "qdbus org.kde.kded5 /modules/plasmavault forceCloseAllVaults"
}
}
onActivated: index => {
if (index > 0) {
nameField.text = sampleCommands.get(index).name
commandField.text = sampleCommands.get(index).command
}
}
}
}
onAccepted: commandModel.addCommand(nameField.text, commandField.text)
}
} }
} }

View file

@ -10,47 +10,52 @@ import QtQuick.Layouts 1.1
import org.kde.kirigami 2.5 as Kirigami import org.kde.kirigami 2.5 as Kirigami
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
Kirigami.FormLayout { Kirigami.Page {
property string device property string device
KdeConnectPluginConfig { Kirigami.FormLayout {
id: config
deviceId: device
pluginName: "kdeconnect_sendnotifications"
}
Component.onCompleted: { anchors.fill: parent
persistent.checked = config.getBool("generalPersistent", false)
includeBody.checked = config.getBool("generalIncludeBody", true)
includeIcon.checked = config.getBool("generalSynchronizeIcons", true)
urgency.value = config.getInt("generalUrgency", 0)
}
CheckBox { KdeConnectPluginConfig {
id: persistent id: config
text: i18n("Persistent notifications only") deviceId: device
onClicked: config.set("generalPersistent", checked) pluginName: "kdeconnect_sendnotifications"
} }
CheckBox { Component.onCompleted: {
id: includeBody persistent.checked = config.getBool("generalPersistent", false)
text: i18n("Include body") includeBody.checked = config.getBool("generalIncludeBody", true)
onClicked: config.set("generalIncludeBody", checked) includeIcon.checked = config.getBool("generalSynchronizeIcons", true)
} urgency.value = config.getInt("generalUrgency", 0)
}
CheckBox { CheckBox {
id: includeIcon id: persistent
text: i18n("Include icon") text: i18n("Persistent notifications only")
onClicked: config.set("generalSynchronizeIcons", checked) onClicked: config.set("generalPersistent", checked)
} }
SpinBox { CheckBox {
id: urgency id: includeBody
Kirigami.FormData.label: i18n("Minimum urgency level:") text: i18n("Include body")
from: 0 onClicked: config.set("generalIncludeBody", checked)
to: 2 }
onValueModified: config.set("generalUrgency", value)
}
CheckBox {
id: includeIcon
text: i18n("Include icon")
onClicked: config.set("generalSynchronizeIcons", checked)
}
SpinBox {
id: urgency
Kirigami.FormData.label: i18n("Minimum urgency level:")
from: 0
to: 2
onValueModified: config.set("generalUrgency", value)
}
}
} }

View file

@ -11,49 +11,56 @@ import org.kde.kirigami 2.20 as Kirigami
import Qt.labs.platform 1.1 import Qt.labs.platform 1.1
import org.kde.kdeconnect 1.0 import org.kde.kdeconnect 1.0
Kirigami.FormLayout { Kirigami.Page {
property string device property string device
property var action: Kirigami.Action { actions: [
icon.name: "dialog-ok" Kirigami.Action {
text: i18n("Apply") icon.name: "dialog-ok"
onTriggered: config.set("incoming_path", path.text) text: i18n("Apply")
} onTriggered: config.set("incoming_path", path.text)
FolderDialog {
id: folderDialog
currentFolder: path.text
onAccepted: {
path.text = currentFolder.toString().replace("file://", "")
} }
} ]
KdeConnectPluginConfig { Kirigami.FormLayout {
id: config
deviceId: device
pluginName: "kdeconnect_share"
onConfigChanged: { anchors.fill: parent
path.text = getString("incoming_path", StandardPaths.writableLocation(StandardPaths.DownloadsLocation).toString().replace("file://", ""))
}
}
RowLayout { FolderDialog {
Kirigami.FormData.label: i18n("Save files in:") id: folderDialog
currentFolder: path.text
QQC2.TextField { onAccepted: {
id: path path.text = currentFolder.toString().replace("file://", "")
}
} }
QQC2.Button { KdeConnectPluginConfig {
icon.name: "document-open" id: config
onClicked: folderDialog.open() deviceId: device
} pluginName: "kdeconnect_share"
}
QQC2.Label { onConfigChanged: {
text: i18n("%1 in the path will be replaced with the specific device name", "%1") path.text = getString("incoming_path", StandardPaths.writableLocation(StandardPaths.DownloadsLocation).toString().replace("file://", ""))
}
}
RowLayout {
Kirigami.FormData.label: i18n("Save files in:")
QQC2.TextField {
id: path
}
QQC2.Button {
icon.name: "document-open"
onClicked: folderDialog.open()
}
}
QQC2.Label {
text: i18n("%1 in the path will be replaced with the specific device name", "%1")
}
} }
} }