mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-11 08:57:21 +00:00
Detect the device class, stage the selected experience, and write the resulting setup choices through SetupState. Load the new device and experience modules before the existing setup pages, and use the Shift icon on the finished page.
134 lines
4.3 KiB
C++
134 lines
4.3 KiB
C++
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "wizard.h"
|
|
#include "settings.h"
|
|
#include "setupstate.h"
|
|
#include "utils.h"
|
|
|
|
#include <KPackage/PackageLoader>
|
|
|
|
#include <QFileInfo>
|
|
#include <QQmlComponent>
|
|
|
|
// TODO read distro provided config file
|
|
const QList<QString> WIZARD_MODULE_ORDER = {QStringLiteral("org.kde.plasma.mobileinitialstart.deviceprofile"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.experienceprofile"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.prepare"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.time"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.wifi"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.cellular"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.systemnavigation"),
|
|
QStringLiteral("org.kde.plasma.mobileinitialstart.finished")};
|
|
|
|
int moduleOrderIndex(const QString &pluginId)
|
|
{
|
|
const int index = WIZARD_MODULE_ORDER.indexOf(pluginId);
|
|
return index == -1 ? WIZARD_MODULE_ORDER.size() : index;
|
|
}
|
|
|
|
Wizard::Wizard(QObject *parent, QQmlEngine *engine)
|
|
: QObject{parent}
|
|
, m_testingMode{false}
|
|
, m_engine{engine}
|
|
{
|
|
}
|
|
|
|
void Wizard::load()
|
|
{
|
|
if (!m_engine) {
|
|
return;
|
|
}
|
|
|
|
qCDebug(LOGGING_CATEGORY) << "Loading initialstart packages...";
|
|
|
|
// load initialstart packages
|
|
const auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), QStringLiteral("plasma/mobileinitialstart"));
|
|
for (auto &metaData : packages) {
|
|
KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/GenericQML"), QFileInfo(metaData.fileName()).path());
|
|
if (!package.isValid()) {
|
|
qCWarning(LOGGING_CATEGORY) << "initialstart package invalid:" << metaData.fileName();
|
|
continue;
|
|
}
|
|
m_modulePackages.push_back({new KPluginMetaData{metaData}, package});
|
|
}
|
|
|
|
// sort modules by order
|
|
std::sort(m_modulePackages.begin(), m_modulePackages.end(), [](const auto &lhs, const auto &rhs) {
|
|
return moduleOrderIndex(lhs.first->pluginId()) < moduleOrderIndex(rhs.first->pluginId());
|
|
});
|
|
|
|
QQmlComponent *c = new QQmlComponent(m_engine, this);
|
|
|
|
// load initialstart QML items
|
|
for (const auto &[pluginMetadata, package] : m_modulePackages) {
|
|
// load QML from kpackage
|
|
c->loadUrl(package.fileUrl("mainscript"), QQmlComponent::PreferSynchronous);
|
|
|
|
auto created = c->create(m_engine->rootContext());
|
|
InitialStartModule *createdItem = qobject_cast<InitialStartModule *>(created);
|
|
|
|
// print errors if there were issues loading
|
|
if (!createdItem) {
|
|
qCWarning(LOGGING_CATEGORY) << "Unable to load initialstart module:" << created;
|
|
for (auto error : c->errors()) {
|
|
qCWarning(LOGGING_CATEGORY) << error;
|
|
}
|
|
delete created;
|
|
continue;
|
|
}
|
|
|
|
connect(createdItem, &InitialStartModule::availableChanged, this, &Wizard::determineAvailableModuleItems);
|
|
m_moduleItems.push_back(createdItem);
|
|
|
|
qCDebug(LOGGING_CATEGORY) << "Loaded initialstart module" << pluginMetadata->pluginId();
|
|
}
|
|
|
|
delete c;
|
|
|
|
// Populate model
|
|
determineAvailableModuleItems();
|
|
}
|
|
|
|
void Wizard::setTestingMode(bool testingMode)
|
|
{
|
|
if (testingMode != m_testingMode) {
|
|
m_testingMode = testingMode;
|
|
Q_EMIT testingModeChanged();
|
|
}
|
|
}
|
|
|
|
bool Wizard::testingMode()
|
|
{
|
|
return m_testingMode;
|
|
}
|
|
|
|
QList<InitialStartModule *> Wizard::steps()
|
|
{
|
|
return m_availableModuleItems;
|
|
}
|
|
|
|
int Wizard::stepsCount()
|
|
{
|
|
return m_availableModuleItems.size();
|
|
}
|
|
|
|
void Wizard::wizardFinished()
|
|
{
|
|
if (!m_testingMode) {
|
|
SetupState::self()->apply();
|
|
}
|
|
QCoreApplication::quit();
|
|
}
|
|
|
|
void Wizard::determineAvailableModuleItems()
|
|
{
|
|
m_availableModuleItems.clear();
|
|
for (auto *moduleItem : m_moduleItems) {
|
|
if (moduleItem->available()) {
|
|
m_availableModuleItems.push_back(moduleItem);
|
|
}
|
|
}
|
|
|
|
Q_EMIT stepsChanged();
|
|
}
|