File indexing completed on 2024-04-28 05:35:49

0001 /*
0002     SPDX-FileCopyrightText: 2014 Bhushan Shah <bhush94@gmail.com>
0003     SPDX-FileCopyrightText: 2014 Marco Martin <notmart@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "plasmawindowedcorona.h"
0009 #include "plasmawindowedview.h"
0010 #include <QAction>
0011 #include <QCommandLineParser>
0012 #include <QDebug>
0013 
0014 #include <KActionCollection>
0015 #include <KLocalizedString>
0016 
0017 #include <KPackage/Package>
0018 #include <KPackage/PackageLoader>
0019 #include <Plasma/PluginLoader>
0020 
0021 using namespace Qt::StringLiterals;
0022 
0023 PlasmaWindowedCorona::PlasmaWindowedCorona(const QString &shell, QObject *parent)
0024     : Plasma::Corona(parent)
0025 {
0026     KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Shell"));
0027     package.setPath(shell);
0028     setKPackage(package);
0029     // QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
0030     load();
0031 }
0032 
0033 void PlasmaWindowedCorona::loadApplet(const QString &applet, const QVariantList &arguments)
0034 {
0035     if (containments().isEmpty()) {
0036         return;
0037     }
0038 
0039     Plasma::Containment *cont = containments().first();
0040 
0041     // forbid more instances per applet (todo: activate the corresponding already loaded applet)
0042     for (Plasma::Applet *a : cont->applets()) {
0043         if (a->pluginMetaData().pluginId() == applet) {
0044             return;
0045         }
0046     }
0047     m_view = new PlasmaWindowedView();
0048     m_view->setHasStatusNotifier(m_hasStatusNotifier);
0049     m_view->show();
0050 
0051     KConfigGroup appletsGroup(KSharedConfig::openConfig(), QStringLiteral("Applets"));
0052     QString plugin;
0053     for (const QString &group : appletsGroup.groupList()) {
0054         KConfigGroup cg(&appletsGroup, group);
0055         plugin = cg.readEntry("plugin", QString());
0056 
0057         if (plugin == applet) {
0058             Plasma::Applet *a = Plasma::PluginLoader::self()->loadApplet(applet, group.toInt(), arguments);
0059             if (!a) {
0060                 qWarning() << "Unable to load applet" << applet << "with arguments" << arguments;
0061                 delete m_view;
0062                 m_view = nullptr;
0063                 return;
0064             }
0065             a->restore(cg);
0066 
0067             // Access a->config() before adding to containment
0068             // will cause applets to be saved in palsmawindowedrc
0069             // so applets will only be created on demand
0070             KConfigGroup cg2 = a->config();
0071             cont->addApplet(a);
0072 
0073             m_view->setApplet(a);
0074             return;
0075         }
0076     }
0077 
0078     Plasma::Applet *a = Plasma::PluginLoader::self()->loadApplet(applet, 0, arguments);
0079     if (!a) {
0080         qWarning() << "Unable to load applet" << applet << "with arguments" << arguments;
0081         delete m_view;
0082         m_view = nullptr;
0083         return;
0084     }
0085 
0086     // Access a->config() before adding to containment
0087     // will cause applets to be saved in palsmawindowedrc
0088     // so applets will only be created on demand
0089     KConfigGroup cg2 = a->config();
0090     cont->addApplet(a);
0091 
0092     m_view->setApplet(a);
0093 }
0094 
0095 void PlasmaWindowedCorona::activateRequested(const QStringList &arguments, const QString &workingDirectory)
0096 {
0097     Q_UNUSED(workingDirectory)
0098     if (arguments.count() <= 1) {
0099         return;
0100     }
0101 
0102     QCommandLineParser parser;
0103     parser.setApplicationDescription(i18n("Plasma Windowed"));
0104     parser.addOption(
0105         QCommandLineOption(QStringLiteral("statusnotifier"), i18n("Makes the plasmoid stay alive in the Notification Area, even when the window is closed.")));
0106     parser.addPositionalArgument(QStringLiteral("applet"), i18n("The applet to open."));
0107     parser.addPositionalArgument(QStringLiteral("args"), i18n("Arguments to pass to the plasmoid."), QStringLiteral("[args...]"));
0108     QCommandLineOption configOpt(u"config"_s);
0109     parser.addOption(configOpt);
0110     parser.addVersionOption();
0111     parser.addHelpOption();
0112     parser.process(arguments);
0113 
0114     if (parser.isSet(configOpt)) {
0115         m_view->showConfigurationInterface();
0116         return;
0117     }
0118 
0119     if (parser.positionalArguments().isEmpty()) {
0120         parser.showHelp(1);
0121     }
0122 
0123     const QStringList positionalArguments = parser.positionalArguments();
0124 
0125     QVariantList args;
0126     QStringList::const_iterator constIterator = positionalArguments.constBegin() + 1;
0127     for (; constIterator != positionalArguments.constEnd(); ++constIterator) {
0128         args << (*constIterator);
0129     }
0130 
0131     loadApplet(positionalArguments.first(), args);
0132 }
0133 
0134 QRect PlasmaWindowedCorona::screenGeometry(int id) const
0135 {
0136     Q_UNUSED(id);
0137     // TODO?
0138     return QRect();
0139 }
0140 
0141 void PlasmaWindowedCorona::load()
0142 {
0143     /*this won't load applets, since applets are in plasmawindowedrc*/
0144     loadLayout(QStringLiteral("plasmawindowed-appletsrc"));
0145 
0146     bool found = false;
0147     for (auto c : containments()) {
0148         if (c->containmentType() == Plasma::Containment::Desktop) {
0149             found = true;
0150             break;
0151         }
0152     }
0153 
0154     if (!found) {
0155         qDebug() << "Loading default layout";
0156         createContainment(QStringLiteral("empty"));
0157         saveLayout(QStringLiteral("plasmawindowed-appletsrc"));
0158     }
0159 
0160     for (auto c : containments()) {
0161         if (c->containmentType() == Plasma::Containment::Desktop) {
0162             m_containment = c;
0163             m_containment->setFormFactor(Plasma::Types::Application);
0164             QAction *removeAction = c->internalAction(QStringLiteral("remove"));
0165             if (removeAction) {
0166                 removeAction->deleteLater();
0167             }
0168             break;
0169         }
0170     }
0171 }
0172 
0173 void PlasmaWindowedCorona::setHasStatusNotifier(bool stay)
0174 {
0175     m_hasStatusNotifier = stay;
0176 }