File indexing completed on 2025-01-12 05:02:54

0001 /*
0002     SPDX-FileCopyrightText: 2022 Julius Zint <julius@zint.sh>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "wallpaperfileitemaction.h"
0008 
0009 #include <QAction>
0010 #include <QDBusConnection>
0011 #include <QDBusMessage>
0012 #include <QDBusPendingCall>
0013 #include <QDBusPendingReply>
0014 #include <QIcon>
0015 #include <QList>
0016 #include <QMenu>
0017 #include <QScopedPointer>
0018 #include <QVariantList>
0019 #include <QWidget>
0020 
0021 #include <KLocalizedString>
0022 #include <KPluginFactory>
0023 
0024 #include <KConfig>
0025 #include <KConfigGroup>
0026 #include <KSharedConfig>
0027 
0028 using namespace Qt::StringLiterals;
0029 
0030 K_PLUGIN_CLASS_WITH_JSON(WallpaperFileItemAction, "wallpaperfileitemaction.json")
0031 
0032 WallpaperFileItemAction::WallpaperFileItemAction(QObject *parent, const QVariantList &)
0033     : KAbstractFileItemActionPlugin(parent)
0034 {
0035 }
0036 
0037 WallpaperFileItemAction::~WallpaperFileItemAction()
0038 {
0039 }
0040 
0041 QList<QAction *> WallpaperFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget)
0042 {
0043     if (fileItemInfos.urlList().size() > 1) {
0044         return {};
0045     }
0046 
0047     const QString filePath = fileItemInfos.urlList().constFirst().toLocalFile();
0048 
0049     auto menu = new QMenu(i18ndc("plasma_wallpaper_org.kde.image", "@action:inmenu", "Set as Wallpaper"));
0050     menu->setIcon(QIcon::fromTheme(QStringLiteral("viewimage")));
0051 
0052     auto desktopAction = new QAction(i18ndc("plasma_wallpaper_org.kde.image", "@action:inmenu Set as Desktop Wallpaper", "Desktop"));
0053     connect(desktopAction, &QAction::triggered, this, [this, filePath] {
0054         setAsDesktopBackground(filePath);
0055     });
0056     menu->addAction(desktopAction);
0057 
0058     auto lockAction = new QAction(i18ndc("plasma_wallpaper_org.kde.image", "@action:inmenu Set as Lockscreen Wallpaper", "Lockscreen"));
0059     connect(lockAction, &QAction::triggered, this, [this, filePath] {
0060         setAsLockscreenBackground(filePath);
0061     });
0062     menu->addAction(lockAction);
0063 
0064     auto bothAction = new QAction(i18ndc("plasma_wallpaper_org.kde.image", "@action:inmenu Set as both lockscreen and Desktop Wallpaper", "Both"));
0065     connect(bothAction, &QAction::triggered, this, [this, filePath] {
0066         setAsDesktopBackground(filePath);
0067         setAsLockscreenBackground(filePath);
0068     });
0069     menu->addAction(bothAction);
0070 
0071     menu->setParent(parentWidget, Qt::Popup);
0072     return {menu->menuAction()};
0073 }
0074 
0075 void WallpaperFileItemAction::setAsDesktopBackground(const QString &file)
0076 {
0077     auto script = QString(
0078                       "const allDesktops = desktopsForActivity(currentActivity());"
0079                       " for (i=0; i<allDesktops.length; i++) {"
0080                       "    d = allDesktops[i];"
0081                       "    d.wallpaperPlugin = \"org.kde.image\";"
0082                       "    d.currentConfigGroup = Array(\"Wallpaper\", \"org.kde.image\", \"General\");"
0083                       "    d.writeConfig(\"Image\", \"%1\")"
0084                       "}")
0085                       .arg(file);
0086 
0087     auto message = QDBusMessage::createMethodCall(u"org.kde.plasmashell"_s, u"/PlasmaShell"_s, u"org.kde.PlasmaShell"_s, u"evaluateScript"_s);
0088     message.setArguments(QVariantList() << QVariant(script));
0089     QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
0090     auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
0091     connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, watcher]() {
0092         watcher->deleteLater();
0093         const QDBusPendingReply<QString> reply = *watcher;
0094         if (reply.isError()) {
0095             auto errorMessage = QString(xi18ndc("plasma_wallpaper_org.kde.image",
0096                                                 "@info %1 is the dbus error message",
0097                                                 "An error occurred while attempting to set the Plasma wallpaper:<nl/>%1"))
0098                                     .arg(reply.error().message());
0099             qWarning() << errorMessage;
0100             error(errorMessage);
0101         }
0102     });
0103 }
0104 
0105 void WallpaperFileItemAction::setAsLockscreenBackground(const QString &file)
0106 {
0107     KSharedConfigPtr screenLockerConfig = KSharedConfig::openConfig(u"kscreenlockerrc"_s);
0108     KConfigGroup cfgGroup = screenLockerConfig->group(QString()).group(u"Greeter"_s).group(u"Wallpaper"_s).group(u"org.kde.image"_s).group(u"General"_s);
0109     if (screenLockerConfig->accessMode() != KConfig::ReadWrite) {
0110         auto errorMessage = QString(i18nd("plasma_wallpaper_org.kde.image", "An error occurred while attempting to open kscreenlockerrc config file."));
0111         qWarning() << errorMessage;
0112         error(errorMessage);
0113         return;
0114     }
0115     cfgGroup.writeEntry("Image", file);
0116     cfgGroup.writeEntry("PreviewImage", file);
0117     screenLockerConfig->sync();
0118 }
0119 
0120 #include "wallpaperfileitemaction.moc"