Skip to content

Commit 5ac0355

Browse files
Merge pull request brettdottech#241 from flattermann/i18n-improvements
I18n improvements
2 parents 28963a8 + 2b99dc4 commit 5ac0355

22 files changed

+631
-156
lines changed

firmware/src/core/configmanager/ConfigManager.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,47 +193,67 @@ void ConfigManager::addConfig(ParamType paramType, const char *section, const ch
193193
m_parameters.push_back({param, paramType, section, varName, advanced, saveLambda});
194194
}
195195

196-
void ConfigManager::addConfigString(const char *section, const char *varName, std::string *var, size_t length, const char *description, bool advanced) {
196+
void ConfigManager::addConfigString(const char *section, const char *varName, std::string *var, const size_t length, const char *description, const bool advanced) {
197197
addConfig<std::string, StringParameter>(
198198
ParamType::String, section, varName, var, description, length, advanced,
199199
[this, varName](std::string &var) { var = m_preferences.getString(varName, var.c_str()).c_str(); },
200200
[](StringParameter *param, std::string &var) { var = param->getValue(); },
201201
[this, varName](std::string &var) { m_preferences.putString(varName, var.c_str()); });
202202
}
203203

204-
void ConfigManager::addConfigInt(const char *section, const char *varName, int *var, const char *description, bool advanced) {
204+
void ConfigManager::addConfigString(const char *section, const char *varName, std::string *var, const size_t length, Translation &description, const bool advanced) {
205+
addConfigString(section, varName, var, length, i18n(description), advanced);
206+
}
207+
208+
void ConfigManager::addConfigInt(const char *section, const char *varName, int *var, const char *description, const bool advanced) {
205209
addConfig<int, IntParameter>(
206210
ParamType::Int, section, varName, var, description, 10, advanced,
207211
[this, varName](int &var) { var = m_preferences.getInt(varName, var); },
208212
[](IntParameter *param, int &var) { var = param->getValue(); },
209213
[this, varName](int &var) { m_preferences.putInt(varName, var); });
210214
}
211215

212-
void ConfigManager::addConfigBool(const char *section, const char *varName, bool *var, const char *description, bool advanced) {
216+
void ConfigManager::addConfigInt(const char *section, const char *varName, int *var, Translation &description, const bool advanced) {
217+
addConfigInt(section, varName, var, i18n(description), advanced);
218+
}
219+
220+
void ConfigManager::addConfigBool(const char *section, const char *varName, bool *var, const char *description, const bool advanced) {
213221
addConfig<bool, BoolParameter>(
214222
ParamType::Bool, section, varName, var, description, 2, advanced,
215223
[this, varName](bool &var) { var = m_preferences.getBool(varName, var); },
216224
[this](BoolParameter *param, bool &var) { var = param->getValue(this->m_wm); },
217225
[this, varName](bool &var) { m_preferences.putBool(varName, var); });
218226
}
219227

220-
void ConfigManager::addConfigFloat(const char *section, const char *varName, float *var, const char *description, bool advanced) {
228+
void ConfigManager::addConfigBool(const char *section, const char *varName, bool *var, Translation &description, const bool advanced) {
229+
addConfigBool(section, varName, var, i18n(description), advanced);
230+
}
231+
232+
void ConfigManager::addConfigFloat(const char *section, const char *varName, float *var, const char *description, const bool advanced) {
221233
addConfig<float, FloatParameter>(
222234
ParamType::Float, section, varName, var, description, 10, advanced,
223235
[this, varName](float &var) { var = m_preferences.getFloat(varName, var); },
224236
[](FloatParameter *param, float &var) { var = param->getValue(); },
225237
[this, varName](float &var) { m_preferences.putFloat(varName, var); });
226238
}
227239

228-
void ConfigManager::addConfigColor(const char *section, const char *varName, int *var, const char *description, bool advanced) {
240+
void ConfigManager::addConfigFloat(const char *section, const char *varName, float *var, Translation &description, const bool advanced) {
241+
addConfigFloat(section, varName, var, i18n(description), advanced);
242+
}
243+
244+
void ConfigManager::addConfigColor(const char *section, const char *varName, int *var, const char *description, const bool advanced) {
229245
addConfig<int, ColorParameter>(
230246
ParamType::Color, section, varName, var, description, 8, advanced,
231247
[this, varName](int &var) { var = m_preferences.getInt(varName, var); },
232248
[](ColorParameter *param, int &var) { var = param->getValue(); },
233249
[this, varName](int &var) { m_preferences.putInt(varName, var); });
234250
}
235251

236-
void ConfigManager::addConfigComboBox(const char *section, const char *varName, int *var, String options[], int numOptions, const char *description, bool advanced) {
252+
void ConfigManager::addConfigColor(const char *section, const char *varName, int *var, Translation &description, const bool advanced) {
253+
addConfigColor(section, varName, var, i18n(description), advanced);
254+
}
255+
256+
void ConfigManager::addConfigComboBox(const char *section, const char *varName, int *var, String options[], const int numOptions, const char *description, const bool advanced) {
237257
addConfig<int, ComboBoxParameter>(
238258
ParamType::ComboBox, section, varName, var, description, 0, advanced,
239259
[this, varName](int &var) { var = m_preferences.getInt(varName, var); },
@@ -244,19 +264,23 @@ void ConfigManager::addConfigComboBox(const char *section, const char *varName,
244264
);
245265
}
246266

247-
std::string ConfigManager::getConfigString(const char *varName, std::string defaultValue) {
267+
void ConfigManager::addConfigComboBox(const char *section, const char *varName, int *var, String options[], const int numOptions, Translation &description, const bool advanced) {
268+
addConfigComboBox(section, varName, var, options, numOptions, i18n(description), advanced);
269+
}
270+
271+
std::string ConfigManager::getConfigString(const char *varName, const std::string &defaultValue) {
248272
return m_preferences.getString(varName, defaultValue.c_str()).c_str();
249273
}
250274

251-
bool ConfigManager::getConfigBool(const char *varName, bool defaultValue) {
275+
bool ConfigManager::getConfigBool(const char *varName, const bool defaultValue) {
252276
return m_preferences.getBool(varName, defaultValue);
253277
}
254278

255-
int ConfigManager::getConfigInt(const char *varName, int defaultValue) {
279+
int ConfigManager::getConfigInt(const char *varName, const int defaultValue) {
256280
return m_preferences.getInt(varName, defaultValue);
257281
}
258282

259-
float ConfigManager::getConfigFloat(const char *varName, float defaultValue) {
283+
float ConfigManager::getConfigFloat(const char *varName, const float defaultValue) {
260284
return m_preferences.getFloat(varName, defaultValue);
261285
}
262286

firmware/src/core/configmanager/ConfigManager.h

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CONFIG_MANAGER_H
22
#define CONFIG_MANAGER_H
33

4+
#include "I18n.h"
45
#include "OrbsWiFiManager.h"
56
#include "WifiManagerCustomParameters.h"
67
#include <Preferences.h>
@@ -31,19 +32,50 @@ class ConfigManager {
3132
void setupWebPortal();
3233
void saveAllConfigs();
3334

34-
// Register different types of variables with descriptions
35+
// Add a string configuration variable
3536
void addConfigString(const char *section, const char *varName, std::string *var, size_t length, const char *description, bool advanced = false);
37+
// Add a string configuration variable with a localized description
38+
void addConfigString(const char *section, const char *varName, std::string *var, size_t length, Translation &description, bool advanced = false);
39+
40+
// Add an integer configuration variable
3641
void addConfigInt(const char *section, const char *varName, int *var, const char *description, bool advanced = false);
42+
// Add an integer configuration variable with a localized description
43+
void addConfigInt(const char *section, const char *varName, int *var, Translation &description, bool advanced = false);
44+
45+
// Add a float configuration variable
3746
void addConfigFloat(const char *section, const char *varName, float *var, const char *description, bool advanced = false);
38-
void addConfigIP(const char *section, const char *varName, IPAddress *var, const char *description, bool advanced = false);
47+
// Add a float configuration variable with a localized description
48+
void addConfigFloat(const char *section, const char *varName, float *var, Translation &description, bool advanced = false);
49+
50+
// Add a boolean configuration variable
3951
void addConfigBool(const char *section, const char *varName, bool *var, const char *description, bool advanced = false);
52+
// Add a boolean configuration variable with a localized description
53+
void addConfigBool(const char *section, const char *varName, bool *var, Translation &description, bool advanced = false);
54+
55+
// Add a color configuration variable
4056
void addConfigColor(const char *section, const char *varName, int *var, const char *description, bool advanced = false);
41-
void addConfigComboBox(const char *section, const char *varName, int *var, String options[], int numOptions, const char *description, bool advanced = false);
57+
// Add a color configuration variable with a localized description
58+
void addConfigColor(const char *section, const char *varName, int *var, Translation &description, bool advanced = false);
4259

43-
// Get stored values
44-
std::string getConfigString(const char *varName, std::string defaultValue);
60+
// Add a ComboBox configuration variable
61+
void addConfigComboBox(const char *section, const char *varName, int *var, String options[], int numOptions, const char *description, bool advanced = false);
62+
// Add a ComboBox configuration variable with a localized description
63+
void addConfigComboBox(const char *section, const char *varName, int *var, String options[], int numOptions, Translation &description, bool advanced = false);
64+
// Add a ComboBox configuration variable with localized options and description
65+
template <size_t N>
66+
void addConfigComboBox(const char *section, const char *varName, int *var, TranslationMulti<N> &options, Translation &description, const bool advanced = false) {
67+
String optionsArray[N];
68+
i18nMultiStr(options, optionsArray);
69+
addConfigComboBox(section, varName, var, optionsArray, N, description, advanced);
70+
}
71+
72+
// Retrieve a string configuration value, with a default fallback
73+
std::string getConfigString(const char *varName, const std::string &defaultValue);
74+
// Retrieve a boolean configuration value, with a default fallback
4575
bool getConfigBool(const char *varName, bool defaultValue);
76+
// Retrieve an integer configuration value, with a default fallback
4677
int getConfigInt(const char *varName, int defaultValue);
78+
// Retrieve a float configuration value, with a default fallback
4779
float getConfigFloat(const char *varName, float defaultValue);
4880

4981
// Register callbacks for changes
@@ -56,7 +88,7 @@ class ConfigManager {
5688
const std::function<void(const char *section, const char *varName)> &callback);
5789

5890
// Check if a restart is required
59-
bool requiresRestart() { return m_requiresRestart; }
91+
bool requiresRestart() const { return m_requiresRestart; }
6092

6193
private:
6294
struct Parameter {

firmware/src/core/i18n/I18n.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ String I18n::s_allLanguages[] = ALL_LANGUAGES;
44
int I18n::s_languageId = DEFAULT_LANGUAGE;
55

66
void I18n::setLanguageId(const int langId) {
7-
s_languageId = langId;
7+
if (langId >= 0 && langId < LANG_NUM) {
8+
s_languageId = langId;
9+
} else {
10+
s_languageId = DEFAULT_LANGUAGE;
11+
}
812
}
913

1014
String I18n::getLanguageString(const int langId) {

firmware/src/core/i18n/I18n.h

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,29 @@ enum Language {
1515

1616
#define DEFAULT_LANGUAGE LANG_EN
1717

18+
// Define a custom type for translation arrays
19+
using Translation = const char *const[LANG_NUM];
20+
// Define a template for translation arrays with a fixed number of columns (LANG_NUM)
21+
template <size_t Rows>
22+
using TranslationMulti = const char *const[Rows][LANG_NUM];
23+
1824
class I18n {
1925
public:
2026
static void setLanguageId(int langId);
2127
static String getLanguageString(int langId);
2228
static String *getAllLanguages();
2329

24-
template <size_t N>
25-
static const char *get(const char *const (&translations)[N]) {
30+
static const char *get(Translation &translations) {
2631
const char *text = translations[s_languageId];
2732
if (text == nullptr) {
2833
text = translations[DEFAULT_LANGUAGE];
2934
}
3035
return text ? text : "@missingTranslation@";
3136
}
3237

33-
template <size_t X, size_t Y>
34-
static const char *get(const char *const (&translations)[X][Y], size_t index) {
35-
if (index >= X) {
38+
template <size_t N>
39+
static const char *get(TranslationMulti<N> &translations, size_t index) {
40+
if (index >= N) {
3641
return "@invalidIndex@";
3742
}
3843

@@ -48,16 +53,36 @@ class I18n {
4853
static int s_languageId;
4954
};
5055

51-
// I18n helper
52-
template <size_t N>
53-
static const char *i18n(const char *const (&translations)[N]) {
56+
// I18n helper function for single translation array (returns const char*)
57+
static const char *i18n(Translation &translations) {
5458
return I18n::get(translations);
5559
}
5660

57-
// I18n helper (with index)
58-
template <size_t X, size_t Y>
59-
static const char *i18n(const char *const (&translations)[X][Y], size_t index) {
61+
// I18n helper function for single translation array (returns String)
62+
static String i18nStr(Translation &translations) {
63+
return I18n::get(translations);
64+
}
65+
66+
// I18n helper function for multi-dimensional translation arrays (returns const char*)
67+
template <size_t N>
68+
static const char *i18n(TranslationMulti<N> &translations, size_t index) {
6069
return I18n::get(translations, index);
6170
}
6271

72+
// I18n helper function for multi-dimensional translation arrays (returns String)
73+
template <size_t N>
74+
static String i18nStr(TranslationMulti<N> &translations, size_t index) {
75+
return I18n::get(translations, index);
76+
}
77+
78+
// Helper function to populate a buffer with translated strings and return its size
79+
template <size_t N, size_t BufSize>
80+
static int i18nMultiStr(TranslationMulti<N> &translations, String (&buffer)[BufSize]) {
81+
static_assert(BufSize >= N, "Buffer size is too small");
82+
for (size_t index = 0; index < N; index++) {
83+
buffer[index] = I18n::get(translations, index);
84+
}
85+
return N;
86+
}
87+
6388
#endif // I18N_H

0 commit comments

Comments
 (0)