KFileMetaData

writercollection.cpp
1 /*
2  * This file is part of the KFileMetaData project
3  * Copyright (C) 2016 Varun Joshi <[email protected]>
4  * Copyright (C) 2016 Vishesh Handa <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) version 3, or any
10  * later version accepted by the membership of KDE e.V. (or its
11  * successor approved by the membership of KDE e.V.), which shall
12  * act as a proxy defined in Section 6 of version 3 of the license.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 #include "writercollection.h"
25 #include "writer.h"
26 #include "writer_p.h"
27 #include "writerplugin.h"
28 #include "externalwriter.h"
29 #include "kfilemetadata_debug.h"
30 #include "config-kfilemetadata.h"
31 
32 #include <QCoreApplication>
33 #include <QPluginLoader>
34 #include <QDir>
35 #include <QMimeDatabase>
36 #include <vector>
37 
38 using namespace KFileMetaData;
39 
40 class Q_DECL_HIDDEN WriterCollection::WriterCollectionPrivate
41 {
42 public:
44 
45  std::vector<Writer> m_allWriters;
46 
47  void findWriters();
48 };
49 
50 WriterCollection::WriterCollection()
51  : d(new WriterCollectionPrivate)
52 {
53  d->findWriters();
54 }
55 
56 WriterCollection::~WriterCollection()
57 {
58  delete d;
59 }
60 
61 void WriterCollection::WriterCollectionPrivate::findWriters()
62 {
63  QStringList plugins;
64  QStringList pluginPaths;
65  QStringList externalPlugins;
66  QStringList externalPluginPaths;
67 
69  for (const QString& libraryPath : paths) {
70  QString path(libraryPath + QStringLiteral("/kf5/kfilemetadata/writers"));
71  QDir dir(path);
72 
73  if (!dir.exists()) {
74  continue;
75  }
76 
77  const QStringList entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
78  for (const QString& fileName : entryList) {
79  // Make sure the same plugin is not loaded twice, even if it
80  // installed in two different locations
81  if (plugins.contains(fileName))
82  continue;
83 
84  plugins << fileName;
85  pluginPaths << dir.absoluteFilePath(fileName);
86  }
87  }
88  plugins.clear();
89 
90  QDir externalPluginDir(QStringLiteral(LIBEXEC_INSTALL_DIR) + QStringLiteral("/kfilemetadata/writers/externalwriters"));
91  // For external plugins, we look into the directories
92  const QStringList externalPluginEntryList = externalPluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
93  for (const QString& externalPlugin : externalPluginEntryList) {
94  if (externalPlugins.contains(externalPlugin))
95  continue;
96 
97  externalPlugins << externalPlugin;
98  externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin);
99  }
100  externalPlugins.clear();
101 
102  for (const QString& pluginPath : qAsConst(pluginPaths)) {
103  QPluginLoader loader(pluginPath);
104 
105  if (!loader.load()) {
106  qCWarning(KFILEMETADATA_LOG) << "Could not create Writer: " << pluginPath;
107  qCWarning(KFILEMETADATA_LOG) << loader.errorString();
108  continue;
109  }
110 
111  QObject* obj = loader.instance();
112  if (obj) {
113  WriterPlugin* plugin = qobject_cast<WriterPlugin*>(obj);
114  if (plugin) {
115  Writer writer;
116  writer.d->m_plugin = plugin;
117  writer.setAutoDeletePlugin(Writer::DoNotDeletePlugin);
118 
119  m_allWriters.push_back(std::move(writer));
120  } else {
121  qCDebug(KFILEMETADATA_LOG) << "Plugin could not be converted to a WriterPlugin";
122  qCDebug(KFILEMETADATA_LOG) << pluginPath;
123  }
124  }
125  else {
126  qCDebug(KFILEMETADATA_LOG) << "Plugin could not create instance" << pluginPath;
127  }
128  }
129 
130  for (const QString& externalPluginPath : qAsConst(externalPluginPaths)) {
131  ExternalWriter *plugin = new ExternalWriter(externalPluginPath);
132  Writer writer;
133  writer.d->m_plugin = plugin;
134  writer.setAutoDeletePlugin(Writer::AutoDeletePlugin);
135 
136  m_allWriters.push_back(std::move(writer));
137  }
138 
139  for (Writer& writer : m_allWriters) {
140  const QStringList lst = writer.mimetypes();
141  for (const QString& type : lst) {
142  m_writers.insert(type, &writer);
143  }
144  }
145 }
146 
147 QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const
148 {
149  QList<Writer*> plugins = d->m_writers.values(mimetype);
150  if (!plugins.isEmpty()) {
151  return plugins;
152  }
153 
154  // try to find the best matching more generic writer by mimetype inheritance
155  QMimeDatabase db;
156  auto type = db.mimeTypeForName(mimetype);
157  const QStringList ancestors = type.allAncestors();
158 
159  for (const auto &ancestor : ancestors) {
160  if (ancestor == QLatin1String("application/octet-stream")) {
161  continue;
162  }
163  QList<Writer*> plugins = d->m_writers.values(ancestor);
164  if (!plugins.isEmpty()) {
165  qCDebug(KFILEMETADATA_LOG) << "Using inherited mimetype" << ancestor << "for" << mimetype;
166  return plugins;
167  }
168  }
169 
170  return plugins;
171 }
172 
173 
174 
void clear()
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
Type type(const QSqlDatabase &db)
bool isEmpty() const const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QStringList libraryPaths()
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
void insert(int i, const T &value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon May 25 2020 23:11:17 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.