KFileMetaData

writercollection.cpp
1/*
2 This file is part of the KFileMetaData project
3 SPDX-FileCopyrightText: 2016 Varun Joshi <varunj.1011@gmail.com>
4 SPDX-FileCopyrightText: 2016 Vishesh Handa <me@vhanda.in>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7*/
8
9#include "writercollection.h"
10#include "writer_p.h"
11#include "writerplugin.h"
12#include "externalwriter.h"
13#include "kfilemetadata_debug.h"
14#include "config-kfilemetadata.h"
15
16#include <KPluginMetaData>
17#include <QCoreApplication>
18#include <QDir>
19#include <QMimeDatabase>
20#include <QPluginLoader>
21#include <vector>
22
23using namespace KFileMetaData;
24
25class KFileMetaData::WriterCollectionPrivate
26{
27public:
29
30 std::vector<Writer> m_allWriters;
31
32 void findWriters();
33};
34
35WriterCollection::WriterCollection()
36 : d(new WriterCollectionPrivate)
37{
38 d->findWriters();
39}
40
41WriterCollection::~WriterCollection() = default;
42
43void WriterCollectionPrivate::findWriters()
44{
45 const auto internalPlugins = KPluginMetaData::findPlugins(QStringLiteral("kf6/kfilemetadata/writers"), {}, KPluginMetaData::AllowEmptyMetaData);
46
47 for (const KPluginMetaData &metaData : internalPlugins) {
48 QPluginLoader loader(metaData.fileName());
49 if (QObject *obj = loader.instance()) {
50 if (WriterPlugin *plugin = qobject_cast<WriterPlugin *>(obj)) {
51 Writer writer;
52 writer.d->m_plugin = plugin;
53 writer.setAutoDeletePlugin(Writer::DoNotDeletePlugin);
54
55 m_allWriters.push_back(std::move(writer));
56 } else {
57 qCDebug(KFILEMETADATA_LOG) << "Plugin could not be converted to a WriterPlugin";
58 qCDebug(KFILEMETADATA_LOG) << metaData.fileName();
59 }
60 } else {
61 qCDebug(KFILEMETADATA_LOG) << "Plugin could not create instance" << metaData.fileName();
62 }
63 }
64
65 QStringList externalPlugins;
66 QStringList externalPluginPaths;
67 QDir externalPluginDir(QStringLiteral(LIBEXEC_INSTALL_DIR) + QStringLiteral("/kfilemetadata/writers/externalwriters"));
68 // For external plugins, we look into the directories. Those are executables and not C++ plugins.
69 const QStringList externalPluginEntryList = externalPluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
70 for (const QString& externalPlugin : externalPluginEntryList) {
71 if (externalPlugins.contains(externalPlugin)) {
72 continue;
73 }
74
75 externalPlugins << externalPlugin;
76 externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin);
77 }
78
79 for (const QString& externalPluginPath : std::as_const(externalPluginPaths)) {
80 ExternalWriter *plugin = new ExternalWriter(externalPluginPath);
81 Writer writer;
82 writer.d->m_plugin = plugin;
83 writer.setAutoDeletePlugin(Writer::AutoDeletePlugin);
84
85 m_allWriters.push_back(std::move(writer));
86 }
87
88 for (Writer& writer : m_allWriters) {
89 const QStringList lst = writer.mimetypes();
90 for (const QString& type : lst) {
91 m_writers.insert(type, &writer);
92 }
93 }
94}
95
96QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const
97{
98 QList<Writer*> plugins = d->m_writers.values(mimetype);
99 if (!plugins.isEmpty()) {
100 return plugins;
101 }
102
103 // try to find the best matching more generic writer by mimetype inheritance
104 QMimeDatabase db;
105 auto type = db.mimeTypeForName(mimetype);
106 const QStringList ancestors = type.allAncestors();
107
108 for (const auto &ancestor : ancestors) {
109 if (ancestor == QLatin1String("application/octet-stream")) {
110 continue;
111 }
112 QList<Writer*> plugins = d->m_writers.values(ancestor);
113 if (!plugins.isEmpty()) {
114 qCDebug(KFILEMETADATA_LOG) << "Using inherited mimetype" << ancestor << "for" << mimetype;
115 return plugins;
116 }
117 }
118
119 return plugins;
120}
121
122
123
static QList< KPluginMetaData > findPlugins(const QString &directory, std::function< bool(const KPluginMetaData &)> filter={}, KPluginMetaDataOptions options={})
Type type(const QSqlDatabase &db)
KIOCORE_EXPORT MimetypeJob * mimetype(const QUrl &url, JobFlags flags=DefaultFlags)
bool isEmpty() const const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
typename QHash< Key, T >::iterator insert(const Key &key, const T &value)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:44:24 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.