File indexing completed on 2024-12-22 05:15:19
0001 /* 0002 SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "containmentinterface.h" 0008 0009 #include <Plasma/Applet> 0010 #include <Plasma/Containment> 0011 #include <Plasma/Corona> 0012 #include <PlasmaQuick/AppletQuickItem> 0013 0014 #include <KActionCollection> 0015 0016 // FIXME HACK TODO: Unfortunately we have no choice but to hard-code a list of 0017 // applets we know to expose the correct interface right now -- this is slated 0018 // for replacement with some form of generic service. 0019 QStringList ContainmentInterface::m_knownTaskManagers{ 0020 QLatin1String("org.kde.plasma.taskmanager"), 0021 QLatin1String("org.kde.plasma.icontasks"), 0022 QLatin1String("org.kde.plasma.expandingiconstaskmanager"), 0023 }; 0024 0025 ContainmentInterface::ContainmentInterface(QObject *parent) 0026 : QObject(parent) 0027 { 0028 } 0029 0030 ContainmentInterface::~ContainmentInterface() 0031 { 0032 } 0033 0034 bool ContainmentInterface::mayAddLauncher(QObject *appletInterface, ContainmentInterface::Target target, const KService::Ptr &service) 0035 { 0036 if (!appletInterface) { 0037 return false; 0038 } 0039 0040 Plasma::Applet *applet = appletInterface->property("_plasma_applet").value<Plasma::Applet *>(); 0041 Plasma::Containment *containment = applet->containment(); 0042 0043 if (!containment) { 0044 return false; 0045 } 0046 0047 Plasma::Corona *corona = containment->corona(); 0048 0049 if (!corona) { 0050 return false; 0051 } 0052 0053 switch (target) { 0054 case Desktop: { 0055 containment = corona->containmentForScreen(containment->screen(), QString(), QString()); 0056 0057 if (containment) { 0058 return (containment->immutability() == Plasma::Types::Mutable); 0059 } 0060 0061 break; 0062 } 0063 case Panel: { 0064 if (containment->pluginMetaData().pluginId() == QLatin1String("org.kde.panel")) { 0065 return (containment->immutability() == Plasma::Types::Mutable); 0066 } 0067 0068 break; 0069 } 0070 case TaskManager: { 0071 if (service && containment->pluginMetaData().pluginId() == QLatin1String("org.kde.panel")) { 0072 auto *taskManager = findTaskManagerApplet(containment); 0073 0074 if (!taskManager) { 0075 return false; 0076 } 0077 0078 auto *taskManagerQuickItem = PlasmaQuick::AppletQuickItem::itemForApplet(taskManager); 0079 0080 if (!taskManagerQuickItem) { 0081 return false; 0082 } 0083 0084 return taskManagerQuickItem->property("supportsLaunchers").toBool(); 0085 } 0086 0087 break; 0088 } 0089 } 0090 0091 return false; 0092 } 0093 0094 bool ContainmentInterface::hasLauncher(QObject *appletInterface, ContainmentInterface::Target target, const KService::Ptr &service) 0095 { 0096 // Only the task manager supports toggle-able launchers 0097 if (target != TaskManager) { 0098 return false; 0099 } 0100 if (!appletInterface) { 0101 return false; 0102 } 0103 0104 Plasma::Applet *applet = appletInterface->property("_plasma_applet").value<Plasma::Applet *>(); 0105 Plasma::Containment *containment = applet->containment(); 0106 0107 if (!containment) { 0108 return false; 0109 } 0110 0111 if (service && containment->pluginMetaData().pluginId() == QLatin1String("org.kde.panel")) { 0112 auto *taskManager = findTaskManagerApplet(containment); 0113 0114 if (!taskManager) { 0115 return false; 0116 } 0117 0118 auto *taskManagerQuickItem = PlasmaQuick::AppletQuickItem::itemForApplet(taskManager); 0119 0120 if (!taskManagerQuickItem) { 0121 return false; 0122 } 0123 0124 QVariant ret; 0125 QMetaObject::invokeMethod(taskManagerQuickItem, 0126 "hasLauncher", 0127 Q_RETURN_ARG(QVariant, ret), 0128 Q_ARG(QVariant, QUrl(QLatin1String("applications:") + service->storageId()))); 0129 return ret.toBool(); 0130 } 0131 0132 return false; 0133 } 0134 0135 void ContainmentInterface::addLauncher(QObject *appletInterface, ContainmentInterface::Target target, const QString &entryPath) 0136 { 0137 if (!appletInterface) { 0138 return; 0139 } 0140 0141 Plasma::Applet *applet = appletInterface->property("_plasma_applet").value<Plasma::Applet *>(); 0142 Plasma::Containment *containment = applet->containment(); 0143 0144 if (!containment) { 0145 return; 0146 } 0147 0148 Plasma::Corona *corona = containment->corona(); 0149 0150 if (!corona) { 0151 return; 0152 } 0153 0154 switch (target) { 0155 case Desktop: { 0156 containment = corona->containmentForScreen(containment->screen(), QString(), QString()); 0157 0158 if (!containment) { 0159 return; 0160 } 0161 0162 const QStringList &containmentProvides = containment->pluginMetaData().value(QStringLiteral("X-Plasma-Provides"), QStringList()); 0163 0164 if (containmentProvides.contains(QLatin1String("org.kde.plasma.filemanagement"))) { 0165 auto *folderQuickItem = PlasmaQuick::AppletQuickItem::itemForApplet(containment); 0166 0167 if (!folderQuickItem) { 0168 return; 0169 } 0170 0171 QMetaObject::invokeMethod(folderQuickItem, "addLauncher", Q_ARG(QVariant, QUrl::fromLocalFile(entryPath))); 0172 } else { 0173 containment->createApplet(QStringLiteral("org.kde.plasma.icon"), QVariantList() << QUrl::fromLocalFile(entryPath)); 0174 } 0175 0176 break; 0177 } 0178 case Panel: { 0179 if (containment->pluginMetaData().pluginId() == QLatin1String("org.kde.panel")) { 0180 containment->createApplet(QStringLiteral("org.kde.plasma.icon"), QVariantList() << QUrl::fromLocalFile(entryPath)); 0181 } 0182 0183 break; 0184 } 0185 case TaskManager: { 0186 if (containment->pluginMetaData().pluginId() == QLatin1String("org.kde.panel")) { 0187 auto *taskManager = findTaskManagerApplet(containment); 0188 0189 if (!taskManager) { 0190 return; 0191 } 0192 0193 auto *taskManagerQuickItem = PlasmaQuick::AppletQuickItem::itemForApplet(taskManager); 0194 0195 if (!taskManagerQuickItem) { 0196 return; 0197 } 0198 0199 QMetaObject::invokeMethod(taskManagerQuickItem, "addLauncher", Q_ARG(QVariant, QUrl::fromLocalFile(entryPath))); 0200 } 0201 0202 break; 0203 } 0204 } 0205 } 0206 0207 QObject *ContainmentInterface::screenContainment(QObject *appletInterface) 0208 { 0209 if (!appletInterface) { 0210 return nullptr; 0211 } 0212 0213 const Plasma::Applet *applet = appletInterface->property("_plasma_applet").value<Plasma::Applet *>(); 0214 Plasma::Containment *containment = applet->containment(); 0215 0216 if (!containment) { 0217 return nullptr; 0218 } 0219 0220 Plasma::Corona *corona = containment->corona(); 0221 0222 if (!corona) { 0223 return nullptr; 0224 } 0225 0226 return corona->containmentForScreen(containment->screen(), QString(), QString()); 0227 } 0228 0229 bool ContainmentInterface::screenContainmentMutable(QObject *appletInterface) 0230 { 0231 const Plasma::Containment *containment = static_cast<const Plasma::Containment *>(screenContainment(appletInterface)); 0232 0233 if (containment) { 0234 return (containment->immutability() == Plasma::Types::Mutable); 0235 } 0236 0237 return false; 0238 } 0239 0240 void ContainmentInterface::ensureMutable(Plasma::Containment *containment) 0241 { 0242 if (containment && containment->immutability() != Plasma::Types::Mutable) { 0243 containment->internalAction(QStringLiteral("lock widgets"))->trigger(); 0244 } 0245 } 0246 0247 Plasma::Applet *ContainmentInterface::findTaskManagerApplet(Plasma::Containment *containment) 0248 { 0249 const QList<Plasma::Applet *> applets = containment->applets(); 0250 const auto found = std::find_if(applets.cbegin(), applets.cend(), [](const Plasma::Applet *applet) { 0251 return m_knownTaskManagers.contains(applet->pluginMetaData().pluginId()); 0252 }); 0253 return found != applets.cend() ? *found : nullptr; 0254 }