File indexing completed on 2024-05-12 05:38:24

0001 /*
0002     SPDX-FileCopyrightText: 2009 Aaron Seigo <aseigo@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "containment.h"
0008 
0009 #include <QAction>
0010 #include <QQuickItem>
0011 
0012 #include <klocalizedstring.h>
0013 
0014 #include <Plasma/Containment>
0015 #include <Plasma/Corona>
0016 #include <Plasma/PluginLoader>
0017 #include <PlasmaQuick/AppletQuickItem>
0018 
0019 #include "scriptengine.h"
0020 #include "shellcorona.h"
0021 #include "widget.h"
0022 
0023 namespace WorkspaceScripting
0024 {
0025 class Containment::Private
0026 {
0027 public:
0028     QPointer<Plasma::Containment> containment;
0029     ShellCorona *corona;
0030     QString oldWallpaperPlugin;
0031     QString wallpaperPlugin;
0032     QString oldWallpaperMode;
0033     QString wallpaperMode;
0034 
0035     QString type;
0036     QString plugin;
0037 };
0038 
0039 Containment::Containment(Plasma::Containment *containment, ScriptEngine *engine)
0040     : Applet(engine)
0041     , d(new Containment::Private)
0042 {
0043     d->containment = containment;
0044     d->corona = qobject_cast<ShellCorona *>(containment->corona());
0045 
0046     setCurrentConfigGroup(QStringList());
0047     setCurrentGlobalConfigGroup(QStringList());
0048     if (containment) {
0049         d->oldWallpaperPlugin = d->wallpaperPlugin = containment->wallpaperPlugin();
0050     }
0051 }
0052 
0053 Containment::~Containment()
0054 {
0055     if (d->containment) {
0056         if (d->oldWallpaperPlugin != d->wallpaperPlugin || d->oldWallpaperMode != d->wallpaperMode) {
0057             d->containment->setWallpaperPlugin(d->wallpaperPlugin);
0058         }
0059     }
0060 
0061     reloadConfigIfNeeded();
0062 
0063     delete d;
0064 }
0065 
0066 ShellCorona *Containment::corona() const
0067 {
0068     return d->corona;
0069 }
0070 
0071 int Containment::screen() const
0072 {
0073     if (!d->containment) {
0074         return -1;
0075     }
0076 
0077     return d->containment->screen();
0078 }
0079 
0080 QString Containment::wallpaperPlugin() const
0081 {
0082     return d->wallpaperPlugin;
0083 }
0084 
0085 void Containment::setWallpaperPlugin(const QString &wallpaperPlugin)
0086 {
0087     d->wallpaperPlugin = wallpaperPlugin;
0088 }
0089 
0090 QString Containment::wallpaperMode() const
0091 {
0092     return d->wallpaperMode;
0093 }
0094 
0095 void Containment::setWallpaperMode(const QString &wallpaperMode)
0096 {
0097     d->wallpaperMode = wallpaperMode;
0098 }
0099 
0100 QString Containment::formFactor() const
0101 {
0102     if (!d->containment) {
0103         return QStringLiteral("Planar");
0104     }
0105 
0106     switch (d->containment->formFactor()) {
0107     case Plasma::Types::Planar:
0108         return QStringLiteral("planar");
0109     case Plasma::Types::MediaCenter:
0110         return QStringLiteral("mediacenter");
0111     case Plasma::Types::Horizontal:
0112         return QStringLiteral("horizontal");
0113     case Plasma::Types::Vertical:
0114         return QStringLiteral("vertical");
0115     case Plasma::Types::Application:
0116         return QStringLiteral("application");
0117     }
0118 
0119     return QStringLiteral("Planar");
0120 }
0121 
0122 QList<int> Containment::widgetIds() const
0123 {
0124     // FIXME: the ints could overflow since Applet::id() returns a uint,
0125     //       however QScript deals with QList<uint> very, very poory
0126     QList<int> w;
0127 
0128     if (d->containment) {
0129         foreach (const Plasma::Applet *applet, d->containment->applets()) {
0130             w.append(applet->id());
0131         }
0132     }
0133 
0134     return w;
0135 }
0136 
0137 QJSValue Containment::widgetById(const QJSValue &paramId) const
0138 {
0139     if (!paramId.isNumber()) {
0140         return engine()->newError(i18n("widgetById requires an id"));
0141     }
0142 
0143     const uint id = paramId.toInt();
0144 
0145     if (d->containment) {
0146         foreach (Plasma::Applet *w, d->containment->applets()) {
0147             if (w->id() == id) {
0148                 return engine()->wrap(w);
0149             }
0150         }
0151     }
0152 
0153     return QJSValue();
0154 }
0155 
0156 QJSValue Containment::addWidget(const QJSValue &v, qreal x, qreal y, qreal w, qreal h, const QVariantList &args)
0157 {
0158     if (!v.isString() && !v.isQObject()) {
0159         return engine()->newError(i18n("addWidget requires a name of a widget or a widget object"));
0160     }
0161 
0162     if (!d->containment) {
0163         return QJSValue();
0164     }
0165 
0166     QRectF geometry(x, y, w, h);
0167 
0168     Plasma::Applet *applet = nullptr;
0169     if (v.isString()) {
0170         // A position has been supplied: search for the containment's graphics object
0171         QQuickItem *containmentItem = nullptr;
0172 
0173         if (geometry.x() >= 0 && geometry.y() >= 0) {
0174             containmentItem = PlasmaQuick::AppletQuickItem::itemForApplet(d->containment);
0175 
0176             if (containmentItem) {
0177                 QMetaObject::invokeMethod(containmentItem,
0178                                           "createApplet",
0179                                           Qt::DirectConnection,
0180                                           Q_RETURN_ARG(Plasma::Applet *, applet),
0181                                           Q_ARG(QString, v.toString()),
0182                                           Q_ARG(QVariantList, args),
0183                                           Q_ARG(QRectF, geometry));
0184             }
0185             if (applet) {
0186                 return engine()->wrap(applet);
0187             }
0188             return engine()->newError(i18n("Could not create the %1 widget!", v.toString()));
0189         }
0190 
0191         // Case in which either:
0192         // * a geometry wasn't provided
0193         // * containmentItem wasn't found
0194         applet = d->containment->createApplet(v.toString(), args);
0195 
0196         if (applet) {
0197             return engine()->wrap(applet);
0198         }
0199 
0200         return engine()->newError(i18n("Could not create the %1 widget!", v.toString()));
0201     } else if (Widget *widget = qobject_cast<Widget *>(v.toQObject())) {
0202         applet = widget->applet();
0203         d->containment->addApplet(applet);
0204         return v;
0205     }
0206 
0207     return QJSValue();
0208 }
0209 
0210 QJSValue Containment::widgets(const QString &widgetType) const
0211 {
0212     if (!d->containment) {
0213         return QJSValue();
0214     }
0215 
0216     QJSValue widgets = engine()->newArray();
0217     int count = 0;
0218 
0219     foreach (Plasma::Applet *widget, d->containment->applets()) {
0220         if (widgetType.isEmpty() || widget->pluginMetaData().pluginId() == widgetType) {
0221             widgets.setProperty(count, engine()->wrap(widget));
0222             ++count;
0223         }
0224     }
0225 
0226     widgets.setProperty(QStringLiteral("length"), count);
0227     return widgets;
0228 }
0229 
0230 uint Containment::id() const
0231 {
0232     if (!d->containment) {
0233         return 0;
0234     }
0235 
0236     return d->containment->id();
0237 }
0238 
0239 QString Containment::type() const
0240 {
0241     if (!d->containment) {
0242         return QString();
0243     }
0244 
0245     return d->containment->pluginMetaData().pluginId();
0246 }
0247 
0248 void Containment::remove()
0249 {
0250     if (d->containment) {
0251         d->containment->destroy();
0252     }
0253 }
0254 
0255 void Containment::showConfigurationInterface()
0256 {
0257     if (d->containment) {
0258         QAction *configAction = d->containment->internalAction(QStringLiteral("configure"));
0259         if (configAction && configAction->isEnabled()) {
0260             configAction->trigger();
0261         }
0262     }
0263 }
0264 
0265 Plasma::Applet *Containment::applet() const
0266 {
0267     return d->containment;
0268 }
0269 
0270 Plasma::Containment *Containment::containment() const
0271 {
0272     return d->containment;
0273 }
0274 
0275 }