forked from Qortal/Brooklyn
257 lines
10 KiB
QML
257 lines
10 KiB
QML
|
/*
|
||
|
SPDX-FileCopyrightText: 2020 Kai Uwe Broulik <kde@broulik.de>
|
||
|
|
||
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||
|
*/
|
||
|
|
||
|
import QtQuick 2.6
|
||
|
import QtQuick.Layouts 1.1
|
||
|
import QtQuick.Controls 2.3 as QQC2
|
||
|
import QtQml 2.15
|
||
|
|
||
|
import org.kde.kirigami 2.10 as Kirigami
|
||
|
import org.kde.kcm 1.5 as KCM
|
||
|
import org.kde.private.kcms.style 1.0 as Private
|
||
|
|
||
|
KCM.ScrollViewKCM {
|
||
|
id: root
|
||
|
|
||
|
KCM.ConfigModule.quickHelp: i18n("<p>This module allows you to have an overview of all plugins of the KDE Daemon, also referred to as KDE Services. Generally, there are two types of service:</p> <ul><li>Services invoked at startup</li><li>Services called on demand</li></ul> <p>The latter are only listed for convenience. The startup services can be started and stopped. You can also define whether services should be loaded at startup.</p> <p><b>Use this with care: some services are vital for Plasma; do not deactivate services if you do not know what you are doing.</b></p>")
|
||
|
|
||
|
Binding {
|
||
|
target: kcm.filteredModel
|
||
|
property: "query"
|
||
|
value: searchField.text
|
||
|
restoreMode: Binding.RestoreBinding
|
||
|
}
|
||
|
|
||
|
Binding {
|
||
|
target: kcm.filteredModel
|
||
|
property: "statusFilter"
|
||
|
value: filterCombo.model[filterCombo.currentIndex].statusFilter
|
||
|
restoreMode: Binding.RestoreBinding
|
||
|
}
|
||
|
|
||
|
header: ColumnLayout {
|
||
|
Kirigami.InlineMessage {
|
||
|
Layout.fillWidth: true
|
||
|
text: i18n("The background services manager (kded5) is currently not running. Make sure it is installed correctly.");
|
||
|
type: Kirigami.MessageType.Error
|
||
|
showCloseButton: false
|
||
|
visible: !kcm.kdedRunning
|
||
|
}
|
||
|
|
||
|
Kirigami.InlineMessage {
|
||
|
id: selfDisablingModulesHint
|
||
|
Layout.fillWidth: true
|
||
|
text: i18n("Some services disable themselves again when manually started if they are not useful in the current environment.")
|
||
|
type: Kirigami.MessageType.Information
|
||
|
showCloseButton: true
|
||
|
visible: false
|
||
|
}
|
||
|
|
||
|
Kirigami.InlineMessage {
|
||
|
id: runningModulesChangedAfterSaveHint
|
||
|
Layout.fillWidth: true
|
||
|
text: i18n("Some services were automatically started/stopped when the background services manager (kded5) was restarted to apply your changes.")
|
||
|
type: Kirigami.MessageType.Information
|
||
|
showCloseButton: true
|
||
|
visible: false
|
||
|
}
|
||
|
|
||
|
Kirigami.InlineMessage {
|
||
|
id: errorMessage
|
||
|
Layout.fillWidth: true
|
||
|
|
||
|
type: Kirigami.MessageType.Error
|
||
|
showCloseButton: true
|
||
|
visible: false
|
||
|
|
||
|
Connections {
|
||
|
target: kcm
|
||
|
function onErrorMessage(errorString) {
|
||
|
errorMessage.text = errorString;
|
||
|
errorMessage.visible = true;
|
||
|
}
|
||
|
function onShowSelfDisablingModulesHint() {
|
||
|
selfDisablingModulesHint.visible = true;
|
||
|
}
|
||
|
function onShowRunningModulesChangedAfterSaveHint() {
|
||
|
runningModulesChangedAfterSaveHint.visible = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RowLayout {
|
||
|
Layout.fillWidth: true
|
||
|
|
||
|
Kirigami.SearchField {
|
||
|
id: searchField
|
||
|
Layout.fillWidth: true
|
||
|
}
|
||
|
|
||
|
QQC2.ComboBox {
|
||
|
id: filterCombo
|
||
|
textRole: "text"
|
||
|
enabled: kcm.kdedRunning || currentIndex > 0
|
||
|
model: [
|
||
|
{text: i18n("All Services"), statusFilter: Private.KCM.UnknownStatus},
|
||
|
{text: i18nc("List running services", "Running"), statusFilter: Private.KCM.Running},
|
||
|
{text: i18nc("List not running services", "Not Running"), statusFilter: Private.KCM.NotRunning}
|
||
|
]
|
||
|
|
||
|
// HACK QQC2 doesn't support icons, so we just tamper with the desktop style ComboBox's background
|
||
|
// and inject a nice little filter icon.
|
||
|
Component.onCompleted: {
|
||
|
if (!background || !background.hasOwnProperty("properties")) {
|
||
|
// not a KQuickStyleItem
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var props = background.properties || {};
|
||
|
|
||
|
background.properties = Qt.binding(function() {
|
||
|
var newProps = props;
|
||
|
newProps.currentIcon = "view-filter";
|
||
|
newProps.iconColor = Kirigami.Theme.textColor;
|
||
|
return newProps;
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
view: ListView {
|
||
|
id: list
|
||
|
clip: true
|
||
|
activeFocusOnTab: true
|
||
|
|
||
|
model: kcm.filteredModel
|
||
|
|
||
|
section.property: "type"
|
||
|
section.delegate: Kirigami.ListSectionHeader {
|
||
|
width: list.width
|
||
|
label: {
|
||
|
switch (Number(section)) {
|
||
|
case Private.KCM.AutostartType: return i18n("Startup Services");
|
||
|
case Private.KCM.OnDemandType: return i18n("Load-on-Demand Services");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Component {
|
||
|
id: listDelegateComponent
|
||
|
|
||
|
Kirigami.AbstractListItem {
|
||
|
id: delegate
|
||
|
// FIXME why does the padding logic to dodge the ScrollBars not work here?
|
||
|
text: model.display
|
||
|
enabled: !model.immutable
|
||
|
checkable: model.type !== Private.KCM.OnDemandType
|
||
|
checked: model.autoloadEnabled === true
|
||
|
hoverEnabled: checkable
|
||
|
focusPolicy: Qt.ClickFocus
|
||
|
Accessible.description: i18n("Toggle automatically loading this service on startup")
|
||
|
onClicked: {
|
||
|
if (checkable) {
|
||
|
model.autoloadEnabled = !model.autoloadEnabled;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Component.onCompleted: {
|
||
|
// Checkable Kirigami.ListItem has blue background which we don't want
|
||
|
// as we have a dedicated CheckBox. Still using those properties for accessibility.
|
||
|
background.color = Qt.binding(function() {
|
||
|
return delegate.highlighted || (delegate.supportsMouseEvents && delegate.pressed)
|
||
|
? delegate.activeBackgroundColor
|
||
|
: delegate.backgroundColor
|
||
|
});
|
||
|
}
|
||
|
|
||
|
contentItem: RowLayout {
|
||
|
QQC2.CheckBox {
|
||
|
id: autoloadCheck
|
||
|
// Keep focus on the delegate
|
||
|
focusPolicy: Qt.NoFocus
|
||
|
checked: delegate.checked
|
||
|
visible: delegate.checkable
|
||
|
onToggled: model.autoloadEnabled = !model.autoloadEnabled
|
||
|
|
||
|
QQC2.ToolTip {
|
||
|
text: delegate.Accessible.description
|
||
|
}
|
||
|
|
||
|
KCM.SettingHighlighter {
|
||
|
highlight: !model.autoloadEnabled
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ColumnLayout {
|
||
|
Layout.fillWidth: true
|
||
|
spacing: 0
|
||
|
|
||
|
QQC2.Label {
|
||
|
id: displayLabel
|
||
|
Layout.fillWidth: true
|
||
|
text: delegate.text
|
||
|
elide: Text.ElideRight
|
||
|
textFormat: Text.PlainText
|
||
|
color: (delegate.highlighted || (delegate.pressed && delegate.supportsMouseEvents)) ? delegate.activeTextColor : delegate.textColor
|
||
|
}
|
||
|
|
||
|
QQC2.Label {
|
||
|
Layout.fillWidth: true
|
||
|
text: model.description
|
||
|
// FIXME do we have a descriptive label component?
|
||
|
opacity: delegate.hovered ? 0.8 : 0.6
|
||
|
wrapMode: Text.WordWrap
|
||
|
textFormat: Text.PlainText
|
||
|
color: displayLabel.color
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QQC2.Label {
|
||
|
id: statusLabel
|
||
|
horizontalAlignment: Text.AlignRight
|
||
|
opacity: model.status === Private.KCM.Running ? 1 : delegate.hovered ? 0.8 : 0.6
|
||
|
color: model.status === Private.KCM.Running ? Kirigami.Theme.positiveTextColor : displayLabel.color
|
||
|
visible: kcm.kdedRunning && model.type !== Private.KCM.OnDemandType
|
||
|
text: {
|
||
|
switch (model.status) {
|
||
|
case Private.KCM.NotRunning: return i18n("Not running");
|
||
|
case Private.KCM.Running: return i18n("Running");
|
||
|
}
|
||
|
return "";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QQC2.Button {
|
||
|
icon.name: model.status === Private.KCM.Running ? "media-playback-pause" : "media-playback-start"
|
||
|
visible: kcm.kdedRunning && model.status !== Private.KCM.UnknownStatus && model.type !== Private.KCM.OnDemandType
|
||
|
onClicked: {
|
||
|
errorMessage.visible = false;
|
||
|
|
||
|
console.log("DELEGATE", delegate)
|
||
|
if (model.status === Private.KCM.Running) {
|
||
|
kcm.stopModule(model.moduleName);
|
||
|
} else {
|
||
|
kcm.startModule(model.moduleName);
|
||
|
}
|
||
|
}
|
||
|
Accessible.name: model.status === Private.KCM.Running ? i18n("Stop Service") : i18n("Start Service")
|
||
|
|
||
|
QQC2.ToolTip {
|
||
|
text: parent.Accessible.name
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delegate: Kirigami.DelegateRecycler {
|
||
|
width: list.width
|
||
|
sourceComponent: listDelegateComponent
|
||
|
}
|
||
|
}
|
||
|
}
|