KFileMetaData

writercollection.cpp
1 /*
2  This file is part of the KFileMetaData project
3  SPDX-FileCopyrightText: 2016 Varun Joshi <[email protected]>
4  SPDX-FileCopyrightText: 2016 Vishesh Handa <[email protected]>
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:
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("kf" QT_STRINGIFY(QT_VERSION_MAJOR)) + QStringLiteral("/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 (!QLibrary::isLibrary(externalPlugin)) {
72  continue;
73  }
74  if (externalPlugins.contains(externalPlugin)) {
75  continue;
76  }
77 
78  externalPlugins << externalPlugin;
79  externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin);
80  }
81 
82  for (const QString& externalPluginPath : std::as_const(externalPluginPaths)) {
83  ExternalWriter *plugin = new ExternalWriter(externalPluginPath);
84  Writer writer;
85  writer.d->m_plugin = plugin;
86  writer.setAutoDeletePlugin(Writer::AutoDeletePlugin);
87 
88  m_allWriters.push_back(std::move(writer));
89  }
90 
91  for (Writer& writer : m_allWriters) {
92  const QStringList lst = writer.mimetypes();
93  for (const QString& type : lst) {
94  m_writers.insert(type, &writer);
95  }
96  }
97 }
98 
99 QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const
100 {
101  QList<Writer*> plugins = d->m_writers.values(mimetype);
102  if (!plugins.isEmpty()) {
103  return plugins;
104  }
105 
106  // try to find the best matching more generic writer by mimetype inheritance
107  QMimeDatabase db;
108  auto type = db.mimeTypeForName(mimetype);
109  const QStringList ancestors = type.allAncestors();
110 
111  for (const auto &ancestor : ancestors) {
112  if (ancestor == QLatin1String("application/octet-stream")) {
113  continue;
114  }
115  QList<Writer*> plugins = d->m_writers.values(ancestor);
116  if (!plugins.isEmpty()) {
117  qCDebug(KFILEMETADATA_LOG) << "Using inherited mimetype" << ancestor << "for" << mimetype;
118  return plugins;
119  }
120  }
121 
122  return plugins;
123 }
124 
125 
126 
Type type(const QSqlDatabase &db)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
KIOCORE_EXPORT MimetypeJob * mimetype(const QUrl &url, JobFlags flags=DefaultFlags)
bool isLibrary(const QString &fileName)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
bool isEmpty() const const
void insert(int i, const T &value)
static QVector< KPluginMetaData > findPlugins(const QString &directory, std::function< bool(const KPluginMetaData &)> filter, KPluginMetaDataOption option)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri May 27 2022 03:47:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.