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:
Devin Lin 2022-03-17 15:34:27 -04:00
parent 35dec9d3d7
commit 17b4b774a3
19 changed files with 670 additions and 47 deletions

View file

@ -9,35 +9,120 @@ import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.19 as Kirigami
import org.kde.kcm 1.3 as KCM import org.kde.kcm 1.3 as KCM
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import "mobileform" as MobileForm
KCM.SimpleKCM { KCM.SimpleKCM {
id: root id: root
title: i18n("Shell") title: i18n("Shell")
leftPadding: Kirigami.Units.largeSpacing leftPadding: 0
rightPadding: Kirigami.Units.largeSpacing rightPadding: 0
topPadding: Kirigami.Units.gridUnit
bottomPadding: Kirigami.Units.gridUnit
Kirigami.FormLayout { ColumnLayout {
id: form spacing: 0
wideMode: false width: root.width
Item { MobileForm.FormCard {
Layout.fillWidth: true Layout.fillWidth: true
Kirigami.FormData.label: i18n("Navigation Panel")
Kirigami.FormData.isSection: true contentItem: ColumnLayout {
spacing: 0
MobileForm.FormCardHeader {
title: i18n("Navigation Panel")
} }
QQC2.CheckBox { MobileForm.FormSwitchDelegate {
Kirigami.FormData.label: i18n("Remove panel (only use gestures):") text: i18n("Gesture-only Mode")
Layout.maximumWidth: form.width description: i18n("Whether to hide the navigation panel.")
text: checked ? i18n("On") : i18n("Off")
checked: !kcm.navigationPanelEnabled checked: !kcm.navigationPanelEnabled
onCheckStateChanged: { switchControl.onCheckStateChanged: {
if (checked != !kcm.navigationPanelEnabled) { if (checked != !kcm.navigationPanelEnabled) {
kcm.navigationPanelEnabled = !checked; 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
}
}
}
} }

View file

@ -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();
}
}
}
}

View file

@ -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
}
}
}

View 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
}
}
}

View file

@ -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
}
}

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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
}

View file

@ -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
}
}
}

View file

@ -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 !== ""
}
}
}
}

View file

@ -6,6 +6,8 @@
#include "mobileshellsettings.h" #include "mobileshellsettings.h"
#include <QDebug>
using namespace MobileShell; using namespace MobileShell;
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc"); const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
@ -25,6 +27,7 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
m_configWatcher = KConfigWatcher::create(m_config); m_configWatcher = KConfigWatcher::create(m_config);
connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) -> void { 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) { if (group.name() == GENERAL_CONFIG_GROUP) {
Q_EMIT navigationPanelEnabledChanged(); Q_EMIT navigationPanelEnabledChanged();
} else if (group.name() == QUICKSETTINGS_CONFIG_GROUP) { } else if (group.name() == QUICKSETTINGS_CONFIG_GROUP) {
@ -74,7 +77,7 @@ QList<QString> MobileShellSettings::enabledQuickSettings() const
void MobileShellSettings::setEnabledQuickSettings(QList<QString> &list) 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); group.writeEntry("enabledQuickSettings", list, KConfigGroup::Notify);
m_config->sync(); m_config->sync();
} }
@ -87,7 +90,7 @@ QList<QString> MobileShellSettings::disabledQuickSettings() const
void MobileShellSettings::setDisabledQuickSettings(QList<QString> &list) 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); group.writeEntry("disabledQuickSettings", list, KConfigGroup::Notify);
m_config->sync(); m_config->sync();
} }

View file

@ -61,6 +61,8 @@ void QuickSettingsModel::loadQuickSettings()
return; return;
} }
beginResetModel();
for (auto *quickSetting : m_quickSettings) { for (auto *quickSetting : m_quickSettings) {
quickSetting->deleteLater(); quickSetting->deleteLater();
} }
@ -72,7 +74,7 @@ void QuickSettingsModel::loadQuickSettings()
// loop through enabled quick settings metadata // loop through enabled quick settings metadata
for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) { for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
// load kpackage // 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()) { if (!package.isValid()) {
continue; continue;
} }
@ -91,10 +93,12 @@ void QuickSettingsModel::loadQuickSettings()
} }
delete created; delete created;
} else { } else {
qDebug() << "Loaded quicksetting" << metaData.fileName(); qDebug() << "Loaded quicksetting" << metaData->fileName();
m_quickSettings.push_back(createdSetting); m_quickSettings.push_back(createdSetting);
} }
} }
delete c; delete c;
endResetModel();
} }

