mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Also move colorutil.cpp/h linking build fix experiment Delete a bunch of unused CMakeLists.txt files CMakeLists.txt linking fix Don't include NativeApp.h from any headers. Android.mk buildfix Half of the UWP fix Buildfix Minor project file cleanup Buildfixes Guess what? More buildfixes!
150 lines
4.2 KiB
C++
150 lines
4.2 KiB
C++
#include "Common/Data/Text/I18n.h"
|
|
#include "file/ini_file.h"
|
|
#include "file/vfs.h"
|
|
|
|
#include "Common/StringUtils.h"
|
|
|
|
I18NRepo i18nrepo;
|
|
|
|
I18NRepo::~I18NRepo() {
|
|
Clear();
|
|
}
|
|
|
|
std::string I18NRepo::LanguageID() {
|
|
return languageID_;
|
|
}
|
|
|
|
void I18NRepo::Clear() {
|
|
std::lock_guard<std::mutex> guard(catsLock_);
|
|
for (auto iter = cats_.begin(); iter != cats_.end(); ++iter) {
|
|
iter->second.reset();
|
|
}
|
|
cats_.clear();
|
|
}
|
|
|
|
const char *I18NCategory::T(const char *key, const char *def) {
|
|
if (!key) {
|
|
return "ERROR";
|
|
}
|
|
// Replace the \n's with \\n's so that key values with newlines will be found correctly.
|
|
std::string modifiedKey = key;
|
|
modifiedKey = ReplaceAll(modifiedKey, "\n", "\\n");
|
|
|
|
auto iter = map_.find(modifiedKey);
|
|
if (iter != map_.end()) {
|
|
// INFO_LOG(SYSTEM, "translation key found in %s: %s", name_.c_str(), key);
|
|
return iter->second.text.c_str();
|
|
} else {
|
|
std::lock_guard<std::mutex> guard(missedKeyLock_);
|
|
if (def)
|
|
missedKeyLog_[key] = def;
|
|
else
|
|
missedKeyLog_[key] = modifiedKey.c_str();
|
|
// INFO_LOG(SYSTEM, "Missed translation key in %s: %s", name_.c_str(), key);
|
|
return def ? def : key;
|
|
}
|
|
}
|
|
|
|
void I18NCategory::SetMap(const std::map<std::string, std::string> &m) {
|
|
for (auto iter = m.begin(); iter != m.end(); ++iter) {
|
|
if (map_.find(iter->first) == map_.end()) {
|
|
std::string text = ReplaceAll(iter->second, "\\n", "\n");
|
|
map_[iter->first] = I18NEntry(text);
|
|
// INFO_LOG(SYSTEM, "Language entry: %s -> %s", iter->first.c_str(), text.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<I18NCategory> I18NRepo::GetCategory(const char *category) {
|
|
std::lock_guard<std::mutex> guard(catsLock_);
|
|
auto iter = cats_.find(category);
|
|
if (iter != cats_.end()) {
|
|
return iter->second;
|
|
} else {
|
|
I18NCategory *c = new I18NCategory(this, category);
|
|
cats_[category].reset(c);
|
|
return cats_[category];
|
|
}
|
|
}
|
|
|
|
std::string I18NRepo::GetIniPath(const std::string &languageID) const {
|
|
return "lang/" + languageID + ".ini";
|
|
}
|
|
|
|
bool I18NRepo::IniExists(const std::string &languageID) const {
|
|
FileInfo info;
|
|
if (!VFSGetFileInfo(GetIniPath(languageID).c_str(), &info))
|
|
return false;
|
|
if (!info.exists)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool I18NRepo::LoadIni(const std::string &languageID, const std::string &overridePath) {
|
|
IniFile ini;
|
|
std::string iniPath;
|
|
|
|
// INFO_LOG(SYSTEM, "Loading lang ini %s", iniPath.c_str());
|
|
if (!overridePath.empty()) {
|
|
iniPath = overridePath + languageID + ".ini";
|
|
} else {
|
|
iniPath = GetIniPath(languageID);
|
|
}
|
|
|
|
if (!ini.LoadFromVFS(iniPath))
|
|
return false;
|
|
|
|
Clear();
|
|
|
|
const std::vector<Section> §ions = ini.Sections();
|
|
|
|
std::lock_guard<std::mutex> guard(catsLock_);
|
|
for (auto iter = sections.begin(); iter != sections.end(); ++iter) {
|
|
if (iter->name() != "") {
|
|
cats_[iter->name()].reset(LoadSection(&(*iter), iter->name().c_str()));
|
|
}
|
|
}
|
|
|
|
languageID_ = languageID;
|
|
return true;
|
|
}
|
|
|
|
I18NCategory *I18NRepo::LoadSection(const Section *section, const char *name) {
|
|
I18NCategory *cat = new I18NCategory(this, name);
|
|
std::map<std::string, std::string> sectionMap = section->ToMap();
|
|
cat->SetMap(sectionMap);
|
|
return cat;
|
|
}
|
|
|
|
// This is a very light touched save variant - it won't overwrite
|
|
// anything, only create new entries.
|
|
void I18NRepo::SaveIni(const std::string &languageID) {
|
|
IniFile ini;
|
|
ini.Load(GetIniPath(languageID));
|
|
std::lock_guard<std::mutex> guard(catsLock_);
|
|
for (auto iter = cats_.begin(); iter != cats_.end(); ++iter) {
|
|
std::string categoryName = iter->first;
|
|
Section *section = ini.GetOrCreateSection(categoryName.c_str());
|
|
SaveSection(ini, section, iter->second);
|
|
}
|
|
ini.Save(GetIniPath(languageID));
|
|
}
|
|
|
|
void I18NRepo::SaveSection(IniFile &ini, Section *section, std::shared_ptr<I18NCategory> cat) {
|
|
const std::map<std::string, std::string> &missed = cat->Missed();
|
|
|
|
for (auto iter = missed.begin(); iter != missed.end(); ++iter) {
|
|
if (!section->Exists(iter->first.c_str())) {
|
|
std::string text = ReplaceAll(iter->second, "\n", "\\n");
|
|
section->Set(iter->first, text);
|
|
}
|
|
}
|
|
|
|
const std::map<std::string, I18NEntry> &entries = cat->GetMap();
|
|
for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
|
|
std::string text = ReplaceAll(iter->second.text, "\n", "\\n");
|
|
section->Set(iter->first, text);
|
|
}
|
|
|
|
cat->ClearMissed();
|
|
}
|