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 | |
23 | using namespace KFileMetaData; |
24 | |
25 | class KFileMetaData::WriterCollectionPrivate |
26 | { |
27 | public: |
28 | QMultiHash<QString, Writer*> m_writers; |
29 | |
30 | std::vector<Writer> m_allWriters; |
31 | |
32 | void findWriters(); |
33 | }; |
34 | |
35 | WriterCollection::WriterCollection() |
36 | : d(new WriterCollectionPrivate) |
37 | { |
38 | d->findWriters(); |
39 | } |
40 | |
41 | WriterCollection::~WriterCollection() = default; |
42 | |
43 | void WriterCollectionPrivate::findWriters() |
44 | { |
45 | const auto internalPlugins = KPluginMetaData::findPlugins(QStringLiteral("kf6/kfilemetadata/writers"), filter: {}, options: 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 *>(object: obj)) { |
51 | Writer writer; |
52 | writer.d->m_plugin = plugin; |
53 | writer.setAutoDeletePlugin(Writer::DoNotDeletePlugin); |
54 | |
55 | m_allWriters.push_back(x: 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(filters: QDir::Dirs | QDir::NoDotAndDotDot); |
70 | for (const QString& externalPlugin : externalPluginEntryList) { |
71 | if (externalPlugins.contains(str: externalPlugin)) { |
72 | continue; |
73 | } |
74 | |
75 | externalPlugins << externalPlugin; |
76 | externalPluginPaths << externalPluginDir.absoluteFilePath(fileName: externalPlugin); |
77 | } |
78 | |
79 | for (const QString& externalPluginPath : std::as_const(t&: 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(x: 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(key: type, value: &writer); |
92 | } |
93 | } |
94 | } |
95 | |
96 | QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const |
97 | { |
98 | QList<Writer*> plugins = d->m_writers.values(key: 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(nameOrAlias: 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(key: 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 | |
124 |