added: winix functions: locale, timezone
changed: time zones -- now we have the daylight saving time different for each year (start, end) added: config option: time_zone_id (size_t) time zone identifier for not logged users or for newly created accounts those identifiers you can see in etc/time_zones.conf file or by using timezone winix function with 'a' parameter (timezone/a) (!!IMPROVE ME NOT IMPLEMENTED YET) default: 34 (Coordinated Universal Time UTC+00:00) added: config option: locale_default_id (size_t) locale for not logged users or for newly created accounts added: config option: locale_max_id (size_t) a maximum value of a locale identifier default: 100 (maximum: 1000) each locale files should have its own identifier (in "winix_locale_id" field) from zero to this value added: config option: time_zone_max_id (size_t) maximum value of a time zone identifier time zones with an id greater than this will be skipped default: 130 (maximum: 1000) removed: config option: locale_default git-svn-id: svn://ttmath.org/publicrep/winix/trunk@852 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
@@ -10,16 +10,13 @@
|
||||
#include <algorithm>
|
||||
#include "locale.h"
|
||||
#include "core/log.h"
|
||||
#include "core/misc.h"
|
||||
#include "utf8/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;
|
||||
@@ -29,55 +26,75 @@ Locale::Locale()
|
||||
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)
|
||||
void Locale::SetLocaleMaxId(size_t max_id)
|
||||
{
|
||||
if( lang >= loc_tab.size() )
|
||||
return;
|
||||
if( max_id > 1000 )
|
||||
{
|
||||
max_id = 1000;
|
||||
log << log1 << "Locale: locale_max_id is too big (changed to 1000)" << logend;
|
||||
}
|
||||
|
||||
loc_tab[lang].clear();
|
||||
bool read = false;
|
||||
size_t old_size = locale_indices.size();
|
||||
locale_indices.resize(max_id + 1);
|
||||
|
||||
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;
|
||||
for(size_t i=old_size ; i<locale_indices.size() ; ++i)
|
||||
locale_indices[i] = size_t(-1);
|
||||
}
|
||||
|
||||
|
||||
bool Locale::ReadFile(const char * dir, size_t lang, const char * file)
|
||||
|
||||
|
||||
bool Locale::HasLanguage(size_t lang_id)
|
||||
{
|
||||
if( lang_id < locale_indices.size() )
|
||||
return locale_indices[lang_id] < locale_tab.size();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Locale::ReadFile(const char * dir, const char * dir_def, const char * file)
|
||||
{
|
||||
bool read = false;
|
||||
temp_space.Clear();
|
||||
|
||||
if( dir_def && ReadFile(dir_def, file) )
|
||||
read = true;
|
||||
|
||||
if( dir && ReadFile(dir, file) )
|
||||
read = true;
|
||||
|
||||
if( read )
|
||||
AddLocale(file);
|
||||
else
|
||||
log << log1 << "Locale: can't open locale's file: " << file << logend;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Locale::ReadFile(const char * dir, const char * file)
|
||||
{
|
||||
bool read = false;
|
||||
|
||||
file_name = dir;
|
||||
file_name += '/';
|
||||
file_name += file; // !! dodac sprawdzenie poprawnosci nazwy pliku (czy nie zawiera specjalnych znakow)
|
||||
file_name += file;
|
||||
|
||||
loc_parser.SplitSingle(true);
|
||||
loc_parser.UTF8(input_as_utf8);
|
||||
loc_parser.SetSpace(space);
|
||||
loc_parser.SetSpace(temp_space);
|
||||
|
||||
PT::SpaceParser::Status status = loc_parser.Parse(file_name);
|
||||
|
||||
if( status == PT::SpaceParser::ok )
|
||||
{
|
||||
read = true;
|
||||
AddLocale(lang);
|
||||
log << log3 << "Locale: read locale from: " << file_name << logend;
|
||||
}
|
||||
else
|
||||
@@ -91,22 +108,31 @@ return read;
|
||||
|
||||
|
||||
|
||||
void Locale::AddLocale(size_t lang)
|
||||
void Locale::AddLocale(const char * file)
|
||||
{
|
||||
PT::Space::TableSingle::iterator i = space.table_single.begin();
|
||||
std::wstring * id_str = temp_space.GetValue(L"winix_locale_id");
|
||||
|
||||
for( ; i != space.table_single.end() ; ++i)
|
||||
loc_tab[lang][i->first] = i->second;
|
||||
if( !id_str )
|
||||
{
|
||||
log << log1 << "Locale: winix_locale_id field should be defined in locale file: "
|
||||
<< file << " (skipping)" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t id = (size_t)Tol(*id_str);
|
||||
|
||||
// lists
|
||||
PT::Space::Table::iterator i2 = space.table.begin();
|
||||
if( id >= locale_indices.size() )
|
||||
{
|
||||
log << log1 << "Locale: locale identifier is greater than locale_max_id (skipping)" << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
for( ; i2 != space.table.end() ; ++i2)
|
||||
loc_tab_multi[lang][i2->first] = i2->second;
|
||||
locale_tab.push_back(temp_space);
|
||||
locale_indices[id] = locale_tab.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Locale::ReadSubstTable(const char * dir, const char * dir_def)
|
||||
{
|
||||
bool read = false;
|
||||
@@ -137,14 +163,15 @@ bool read = false;
|
||||
|
||||
loc_parser.SplitSingle(true);
|
||||
loc_parser.UTF8(input_as_utf8);
|
||||
loc_parser.SetSpace(temp_space);
|
||||
|
||||
if( loc_parser.Parse(file_name) == PT::SpaceParser::ok )
|
||||
{
|
||||
read = true;
|
||||
CreateSubstVector(subst_url, space.table_single[L"url_original"], space.table_single[L"url_changeto"]);
|
||||
CreateSubstVector(subst_smalllet, space.table_single[L"smallleters"], space.table_single[L"capitalics"]);
|
||||
CreateSubstVector(subst_capitallet, space.table_single[L"capitalics"], space.table_single[L"smallleters"]);
|
||||
CreateSubstSortVector(subst_sort, space.table[L"sort"]);
|
||||
CreateSubstVector(subst_url, temp_space.table_single[L"url_original"], temp_space.table_single[L"url_changeto"]);
|
||||
CreateSubstVector(subst_smalllet, temp_space.table_single[L"smallleters"], temp_space.table_single[L"capitalics"]);
|
||||
CreateSubstVector(subst_capitallet, temp_space.table_single[L"capitalics"], temp_space.table_single[L"smallleters"]);
|
||||
CreateSubstSortVector(subst_sort, temp_space.table[L"sort"]);
|
||||
|
||||
log << log3 << "Locale: read characters substitution tables from: " << file_name << logend;
|
||||
}
|
||||
@@ -206,10 +233,15 @@ void Locale::CreateSubstSortVector(std::vector<SubstItem> & vect, std::vector<st
|
||||
|
||||
void Locale::Read(const char * dir, const char * dir_def)
|
||||
{
|
||||
locale_tab.clear();
|
||||
|
||||
for(size_t i=0 ; i<locale_indices.size() ; ++i)
|
||||
locale_indices[i] = size_t(-1);
|
||||
|
||||
for(size_t i=0 ; i<locale_files.size() ; ++i)
|
||||
{
|
||||
PT::WideToUTF8(locale_files[i], locale_filea);
|
||||
ReadFile(dir, dir_def, i, locale_filea.c_str());
|
||||
ReadFile(dir, dir_def, locale_filea.c_str());
|
||||
}
|
||||
|
||||
ReadSubstTable(dir, dir_def);
|
||||
@@ -250,37 +282,27 @@ void Locale::Read(const std::wstring & dir, const std::wstring & dir_def)
|
||||
}
|
||||
|
||||
|
||||
size_t Locale::Size() const
|
||||
|
||||
|
||||
void Locale::SetCurLang(size_t lang_id)
|
||||
{
|
||||
return loc_tab.size();
|
||||
current_lang = lang_id;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
size_t Locale::GetCurLang() const
|
||||
{
|
||||
return current_lang;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Locale::SetLangDef(size_t lang)
|
||||
void Locale::SetDefLang(size_t lang_id)
|
||||
{
|
||||
default_lang = lang;
|
||||
|
||||
if( default_lang >= loc_tab.size() )
|
||||
default_lang = loc_tab.size() - 1;
|
||||
default_lang = lang_id;
|
||||
}
|
||||
|
||||
size_t Locale::GetLangDef() const
|
||||
|
||||
size_t Locale::GetDefLang() const
|
||||
{
|
||||
return default_lang;
|
||||
}
|
||||
@@ -293,10 +315,10 @@ bool Locale::IsKey(const wchar_t * key)
|
||||
}
|
||||
|
||||
|
||||
bool Locale::IsKey(const wchar_t * key, size_t lang)
|
||||
bool Locale::IsKey(const wchar_t * key, size_t lang_id)
|
||||
{
|
||||
key_str = key;
|
||||
return IsKey(key_str, lang);
|
||||
return IsKey(key_str, lang_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -307,32 +329,31 @@ bool Locale::IsKey(const std::wstring & key) const
|
||||
}
|
||||
|
||||
|
||||
bool Locale::IsKey(const std::wstring & key, size_t lang) const
|
||||
const std::wstring * Locale::GetKeyInLanguage(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
if( lang >= loc_tab.size() )
|
||||
return false;
|
||||
if( lang_id < locale_indices.size() )
|
||||
{
|
||||
size_t index = locale_indices[lang_id];
|
||||
|
||||
if( index < locale_tab.size() )
|
||||
return locale_tab[index].GetValue(key);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool Locale::IsKey(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
const std::wstring * value = GetKeyInLanguage(key, lang_id);
|
||||
|
||||
// looking in the 'lang' language
|
||||
PT::Space::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
||||
|
||||
if( i != loc_tab[lang].end() )
|
||||
if( value )
|
||||
return true;
|
||||
|
||||
if( lang == default_lang )
|
||||
if( lang_id == 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;
|
||||
return GetKeyInLanguage(key, default_lang) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,19 +364,12 @@ bool Locale::IsKeyLang(const wchar_t * key, size_t lang)
|
||||
}
|
||||
|
||||
|
||||
bool Locale::IsKeyLang(const std::wstring & key, size_t lang) const
|
||||
bool Locale::IsKeyLang(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
if( lang >= loc_tab.size() )
|
||||
return false;
|
||||
|
||||
// looking in the 'lang' language
|
||||
PT::Space::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
||||
|
||||
return i != loc_tab[lang].end();
|
||||
return GetKeyInLanguage(key, lang_id) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::wstring & Locale::Get(const wchar_t * key)
|
||||
{
|
||||
key_str = key;
|
||||
@@ -363,10 +377,10 @@ const std::wstring & Locale::Get(const wchar_t * key)
|
||||
}
|
||||
|
||||
|
||||
const std::wstring & Locale::Get(const wchar_t * key, size_t lang)
|
||||
const std::wstring & Locale::Get(const wchar_t * key, size_t lang_id)
|
||||
{
|
||||
key_str = key;
|
||||
return Get(key_str, lang);
|
||||
return Get(key_str, lang_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -378,52 +392,36 @@ const std::wstring & Locale::Get(const std::wstring & key) const
|
||||
|
||||
|
||||
|
||||
const std::wstring & Locale::Get(const std::wstring & key, size_t lang) const
|
||||
const std::wstring & Locale::Get(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
if( lang >= loc_tab.size() )
|
||||
return empty;
|
||||
const std::wstring * value = GetKeyInLanguage(key, lang_id);
|
||||
|
||||
if( value )
|
||||
return *value;
|
||||
|
||||
// looking in the 'lang' language
|
||||
PT::Space::TableSingle::const_iterator i = loc_tab[lang].find(key);
|
||||
|
||||
if( i != loc_tab[lang].end() )
|
||||
return i->second;
|
||||
|
||||
if( lang == default_lang )
|
||||
if( lang_id == default_lang )
|
||||
return empty;
|
||||
|
||||
value = GetKeyInLanguage(key, default_lang);
|
||||
|
||||
if( default_lang >= loc_tab.size() )
|
||||
return empty;
|
||||
if( value )
|
||||
return *value;
|
||||
|
||||
// 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;
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Locale::IsKeyLangList(const wchar_t * key, size_t lang)
|
||||
bool Locale::IsKeyLangList(const wchar_t * key, size_t lang_id)
|
||||
{
|
||||
key_str = key;
|
||||
return IsKeyLangList(key_str, lang);
|
||||
return IsKeyLangList(key_str, lang_id);
|
||||
}
|
||||
|
||||
|
||||
bool Locale::IsKeyLangList(const std::wstring & key, size_t lang) const
|
||||
bool Locale::IsKeyLangList(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
if( lang >= loc_tab_multi.size() )
|
||||
return false;
|
||||
|
||||
// looking in the 'lang' language
|
||||
PT::Space::Table::const_iterator i = loc_tab_multi[lang].find(key);
|
||||
|
||||
return i != loc_tab_multi[lang].end();
|
||||
return GetListInLanguage(key, lang_id) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -433,56 +431,88 @@ const std::vector<std::wstring> & Locale::GetList(const std::wstring & key) cons
|
||||
}
|
||||
|
||||
|
||||
const std::vector<std::wstring> & Locale::GetList(const std::wstring & key, size_t lang) const
|
||||
|
||||
const std::vector<std::wstring> * Locale::GetListInLanguage(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
if( lang >= loc_tab_multi.size() )
|
||||
if( lang_id < locale_indices.size() )
|
||||
{
|
||||
size_t index = locale_indices[lang_id];
|
||||
|
||||
if( index < locale_tab.size() )
|
||||
{
|
||||
PT::Space::Table::const_iterator i = locale_tab[index].table.find(key);
|
||||
|
||||
if( i != locale_tab[index].table.end() )
|
||||
return &i->second;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<std::wstring> & Locale::GetList(const std::wstring & key, size_t lang_id) const
|
||||
{
|
||||
const std::vector<std::wstring> * list = GetListInLanguage(key, lang_id);
|
||||
|
||||
if( list )
|
||||
return *list;
|
||||
|
||||
if( lang_id == default_lang )
|
||||
return empty_list;
|
||||
|
||||
// looking in the 'lang' language
|
||||
PT::Space::Table::const_iterator i = loc_tab_multi[lang].find(key);
|
||||
list = GetListInLanguage(key, default_lang);
|
||||
|
||||
if( i != loc_tab_multi[lang].end() )
|
||||
return i->second;
|
||||
if( list )
|
||||
return *list;
|
||||
|
||||
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;
|
||||
return empty_list;
|
||||
}
|
||||
|
||||
|
||||
size_t Locale::FileNameToLang(const std::wstring & str) const
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t Locale::IdToIndex(size_t lang_id)
|
||||
{
|
||||
for(size_t i=0 ; i<locale_files.size() ; ++i)
|
||||
if( lang_id < locale_indices.size() )
|
||||
return locale_indices[lang_id]; // here can be size(-1) as well
|
||||
|
||||
return size_t(-1);
|
||||
}
|
||||
|
||||
|
||||
size_t Locale::Size() const
|
||||
{
|
||||
return locale_tab.size();
|
||||
}
|
||||
|
||||
|
||||
const std::wstring & Locale::GetByIndex(const wchar_t * key, size_t index)
|
||||
{
|
||||
key_str = key;
|
||||
return GetByIndex(key_str, index);
|
||||
}
|
||||
|
||||
|
||||
const std::wstring & Locale::GetByIndex(const std::wstring & key, size_t index) const
|
||||
{
|
||||
if( index < locale_tab.size() )
|
||||
{
|
||||
if( locale_files[i] == str )
|
||||
return i;
|
||||
const std::wstring * value = locale_tab[index].GetValue(key);
|
||||
|
||||
if( value )
|
||||
return *value;
|
||||
}
|
||||
|
||||
// we have at least one item "en"
|
||||
return 0;
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::wstring & Locale::LangToFileName(size_t lang) const
|
||||
{
|
||||
if( lang >=locale_files.size() )
|
||||
return empty;
|
||||
|
||||
return locale_files[lang];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -492,6 +522,7 @@ void Locale::UTF8(bool utf)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
binary search in vect
|
||||
vect should be sorted by 'from'
|
||||
|
Reference in New Issue
Block a user