File indexing completed on 2025-02-16 13:03:42
0001 /* 0002 This file is part of the KFileMetaData project 0003 SPDX-FileCopyrightText: 2016 Varun Joshi <varunj.1011@gmail.com> 0004 SPDX-FileCopyrightText: 2016 Vishesh Handa <me@vhanda.in> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "writercollection.h" 0010 #include "writer_p.h" 0011 #include "writerplugin.h" 0012 #include "externalwriter.h" 0013 #include "kfilemetadata_debug.h" 0014 #include "config-kfilemetadata.h" 0015 0016 #include <KPluginMetaData> 0017 #include <QCoreApplication> 0018 #include <QDir> 0019 #include <QMimeDatabase> 0020 #include <QPluginLoader> 0021 #include <vector> 0022 0023 using namespace KFileMetaData; 0024 0025 class KFileMetaData::WriterCollectionPrivate 0026 { 0027 public: 0028 QMultiHash<QString, Writer*> m_writers; 0029 0030 std::vector<Writer> m_allWriters; 0031 0032 void findWriters(); 0033 }; 0034 0035 WriterCollection::WriterCollection() 0036 : d(new WriterCollectionPrivate) 0037 { 0038 d->findWriters(); 0039 } 0040 0041 WriterCollection::~WriterCollection() = default; 0042 0043 void WriterCollectionPrivate::findWriters() 0044 { 0045 const auto internalPlugins = KPluginMetaData::findPlugins(QStringLiteral("kf" QT_STRINGIFY(QT_VERSION_MAJOR)) + QStringLiteral("/kfilemetadata/writers"), {}, KPluginMetaData::AllowEmptyMetaData); 0046 0047 for (const KPluginMetaData &metaData : internalPlugins) { 0048 QPluginLoader loader(metaData.fileName()); 0049 if (QObject *obj = loader.instance()) { 0050 if (WriterPlugin *plugin = qobject_cast<WriterPlugin *>(obj)) { 0051 Writer writer; 0052 writer.d->m_plugin = plugin; 0053 writer.setAutoDeletePlugin(Writer::DoNotDeletePlugin); 0054 0055 m_allWriters.push_back(std::move(writer)); 0056 } else { 0057 qCDebug(KFILEMETADATA_LOG) << "Plugin could not be converted to a WriterPlugin"; 0058 qCDebug(KFILEMETADATA_LOG) << metaData.fileName(); 0059 } 0060 } else { 0061 qCDebug(KFILEMETADATA_LOG) << "Plugin could not create instance" << metaData.fileName(); 0062 } 0063 } 0064 0065 QStringList externalPlugins; 0066 QStringList externalPluginPaths; 0067 QDir externalPluginDir(QStringLiteral(LIBEXEC_INSTALL_DIR) + QStringLiteral("/kfilemetadata/writers/externalwriters")); 0068 // For external plugins, we look into the directories. Those are executables and not C++ plugins. 0069 const QStringList externalPluginEntryList = externalPluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); 0070 for (const QString& externalPlugin : externalPluginEntryList) { 0071 if (externalPlugins.contains(externalPlugin)) { 0072 continue; 0073 } 0074 0075 externalPlugins << externalPlugin; 0076 externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin); 0077 } 0078 0079 for (const QString& externalPluginPath : std::as_const(externalPluginPaths)) { 0080 ExternalWriter *plugin = new ExternalWriter(externalPluginPath); 0081 Writer writer; 0082 writer.d->m_plugin = plugin; 0083 writer.setAutoDeletePlugin(Writer::AutoDeletePlugin); 0084 0085 m_allWriters.push_back(std::move(writer)); 0086 } 0087 0088 for (Writer& writer : m_allWriters) { 0089 const QStringList lst = writer.mimetypes(); 0090 for (const QString& type : lst) { 0091 m_writers.insert(type, &writer); 0092 } 0093 } 0094 } 0095 0096 QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const 0097 { 0098 QList<Writer*> plugins = d->m_writers.values(mimetype); 0099 if (!plugins.isEmpty()) { 0100 return plugins; 0101 } 0102 0103 // try to find the best matching more generic writer by mimetype inheritance 0104 QMimeDatabase db; 0105 auto type = db.mimeTypeForName(mimetype); 0106 const QStringList ancestors = type.allAncestors(); 0107 0108 for (const auto &ancestor : ancestors) { 0109 if (ancestor == QLatin1String("application/octet-stream")) { 0110 continue; 0111 } 0112 QList<Writer*> plugins = d->m_writers.values(ancestor); 0113 if (!plugins.isEmpty()) { 0114 qCDebug(KFILEMETADATA_LOG) << "Using inherited mimetype" << ancestor << "for" << mimetype; 0115 return plugins; 0116 } 0117 } 0118 0119 return plugins; 0120 } 0121 0122 0123