Skip to content

Commit d4502fa

Browse files
committed
Implement theme and translation additions for plugin extension.
1 parent 8737af8 commit d4502fa

File tree

1 file changed

+82
-18
lines changed

1 file changed

+82
-18
lines changed

src/extension.cpp

Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,34 @@
1010
namespace MOBase
1111
{
1212

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+
1341
ExtensionMetaData::ExtensionMetaData(QJsonObject const& jsonData) : m_JsonData{jsonData}
1442
{
1543
// read basic fields
@@ -182,9 +210,9 @@ TranslationExtension::loadExtension(std::filesystem::path path,
182210
std::vector<std::shared_ptr<const Translation>> translations;
183211
const auto& jsonTranslations = metadata.json()["translations"].toObject();
184212
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);
188216
} else {
189217
log::warn("failed to parse translation '{}' from '{}'", it.key(), path.native());
190218
}
@@ -207,19 +235,8 @@ TranslationExtension::parseTranslation(std::filesystem::path const& extensionFol
207235
const auto name = jsonTranslation["name"].toString();
208236
const auto jsonGlobFiles = jsonTranslation["files"].toVariant().toStringList();
209237

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);
223240

224241
if (name.isEmpty() || qm_files.empty()) {
225242
return nullptr;
@@ -242,9 +259,56 @@ PluginExtension::PluginExtension(
242259
std::unique_ptr<PluginExtension>
243260
PluginExtension::loadExtension(std::filesystem::path path, ExtensionMetaData metadata)
244261
{
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+
246309
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)));
248312
}
249313

250314
GameExtension::GameExtension(PluginExtension&& pluginExtension)

0 commit comments

Comments
 (0)