Merge pull request #6789 from Lawrence37/lang-names

Language names
This commit is contained in:
Lawrence37
2023-08-06 14:47:37 -07:00
committed by GitHub
23 changed files with 453 additions and 282 deletions

View File

@@ -20,6 +20,8 @@
#include <fstream>
#include <glib.h>
#include <iostream>
#include <utility>
#ifdef WIN32
#include <windows.h>
#include <winnls.h>
@@ -28,6 +30,8 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
#include "../rtengine/settings.h"
namespace
{
@@ -162,6 +166,25 @@ void setGtkLanguage(const Glib::ustring &language)
}
TranslationMetadata::TranslationMetadata(std::map<std::string, std::string> &&metadata) :
metadata(std::move(metadata))
{
}
std::string TranslationMetadata::get(const std::string &key, const std::string &default_value) const
{
const auto found_entry = metadata.find(key);
if (found_entry == metadata.end()) {
return default_value;
}
return found_entry->second;
}
std::string TranslationMetadata::getLanguageName(const std::string &default_name) const
{
return get("LANGUAGE_DISPLAY_NAME", default_name);
}
MultiLangMgr langMgr;
MultiLangMgr::MultiLangMgr ()
@@ -219,6 +242,77 @@ Glib::ustring MultiLangMgr::getStr (const std::string& key) const
return key;
}
const TranslationMetadata *MultiLangMgr::getMetadata(const Glib::ustring &fname) const
{
static const char comment_symbol = '#';
static const char *space_chars = " \t";
static const char var_symbol = '@';
static const char key_value_separator = '=';
// Look for the metadata in the cache.
const auto &found_metadata = lang_files_metadata.find(fname);
if (found_metadata != lang_files_metadata.end()) {
return &found_metadata->second;
}
std::ifstream file(fname.c_str());
if (!file.is_open()) {
if (rtengine::settings->verbose) {
std::cerr << "Unable to open language file " << fname << " to get metadata." << std::endl;
}
return nullptr;
}
if (rtengine::settings->verbose) {
std::cout << "Reading metadata from language file " << fname << std::endl;
}
std::map<std::string, std::string> raw_metadata;
const auto read_key_value = [&raw_metadata](const std::string &meta_line) {
// One metadata key-value pair per line. The format is as follows:
// #001 @KEY=VALUE
// The line must begin with the comment symbol (#). After the first
// sequence of whitespace characters, the metadata variable symbol (@)
// must appear. It is followed immediately with the key name. The end of
// the key name is marked with the equal sign (=). All remaining
// characters until the end of the line make up the metadata value.
if (meta_line.empty() || meta_line.front() != comment_symbol) {
return;
}
const auto first_space = meta_line.find_first_of(space_chars, 1);
if (first_space == std::string::npos) {
return;
}
const auto definition_start = meta_line.find_first_not_of(space_chars, first_space + 1);
if (definition_start == std::string::npos || meta_line[definition_start] != var_symbol) {
return;
}
const auto separator_pos = meta_line.find(key_value_separator, definition_start + 1);
if (separator_pos == std::string::npos) {
return;
}
std::string key = meta_line.substr(definition_start + 1, separator_pos - definition_start - 1);
std::string value = meta_line.substr(separator_pos + 1);
if (rtengine::settings->verbose) {
std::cout << "Found metadata key " << key << " with value " << value << std::endl;
}
raw_metadata.emplace(std::move(key), std::move(value));
};
// Read lines in order. Metadata only appear in the first section of each
// file.
for (
std::string line;
std::getline(file, line) && (line.empty() ||
line.front() == comment_symbol ||
line.find_first_not_of(space_chars) == std::string::npos);) {
read_key_value(line);
}
// Add metadata to cache and return.
lang_files_metadata[fname] = TranslationMetadata(std::move(raw_metadata));
return &lang_files_metadata[fname];
}
bool MultiLangMgr::isOSLanguageDetectSupported ()
{
#if defined (WIN32) || defined (__linux__) || defined (__APPLE__)

View File

@@ -24,6 +24,25 @@
#include <glibmm/ustring.h>
class TranslationMetadata
{
public:
TranslationMetadata() = default;
~TranslationMetadata() = default;
TranslationMetadata(const TranslationMetadata &other) = delete;
TranslationMetadata(TranslationMetadata &&other) = delete;
explicit TranslationMetadata(std::map<std::string, std::string> &&metadata);
TranslationMetadata &operator =(const TranslationMetadata &other) = delete;
TranslationMetadata &operator =(TranslationMetadata &&other) noexcept = default;
std::string get(const std::string &key, const std::string &default_value) const;
std::string getLanguageName(const std::string &default_name) const;
private:
std::map<std::string, std::string> metadata;
};
class MultiLangMgr
{
public:
@@ -31,11 +50,13 @@ public:
void load(const Glib::ustring &language, const std::vector<Glib::ustring> &fnames);
Glib::ustring getStr(const std::string& key) const;
const TranslationMetadata *getMetadata(const Glib::ustring &fname) const;
static bool isOSLanguageDetectSupported();
static Glib::ustring getOSUserLanguage();
private:
std::map<std::string, Glib::ustring> translations;
mutable std::map<Glib::ustring, TranslationMetadata> lang_files_metadata;
};
extern MultiLangMgr langMgr;

View File

@@ -16,21 +16,27 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
*/
#include <sstream>
#include <glibmm/miscutils.h>
#include <glibmm/ustring.h>
#include <sigc++/slot.h>
#include "externaleditorpreferences.h"
#include "preferences.h"
#include "multilangmgr.h"
#include "splash.h"
#include "cachemanager.h"
#include "addsetids.h"
#include "cachemanager.h"
#include "externaleditorpreferences.h"
#include "multilangmgr.h"
#include "preferences.h"
#include "rtimage.h"
#include "rtwindow.h"
#include "splash.h"
#include "toollocationpref.h"
#include "../rtengine/dfmanager.h"
#include "../rtengine/ffmanager.h"
#include "../rtengine/iccstore.h"
#include "../rtengine/procparams.h"
#include <sstream>
#include "rtimage.h"
#include "rtwindow.h"
#include "toollocationpref.h"
#ifdef _OPENMP
#include <omp.h>
#endif
@@ -1112,9 +1118,14 @@ Gtk::Widget* Preferences::getGeneralPanel()
std::vector<Glib::ustring> langs;
parseDir(argv0 + "/languages", langs, "");
for (size_t i = 0; i < langs.size(); i++) {
if ("default" != langs[i] && "README" != langs[i] && "LICENSE" != langs[i]) {
languages->append(langs[i]);
for (const auto &lang : langs) {
if ("default" != lang && "README" != lang && "LICENSE" != lang) {
auto lang_metadata = langMgr.getMetadata(Glib::build_filename(argv0 + "/languages", lang));
const auto &display_name =
lang_metadata != nullptr
? Glib::ustring(lang_metadata->getLanguageName(lang))
: lang;
languages->append(lang, display_name);
}
}
@@ -1738,7 +1749,7 @@ void Preferences::storePreferences()
moptions.menuGroupExtProg = ckbmenuGroupExtProg->get_active();
moptions.highlightThreshold = (int)hlThresh->get_value();
moptions.shadowThreshold = (int)shThresh->get_value();
moptions.language = languages->get_active_text();
moptions.language = languages->get_active_id();
moptions.languageAutoDetect = ckbLangAutoDetect->get_active();
moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName;
@@ -2021,7 +2032,7 @@ void Preferences::fillPreferences()
}
cprevdemo->set_active (moptions.prevdemo);
languages->set_active_text(moptions.language);
languages->set_active_id(moptions.language);
ckbLangAutoDetect->set_active(moptions.languageAutoDetect);
int themeNbr = getThemeRowNumber(moptions.theme);
themeCBT->set_active (themeNbr == -1 ? 0 : themeNbr);