void PlasmoidProtocol::restorePlasmoids() { if (!m_systrayApplet) { return; } //First: remove all that are not allowed anymore QStringList tasksToDelete; foreach (const QString &task, m_tasks.keys()) { if (!m_allowedPlugins.contains(task)) { tasksToDelete << task; } } // Check if we want to remove applets based on formfactor foreach (const QString &task, m_tasks.keys()) { PlasmoidTask *plasmoidtask = qobject_cast<PlasmoidTask*>(m_tasks[task]); if (plasmoidtask) { KPluginMetaData md = plasmoidtask->pluginInfo().toMetaData(); if (!md.formFactors().isEmpty() && !md.formFactors().contains(m_formFactor)) { if (!tasksToDelete.contains(task)) { tasksToDelete << task; } } } } foreach (const QString &task, tasksToDelete) { cleanupTask(task); }
ThemeInfo::ThemeInfo( const KPluginMetaData& data ) : id( data.pluginId() ) , name( data.name() ) , description( data.description() ) , widget( nullptr ) { }
void Device::reloadPlugins() { QHash<QString, KdeConnectPlugin*> newPluginMap; QMultiMap<QString, KdeConnectPlugin*> newPluginsByIncomingInterface; QMultiMap<QString, KdeConnectPlugin*> newPluginsByOutgoingInterface; QSet<QString> supportedIncomingInterfaces; QSet<QString> supportedOutgoingInterfaces; QStringList unsupportedPlugins; if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); PluginLoader* loader = PluginLoader::instance(); const bool deviceSupportsCapabilities = !m_incomingCapabilities.isEmpty() || !m_outgoingCapabilities.isEmpty(); foreach (const QString& pluginName, loader->getPluginList()) { const KPluginMetaData service = loader->getPluginInfo(pluginName); const QSet<QString> incomingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-SupportedPackageType").toSet(); const QSet<QString> outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-OutgoingPackageType").toSet(); const bool pluginEnabled = isPluginEnabled(pluginName); if (pluginEnabled) { supportedIncomingInterfaces += incomingInterfaces; supportedOutgoingInterfaces += outgoingInterfaces; } //If we don't find intersection with the received on one end and the sent on the other, we don't //let the plugin stay //Also, if no capabilities are specified on the other end, we don't apply this optimizaton, as //we assume that the other client doesn't know about capabilities. const bool capabilitiesSupported = deviceSupportsCapabilities && (!incomingInterfaces.isEmpty() || !outgoingInterfaces.isEmpty()); if (capabilitiesSupported && (m_incomingCapabilities & outgoingInterfaces).isEmpty() && (m_outgoingCapabilities & incomingInterfaces).isEmpty() ) { qCWarning(KDECONNECT_CORE) << "not loading " << pluginName << "because of unmatched capabilities"; unsupportedPlugins.append(pluginName); continue; } if (pluginEnabled) { KdeConnectPlugin* plugin = m_plugins.take(pluginName); if (!plugin) { plugin = loader->instantiatePluginForDevice(pluginName, this); } foreach(const QString& interface, incomingInterfaces) { newPluginsByIncomingInterface.insert(interface, plugin); } foreach(const QString& interface, outgoingInterfaces) { newPluginsByOutgoingInterface.insert(interface, plugin); } newPluginMap[pluginName] = plugin; }
void Device::reloadPlugins() { QHash<QString, KdeConnectPlugin*> newPluginMap; QMultiMap<QString, KdeConnectPlugin*> newPluginsByIncomingInterface; QMultiMap<QString, KdeConnectPlugin*> newPluginsByOutgoingInterface; if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); PluginLoader* loader = PluginLoader::instance(); //Code borrowed from KWin foreach (const QString& pluginName, loader->getPluginList()) { QString enabledKey = pluginName + QString::fromLatin1("Enabled"); bool isPluginEnabled = (pluginStates.hasKey(enabledKey) ? pluginStates.readEntry(enabledKey, false) : loader->getPluginInfo(pluginName).isEnabledByDefault()); if (isPluginEnabled) { KdeConnectPlugin* plugin = m_plugins.take(pluginName); QStringList incomingInterfaces, outgoingInterfaces; if (plugin) { incomingInterfaces = m_pluginsByIncomingInterface.keys(plugin); outgoingInterfaces = m_pluginsByOutgoingInterface.keys(plugin); } else { const KPluginMetaData service = loader->getPluginInfo(pluginName); incomingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-SupportedPackageType"); outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), "X-KdeConnect-OutgoingPackageType"); } //If we don't find intersection with the received on one end and the sent on the other, we don't //let the plugin stay //Also, if no capabilities are specified on the other end, we don't apply this optimizaton, as //we assume that the other client doesn't know about capabilities. if (!m_incomingCapabilities.isEmpty() && !m_outgoingCapabilities.isEmpty() && (m_incomingCapabilities & outgoingInterfaces.toSet()).isEmpty() && (m_outgoingCapabilities & incomingInterfaces.toSet()).isEmpty() ) { delete plugin; continue; } if (!plugin) { plugin = loader->instantiatePluginForDevice(pluginName, this); } foreach(const QString& interface, incomingInterfaces) { newPluginsByIncomingInterface.insert(interface, plugin); } foreach(const QString& interface, outgoingInterfaces) { newPluginsByOutgoingInterface.insert(interface, plugin); } newPluginMap[pluginName] = plugin; }
void FrameBufferManager::loadPlugins() { //qDebug(); const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("krfb"), [](const KPluginMetaData & md) { return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer")); }); QVectorIterator<KPluginMetaData> i(plugins); i.toBack(); QSet<QString> unique; while (i.hasPrevious()) { KPluginMetaData data = i.previous(); // only load plugins once, even if found multiple times! if (unique.contains(data.name())) continue; KPluginFactory *factory = KPluginLoader(data.fileName()).factory(); if (!factory) { qDebug() << "KPluginFactory could not load the plugin:" << data.fileName(); } else { qDebug() << "found plugin at " << data.fileName(); } FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this); if (plugin) { m_plugins.insert(data.pluginId(), plugin); qDebug() << "Loaded plugin with name " << data.pluginId(); } else { qDebug() << "unable to load pluign for " << data.fileName(); } unique.insert (data.name()); } }
bool PluginEffectLoader::loadEffect(const KPluginMetaData &info, LoadEffectFlags flags) { if (!info.isValid()) { qCDebug(KWIN_CORE) << "Plugin info is not valid"; return false; } const QString name = info.pluginId(); if (!flags.testFlag(LoadEffectFlag::Load)) { qCDebug(KWIN_CORE) << "Loading flags disable effect: " << name; return false; } if (m_loadedEffects.contains(name)) { qCDebug(KWIN_CORE) << name << " already loaded"; return false; } EffectPluginFactory *effectFactory = factory(info); if (!effectFactory) { qCDebug(KWIN_CORE) << "Couldn't get an EffectPluginFactory for: " << name; return false; } #ifndef KWIN_UNIT_TEST effects->makeOpenGLContextCurrent(); #endif if (!effectFactory->isSupported()) { qCDebug(KWIN_CORE) << "Effect is not supported: " << name; return false; } if (flags.testFlag(LoadEffectFlag::CheckDefaultFunction)) { if (!effectFactory->enabledByDefault()) { qCDebug(KWIN_CORE) << "Enabled by default function disables effect: " << name; return false; } } // ok, now we can try to create the Effect Effect *e = effectFactory->createEffect(); if (!e) { qCDebug(KWIN_CORE) << "Failed to create effect: " << name; return false; } // insert in our loaded effects m_loadedEffects << name; connect(e, &Effect::destroyed, this, [this, name]() { m_loadedEffects.removeAll(name); } ); qCDebug(KWIN_CORE) << "Successfully loaded plugin effect: " << name; emit effectLoaded(e, name); return true; }
bool ScriptedEffectLoader::loadEffect(const KPluginMetaData &effect, LoadEffectFlags flags) { const QString name = effect.pluginId(); if (!flags.testFlag(LoadEffectFlag::Load)) { qCDebug(KWIN_CORE) << "Loading flags disable effect: " << name; return false; } if (m_loadedEffects.contains(name)) { qCDebug(KWIN_CORE) << name << "already loaded"; return false; } if (!ScriptedEffect::supported()) { qCDebug(KWIN_CORE) << "Effect is not supported: " << name; return false; } ScriptedEffect *e = ScriptedEffect::create(effect); if (!e) { qCDebug(KWIN_CORE) << "Could not initialize scripted effect: " << name; return false; } connect(e, &ScriptedEffect::destroyed, this, [this, name]() { m_loadedEffects.removeAll(name); } ); qCDebug(KWIN_CORE) << "Successfully loaded scripted effect: " << name; emit effectLoaded(e, name); m_loadedEffects << name; return true; }
QString ViewerPluginInfo::saveName() const { return QFileInfo(metaData.fileName()).baseName(); }
QString PluginEditorCheckBeforeSendInfo::saveName() const { return QFileInfo(metaData.fileName()).baseName(); }
bool PackageJobThread::installPackage(const QString &src, const QString &dest, OperationType operation) { QDir root(dest); if (!root.exists()) { QDir().mkpath(dest); if (!root.exists()) { d->errorMessage = i18n("Could not create package root directory: %1", dest); d->errorCode = Package::JobError::RootCreationError; //qWarning() << "Could not create package root directory: " << dest; return false; } } QFileInfo fileInfo(src); if (!fileInfo.exists()) { d->errorMessage = i18n("No such file: %1", src); d->errorCode = Package::JobError::PackageFileNotFoundError; return false; } QString path; QTemporaryDir tempdir; bool archivedPackage = false; if (fileInfo.isDir()) { // we have a directory, so let's just install what is in there path = src; // make sure we end in a slash! if (!path.endsWith('/')) { path.append('/'); } } else { KArchive *archive = 0; QMimeDatabase db; QMimeType mimetype = db.mimeTypeForFile(src); if (mimetype.inherits(QStringLiteral("application/zip"))) { archive = new KZip(src); } else if (mimetype.inherits(QStringLiteral("application/x-compressed-tar")) || mimetype.inherits(QStringLiteral("application/x-tar")) || mimetype.inherits(QStringLiteral("application/x-bzip-compressed-tar")) || mimetype.inherits(QStringLiteral("application/x-xz")) || mimetype.inherits(QStringLiteral("application/x-lzma"))) { archive = new KTar(src); } else { //qWarning() << "Could not open package file, unsupported archive format:" << src << mimetype.name(); d->errorMessage = i18n("Could not open package file, unsupported archive format: %1 %2", src, mimetype.name()); d->errorCode = Package::JobError::UnsupportedArchiveFormatError; return false; } if (!archive->open(QIODevice::ReadOnly)) { //qWarning() << "Could not open package file:" << src; delete archive; d->errorMessage = i18n("Could not open package file: %1", src); d->errorCode = Package::JobError::PackageOpenError; return false; } archivedPackage = true; path = tempdir.path() + '/'; d->installPath = path; const KArchiveDirectory *source = archive->directory(); source->copyTo(path); QStringList entries = source->entries(); if (entries.count() == 1) { const KArchiveEntry *entry = source->entry(entries[0]); if (entry->isDirectory()) { path.append(entry->name()).append("/"); } } delete archive; } QDir packageDir(path); QFileInfoList entries = packageDir.entryInfoList(*metaDataFiles); KPluginMetaData meta; if (!entries.isEmpty()) { const QString metadataFilePath = entries.first().filePath(); if (metadataFilePath.endsWith(QLatin1String(".desktop"))) meta = KPluginMetaData(metadataFilePath); else { QFile f(metadataFilePath); if(!f.open(QIODevice::ReadOnly)){ qWarning() << "Couldn't open metadata file" << src << path; d->errorMessage = i18n("Could not open metadata file: %1", src); d->errorCode = Package::JobError::MetadataFileMissingError; return false; } QJsonObject metadataObject = QJsonDocument::fromJson(f.readAll()).object(); meta = KPluginMetaData(metadataObject, QString(), metadataFilePath); } } if (!meta.isValid()) { qDebug() << "No metadata file in package" << src << path; d->errorMessage = i18n("No metadata file in package: %1", src); d->errorCode = Package::JobError::MetadataFileMissingError; return false; } QString pluginName = meta.pluginId(); qDebug() << "pluginname: " << meta.pluginId(); if (pluginName.isEmpty()) { //qWarning() << "Package plugin name not specified"; d->errorMessage = i18n("Package plugin name not specified: %1", src); d->errorCode = Package::JobError::PluginNameMissingError; return false; } // Ensure that package names are safe so package uninstall can't inject // bad characters into the paths used for removal. QRegExp validatePluginName("^[\\w-\\.]+$"); // Only allow letters, numbers, underscore and period. if (!validatePluginName.exactMatch(pluginName)) { //qDebug() << "Package plugin name " << pluginName << "contains invalid characters"; d->errorMessage = i18n("Package plugin name %1 contains invalid characters", pluginName); d->errorCode = Package::JobError::PluginNameInvalidError; return false; } QString targetName = dest; if (targetName[targetName.size() - 1] != '/') { targetName.append('/'); } targetName.append(pluginName); if (QFile::exists(targetName)) { if (operation == Update) { KPluginMetaData oldMeta(targetName + QLatin1String("/metadata.desktop")); if (oldMeta.serviceTypes() != meta.serviceTypes()) { d->errorMessage = i18n("The new package has a different type from the old version already installed.", meta.version(), meta.pluginId(), oldMeta.version()); d->errorCode = Package::JobError::UpdatePackageTypeMismatchError; } else if (isVersionNewer(oldMeta.version(), meta.version())) { const bool ok = uninstallPackage(targetName); if (!ok) { d->errorMessage = i18n("Impossible to remove the old installation of %1 located at %2. error: %3", pluginName, targetName, d->errorMessage); d->errorCode = Package::JobError::OldVersionRemovalError; } } else { d->errorMessage = i18n("Not installing version %1 of %2. Version %3 already installed.", meta.version(), meta.pluginId(), oldMeta.version()); d->errorCode = Package::JobError::NewerVersionAlreadyInstalledError; } } else { d->errorMessage = i18n("%1 already exists", targetName); d->errorCode = Package::JobError::PackageAlreadyInstalledError; } if (d->errorCode != KJob::NoError) { d->installPath = targetName; return false; } } //install dependencies const QStringList dependencies = KPluginMetaData::readStringList(meta.rawData(), QStringLiteral("X-KPackage-Dependencies")); for(const QString &dep : dependencies) { QUrl depUrl(dep); if (!installDependency(depUrl)) { d->errorMessage = i18n("Could not install dependency: %1", dep); d->errorCode = Package::JobError::PackageCopyError; return false; } } if (archivedPackage) { // it's in a temp dir, so just move it over. const bool ok = copyFolder(path, targetName); removeFolder(path); if (!ok) { //qWarning() << "Could not move package to destination:" << targetName; d->errorMessage = i18n("Could not move package to destination: %1", targetName); d->errorCode = Package::JobError::PackageMoveError; return false; } } else { // it's a directory containing the stuff, so copy the contents rather // than move them const bool ok = copyFolder(path, targetName); if (!ok) { //qWarning() << "Could not copy package to destination:" << targetName; d->errorMessage = i18n("Could not copy package to destination: %1", targetName); d->errorCode = Package::JobError::PackageCopyError; return false; } } if (archivedPackage) { // no need to remove the temp dir (which has been successfully moved if it's an archive) tempdir.setAutoRemove(false); } indexDirectory(dest, QStringLiteral("kpluginindex.json")); d->installPath = targetName; //qWarning() << "Not updating kbuildsycoca4, since that will go away. Do it yourself for now if needed."; return true; }
void PanelPlugin::setPluginInfo(KPluginMetaData info) { d->name=info.name(); d->requiredExtensions=info.value(QLatin1String("RequiredExtensions")).split(QLatin1Char(',')); }