mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 22:33:08 +00:00
quicksettings: Add infrastructure to customize quicksettings order
This commit is contained in:
parent
9941c23752
commit
24c5b4a6d2
11 changed files with 441 additions and 58 deletions
|
|
@ -15,10 +15,10 @@ This repository contains shell components for Plasma Mobile.
|
||||||
* Development channel: https://matrix.to/#/#plasmamobile:matrix.org
|
* Development channel: https://matrix.to/#/#plasmamobile:matrix.org
|
||||||
|
|
||||||
### Locations
|
### Locations
|
||||||
* [libmobileshell](libmobileshell) - shell component library
|
* [libmobileshell](libmobileshell) - shell component library (not guaranteed to be binary compatible between releases!)
|
||||||
* [containments](containments) - shell panels (homescreen, status bar, task panel)
|
* [containments](containments) - shell panels (homescreen, status bar, task panel)
|
||||||
* [homescreens](homescreens) - homescreen packages
|
* [homescreens](homescreens) - homescreen packages
|
||||||
* [kcms]() - settings modules
|
* [kcms](kcms) - settings modules
|
||||||
* [look-and-feel](look-and-feel/contents) - Plasma look-and-feel packages (ex. lockscreen, logout, etc.)
|
* [look-and-feel](look-and-feel/contents) - Plasma look-and-feel packages (ex. lockscreen, logout, etc.)
|
||||||
* [quicksettings](quicksettings) - quick settings packages for the action drawer
|
* [quicksettings](quicksettings) - quick settings packages for the action drawer
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,14 @@ qt_add_dbus_interfaces(DBUS_SRCS dbus/org.kde.KWin.ScreenShot2.xml
|
||||||
set(mobileshell_LIB_SRCS
|
set(mobileshell_LIB_SRCS
|
||||||
displaysmodel.cpp
|
displaysmodel.cpp
|
||||||
mobileshellsettings.cpp
|
mobileshellsettings.cpp
|
||||||
quicksetting.cpp
|
|
||||||
quicksettingsmodel.cpp
|
|
||||||
shellutil.cpp
|
shellutil.cpp
|
||||||
kwinvirtualkeyboardinterface.cpp
|
kwinvirtualkeyboardinterface.cpp
|
||||||
|
|
||||||
|
quicksetting.cpp
|
||||||
|
quicksettingsmodel.cpp
|
||||||
|
savedquicksettingsmodel.cpp
|
||||||
|
savedquicksettings.cpp
|
||||||
|
|
||||||
${DBUS_SRCS}
|
${DBUS_SRCS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -59,9 +62,13 @@ install(FILES
|
||||||
displaysmodel.h
|
displaysmodel.h
|
||||||
kwinvirtualkeyboardinterface.h
|
kwinvirtualkeyboardinterface.h
|
||||||
mobileshellsettings.h
|
mobileshellsettings.h
|
||||||
|
shellutil.h
|
||||||
|
|
||||||
quicksetting.h
|
quicksetting.h
|
||||||
quicksettingsmodel.h
|
quicksettingsmodel.h
|
||||||
shellutil.h
|
savedquicksettingsmodel.h
|
||||||
|
savedquicksettings.h
|
||||||
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/mobileshell_export.h
|
${CMAKE_CURRENT_BINARY_DIR}/mobileshell_export.h
|
||||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/mobileshell COMPONENT Devel
|
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/mobileshell COMPONENT Devel
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ void MobileShellPlugin::registerTypes(const char *uri)
|
||||||
|
|
||||||
qmlRegisterType<QuickSetting>(uri, 1, 0, "QuickSetting");
|
qmlRegisterType<QuickSetting>(uri, 1, 0, "QuickSetting");
|
||||||
qmlRegisterType<QuickSettingsModel>(uri, 1, 0, "QuickSettingsModel");
|
qmlRegisterType<QuickSettingsModel>(uri, 1, 0, "QuickSettingsModel");
|
||||||
|
qmlRegisterType<SavedQuickSettings>(uri, 1, 0, "SavedQuickSettings");
|
||||||
|
qmlRegisterType<SavedQuickSettingsModel>(uri, 1, 0, "SavedQuickSettingsModel");
|
||||||
|
|
||||||
qmlRegisterType<DisplaysModel>(uri, 1, 0, "DisplaysModel");
|
qmlRegisterType<DisplaysModel>(uri, 1, 0, "DisplaysModel");
|
||||||
qmlRegisterSingletonType<KwinVirtualKeyboardInterface>(uri, 1, 0, "KWinVirtualKeyboard", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
qmlRegisterSingletonType<KwinVirtualKeyboardInterface>(uri, 1, 0, "KWinVirtualKeyboard", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using namespace MobileShell;
|
||||||
|
|
||||||
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
|
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
|
||||||
const QString GENERAL_CONFIG_GROUP = QStringLiteral("General");
|
const QString GENERAL_CONFIG_GROUP = QStringLiteral("General");
|
||||||
|
const QString QUICKSETTINGS_CONFIG_GROUP = QStringLiteral("QuickSettings");
|
||||||
|
|
||||||
MobileShellSettings *MobileShellSettings::self()
|
MobileShellSettings *MobileShellSettings::self()
|
||||||
{
|
{
|
||||||
|
|
@ -26,6 +27,9 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
|
||||||
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 {
|
||||||
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) {
|
||||||
|
Q_EMIT enabledQuickSettingsChanged();
|
||||||
|
Q_EMIT disabledQuickSettingsChanged();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -35,3 +39,55 @@ bool MobileShellSettings::navigationPanelEnabled() const
|
||||||
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
return group.readEntry("navigationPanelEnabled", true);
|
return group.readEntry("navigationPanelEnabled", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MobileShellSettings::setNavigationPanelEnabled(bool navigationPanelEnabled)
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
group.writeEntry("navigationPanelEnabled", navigationPanelEnabled, KConfigGroup::Notify);
|
||||||
|
m_config->sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> MobileShellSettings::enabledQuickSettings() const
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, QUICKSETTINGS_CONFIG_GROUP};
|
||||||
|
// TODO move defaults to file
|
||||||
|
// we aren't worried about quicksettings not showing up though, any that are not specified will be automatically added to the end
|
||||||
|
return group.readEntry("enabledQuickSettings",
|
||||||
|
QList<QString>{
|
||||||
|
QStringLiteral("org.kde.plasma.wifi"),
|
||||||
|
QStringLiteral("org.kde.plasma.mobiledata"),
|
||||||
|
QStringLiteral("org.kde.plasma.bluetooth"),
|
||||||
|
QStringLiteral("org.kde.plasma.flashlight"),
|
||||||
|
QStringLiteral("org.kde.plasma.screenrotation"),
|
||||||
|
QStringLiteral("org.kde.plasma.settingsapp"),
|
||||||
|
QStringLiteral("org.kde.plasma.airplanemode"),
|
||||||
|
QStringLiteral("org.kde.plasma.audio"),
|
||||||
|
QStringLiteral("org.kde.plasma.battery"),
|
||||||
|
QStringLiteral("org.kde.plasma.location"),
|
||||||
|
QStringLiteral("org.kde.plasma.nightcolor"),
|
||||||
|
QStringLiteral("org.kde.plasma.screenshot"),
|
||||||
|
QStringLiteral("org.kde.plasma.powermenu"),
|
||||||
|
QStringLiteral("org.kde.plasma.keyboardtoggle"),
|
||||||
|
QStringLiteral("org.kde.plasma.caffeine"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MobileShellSettings::setEnabledQuickSettings(QList<QString> &list)
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
group.writeEntry("enabledQuickSettings", list, KConfigGroup::Notify);
|
||||||
|
m_config->sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> MobileShellSettings::disabledQuickSettings() const
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, QUICKSETTINGS_CONFIG_GROUP};
|
||||||
|
return group.readEntry("disabledQuickSettings", QList<QString>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MobileShellSettings::setDisabledQuickSettings(QList<QString> &list)
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
group.writeEntry("disabledQuickSettings", list, KConfigGroup::Notify);
|
||||||
|
m_config->sync();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace MobileShell
|
||||||
class MOBILESHELL_EXPORT MobileShellSettings : public QObject
|
class MOBILESHELL_EXPORT MobileShellSettings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool navigationPanelEnabled READ navigationPanelEnabled NOTIFY navigationPanelEnabledChanged)
|
Q_PROPERTY(bool navigationPanelEnabled READ navigationPanelEnabled WRITE setNavigationPanelEnabled NOTIFY navigationPanelEnabledChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static MobileShellSettings *self();
|
static MobileShellSettings *self();
|
||||||
|
|
@ -27,9 +27,18 @@ public:
|
||||||
MobileShellSettings(QObject *parent = nullptr);
|
MobileShellSettings(QObject *parent = nullptr);
|
||||||
|
|
||||||
bool navigationPanelEnabled() const;
|
bool navigationPanelEnabled() const;
|
||||||
|
void setNavigationPanelEnabled(bool navigationPanelEnabled);
|
||||||
|
|
||||||
|
QList<QString> enabledQuickSettings() const;
|
||||||
|
void setEnabledQuickSettings(QList<QString> &list);
|
||||||
|
|
||||||
|
QList<QString> disabledQuickSettings() const;
|
||||||
|
void setDisabledQuickSettings(QList<QString> &list);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void navigationPanelEnabledChanged();
|
void navigationPanelEnabledChanged();
|
||||||
|
void enabledQuickSettingsChanged();
|
||||||
|
void disabledQuickSettingsChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KConfigWatcher::Ptr m_configWatcher;
|
KConfigWatcher::Ptr m_configWatcher;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
|
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
@ -7,6 +8,7 @@
|
||||||
#include "quicksettingsmodel.h"
|
#include "quicksettingsmodel.h"
|
||||||
|
|
||||||
#include <KPackage/PackageLoader>
|
#include <KPackage/PackageLoader>
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QQmlComponent>
|
#include <QQmlComponent>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
@ -14,7 +16,21 @@
|
||||||
using namespace MobileShell;
|
using namespace MobileShell;
|
||||||
|
|
||||||
QuickSettingsModel::QuickSettingsModel(QObject *parent)
|
QuickSettingsModel::QuickSettingsModel(QObject *parent)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel{parent}
|
||||||
|
, m_savedQuickSettings{new SavedQuickSettings{this}}
|
||||||
|
{
|
||||||
|
connect(m_savedQuickSettings->enabledQuickSettingsModel(), &SavedQuickSettingsModel::dataUpdated, this, [this]() {
|
||||||
|
loadQuickSettings();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingsModel::classBegin()
|
||||||
|
{
|
||||||
|
m_loaded = true;
|
||||||
|
loadQuickSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingsModel::componentComplete()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,17 +39,10 @@ QHash<int, QByteArray> QuickSettingsModel::roleNames() const
|
||||||
return {{Qt::UserRole, "modelData"}};
|
return {{Qt::UserRole, "modelData"}};
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<QuickSetting> QuickSettingsModel::children()
|
|
||||||
{
|
|
||||||
return QQmlListProperty<QuickSetting>(this, &m_children);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QuickSettingsModel::rowCount(const QModelIndex &parent) const
|
int QuickSettingsModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (parent.isValid())
|
Q_UNUSED(parent);
|
||||||
return 0;
|
return m_quickSettings.size();
|
||||||
|
|
||||||
return m_children.count() + m_external.count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QuickSettingsModel::data(const QModelIndex &index, int role) const
|
QVariant QuickSettingsModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
@ -42,59 +51,50 @@ QVariant QuickSettingsModel::data(const QModelIndex &index, int role) const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject *obj = nullptr;
|
QObject *obj = m_quickSettings[index.row()];
|
||||||
if (index.row() < m_children.count()) {
|
|
||||||
obj = m_children[index.row()];
|
|
||||||
} else {
|
|
||||||
obj = m_external[index.row() - m_children.count()];
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant::fromValue<QObject *>(obj);
|
return QVariant::fromValue<QObject *>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickSettingsModel::classBegin()
|
void QuickSettingsModel::loadQuickSettings()
|
||||||
{
|
{
|
||||||
|
if (!m_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto *quickSetting : m_quickSettings) {
|
||||||
|
quickSetting->deleteLater();
|
||||||
|
}
|
||||||
|
m_quickSettings.clear();
|
||||||
|
|
||||||
QQmlEngine *engine = qmlEngine(this);
|
QQmlEngine *engine = qmlEngine(this);
|
||||||
|
QQmlComponent *c = new QQmlComponent(engine, this);
|
||||||
|
|
||||||
const auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), "plasma/quicksettings");
|
// loop through enabled quick settings metadata
|
||||||
auto c = new QQmlComponent(engine, this);
|
for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
|
||||||
|
// load kpackage
|
||||||
for (const auto &metaData : packages) {
|
|
||||||
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()) {
|
||||||
qWarning() << "Quick setting package invalid:" << metaData.fileName();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load QML from kpackage
|
||||||
c->loadUrl(package.fileUrl("mainscript"), QQmlComponent::PreferSynchronous);
|
c->loadUrl(package.fileUrl("mainscript"), QQmlComponent::PreferSynchronous);
|
||||||
|
|
||||||
auto created = c->create(engine->rootContext());
|
auto created = c->create(engine->rootContext());
|
||||||
auto createdSetting = qobject_cast<QuickSetting *>(created);
|
auto createdSetting = qobject_cast<QuickSetting *>(created);
|
||||||
|
|
||||||
|
// print errors if there were issues loading
|
||||||
if (!createdSetting) {
|
if (!createdSetting) {
|
||||||
qWarning() << "Could not load" << metaData.fileName() << created;
|
qWarning() << "Unable to load quick setting element:" << created;
|
||||||
if (c->isError()) {
|
for (auto error : c->errors()) {
|
||||||
for (const auto &error : c->errors()) {
|
qWarning() << error;
|
||||||
qDebug() << error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete created;
|
delete created;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Loaded quicksetting" << metaData.fileName();
|
qDebug() << "Loaded quicksetting" << metaData.fileName();
|
||||||
m_external += createdSetting;
|
m_quickSettings.push_back(createdSetting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickSettingsModel::componentComplete()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuickSettingsModel::include(QuickSetting *item)
|
|
||||||
{
|
|
||||||
const int c = m_children.count() + m_external.count();
|
|
||||||
beginInsertRows({}, c, c);
|
|
||||||
m_external.append(item);
|
|
||||||
endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
|
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
@ -8,6 +9,8 @@
|
||||||
|
|
||||||
#include "qqml.h"
|
#include "qqml.h"
|
||||||
#include "quicksetting.h"
|
#include "quicksetting.h"
|
||||||
|
#include "savedquicksettings.h"
|
||||||
|
#include "savedquicksettingsmodel.h"
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QQmlListProperty>
|
#include <QQmlListProperty>
|
||||||
|
|
@ -21,8 +24,6 @@ class MOBILESHELL_EXPORT QuickSettingsModel : public QAbstractListModel, public
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QQmlParserStatus)
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
Q_PROPERTY(QQmlListProperty<QuickSetting> children READ children NOTIFY childrenChanged)
|
|
||||||
Q_CLASSINFO("DefaultProperty", "children")
|
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -32,18 +33,14 @@ public:
|
||||||
int rowCount(const QModelIndex &parent) const override;
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
QQmlListProperty<QuickSetting> children();
|
|
||||||
|
|
||||||
void classBegin() override;
|
void classBegin() override;
|
||||||
void componentComplete() override;
|
void componentComplete() override;
|
||||||
Q_SCRIPTABLE void include(QuickSetting *item);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void childrenChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QuickSetting *> m_children;
|
void loadQuickSettings();
|
||||||
QList<QuickSetting *> m_external;
|
|
||||||
|
bool m_loaded = false;
|
||||||
|
QList<QuickSetting *> m_quickSettings;
|
||||||
|
SavedQuickSettings *m_savedQuickSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MobileShell
|
} // namespace MobileShell
|
||||||
|
|
|
||||||
122
libmobileshell/savedquicksettings.cpp
Normal file
122
libmobileshell/savedquicksettings.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "savedquicksettings.h"
|
||||||
|
|
||||||
|
#include <KPackage/PackageLoader>
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
using namespace MobileShell;
|
||||||
|
|
||||||
|
SavedQuickSettings::SavedQuickSettings(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
, m_settings{new MobileShellSettings{this}}
|
||||||
|
, m_validPackages{}
|
||||||
|
, m_enabledPackages{}
|
||||||
|
, m_disabledPackages{}
|
||||||
|
, m_enabledQSModel{new SavedQuickSettingsModel{this}}
|
||||||
|
, m_disabledQSModel{new SavedQuickSettingsModel{this}}
|
||||||
|
{
|
||||||
|
// load quicksettings packages
|
||||||
|
auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), "plasma/quicksettings");
|
||||||
|
|
||||||
|
for (auto &metaData : packages) {
|
||||||
|
KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData.fileName()).path());
|
||||||
|
if (!package.isValid()) {
|
||||||
|
qWarning() << "Quick setting package invalid:" << metaData.fileName();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_validPackages.push_back(metaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// subscribe to config changes
|
||||||
|
connect(m_settings, &MobileShellSettings::enabledQuickSettingsChanged, this, [this]() {
|
||||||
|
refreshModel();
|
||||||
|
});
|
||||||
|
connect(m_settings, &MobileShellSettings::disabledQuickSettingsChanged, this, [this]() {
|
||||||
|
refreshModel();
|
||||||
|
});
|
||||||
|
|
||||||
|
// subscribe to model changes
|
||||||
|
connect(m_enabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
|
||||||
|
m_enabledPackages.clear();
|
||||||
|
for (auto metaData : data) {
|
||||||
|
m_enabledPackages.push_back(metaData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_disabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
|
||||||
|
m_disabledPackages.clear();
|
||||||
|
for (auto metaData : data) {
|
||||||
|
m_disabledPackages.push_back(metaData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// load
|
||||||
|
refreshModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedQuickSettingsModel *SavedQuickSettings::enabledQuickSettingsModel() const
|
||||||
|
{
|
||||||
|
return m_enabledQSModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedQuickSettingsModel *SavedQuickSettings::disabledQuickSettingsModel() const
|
||||||
|
{
|
||||||
|
return m_disabledQSModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettings::refreshModel()
|
||||||
|
{
|
||||||
|
QList<QString> enabledQS = m_settings->enabledQuickSettings();
|
||||||
|
QList<QString> disabledQS = m_settings->disabledQuickSettings();
|
||||||
|
|
||||||
|
m_enabledPackages.clear();
|
||||||
|
m_disabledPackages.clear();
|
||||||
|
|
||||||
|
// add enabled quick settings in order
|
||||||
|
for (const QString &pluginId : enabledQS) {
|
||||||
|
for (auto &metaData : m_validPackages) {
|
||||||
|
if (pluginId == metaData.pluginId()) {
|
||||||
|
m_enabledPackages.push_back(metaData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add disabled quick settings in order
|
||||||
|
for (const QString &pluginId : disabledQS) {
|
||||||
|
for (auto &metaData : m_validPackages) {
|
||||||
|
if (pluginId == metaData.pluginId()) {
|
||||||
|
m_disabledPackages.push_back(metaData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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())) {
|
||||||
|
m_enabledPackages.push_back(metaData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enabledQSModel->updateData(m_enabledPackages);
|
||||||
|
m_disabledQSModel->updateData(m_disabledPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettings::saveModel()
|
||||||
|
{
|
||||||
|
QList<QString> enabledQS;
|
||||||
|
QList<QString> disabledQS;
|
||||||
|
|
||||||
|
for (auto &metaData : m_enabledPackages) {
|
||||||
|
enabledQS.push_back(metaData.pluginId());
|
||||||
|
}
|
||||||
|
for (auto &metaData : m_disabledPackages) {
|
||||||
|
disabledQS.push_back(metaData.pluginId());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settings->setEnabledQuickSettings(enabledQS);
|
||||||
|
m_settings->setDisabledQuickSettings(disabledQS);
|
||||||
|
}
|
||||||
45
libmobileshell/savedquicksettings.h
Normal file
45
libmobileshell/savedquicksettings.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mobileshellsettings.h"
|
||||||
|
#include "qqml.h"
|
||||||
|
#include "quicksetting.h"
|
||||||
|
#include "savedquicksettingsmodel.h"
|
||||||
|
|
||||||
|
#include <KPackage/Package>
|
||||||
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QQmlListProperty>
|
||||||
|
|
||||||
|
#include "mobileshell_export.h"
|
||||||
|
|
||||||
|
namespace MobileShell
|
||||||
|
{
|
||||||
|
|
||||||
|
class MOBILESHELL_EXPORT SavedQuickSettings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SavedQuickSettings(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
SavedQuickSettingsModel *enabledQuickSettingsModel() const;
|
||||||
|
SavedQuickSettingsModel *disabledQuickSettingsModel() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void refreshModel();
|
||||||
|
void saveModel();
|
||||||
|
|
||||||
|
MobileShellSettings *m_settings;
|
||||||
|
QList<KPluginMetaData> m_validPackages;
|
||||||
|
QList<KPluginMetaData> m_enabledPackages;
|
||||||
|
QList<KPluginMetaData> m_disabledPackages;
|
||||||
|
|
||||||
|
SavedQuickSettingsModel *m_enabledQSModel;
|
||||||
|
SavedQuickSettingsModel *m_disabledQSModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace MobileShell
|
||||||
92
libmobileshell/savedquicksettingsmodel.cpp
Normal file
92
libmobileshell/savedquicksettingsmodel.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "savedquicksettingsmodel.h"
|
||||||
|
|
||||||
|
using namespace MobileShell;
|
||||||
|
|
||||||
|
SavedQuickSettingsModel::SavedQuickSettingsModel(QObject *parent)
|
||||||
|
: QAbstractListModel{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SavedQuickSettingsModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid() || index.row() >= m_data.count()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == NameRole) {
|
||||||
|
return m_data[index.row()].name();
|
||||||
|
} else if (role == IconRole) {
|
||||||
|
return QString(); // TODO m_data[index.row()].icon();
|
||||||
|
} else if (role == IdRole) {
|
||||||
|
return m_data[index.row()].pluginId();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SavedQuickSettingsModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return m_data.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> SavedQuickSettingsModel::roleNames() const
|
||||||
|
{
|
||||||
|
return {{NameRole, "name"}, {IdRole, "id"}, {IconRole, "icon"}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettingsModel::moveRow(int oldIndex, int newIndex)
|
||||||
|
{
|
||||||
|
if (oldIndex < 0 || oldIndex >= m_data.count() || newIndex < 0 || newIndex >= m_data.count()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
|
||||||
|
std::iter_swap(m_data.begin() + oldIndex, m_data.end() + newIndex);
|
||||||
|
Q_EMIT endMoveRows();
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettingsModel::insertRow(KPluginMetaData metaData, int index)
|
||||||
|
{
|
||||||
|
Q_EMIT beginInsertRows(QModelIndex(), index, index);
|
||||||
|
m_data.insert(index, metaData);
|
||||||
|
Q_EMIT endInsertRows();
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettingsModel::removeRow(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_data.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
m_data.erase(m_data.begin() + index);
|
||||||
|
Q_EMIT endRemoveRows();
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<KPluginMetaData> SavedQuickSettingsModel::list() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedQuickSettingsModel::updateData(QList<KPluginMetaData> data)
|
||||||
|
{
|
||||||
|
Q_EMIT beginResetModel();
|
||||||
|
|
||||||
|
m_data.clear();
|
||||||
|
for (auto metaData : data) {
|
||||||
|
m_data.push_back(metaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT endResetModel();
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(m_data);
|
||||||
|
}
|
||||||
53
libmobileshell/savedquicksettingsmodel.h
Normal file
53
libmobileshell/savedquicksettingsmodel.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mobileshellsettings.h"
|
||||||
|
#include "qqml.h"
|
||||||
|
#include "quicksetting.h"
|
||||||
|
|
||||||
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QQmlListProperty>
|
||||||
|
|
||||||
|
#include "mobileshell_export.h"
|
||||||
|
|
||||||
|
namespace MobileShell
|
||||||
|
{
|
||||||
|
|
||||||
|
class MOBILESHELL_EXPORT SavedQuickSettingsModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SavedQuickSettingsModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NameRole,
|
||||||
|
IdRole,
|
||||||
|
IconRole,
|
||||||
|
};
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
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 removeRow(int index);
|
||||||
|
|
||||||
|
QList<KPluginMetaData> list() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void updateData(QList<KPluginMetaData> data);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void dataUpdated(QList<KPluginMetaData> data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<KPluginMetaData> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace MobileShell
|
||||||
Loading…
Reference in a new issue