10
10
namespace MOBase
11
11
{
12
12
13
+ namespace
14
+ {
15
+ // retrieve all files matching one of the glob pattern in globPatterns, assuming paths
16
+ // (in patterns) are relative to basePath
17
+ //
18
+ auto globExtensionFiles (std::filesystem::path basePath,
19
+ QStringList const & globPatterns)
20
+ {
21
+ std::vector<std::filesystem::path> files;
22
+
23
+ for (const auto & globFile : globPatterns) {
24
+ // use a QFileInfo to extract the name (glob) and the directory - we currently do
25
+ // not handle recursive glob (**)
26
+ QFileInfo globFileInfo (basePath, globFile);
27
+
28
+ QDirIterator dirIterator (globFileInfo.absolutePath (), {globFileInfo.fileName ()},
29
+ QDir::Files);
30
+ while (dirIterator.hasNext ()) {
31
+ dirIterator.next ();
32
+ files.push_back (dirIterator.fileInfo ().filesystemAbsoluteFilePath ());
33
+ }
34
+ }
35
+
36
+ return files;
37
+ }
38
+
39
+ } // namespace
40
+
13
41
ExtensionMetaData::ExtensionMetaData (QJsonObject const & jsonData) : m_JsonData{jsonData}
14
42
{
15
43
// read basic fields
@@ -182,9 +210,9 @@ TranslationExtension::loadExtension(std::filesystem::path path,
182
210
std::vector<std::shared_ptr<const Translation>> translations;
183
211
const auto & jsonTranslations = metadata.json ()[" translations" ].toObject ();
184
212
for (auto it = jsonTranslations.begin (); it != jsonTranslations.end (); ++it) {
185
- const auto theme = parseTranslation (path, it.key (), it.value ().toObject ());
186
- if (theme ) {
187
- translations.push_back (theme );
213
+ const auto translation = parseTranslation (path, it.key (), it.value ().toObject ());
214
+ if (translation ) {
215
+ translations.push_back (translation );
188
216
} else {
189
217
log::warn (" failed to parse translation '{}' from '{}'" , it.key (), path.native ());
190
218
}
@@ -207,19 +235,8 @@ TranslationExtension::parseTranslation(std::filesystem::path const& extensionFol
207
235
const auto name = jsonTranslation[" name" ].toString ();
208
236
const auto jsonGlobFiles = jsonTranslation[" files" ].toVariant ().toStringList ();
209
237
210
- std::vector<std::filesystem::path> qm_files;
211
- for (const auto & globFile : jsonGlobFiles) {
212
- // use a QFileInfo to extract the name (glob) and the directory - we currently do
213
- // not handle recursive glob (**)
214
- QFileInfo globFileInfo (extensionFolder, globFile);
215
-
216
- QDirIterator dirIterator (globFileInfo.absolutePath (), {globFileInfo.fileName ()},
217
- QDir::Files);
218
- while (dirIterator.hasNext ()) {
219
- dirIterator.next ();
220
- qm_files.push_back (dirIterator.fileInfo ().filesystemAbsoluteFilePath ());
221
- }
222
- }
238
+ std::vector<std::filesystem::path> qm_files =
239
+ globExtensionFiles (extensionFolder, jsonGlobFiles);
223
240
224
241
if (name.isEmpty () || qm_files.empty ()) {
225
242
return nullptr ;
@@ -242,9 +259,56 @@ PluginExtension::PluginExtension(
242
259
std::unique_ptr<PluginExtension>
243
260
PluginExtension::loadExtension (std::filesystem::path path, ExtensionMetaData metadata)
244
261
{
245
- // TODO
262
+ // load themes
263
+ std::vector<std::shared_ptr<const ThemeAddition>> themes;
264
+ {
265
+ const auto & jsonThemes = metadata.json ()[" themes" ].toObject ();
266
+ for (auto it = jsonThemes.begin (); it != jsonThemes.end (); ++it) {
267
+ for (auto & file : globExtensionFiles (path, it.value ().toVariant ().toStringList ()))
268
+ themes.push_back (std::make_shared<ThemeAddition>(it.key ().toStdString (), file));
269
+ }
270
+ }
271
+
272
+ // load translations
273
+ std::vector<std::shared_ptr<const TranslationAddition>> translations;
274
+ {
275
+ const auto & jsonTranslations = metadata.json ()[" translations" ].toObject ();
276
+
277
+ // * is a custom entry
278
+ if (jsonTranslations.contains (" *" )) {
279
+ std::map<QString, std::vector<std::filesystem::path>> filesPerLanguage;
280
+ const auto prefixes = jsonTranslations[" *" ].toVariant ().toStringList ();
281
+
282
+ for (auto & prefix : prefixes) {
283
+ const auto filePrefix = QFileInfo (prefix).fileName ();
284
+ auto files = globExtensionFiles (path, {prefix + " *.qm" });
285
+ for (auto & file : files) {
286
+ // extract the identifier from the match, e.g., if the prefix is
287
+ // translations/installer_manual_, the filePrefix is installer_manual_,
288
+ // and glob will be like translations/installer_manual_fr.qm
289
+ const auto identifier =
290
+ QFileInfo (file).fileName ().replace (" .qm" , " " ).replace (filePrefix, " " );
291
+ filesPerLanguage[identifier].push_back (file);
292
+ }
293
+ }
294
+
295
+ for (auto & [language, files] : filesPerLanguage) {
296
+ translations.push_back (std::make_shared<TranslationAddition>(
297
+ language.toStdString (), std::move (files)));
298
+ }
299
+
300
+ } else {
301
+ for (auto it = jsonTranslations.begin (); it != jsonTranslations.end (); ++it) {
302
+ translations.push_back (std::make_shared<TranslationAddition>(
303
+ it.key ().toStdString (),
304
+ globExtensionFiles (path, it.value ().toVariant ().toStringList ())));
305
+ }
306
+ }
307
+ }
308
+
246
309
return std::unique_ptr<PluginExtension>(
247
- new PluginExtension (std::move (path), std::move (metadata), true , {}, {}, {}));
310
+ new PluginExtension (std::move (path), std::move (metadata), true , {},
311
+ std::move (themes), std::move (translations)));
248
312
}
249
313
250
314
GameExtension::GameExtension (PluginExtension&& pluginExtension)
0 commit comments