File indexing completed on 2024-04-28 16:54:57

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "containmentconfigview.h"
0008 #include "config-workspace.h"
0009 #include "currentcontainmentactionsmodel.h"
0010 #include "shellcorona.h"
0011 
0012 #include <QDBusConnection>
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QQmlComponent>
0016 #include <QQmlContext>
0017 #include <QQmlEngine>
0018 #include <QStandardPaths>
0019 
0020 #include <KConfigLoader>
0021 #include <KDeclarative/KDeclarative>
0022 #include <KLocalizedString>
0023 #include <KPackage/Package>
0024 #include <KPackage/PackageLoader>
0025 #include <Plasma/ContainmentActions>
0026 #include <Plasma/Corona>
0027 #include <Plasma/PluginLoader>
0028 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0029 #include <KDeclarative/ConfigPropertyMap>
0030 #else
0031 #include <KConfigPropertyMap>
0032 #endif
0033 
0034 class WallpaperConfigModel : public PlasmaQuick::ConfigModel
0035 {
0036     Q_OBJECT
0037 public:
0038     WallpaperConfigModel(QObject *parent);
0039 public Q_SLOTS:
0040     void repopulate();
0041 };
0042 
0043 //////////////////////////////ContainmentConfigView
0044 ContainmentConfigView::ContainmentConfigView(Plasma::Containment *cont, QWindow *parent)
0045     : ConfigView(cont, parent)
0046     , m_containment(cont)
0047 {
0048     qmlRegisterAnonymousType<QAbstractItemModel>("QAbstractItemModel", 1);
0049     rootContext()->setContextProperty(QStringLiteral("configDialog"), this);
0050     setCurrentWallpaper(cont->containment()->wallpaper());
0051 
0052     KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper"));
0053     pkg.setPath(m_containment->wallpaper());
0054     KConfigGroup cfg = m_containment->config();
0055     cfg = KConfigGroup(&cfg, "Wallpaper");
0056 
0057     syncWallpaperObjects();
0058 }
0059 
0060 ContainmentConfigView::~ContainmentConfigView()
0061 {
0062 }
0063 
0064 void ContainmentConfigView::init()
0065 {
0066     setSource(m_containment->corona()->kPackage().fileUrl("containmentconfigurationui"));
0067 }
0068 
0069 PlasmaQuick::ConfigModel *ContainmentConfigView::containmentActionConfigModel()
0070 {
0071     if (!m_containmentActionConfigModel) {
0072         m_containmentActionConfigModel = new PlasmaQuick::ConfigModel(this);
0073 
0074         const QVector<KPluginMetaData> actions = Plasma::PluginLoader::self()->listContainmentActionsMetaData(QString());
0075 
0076         KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Generic"));
0077 
0078         for (const KPluginMetaData &plugin : actions) {
0079             pkg.setDefaultPackageRoot(QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0080                                                              QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/containmentactions"),
0081                                                              QStandardPaths::LocateDirectory));
0082             m_containmentActionConfigModel->appendCategory(plugin.iconName(),
0083                                                            plugin.name(),
0084                                                            pkg.filePath("ui", QStringLiteral("config.qml")),
0085                                                            plugin.pluginId());
0086         }
0087     }
0088     return m_containmentActionConfigModel;
0089 }
0090 
0091 QAbstractItemModel *ContainmentConfigView::currentContainmentActionsModel()
0092 {
0093     if (!m_currentContainmentActionsModel) {
0094         m_currentContainmentActionsModel = new CurrentContainmentActionsModel(m_containment, this);
0095     }
0096     return m_currentContainmentActionsModel;
0097 }
0098 
0099 QString ContainmentConfigView::containmentPlugin() const
0100 {
0101     return m_containment->pluginMetaData().pluginId();
0102 }
0103 
0104 void ContainmentConfigView::setContainmentPlugin(const QString &plugin)
0105 {
0106     if (plugin.isEmpty() || containmentPlugin() == plugin) {
0107         return;
0108     }
0109 
0110     m_containment = static_cast<ShellCorona *>(m_containment->corona())->setContainmentTypeForScreen(m_containment->screen(), plugin);
0111     Q_EMIT containmentPluginChanged();
0112 }
0113 
0114 PlasmaQuick::ConfigModel *ContainmentConfigView::wallpaperConfigModel()
0115 {
0116     if (!m_wallpaperConfigModel) {
0117         m_wallpaperConfigModel = new WallpaperConfigModel(this);
0118         QDBusConnection::sessionBus().connect(QString(),
0119                                               QStringLiteral("/KPackage/Plasma/Wallpaper"),
0120                                               QStringLiteral("org.kde.plasma.kpackage"),
0121                                               QStringLiteral("packageInstalled"),
0122                                               m_wallpaperConfigModel,
0123                                               SLOT(repopulate()));
0124         QDBusConnection::sessionBus().connect(QString(),
0125                                               QStringLiteral("/KPackage/Plasma/Wallpaper"),
0126                                               QStringLiteral("org.kde.plasma.kpackage"),
0127                                               QStringLiteral("packageUpdated"),
0128                                               m_wallpaperConfigModel,
0129                                               SLOT(repopulate()));
0130         QDBusConnection::sessionBus().connect(QString(),
0131                                               QStringLiteral("/KPackage/Plasma/Wallpaper"),
0132                                               QStringLiteral("org.kde.plasma.kpackage"),
0133                                               QStringLiteral("packageUninstalled"),
0134                                               m_wallpaperConfigModel,
0135                                               SLOT(repopulate()));
0136     }
0137     return m_wallpaperConfigModel;
0138 }
0139 
0140 PlasmaQuick::ConfigModel *ContainmentConfigView::containmentPluginsConfigModel()
0141 {
0142     if (!m_containmentPluginsConfigModel) {
0143         m_containmentPluginsConfigModel = new PlasmaQuick::ConfigModel(this);
0144 
0145         const QList<KPluginMetaData> actions = Plasma::PluginLoader::self()->listContainmentsMetaDataOfType(QStringLiteral("Desktop"));
0146         for (const KPluginMetaData &plugin : actions) {
0147             m_containmentPluginsConfigModel->appendCategory(plugin.iconName(), plugin.name(), QString(), plugin.pluginId());
0148         }
0149     }
0150     return m_containmentPluginsConfigModel;
0151 }
0152 
0153 QQmlPropertyMap *ContainmentConfigView::wallpaperConfiguration() const
0154 {
0155     return m_currentWallpaperConfig;
0156 }
0157 
0158 QString ContainmentConfigView::currentWallpaper() const
0159 {
0160     return m_currentWallpaper;
0161 }
0162 
0163 void ContainmentConfigView::setCurrentWallpaper(const QString &wallpaper)
0164 {
0165     if (m_currentWallpaper == wallpaper) {
0166         return;
0167     }
0168 
0169     delete m_ownWallpaperConfig;
0170     m_ownWallpaperConfig = nullptr;
0171 
0172     if (m_containment->wallpaper() == wallpaper) {
0173         syncWallpaperObjects();
0174     } else {
0175         // we have to construct an independent ConfigPropertyMap when we want to configure wallpapers that are not the current one
0176         KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Generic"));
0177         pkg.setDefaultPackageRoot(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/wallpapers"));
0178         pkg.setPath(wallpaper);
0179         QFile file(pkg.filePath("config", QStringLiteral("main.xml")));
0180         KConfigGroup cfg = m_containment->config();
0181         cfg = KConfigGroup(&cfg, "Wallpaper");
0182         cfg = KConfigGroup(&cfg, wallpaper);
0183 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0184         m_currentWallpaperConfig = m_ownWallpaperConfig = new KDeclarative::ConfigPropertyMap(new KConfigLoader(cfg, &file, this), this);
0185 #else
0186         m_currentWallpaperConfig = m_ownWallpaperConfig = new KConfigPropertyMap(new KConfigLoader(cfg, &file, this), this);
0187 #endif
0188     }
0189 
0190     m_currentWallpaper = wallpaper;
0191     Q_EMIT currentWallpaperChanged();
0192     Q_EMIT wallpaperConfigurationChanged();
0193 }
0194 
0195 void ContainmentConfigView::applyWallpaper()
0196 {
0197     m_containment->setWallpaper(m_currentWallpaper);
0198 
0199     syncWallpaperObjects();
0200 
0201 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0202     if (m_currentWallpaperConfig && m_ownWallpaperConfig) {
0203         for (const auto &key : m_ownWallpaperConfig->keys()) {
0204             auto value = m_ownWallpaperConfig->value(key);
0205             m_currentWallpaperConfig->insert(key, value);
0206             m_currentWallpaperConfig->valueChanged(key, value);
0207         }
0208     }
0209 
0210     delete m_ownWallpaperConfig;
0211     m_ownWallpaperConfig = nullptr;
0212 #else
0213     static_cast<KConfigPropertyMap *>(m_currentWallpaperConfig)->writeConfig();
0214 #endif
0215 
0216     Q_EMIT wallpaperConfigurationChanged();
0217 }
0218 
0219 void ContainmentConfigView::syncWallpaperObjects()
0220 {
0221     QObject *wallpaperGraphicsObject = m_containment->property("wallpaperGraphicsObject").value<QObject *>();
0222 
0223     if (!wallpaperGraphicsObject) {
0224         return;
0225     }
0226     rootContext()->setContextProperty(QStringLiteral("wallpaper"), wallpaperGraphicsObject);
0227 
0228     // FIXME: why m_wallpaperGraphicsObject->property("configuration").value<ConfigPropertyMap *>() doesn't work?
0229     m_currentWallpaperConfig = static_cast<QQmlPropertyMap *>(wallpaperGraphicsObject->property("configuration").value<QObject *>());
0230 }
0231 
0232 WallpaperConfigModel::WallpaperConfigModel(QObject *parent)
0233     : PlasmaQuick::ConfigModel(parent)
0234 {
0235     repopulate();
0236 }
0237 
0238 void WallpaperConfigModel::repopulate()
0239 {
0240     clear();
0241     for (const KPluginMetaData &m : KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Wallpaper"))) {
0242         KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper"), m.pluginId());
0243         if (!pkg.isValid()) {
0244             continue;
0245         }
0246         appendCategory(pkg.metadata().iconName(), pkg.metadata().name(), pkg.fileUrl("ui", QStringLiteral("config.qml")).toString(), m.pluginId());
0247     }
0248 }
0249 
0250 #include "containmentconfigview.moc"