456 lines
8.0 KiB
C++
Executable File
456 lines
8.0 KiB
C++
Executable File
/*
|
|
* This file is a part of Winix
|
|
* and is not publicly distributed
|
|
*
|
|
* Copyright (c) 2010-2011, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include "locale.h"
|
|
#include "core/log.h"
|
|
#include "utf8.h"
|
|
|
|
|
|
|
|
Locale::Locale()
|
|
{
|
|
locale_files.push_back(L"en");
|
|
loc_tab.resize(locale_files.size());
|
|
loc_tab_multi.resize(locale_files.size());
|
|
|
|
default_lang = 0;
|
|
current_lang = 0;
|
|
input_as_utf8 = false;
|
|
}
|
|
|
|
|
|
void Locale::SetLocaleFiles(const std::vector<std::wstring> & files)
|
|
{
|
|
locale_files = files;
|
|
|
|
if( locale_files.empty() )
|
|
locale_files.push_back(L"en");
|
|
|
|
loc_tab.resize(locale_files.size());
|
|
loc_tab_multi.resize(locale_files.size());
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Locale::ReadFile(const char * dir, const char * dir_def, size_t lang, const char * file)
|
|
{
|
|
if( lang >= loc_tab.size() )
|
|
return;
|
|
|
|
loc_tab[lang].clear();
|
|
bool read = false;
|
|
|
|
if( dir_def && ReadFile(dir_def, lang, file) )
|
|
read = true;
|
|
|
|
if( dir && ReadFile(dir, lang, file) )
|
|
read = true;
|
|
|
|
if( !read )
|
|
log << log1 << "Locale: can't open locale's file: " << file << logend;
|
|
}
|
|
|
|
|
|
bool Locale::ReadFile(const char * dir, size_t lang, const char * file)
|
|
{
|
|
bool read = false;
|
|
|
|
file_name = dir;
|
|
file_name += '/';
|
|
file_name += file; // !! dodac sprawdzenie poprawnosci nazwy pliku (czy nie zawiera specjalnych znakow)
|
|
|
|
loc_parser.SplitSingle(true);
|
|
loc_parser.UTF8(input_as_utf8);
|
|
|
|
if( loc_parser.Parse(file_name) == ConfParser::ok )
|
|
{
|
|
read = true;
|
|
AddLocale(lang);
|
|
log << log3 << "Locale: read locale from: " << file_name << logend;
|
|
}
|
|
|
|
return read;
|
|
}
|
|
|
|
|
|
|
|
void Locale::AddLocale(size_t lang)
|
|
{
|
|
ConfParser::TableSingle::iterator i = loc_parser.table_single.begin();
|
|
|
|
for( ; i != loc_parser.table_single.end() ; ++i)
|
|
loc_tab[lang][i->first] = i->second;
|
|
|
|
|
|
// lists
|
|
ConfParser::Table::iterator i2 = loc_parser.table.begin();
|
|
|
|
for( ; i2 != loc_parser.table.end() ; ++i2)
|
|
loc_tab_multi[lang][i2->first] = i2->second;
|
|
}
|
|
|
|
|
|
void Locale::ReadSubstTable(const char * dir, const char * dir_def)
|
|
{
|
|
bool read = false;
|
|
|
|
subst_original.clear();
|
|
subst_changeto.clear();
|
|
|
|
if( dir_def && ReadSubstTable(dir_def) )
|
|
read = true;
|
|
|
|
if( dir && ReadSubstTable(dir) )
|
|
read = true;
|
|
|
|
if( !read )
|
|
log << log1 << "Locale: can't open file for characters substitution" << logend;
|
|
}
|
|
|
|
|
|
bool Locale::ReadSubstTable(const char * dir)
|
|
{
|
|
bool read = false;
|
|
|
|
file_name = dir;
|
|
file_name += '/';
|
|
file_name += "substitute";
|
|
|
|
loc_parser.SplitSingle(true);
|
|
loc_parser.UTF8(input_as_utf8);
|
|
|
|
if( loc_parser.Parse(file_name) == ConfParser::ok )
|
|
{
|
|
read = true;
|
|
subst_original = loc_parser.table_single[L"original"];
|
|
subst_changeto = loc_parser.table_single[L"changeto"];
|
|
log << log3 << "Locale: read characters substitution tables from: " << file_name << logend;
|
|
}
|
|
|
|
return read;
|
|
}
|
|
|
|
|
|
|
|
void Locale::Read(const char * dir, const char * dir_def)
|
|
{
|
|
for(size_t i=0 ; i<locale_files.size() ; ++i)
|
|
{
|
|
Ezc::WideToUTF8(locale_files[i], locale_filea);
|
|
ReadFile(dir, dir_def, i, locale_filea.c_str());
|
|
}
|
|
|
|
ReadSubstTable(dir, dir_def);
|
|
|
|
if( subst_original.size() != subst_changeto.size() )
|
|
log << log1 << "Locale: substitution tables have different sizes" << logend;
|
|
}
|
|
|
|
|
|
void Locale::Read(const std::string & dir, const std::string & dir_def)
|
|
{
|
|
if( dir_def.empty() )
|
|
Read(dir.c_str());
|
|
else
|
|
Read(dir.c_str(), dir_def.c_str());
|
|
}
|
|
|
|
|
|
void Locale::Read(const wchar_t * dir, const wchar_t * dir_def)
|
|
{
|
|
Ezc::WideToUTF8(dir, adir1);
|
|
|
|
if( !dir_def )
|
|
{
|
|
Read(adir1.c_str());
|
|
}
|
|
else
|
|
{
|
|
Ezc::WideToUTF8(dir_def, adir2);
|
|
Read(adir1.c_str(), adir2.c_str());
|
|
}
|
|
}
|
|
|
|
|
|
void Locale::Read(const std::wstring & dir, const std::wstring & dir_def)
|
|
{
|
|
if( dir_def.empty() )
|
|
Read(dir.c_str());
|
|
else
|
|
Read(dir.c_str(), dir_def.c_str());
|
|
}
|
|
|
|
|
|
size_t Locale::Size() const
|
|
{
|
|
return loc_tab.size();
|
|
}
|
|
|
|
|
|
void Locale::SetLang(size_t lang)
|
|
{
|
|
current_lang = lang;
|
|
|
|
if( current_lang >= loc_tab.size() )
|
|
current_lang = loc_tab.size() - 1;
|
|
}
|
|
|
|
|
|
size_t Locale::GetLang() const
|
|
{
|
|
return current_lang;
|
|
}
|
|
|
|
|
|
|
|
void Locale::SetLangDef(size_t lang)
|
|
{
|
|
default_lang = lang;
|
|
|
|
if( default_lang >= loc_tab.size() )
|
|
default_lang = loc_tab.size() - 1;
|
|
}
|
|
|
|
size_t Locale::GetLangDef() const
|
|
{
|
|
return default_lang;
|
|
}
|
|
|
|
|
|
bool Locale::IsKey(const wchar_t * key)
|
|
{
|
|
key_str = key;
|
|
return IsKey(key_str);
|
|
}
|
|
|
|
|
|
bool Locale::IsKey(const wchar_t * key, size_t lang)
|
|
{
|
|
key_str = key;
|
|
return IsKey(key_str, lang);
|
|
}
|
|
|
|
|
|
|
|
bool Locale::IsKey(const std::wstring & key) const
|
|
{
|
|
return IsKey(key, current_lang);
|
|
}
|
|
|
|
|
|
bool Locale::IsKey(const std::wstring & key, size_t lang) const
|
|
{
|
|
if( lang >= loc_tab.size() )
|
|
return false;
|
|
|
|
// looking in the 'lang' language
|
|
ConfParser::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
|
|
|
if( i != loc_tab[lang].end() )
|
|
return true;
|
|
|
|
if( lang == default_lang )
|
|
return false;
|
|
|
|
|
|
if( default_lang >= loc_tab.size() )
|
|
return false;
|
|
|
|
// looking in a default language
|
|
i = loc_tab[default_lang].find(key);
|
|
|
|
if( i != loc_tab[default_lang].end() )
|
|
return true;
|
|
|
|
// there is no such a key
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Locale::IsKeyLang(const wchar_t * key, size_t lang)
|
|
{
|
|
key_str = key;
|
|
return IsKeyLang(key_str, lang);
|
|
}
|
|
|
|
|
|
bool Locale::IsKeyLang(const std::wstring & key, size_t lang) const
|
|
{
|
|
if( lang >= loc_tab.size() )
|
|
return false;
|
|
|
|
// looking in the 'lang' language
|
|
ConfParser::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
|
|
|
return i != loc_tab[lang].end();
|
|
}
|
|
|
|
|
|
|
|
const std::wstring & Locale::Get(const wchar_t * key)
|
|
{
|
|
key_str = key;
|
|
return Get(key_str);
|
|
}
|
|
|
|
|
|
const std::wstring & Locale::Get(const wchar_t * key, size_t lang)
|
|
{
|
|
key_str = key;
|
|
return Get(key_str, lang);
|
|
}
|
|
|
|
|
|
|
|
const std::wstring & Locale::Get(const std::wstring & key) const
|
|
{
|
|
return Get(key, current_lang);
|
|
}
|
|
|
|
|
|
|
|
const std::wstring & Locale::Get(const std::wstring & key, size_t lang) const
|
|
{
|
|
if( lang >= loc_tab.size() )
|
|
return empty;
|
|
|
|
// looking in the 'lang' language
|
|
ConfParser::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
|
|
|
if( i != loc_tab[lang].end() )
|
|
return i->second;
|
|
|
|
if( lang == default_lang )
|
|
return empty;
|
|
|
|
|
|
if( default_lang >= loc_tab.size() )
|
|
return empty;
|
|
|
|
// looking in a default language
|
|
i = loc_tab[default_lang].find(key);
|
|
|
|
if( i != loc_tab[default_lang].end() )
|
|
return i->second;
|
|
|
|
// there is no such a key
|
|
return empty;
|
|
}
|
|
|
|
|
|
|
|
bool Locale::IsKeyLangList(const wchar_t * key, size_t lang)
|
|
{
|
|
key_str = key;
|
|
return IsKeyLangList(key_str, lang);
|
|
}
|
|
|
|
|
|
bool Locale::IsKeyLangList(const std::wstring & key, size_t lang) const
|
|
{
|
|
if( lang >= loc_tab_multi.size() )
|
|
return false;
|
|
|
|
// looking in the 'lang' language
|
|
ConfParser::Table::const_iterator i = loc_tab_multi[lang].find(key);
|
|
|
|
return i != loc_tab_multi[lang].end();
|
|
}
|
|
|
|
|
|
const std::vector<std::wstring> & Locale::GetList(const std::wstring & key) const
|
|
{
|
|
return GetList(key, current_lang);
|
|
}
|
|
|
|
|
|
const std::vector<std::wstring> & Locale::GetList(const std::wstring & key, size_t lang) const
|
|
{
|
|
if( lang >= loc_tab_multi.size() )
|
|
return empty_list;
|
|
|
|
// looking in the 'lang' language
|
|
ConfParser::Table::const_iterator i = loc_tab_multi[lang].find(key);
|
|
|
|
if( i != loc_tab_multi[lang].end() )
|
|
return i->second;
|
|
|
|
if( lang == default_lang )
|
|
return empty_list;
|
|
|
|
|
|
if( default_lang >= loc_tab_multi.size() )
|
|
return empty_list;
|
|
|
|
// looking in a default language
|
|
i = loc_tab_multi[default_lang].find(key);
|
|
|
|
if( i != loc_tab_multi[default_lang].end() )
|
|
return i->second;
|
|
|
|
// there is no such a key
|
|
return empty_list;
|
|
}
|
|
|
|
|
|
size_t Locale::FileNameToLang(const std::wstring & str) const
|
|
{
|
|
for(size_t i=0 ; i<locale_files.size() ; ++i)
|
|
{
|
|
if( locale_files[i] == str )
|
|
return i;
|
|
}
|
|
|
|
// we have at least one item "en"
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
const std::wstring & Locale::LangToFileName(size_t lang) const
|
|
{
|
|
if( lang >=locale_files.size() )
|
|
return empty;
|
|
|
|
return locale_files[lang];
|
|
}
|
|
|
|
|
|
size_t Locale::Size()
|
|
{
|
|
return loc_tab.size();
|
|
}
|
|
|
|
|
|
void Locale::UTF8(bool utf)
|
|
{
|
|
input_as_utf8 = utf;
|
|
}
|
|
|
|
|
|
wchar_t Locale::Subst(wchar_t c)
|
|
{
|
|
size_t i = subst_original.find(c);
|
|
|
|
if( i == std::wstring::npos || i >= subst_changeto.size() )
|
|
return c;
|
|
|
|
return subst_changeto[i];
|
|
}
|
|
|
|
|
|
|
|
void Locale::Subst(std::wstring & str)
|
|
{
|
|
for(size_t i=0 ; i<str.size() ; ++i)
|
|
str[i] = Subst(str[i]);
|
|
}
|