mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
kcm: Add ability to reorder quicksettings
Implements #75, reordering of quick settings, and also includes the mobile form components into the kcm.
This commit is contained in:
parent
35dec9d3d7
commit
17b4b774a3
19 changed files with 670 additions and 47 deletions
|
|
@ -9,34 +9,119 @@ import QtQuick.Controls 2.15 as QQC2
|
|||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.kcm 1.3 as KCM
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
|
||||
import "mobileform" as MobileForm
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
|
||||
title: i18n("Shell")
|
||||
|
||||
leftPadding: Kirigami.Units.largeSpacing
|
||||
rightPadding: Kirigami.Units.largeSpacing
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: Kirigami.Units.gridUnit
|
||||
bottomPadding: Kirigami.Units.gridUnit
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: form
|
||||
wideMode: false
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
width: root.width
|
||||
|
||||
Item {
|
||||
MobileForm.FormCard {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.FormData.label: i18n("Navigation Panel")
|
||||
Kirigami.FormData.isSection: true
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
MobileForm.FormCardHeader {
|
||||
title: i18n("Navigation Panel")
|
||||
}
|
||||
|
||||
MobileForm.FormSwitchDelegate {
|
||||
text: i18n("Gesture-only Mode")
|
||||
description: i18n("Whether to hide the navigation panel.")
|
||||
checked: !kcm.navigationPanelEnabled
|
||||
switchControl.onCheckStateChanged: {
|
||||
if (checked != !kcm.navigationPanelEnabled) {
|
||||
kcm.navigationPanelEnabled = !checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.CheckBox {
|
||||
Kirigami.FormData.label: i18n("Remove panel (only use gestures):")
|
||||
Layout.maximumWidth: form.width
|
||||
text: checked ? i18n("On") : i18n("Off")
|
||||
checked: !kcm.navigationPanelEnabled
|
||||
onCheckStateChanged: {
|
||||
if (checked != !kcm.navigationPanelEnabled) {
|
||||
kcm.navigationPanelEnabled = !checked;
|
||||
MobileForm.FormCard {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
MobileForm.FormCardHeader {
|
||||
title: i18n("Quick Settings")
|
||||
subtitle: i18n("Customize the order of quick settings in the pull-down panel.")
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: enabledQSListView
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
interactive: false
|
||||
|
||||
model: savedQuickSettings.enabledModel
|
||||
|
||||
moveDisplaced: Transition {
|
||||
YAnimator {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: listItemComponent
|
||||
|
||||
MobileForm.AbstractFormDelegate {
|
||||
id: qsDelegate
|
||||
|
||||
contentItem: RowLayout {
|
||||
Kirigami.ListItemDragHandle {
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
listItem: qsDelegate
|
||||
listView: enabledQSListView
|
||||
onMoveRequested: savedQuickSettings.enabledModel.moveRow(oldIndex, newIndex)
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
visible: model.icon !== ""
|
||||
source: model.icon
|
||||
Layout.rightMargin: (model.icon !== "") ? Kirigami.Units.largeSpacing : 0
|
||||
implicitWidth: (model.icon !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
implicitHeight: (model.icon !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Kirigami.DelegateRecycler {
|
||||
width: enabledQSListView.width
|
||||
sourceComponent: listItemComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MobileShell.SavedQuickSettings {
|
||||
id: savedQuickSettings
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
property bool showSeparator: false
|
||||
|
||||
readonly property bool controlHovered: hoverHandler.hovered
|
||||
|
||||
signal clicked()
|
||||
signal rightClicked()
|
||||
|
||||
leftPadding: Kirigami.Units.gridUnit
|
||||
topPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
||||
bottomPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.gridUnit
|
||||
|
||||
hoverEnabled: true
|
||||
background: Rectangle {
|
||||
color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, mouseArea.pressed ? 0.2 : hoverHandler.hovered ? 0.07 : 0)
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: 70 }
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: root.leftPadding
|
||||
anchors.rightMargin: root.rightPadding
|
||||
visible: root.showSeparator
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
root.rightClicked();
|
||||
} else if (mouse.button === Qt.LeftButton) {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property string description: ""
|
||||
property string iconName: ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
Kirigami.Icon {
|
||||
visible: root.iconName !== ""
|
||||
source: root.iconName
|
||||
Layout.rightMargin: (root.iconName !== "") ? Kirigami.Units.largeSpacing : 0
|
||||
implicitWidth: (root.iconName !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
implicitHeight: (root.iconName !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.description
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
visible: root.description !== ""
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
source: "arrow-right"
|
||||
implicitWidth: Kirigami.Units.iconSizes.small
|
||||
implicitHeight: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
}
|
||||
}
|
||||
80
kcms/mobileshell/package/contents/ui/mobileform/FormCard.qml
Normal file
80
kcms/mobileshell/package/contents/ui/mobileform/FormCard.qml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
/**
|
||||
* A single card that is contained in a form.
|
||||
*
|
||||
* The height will take the implicit height of the contentItem, while the width
|
||||
* is expected to be given by the parent.
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* The contents of the form card.
|
||||
*/
|
||||
property Item contentItem: Item {}
|
||||
|
||||
/**
|
||||
* The maximum width of the card.
|
||||
*/
|
||||
property real maximumWidth: Kirigami.Units.gridUnit * 30
|
||||
|
||||
property real padding: 0
|
||||
property real verticalPadding: padding
|
||||
property real horizontalPadding: padding
|
||||
property real topPadding: verticalPadding
|
||||
property real bottomPadding: verticalPadding
|
||||
property real leftPadding: horizontalPadding
|
||||
property real rightPadding: horizontalPadding
|
||||
|
||||
readonly property bool cardWidthRestricted: root.width > root.maximumWidth
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Kirigami.Theme.inherit: false
|
||||
|
||||
implicitHeight: topPadding + bottomPadding + contentItem.implicitHeight
|
||||
|
||||
onContentItemChanged: {
|
||||
// clear old items
|
||||
contentItemLoader.children = "";
|
||||
|
||||
contentItem.parent = contentItemLoader;
|
||||
contentItem.anchors.fill = contentItemLoader;
|
||||
contentItemLoader.children.push(contentItem);
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.color: Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
|
||||
border.width: 1
|
||||
|
||||
// only have card radius if it isn't filling the entire width
|
||||
radius: root.cardWidthRestricted ? Kirigami.Units.smallSpacing : 0
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.leftMargin: root.cardWidthRestricted ? Math.round((root.width - root.maximumWidth) / 2) : -1
|
||||
anchors.rightMargin: root.cardWidthRestricted ? Math.round((root.width - root.maximumWidth) / 2) : -1
|
||||
|
||||
Item {
|
||||
id: contentItemLoader
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: root.leftPadding
|
||||
anchors.rightMargin: root.rightPadding
|
||||
anchors.topMargin: root.topPadding
|
||||
anchors.bottomMargin: root.bottomPadding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: 0
|
||||
|
||||
property string title: ""
|
||||
property string subtitle: ""
|
||||
|
||||
ColumnLayout {
|
||||
visible: title !== "" || subtitle !== ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||
Layout.leftMargin: Kirigami.Units.gridUnit
|
||||
Layout.rightMargin: Kirigami.Units.gridUnit
|
||||
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
font.weight: Font.Bold
|
||||
text: title
|
||||
visible: title !== ""
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Label {
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
text: subtitle
|
||||
visible: subtitle !== ""
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
opacity: 0.5
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property alias checked: checkBoxItem.checked
|
||||
property alias checkBox: checkBoxItem
|
||||
|
||||
onClicked: checked = !checked;
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
CheckBox {
|
||||
id: checkBoxItem
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
Label {
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property string description: ""
|
||||
|
||||
// TODO
|
||||
property string currentValue: ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: root.description !== ""
|
||||
Layout.fillWidth: true
|
||||
text: root.description
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
text: root.currentValue
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
source: "arrow-down"
|
||||
implicitWidth: Kirigami.Units.iconSizes.small
|
||||
implicitHeight: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property alias checked: radioButtonItem.checked
|
||||
property alias radioButton: radioButtonItem
|
||||
|
||||
onClicked: checked = true;
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
RadioButton {
|
||||
id: radioButtonItem
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
Label {
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
Label {
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
wrapMode: Label.Wrap
|
||||
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.leftMargin: Kirigami.Units.gridUnit
|
||||
Layout.rightMargin: Kirigami.Units.gridUnit
|
||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property string description: ""
|
||||
property alias checked: switchItem.checked
|
||||
property alias switchControl: switchItem
|
||||
|
||||
onClicked: checked = !checked;
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: root.description !== ""
|
||||
Layout.fillWidth: true
|
||||
text: root.description
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: switchItem
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2022 Devin Lin <devin@kde.org>
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
AbstractFormDelegate {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property string description: ""
|
||||
property string iconName: ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
background: Item {}
|
||||
|
||||
contentItem: RowLayout {
|
||||
Kirigami.Icon {
|
||||
visible: root.iconName !== ""
|
||||
source: root.iconName
|
||||
Layout.rightMargin: (root.iconName !== "") ? Kirigami.Units.largeSpacing : 0
|
||||
implicitWidth: (root.iconName !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
implicitHeight: (root.iconName !== "") ? Kirigami.Units.iconSizes.small : 0
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.description
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
visible: root.description !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "mobileshellsettings.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace MobileShell;
|
||||
|
||||
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
|
||||
|
|
@ -25,6 +27,7 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
|
|||
m_configWatcher = KConfigWatcher::create(m_config);
|
||||
|
||||
connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) -> void {
|
||||
qDebug() << "config changed"; // TODO
|
||||
if (group.name() == GENERAL_CONFIG_GROUP) {
|
||||
Q_EMIT navigationPanelEnabledChanged();
|
||||
} else if (group.name() == QUICKSETTINGS_CONFIG_GROUP) {
|
||||
|
|
@ -74,7 +77,7 @@ QList<QString> MobileShellSettings::enabledQuickSettings() const
|
|||
|
||||
void MobileShellSettings::setEnabledQuickSettings(QList<QString> &list)
|
||||
{
|
||||
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||
auto group = KConfigGroup{m_config, QUICKSETTINGS_CONFIG_GROUP};
|
||||
group.writeEntry("enabledQuickSettings", list, KConfigGroup::Notify);
|
||||
m_config->sync();
|
||||
}
|
||||
|
|
@ -87,7 +90,7 @@ QList<QString> MobileShellSettings::disabledQuickSettings() const
|
|||
|
||||
void MobileShellSettings::setDisabledQuickSettings(QList<QString> &list)
|
||||
{
|
||||
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||
auto group = KConfigGroup{m_config, QUICKSETTINGS_CONFIG_GROUP};
|
||||
group.writeEntry("disabledQuickSettings", list, KConfigGroup::Notify);
|
||||
m_config->sync();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ void QuickSettingsModel::loadQuickSettings()
|
|||
return;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
|
||||
for (auto *quickSetting : m_quickSettings) {
|
||||
quickSetting->deleteLater();
|
||||
}
|
||||
|
|
@ -72,7 +74,7 @@ void QuickSettingsModel::loadQuickSettings()
|
|||
// loop through enabled quick settings metadata
|
||||
for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
|
||||
// load kpackage
|
||||
KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData.fileName()).path());
|
||||
KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData->fileName()).path());
|
||||
if (!package.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -91,10 +93,12 @@ void QuickSettingsModel::loadQuickSettings()
|
|||
}
|
||||
delete created;
|
||||
} else {
|
||||
qDebug() << "Loaded quicksetting" << metaData.fileName();
|
||||
qDebug() << "Loaded quicksetting" << metaData->fileName();
|
||||
m_quickSettings.push_back(createdSetting);
|
||||
}
|
||||
}
|
||||
|
||||
delete c;
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,14 @@ SavedQuickSettings::SavedQuickSettings(QObject *parent)
|
|||
, m_disabledPackages{}
|
||||
, m_enabledQSModel{new SavedQuickSettingsModel{this}}
|
||||
, m_disabledQSModel{new SavedQuickSettingsModel{this}}
|
||||
, m_updateTimer{new QTimer{this}}
|
||||
{
|
||||
// throttle model updates from config, to avoid performance issues with fast reloading
|
||||
m_updateTimer->setInterval(2000);
|
||||
connect(m_updateTimer, &QTimer::timeout, this, [this]() {
|
||||
refreshModel();
|
||||
});
|
||||
|
||||
// load quicksettings packages
|
||||
auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), "plasma/quicksettings");
|
||||
|
||||
|
|
@ -27,29 +34,33 @@ SavedQuickSettings::SavedQuickSettings(QObject *parent)
|
|||
qWarning() << "Quick setting package invalid:" << metaData.fileName();
|
||||
continue;
|
||||
}
|
||||
m_validPackages.push_back(metaData);
|
||||
m_validPackages.push_back(new KPluginMetaData{metaData});
|
||||
}
|
||||
|
||||
// subscribe to config changes
|
||||
connect(m_settings, &MobileShellSettings::enabledQuickSettingsChanged, this, [this]() {
|
||||
refreshModel();
|
||||
m_updateTimer->start();
|
||||
});
|
||||
connect(m_settings, &MobileShellSettings::disabledQuickSettingsChanged, this, [this]() {
|
||||
refreshModel();
|
||||
m_updateTimer->start();
|
||||
});
|
||||
|
||||
// subscribe to model changes
|
||||
connect(m_enabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
|
||||
connect(m_enabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData *> data) -> void {
|
||||
m_enabledPackages.clear();
|
||||
for (auto metaData : data) {
|
||||
m_enabledPackages.push_back(metaData);
|
||||
}
|
||||
|
||||
saveModel();
|
||||
});
|
||||
connect(m_disabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
|
||||
connect(m_disabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData *> data) -> void {
|
||||
m_disabledPackages.clear();
|
||||
for (auto metaData : data) {
|
||||
m_disabledPackages.push_back(metaData);
|
||||
}
|
||||
|
||||
saveModel();
|
||||
});
|
||||
|
||||
// load
|
||||
|
|
@ -77,7 +88,7 @@ void SavedQuickSettings::refreshModel()
|
|||
// add enabled quick settings in order
|
||||
for (const QString &pluginId : enabledQS) {
|
||||
for (auto &metaData : m_validPackages) {
|
||||
if (pluginId == metaData.pluginId()) {
|
||||
if (pluginId == metaData->pluginId()) {
|
||||
m_enabledPackages.push_back(metaData);
|
||||
break;
|
||||
}
|
||||
|
|
@ -87,7 +98,7 @@ void SavedQuickSettings::refreshModel()
|
|||
// add disabled quick settings in order
|
||||
for (const QString &pluginId : disabledQS) {
|
||||
for (auto &metaData : m_validPackages) {
|
||||
if (pluginId == metaData.pluginId()) {
|
||||
if (pluginId == metaData->pluginId()) {
|
||||
m_disabledPackages.push_back(metaData);
|
||||
break;
|
||||
}
|
||||
|
|
@ -96,7 +107,7 @@ void SavedQuickSettings::refreshModel()
|
|||
|
||||
// add undefined quick settings to the back of enabled quick settings
|
||||
for (auto &metaData : m_validPackages) {
|
||||
if (!enabledQS.contains(metaData.pluginId()) && !disabledQS.contains(metaData.pluginId())) {
|
||||
if (!enabledQS.contains(metaData->pluginId()) && !disabledQS.contains(metaData->pluginId())) {
|
||||
m_enabledPackages.push_back(metaData);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,10 +122,10 @@ void SavedQuickSettings::saveModel()
|
|||
QList<QString> disabledQS;
|
||||
|
||||
for (auto &metaData : m_enabledPackages) {
|
||||
enabledQS.push_back(metaData.pluginId());
|
||||
enabledQS.push_back(metaData->pluginId());
|
||||
}
|
||||
for (auto &metaData : m_disabledPackages) {
|
||||
disabledQS.push_back(metaData.pluginId());
|
||||
disabledQS.push_back(metaData->pluginId());
|
||||
}
|
||||
|
||||
m_settings->setEnabledQuickSettings(enabledQS);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <QAbstractListModel>
|
||||
#include <QQmlListProperty>
|
||||
#include <QTimer>
|
||||
|
||||
#include "mobileshell_export.h"
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ namespace MobileShell
|
|||
class MOBILESHELL_EXPORT SavedQuickSettings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(SavedQuickSettingsModel *enabledModel READ enabledQuickSettingsModel CONSTANT)
|
||||
Q_PROPERTY(SavedQuickSettingsModel *disabledModel READ disabledQuickSettingsModel CONSTANT)
|
||||
|
||||
public:
|
||||
SavedQuickSettings(QObject *parent = nullptr);
|
||||
|
|
@ -34,12 +37,14 @@ private:
|
|||
void saveModel();
|
||||
|
||||
MobileShellSettings *m_settings;
|
||||
QList<KPluginMetaData> m_validPackages;
|
||||
QList<KPluginMetaData> m_enabledPackages;
|
||||
QList<KPluginMetaData> m_disabledPackages;
|
||||
QList<KPluginMetaData *> m_validPackages;
|
||||
QList<KPluginMetaData *> m_enabledPackages;
|
||||
QList<KPluginMetaData *> m_disabledPackages;
|
||||
|
||||
SavedQuickSettingsModel *m_enabledQSModel;
|
||||
SavedQuickSettingsModel *m_disabledQSModel;
|
||||
|
||||
QTimer *m_updateTimer;
|
||||
};
|
||||
|
||||
} // namespace MobileShell
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ QVariant SavedQuickSettingsModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
if (role == NameRole) {
|
||||
return m_data[index.row()].name();
|
||||
return m_data[index.row()]->name();
|
||||
} else if (role == IconRole) {
|
||||
return QString(); // TODO m_data[index.row()].icon();
|
||||
return m_data[index.row()]->iconName();
|
||||
} else if (role == IdRole) {
|
||||
return m_data[index.row()].pluginId();
|
||||
return m_data[index.row()]->pluginId();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
@ -43,14 +43,18 @@ void SavedQuickSettingsModel::moveRow(int oldIndex, int newIndex)
|
|||
return;
|
||||
}
|
||||
|
||||
if (oldIndex < newIndex) {
|
||||
++newIndex;
|
||||
}
|
||||
|
||||
Q_EMIT beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
|
||||
std::iter_swap(m_data.begin() + oldIndex, m_data.end() + newIndex);
|
||||
std::iter_swap(m_data.begin() + oldIndex, m_data.begin() + newIndex);
|
||||
Q_EMIT endMoveRows();
|
||||
|
||||
Q_EMIT dataUpdated(m_data);
|
||||
}
|
||||
|
||||
void SavedQuickSettingsModel::insertRow(KPluginMetaData metaData, int index)
|
||||
void SavedQuickSettingsModel::insertRow(KPluginMetaData *metaData, int index)
|
||||
{
|
||||
Q_EMIT beginInsertRows(QModelIndex(), index, index);
|
||||
m_data.insert(index, metaData);
|
||||
|
|
@ -72,12 +76,12 @@ void SavedQuickSettingsModel::removeRow(int index)
|
|||
Q_EMIT dataUpdated(m_data);
|
||||
}
|
||||
|
||||
QList<KPluginMetaData> SavedQuickSettingsModel::list() const
|
||||
QList<KPluginMetaData *> SavedQuickSettingsModel::list() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void SavedQuickSettingsModel::updateData(QList<KPluginMetaData> data)
|
||||
void SavedQuickSettingsModel::updateData(QList<KPluginMetaData *> data)
|
||||
{
|
||||
Q_EMIT beginResetModel();
|
||||
|
||||
|
|
|
|||
|
|
@ -35,19 +35,19 @@ public:
|
|||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void moveRow(int oldIndex, int newIndex);
|
||||
Q_INVOKABLE void insertRow(KPluginMetaData metaData, int index);
|
||||
Q_INVOKABLE void insertRow(KPluginMetaData *metaData, int index);
|
||||
Q_INVOKABLE void removeRow(int index);
|
||||
|
||||
QList<KPluginMetaData> list() const;
|
||||
QList<KPluginMetaData *> list() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateData(QList<KPluginMetaData> data);
|
||||
void updateData(QList<KPluginMetaData *> data);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dataUpdated(QList<KPluginMetaData> data);
|
||||
void dataUpdated(QList<KPluginMetaData *> data);
|
||||
|
||||
private:
|
||||
QList<KPluginMetaData> m_data;
|
||||
QList<KPluginMetaData *> m_data;
|
||||
};
|
||||
|
||||
} // namespace MobileShell
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
[Desktop Entry]
|
||||
Name=Mobile Data
|
||||
Icon=flashlight-on
|
||||
Icon=network-modem
|
||||
Description=Location quick setting
|
||||
|
||||
Type=Service
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
[Desktop Entry]
|
||||
Name=Wi-Fi
|
||||
Icon=flashlight-on
|
||||
Icon=network-wireless-signal
|
||||
Description=Wi-Fi quick setting
|
||||
|
||||
Type=Service
|
||||
|
|
|
|||
Loading…
Reference in a new issue