~aleteoryx/muditaos

ref: ba8f0ac32d86266ac0082ceecb98970b1f19a6de muditaos/module-utils/i18n/i18n.cpp -rw-r--r-- 4.1 KiB
ba8f0ac3 — Krzysztof Móżdżyński [EGD-5448] Add EULA window 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "log/log.hpp"
#include "i18n.hpp"
#include "Utils.hpp"
#include <cstdio>
#include <purefs/filesystem_paths.hpp>

namespace utils
{
    namespace
    {
        auto returnNonEmptyString(const std::string &str, const std::string &ret) -> const std::string &
        {
            return str.empty() ? ret : str;
        }
    } // namespace

    i18n localize;
    json11::Json LangLoader::createJson(const std::string &filename)
    {
        const auto path = utils::localize.DisplayLanguageDirPath / (filename + utils::files::jsonExtension);
        auto fd         = std::fopen(path.c_str(), "r");
        if (fd == nullptr) {
            LOG_FATAL("Error during opening file %s", path.c_str());
            return json11::Json();
        }

        uint32_t fsize = utils::filesystem::filelength(fd);

        auto stream = std::make_unique<char[]>(fsize + 1); // +1 for NULL terminator

        std::fread(stream.get(), 1, fsize, fd);

        std::string err;
        json11::Json js = json11::Json::parse(stream.get(), err);

        std::fclose(fd);

        // Error
        if (err.length() != 0) {
            LOG_FATAL("%s", err.c_str());
            return json11::Json();
        }
        else {
            return js;
        }
    }

    std::vector<Language> LangLoader::getAvailableDisplayLanguages() const
    {
        std::vector<std::string> languageNames;
        for (const auto &entry : std::filesystem::directory_iterator(utils::localize.DisplayLanguageDirPath)) {
            languageNames.push_back(std::filesystem::path(entry.path()).stem());
        }
        return languageNames;
    }

    std::vector<Language> LangLoader::getAvailableInputLanguages() const
    {
        std::vector<std::string> languageNames;
        for (const auto &entry : std::filesystem::directory_iterator(utils::localize.InputLanguageDirPath)) {
            languageNames.push_back(std::filesystem::path(entry.path()).stem());
        }
        return languageNames;
    }

    void i18n::setInputLanguage(const Language &lang)
    {
        if (lang == inputLanguage) {
            return;
        }
        inputLanguage = lang;
    }

    const std::string &i18n::getInputLanguageFilename(const std::string &inputMode)
    {
        // if language pack returned nothing then try default language
        if (inputLanguage.empty()) {
            inputLanguageFilename = fallbackLanguageName + utils::files::breakSign + inputMode;
        }
        else {
            inputLanguageFilename = inputLanguage + utils::files::breakSign + inputMode;
        }
        return inputLanguageFilename;
    }

    const std::string &i18n::getInputLanguage()
    {
        return inputLanguage;
    }

    const std::string &i18n::getDisplayLanguage()
    {
        return currentDisplayLanguage;
    }

    const std::string &i18n::get(const std::string &str)
    {
        // if language pack returned nothing then try default language
        if (displayLanguage[str].string_value().empty()) {
            return returnNonEmptyString(fallbackLanguage[str].string_value(), str);
        }
        return returnNonEmptyString(displayLanguage[str].string_value(), str);
    }

    void i18n::setDisplayLanguage(const Language &lang)
    {
        if (!backupLanguageInitializer) {
            fallbackLanguage          = loader.createJson(fallbackLanguageName);
            displayLanguage           = fallbackLanguage;
            backupLanguageInitializer = true;
        }
        if (lang == currentDisplayLanguage) {
            return;
        }
        currentDisplayLanguage = lang;
        if (lang == fallbackLanguageName) {
            displayLanguage = fallbackLanguage;
        }
        else {
            json11::Json pack = loader.createJson(lang);
            // Suspend whole system during switching lang packs
            vTaskSuspendAll();
            displayLanguage = pack;
            xTaskResumeAll();
        }
    }

    void i18n::setFallbackLanguage(const Language &lang)
    {
        fallbackLanguageName = std::move(lang);
    }
} // namespace utils