View file

@ -17,7 +17,14 @@ SavedQuickSettings::SavedQuickSettings(QObject *parent)
, m_disabledPackages{} , m_disabledPackages{}
, m_enabledQSModel{new SavedQuickSettingsModel{this}} , m_enabledQSModel{new SavedQuickSettingsModel{this}}
, m_disabledQSModel{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 // load quicksettings packages
auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), "plasma/quicksettings"); 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(); qWarning() << "Quick setting package invalid:" << metaData.fileName();
continue; continue;
} }
m_validPackages.push_back(metaData); m_validPackages.push_back(new KPluginMetaData{metaData});
} }
// subscribe to config changes // subscribe to config changes
connect(m_settings, &MobileShellSettings::enabledQuickSettingsChanged, this, [this]() { connect(m_settings, &MobileShellSettings::enabledQuickSettingsChanged, this, [this]() {
refreshModel(); m_updateTimer->start();
}); });
connect(m_settings, &MobileShellSettings::disabledQuickSettingsChanged, this, [this]() { connect(m_settings, &MobileShellSettings::disabledQuickSettingsChanged, this, [this]() {
refreshModel(); m_updateTimer->start();
}); });
// subscribe to model changes // 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(); m_enabledPackages.clear();
for (auto metaData : data) { for (auto metaData : data) {
m_enabledPackages.push_back(metaData); 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(); m_disabledPackages.clear();
for (auto metaData : data) { for (auto metaData : data) {
m_disabledPackages.push_back(metaData); m_disabledPackages.push_back(metaData);
} }
saveModel();
}); });
// load // load
@ -77,7 +88,7 @@ void SavedQuickSettings::refreshModel()
// add enabled quick settings in order // add enabled quick settings in order
for (const QString &pluginId : enabledQS) { for (const QString &pluginId : enabledQS) {
for (auto &metaData : m_validPackages) { for (auto &metaData : m_validPackages) {
if (pluginId == metaData.pluginId()) { if (pluginId == metaData->pluginId()) {
m_enabledPackages.push_back(metaData); m_enabledPackages.push_back(metaData);
break; break;
} }
@ -87,7 +98,7 @@ void SavedQuickSettings::refreshModel()
// add disabled quick settings in order // add disabled quick settings in order
for (const QString &pluginId : disabledQS) { for (const QString &pluginId : disabledQS) {
for (auto &metaData : m_validPackages) { for (auto &metaData : m_validPackages) {
if (pluginId == metaData.pluginId()) { if (pluginId == metaData->pluginId()) {
m_disabledPackages.push_back(metaData); m_disabledPackages.push_back(metaData);
break; break;
} }
@ -96,7 +107,7 @@ void SavedQuickSettings::refreshModel()
// add undefined quick settings to the back of enabled quick settings // add undefined quick settings to the back of enabled quick settings
for (auto &metaData : m_validPackages) { 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); m_enabledPackages.push_back(metaData);
} }
} }
@ -111,10 +122,10 @@ void SavedQuickSettings::saveModel()
QList<QString> disabledQS; QList<QString> disabledQS;
for (auto &metaData : m_enabledPackages) { for (auto &metaData : m_enabledPackages) {
enabledQS.push_back(metaData.pluginId()); enabledQS.push_back(metaData->pluginId());
} }
for (auto &metaData : m_disabledPackages) { for (auto &metaData : m_disabledPackages) {
disabledQS.push_back(metaData.pluginId()); disabledQS.push_back(metaData->pluginId());
} }
m_settings->setEnabledQuickSettings(enabledQS); m_settings->setEnabledQuickSettings(enabledQS);

View file

@ -13,6 +13,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QQmlListProperty> #include <QQmlListProperty>
#include <QTimer>
#include "mobileshell_export.h" #include "mobileshell_export.h"
@ -22,6 +23,8 @@ namespace MobileShell
class MOBILESHELL_EXPORT SavedQuickSettings : public QObject class MOBILESHELL_EXPORT SavedQuickSettings : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(SavedQuickSettingsModel *enabledModel READ enabledQuickSettingsModel CONSTANT)
Q_PROPERTY(SavedQuickSettingsModel *disabledModel READ disabledQuickSettingsModel CONSTANT)
public: public:
SavedQuickSettings(QObject *parent = nullptr); SavedQuickSettings(QObject *parent = nullptr);
@ -34,12 +37,14 @@ private:
void saveModel(); void saveModel();
MobileShellSettings *m_settings; MobileShellSettings *m_settings;
QList<KPluginMetaData> m_validPackages; QList<KPluginMetaData *> m_validPackages;
QList<KPluginMetaData> m_enabledPackages; QList<KPluginMetaData *> m_enabledPackages;
QList<KPluginMetaData> m_disabledPackages; QList<KPluginMetaData *> m_disabledPackages;
SavedQuickSettingsModel *m_enabledQSModel; SavedQuickSettingsModel *m_enabledQSModel;
SavedQuickSettingsModel *m_disabledQSModel; SavedQuickSettingsModel *m_disabledQSModel;
QTimer *m_updateTimer;
}; };
} // namespace MobileShell } // namespace MobileShell

View file

@ -17,11 +17,11 @@ QVariant SavedQuickSettingsModel::data(const QModelIndex &index, int role) const
} }
if (role == NameRole) { if (role == NameRole) {
return m_data[index.row()].name(); return m_data[index.row()]->name();
} else if (role == IconRole) { } else if (role == IconRole) {
return QString(); // TODO m_data[index.row()].icon(); return m_data[index.row()]->iconName();
} else if (role == IdRole) { } else if (role == IdRole) {
return m_data[index.row()].pluginId(); return m_data[index.row()]->pluginId();
} }
return QVariant(); return QVariant();
} }
@ -43,14 +43,18 @@ void SavedQuickSettingsModel::moveRow(int oldIndex, int newIndex)
return; return;
} }
if (oldIndex < newIndex) {
++newIndex;
}
Q_EMIT beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), 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 endMoveRows();
Q_EMIT dataUpdated(m_data); 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); Q_EMIT beginInsertRows(QModelIndex(), index, index);
m_data.insert(index, metaData); m_data.insert(index, metaData);
@ -72,12 +76,12 @@ void SavedQuickSettingsModel::removeRow(int index)
Q_EMIT dataUpdated(m_data); Q_EMIT dataUpdated(m_data);
} }
QList<KPluginMetaData> SavedQuickSettingsModel::list() const QList<KPluginMetaData *> SavedQuickSettingsModel::list() const
{ {
return m_data; return m_data;
} }
void SavedQuickSettingsModel::updateData(QList<KPluginMetaData> data) void SavedQuickSettingsModel::updateData(QList<KPluginMetaData *> data)
{ {
Q_EMIT beginResetModel(); Q_EMIT beginResetModel();

View file

@ -35,19 +35,19 @@ public:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void moveRow(int oldIndex, int newIndex); 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); Q_INVOKABLE void removeRow(int index);
QList<KPluginMetaData> list() const; QList<KPluginMetaData *> list() const;
public Q_SLOTS: public Q_SLOTS:
void updateData(QList<KPluginMetaData> data); void updateData(QList<KPluginMetaData *> data);
Q_SIGNALS: Q_SIGNALS:
void dataUpdated(QList<KPluginMetaData> data); void dataUpdated(QList<KPluginMetaData *> data);
private: private:
QList<KPluginMetaData> m_data; QList<KPluginMetaData *> m_data;
}; };
} // namespace MobileShell } // namespace MobileShell

View file

@ -3,7 +3,7 @@
[Desktop Entry] [Desktop Entry]
Name=Mobile Data Name=Mobile Data
Icon=flashlight-on Icon=network-modem
Description=Location quick setting Description=Location quick setting
Type=Service Type=Service

View file

@ -3,7 +3,7 @@
[Desktop Entry] [Desktop Entry]
Name=Wi-Fi Name=Wi-Fi
Icon=flashlight-on Icon=network-wireless-signal
Description=Wi-Fi quick setting Description=Wi-Fi quick setting
Type=Service Type=Service