Changeset View
Changeset View
Standalone View
Standalone View
src/writercollection.cpp
Show All 26 Lines | |||||
27 | #include "writerplugin.h" | 27 | #include "writerplugin.h" | ||
28 | #include "externalwriter.h" | 28 | #include "externalwriter.h" | ||
29 | #include "kfilemetadata_debug.h" | 29 | #include "kfilemetadata_debug.h" | ||
30 | #include "config-kfilemetadata.h" | 30 | #include "config-kfilemetadata.h" | ||
31 | 31 | | |||
32 | #include <QCoreApplication> | 32 | #include <QCoreApplication> | ||
33 | #include <QPluginLoader> | 33 | #include <QPluginLoader> | ||
34 | #include <QDir> | 34 | #include <QDir> | ||
35 | #include <QMimeDatabase> | ||||
36 | #include <vector> | ||||
35 | 37 | | |||
36 | using namespace KFileMetaData; | 38 | using namespace KFileMetaData; | ||
37 | 39 | | |||
38 | class Q_DECL_HIDDEN WriterCollection::WriterCollectionPrivate | 40 | class Q_DECL_HIDDEN WriterCollection::WriterCollectionPrivate | ||
39 | { | 41 | { | ||
40 | public: | 42 | public: | ||
41 | QHash<QString, Writer*> m_writers; | 43 | QHash<QString, Writer*> m_writers; | ||
42 | 44 | | |||
43 | QList<Writer*> allWriters() const; | 45 | std::vector<Writer> m_allWriters; | ||
46 | | ||||
47 | void findWriters(); | ||||
44 | }; | 48 | }; | ||
45 | 49 | | |||
46 | WriterCollection::WriterCollection() | 50 | WriterCollection::WriterCollection() | ||
47 | : d_ptr(new WriterCollectionPrivate) | 51 | : d(new WriterCollectionPrivate) | ||
48 | { | 52 | { | ||
49 | Q_D(WriterCollection); | 53 | d->findWriters(); | ||
50 | const QList<Writer*> all = d->allWriters(); | | |||
51 | | ||||
52 | for (Writer* writer : all) { | | |||
53 | const QStringList lst = writer->mimetypes(); | | |||
54 | for (const QString& type : lst) { | | |||
55 | d->m_writers.insertMulti(type, writer); | | |||
56 | } | | |||
57 | } | | |||
58 | } | 54 | } | ||
59 | 55 | | |||
60 | WriterCollection::~WriterCollection() | 56 | WriterCollection::~WriterCollection() | ||
61 | { | 57 | { | ||
62 | Q_D(WriterCollection); | | |||
63 | qDeleteAll(d->m_writers.begin(), d->m_writers.end()); | | |||
64 | delete d; | 58 | delete d; | ||
65 | } | 59 | } | ||
66 | 60 | | |||
67 | 61 | void WriterCollection::WriterCollectionPrivate::findWriters() | |||
68 | QList<Writer*> WriterCollection::WriterCollectionPrivate::allWriters() const | | |||
69 | { | 62 | { | ||
70 | QStringList plugins; | 63 | QStringList plugins; | ||
71 | QStringList pluginPaths; | 64 | QStringList pluginPaths; | ||
72 | QStringList externalPlugins; | 65 | QStringList externalPlugins; | ||
73 | QStringList externalPluginPaths; | 66 | QStringList externalPluginPaths; | ||
74 | 67 | | |||
75 | const QStringList paths = QCoreApplication::libraryPaths(); | 68 | const QStringList paths = QCoreApplication::libraryPaths(); | ||
76 | for (const QString& libraryPath : paths) { | 69 | for (const QString& libraryPath : paths) { | ||
Show All 24 Lines | 93 | for (const QString& externalPlugin : externalPluginEntryList) { | |||
101 | if (externalPlugins.contains(externalPlugin)) | 94 | if (externalPlugins.contains(externalPlugin)) | ||
102 | continue; | 95 | continue; | ||
103 | 96 | | |||
104 | externalPlugins << externalPlugin; | 97 | externalPlugins << externalPlugin; | ||
105 | externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin); | 98 | externalPluginPaths << externalPluginDir.absoluteFilePath(externalPlugin); | ||
106 | } | 99 | } | ||
107 | externalPlugins.clear(); | 100 | externalPlugins.clear(); | ||
108 | 101 | | |||
109 | QList<Writer*> writers; | | |||
110 | for (const QString& pluginPath : qAsConst(pluginPaths)) { | 102 | for (const QString& pluginPath : qAsConst(pluginPaths)) { | ||
111 | QPluginLoader loader(pluginPath); | 103 | QPluginLoader loader(pluginPath); | ||
112 | 104 | | |||
113 | if (!loader.load()) { | 105 | if (!loader.load()) { | ||
114 | qCWarning(KFILEMETADATA_LOG) << "Could not create Writer: " << pluginPath; | 106 | qCWarning(KFILEMETADATA_LOG) << "Could not create Writer: " << pluginPath; | ||
115 | qCWarning(KFILEMETADATA_LOG) << loader.errorString(); | 107 | qCWarning(KFILEMETADATA_LOG) << loader.errorString(); | ||
116 | continue; | 108 | continue; | ||
117 | } | 109 | } | ||
118 | 110 | | |||
119 | QObject* obj = loader.instance(); | 111 | QObject* obj = loader.instance(); | ||
120 | if (obj) { | 112 | if (obj) { | ||
121 | WriterPlugin* plugin = qobject_cast<WriterPlugin*>(obj); | 113 | WriterPlugin* plugin = qobject_cast<WriterPlugin*>(obj); | ||
122 | if (plugin) { | 114 | if (plugin) { | ||
123 | Writer* writer = new Writer; | 115 | Writer writer; | ||
124 | writer->d_ptr->m_plugin = plugin; | 116 | writer.d->m_plugin = plugin; | ||
117 | writer.setAutoDeletePlugin(Writer::DoNotDeletePlugin); | ||||
125 | 118 | | |||
126 | writers << writer; | 119 | m_allWriters.push_back(std::move(writer)); | ||
127 | } else { | 120 | } else { | ||
128 | qCDebug(KFILEMETADATA_LOG) << "Plugin could not be converted to a WriterPlugin"; | 121 | qCDebug(KFILEMETADATA_LOG) << "Plugin could not be converted to a WriterPlugin"; | ||
129 | qCDebug(KFILEMETADATA_LOG) << pluginPath; | 122 | qCDebug(KFILEMETADATA_LOG) << pluginPath; | ||
130 | } | 123 | } | ||
131 | } | 124 | } | ||
132 | else { | 125 | else { | ||
133 | qCDebug(KFILEMETADATA_LOG) << "Plugin could not create instance" << pluginPath; | 126 | qCDebug(KFILEMETADATA_LOG) << "Plugin could not create instance" << pluginPath; | ||
134 | } | 127 | } | ||
135 | } | 128 | } | ||
136 | 129 | | |||
137 | for (const QString& externalPluginPath : qAsConst(externalPluginPaths)) { | 130 | for (const QString& externalPluginPath : qAsConst(externalPluginPaths)) { | ||
138 | ExternalWriter *plugin = new ExternalWriter(externalPluginPath); | 131 | ExternalWriter *plugin = new ExternalWriter(externalPluginPath); | ||
139 | Writer* writer = new Writer; | 132 | Writer writer; | ||
140 | writer->d_ptr->m_plugin = plugin; | 133 | writer.d->m_plugin = plugin; | ||
apol: maybe it would make sense to use shared pointers there? | |||||
No. m_plugin is either a QPluginLoader::instance(), i.e. shared, or a collection-owned ExternalWriter. bruns: No. `m_plugin` is either a QPluginLoader::instance(), i.e. shared, or a collection-owned… | |||||
134 | writer.setAutoDeletePlugin(Writer::AutoDeletePlugin); | ||||
141 | 135 | | |||
142 | writers << writer; | 136 | m_allWriters.push_back(std::move(writer)); | ||
143 | } | 137 | } | ||
144 | 138 | | |||
145 | return writers; | 139 | for (Writer& writer : m_allWriters) { | ||
140 | const QStringList lst = writer.mimetypes(); | ||||
141 | for (const QString& type : lst) { | ||||
142 | m_writers.insertMulti(type, &writer); | ||||
143 | } | ||||
144 | } | ||||
146 | } | 145 | } | ||
147 | 146 | | |||
148 | QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const | 147 | QList<Writer*> WriterCollection::fetchWriters(const QString& mimetype) const | ||
149 | { | 148 | { | ||
150 | Q_D(const WriterCollection); | | |||
151 | QList<Writer*> plugins = d->m_writers.values(mimetype); | 149 | QList<Writer*> plugins = d->m_writers.values(mimetype); | ||
152 | if (plugins.isEmpty()) { | 150 | if (!plugins.isEmpty()) { | ||
153 | auto it = d->m_writers.constBegin(); | 151 | return plugins; | ||
154 | for (; it != d->m_writers.constEnd(); ++it) { | 152 | } | ||
155 | if (mimetype.startsWith(it.key())) | 153 | | ||
156 | plugins << it.value(); | 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 (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; | ||||
157 | } | 167 | } | ||
158 | } | 168 | } | ||
159 | 169 | | |||
160 | return plugins; | 170 | return plugins; | ||
161 | } | 171 | } | ||
162 | 172 | | |||
163 | 173 | | |||
164 | 174 | |
maybe it would make sense to use shared pointers there?