mirror of https://github.com/PCSX2/pcsx2.git
i18n: more minor bugfixes to handling of Chinese dialects/sub-languages, and some bug fixes to language enumeration and language settings ini stuff.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4080 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d9fdecd176
commit
2b9e609529
|
@ -364,6 +364,7 @@ AppConfig::AppConfig()
|
||||||
, GameDatabaseTabName( L"none" )
|
, GameDatabaseTabName( L"none" )
|
||||||
, DeskTheme( L"default" )
|
, DeskTheme( L"default" )
|
||||||
{
|
{
|
||||||
|
LanguageId = wxLANGUAGE_DEFAULT;
|
||||||
LanguageCode = L"default";
|
LanguageCode = L"default";
|
||||||
RecentIsoCount = 12;
|
RecentIsoCount = 12;
|
||||||
Listbook_ImageSize = 32;
|
Listbook_ImageSize = 32;
|
||||||
|
@ -467,6 +468,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini )
|
||||||
IniEntry( McdSettingsTabName );
|
IniEntry( McdSettingsTabName );
|
||||||
IniEntry( AppSettingsTabName );
|
IniEntry( AppSettingsTabName );
|
||||||
IniEntry( GameDatabaseTabName );
|
IniEntry( GameDatabaseTabName );
|
||||||
|
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
|
||||||
IniEntry( LanguageCode );
|
IniEntry( LanguageCode );
|
||||||
IniEntry( RecentIsoCount );
|
IniEntry( RecentIsoCount );
|
||||||
IniEntry( DeskTheme );
|
IniEntry( DeskTheme );
|
||||||
|
|
|
@ -195,7 +195,12 @@ public:
|
||||||
wxString AppSettingsTabName;
|
wxString AppSettingsTabName;
|
||||||
wxString GameDatabaseTabName;
|
wxString GameDatabaseTabName;
|
||||||
|
|
||||||
|
// Currently selected language ID -- wxWidgets version-specific identifier. This is one side of
|
||||||
|
// a two-part configuration that also includes LanguageCode.
|
||||||
|
wxLanguage LanguageId;
|
||||||
|
|
||||||
// Current language in use (correlates to the universal language codes, such as "en_US", "de_DE", etc).
|
// Current language in use (correlates to the universal language codes, such as "en_US", "de_DE", etc).
|
||||||
|
// This code is not always unique, which is why we use the language ID also.
|
||||||
wxString LanguageCode;
|
wxString LanguageCode;
|
||||||
|
|
||||||
int RecentIsoCount; // number of files displayed in the Recent Isos list.
|
int RecentIsoCount; // number of files displayed in the Recent Isos list.
|
||||||
|
|
|
@ -669,11 +669,11 @@ void AppApplySettings( const AppConfig* oldconf )
|
||||||
if( (oldconf == NULL) || (oldconf->LanguageCode.CmpNoCase(g_Conf->LanguageCode)) )
|
if( (oldconf == NULL) || (oldconf->LanguageCode.CmpNoCase(g_Conf->LanguageCode)) )
|
||||||
{
|
{
|
||||||
wxDoNotLogInThisScope please;
|
wxDoNotLogInThisScope please;
|
||||||
if( !i18n_SetLanguage( g_Conf->LanguageCode ) )
|
if( !i18n_SetLanguage( g_Conf->LanguageId, g_Conf->LanguageCode ) )
|
||||||
{
|
{
|
||||||
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
|
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
|
||||||
{
|
{
|
||||||
i18n_SetLanguage( wxLANGUAGE_ENGLISH );
|
i18n_SetLanguage( wxLANGUAGE_ENGLISH_US );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,7 @@ void Panels::LanguageSelectionPanel::Apply()
|
||||||
if( m_langs[i].englishName == sel )
|
if( m_langs[i].englishName == sel )
|
||||||
{
|
{
|
||||||
g_Conf->LanguageCode = m_langs[i].canonicalName;
|
g_Conf->LanguageCode = m_langs[i].canonicalName;
|
||||||
|
g_Conf->LanguageId = m_langs[i].wxLangId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,32 @@
|
||||||
|
|
||||||
#include "Utilities/SafeArray.h"
|
#include "Utilities/SafeArray.h"
|
||||||
|
|
||||||
|
// Some of the codes provided by wxWidgets are 'obsolete' -- effectively replaced by more specific
|
||||||
|
// region-qualified language codes. This function can be used to filter them out.
|
||||||
|
bool i18n_IsLegacyLanguageId( wxLanguage lang )
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(lang == wxLANGUAGE_ENGLISH) ||
|
||||||
|
(lang == wxLANGUAGE_CHINESE) ||
|
||||||
|
(lang == wxLANGUAGE_CHINESE_TRADITIONAL) ||
|
||||||
|
(lang == wxLANGUAGE_SERBIAN) ||
|
||||||
|
(lang == wxLANGUAGE_SPANISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static wxString i18n_GetBetterLanguageName( const wxLanguageInfo* info )
|
||||||
|
{
|
||||||
|
switch (info->Language)
|
||||||
|
{
|
||||||
|
case wxLANGUAGE_CHINESE: return L"Chinese (Traditional)";
|
||||||
|
case wxLANGUAGE_CHINESE_TRADITIONAL: return L"Chinese (Traditional)";
|
||||||
|
case wxLANGUAGE_CHINESE_TAIWAN: return L"Chinese (Traditional, Taiwan)";
|
||||||
|
case wxLANGUAGE_CHINESE_HONGKONG: return L"Chinese (Traditional, Hong Kong)";
|
||||||
|
case wxLANGUAGE_CHINESE_MACAU: return L"Chinese (Traditional, Macau)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return info->Description;
|
||||||
|
}
|
||||||
|
|
||||||
LangPackEnumeration::LangPackEnumeration( wxLanguage langId )
|
LangPackEnumeration::LangPackEnumeration( wxLanguage langId )
|
||||||
{
|
{
|
||||||
wxLangId = langId;
|
wxLangId = langId;
|
||||||
|
@ -26,7 +52,7 @@ LangPackEnumeration::LangPackEnumeration( wxLanguage langId )
|
||||||
if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( wxLangId ))
|
if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( wxLangId ))
|
||||||
{
|
{
|
||||||
canonicalName = info->CanonicalName;
|
canonicalName = info->CanonicalName;
|
||||||
englishName = info->Description;
|
englishName = i18n_GetBetterLanguageName(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,31 +65,22 @@ LangPackEnumeration::LangPackEnumeration()
|
||||||
int sysLang = wxLocale::GetSystemLanguage();
|
int sysLang = wxLocale::GetSystemLanguage();
|
||||||
|
|
||||||
if (sysLang == wxLANGUAGE_UNKNOWN)
|
if (sysLang == wxLANGUAGE_UNKNOWN)
|
||||||
sysLang = wxLANGUAGE_ENGLISH;
|
sysLang = wxLANGUAGE_ENGLISH_US;
|
||||||
|
|
||||||
if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( sysLang ))
|
if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( sysLang ))
|
||||||
englishName += L" [" + info->Description + L"]";
|
englishName += L" [" + i18n_GetBetterLanguageName(info) + L"]";
|
||||||
}
|
|
||||||
|
|
||||||
// Some of the codes provided by wxWidgets are 'obsolete' -- effectively replaced by more specific
|
|
||||||
// region-qualified language codes. This function can be used to filter them out.
|
|
||||||
bool i18n_IsLegacyLanguageId( wxLanguage lang )
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(lang == wxLANGUAGE_ENGLISH) ||
|
|
||||||
(lang == wxLANGUAGE_CHINESE) ||
|
|
||||||
(lang == wxLANGUAGE_CHINESE_TAIWAN) ||
|
|
||||||
(lang == wxLANGUAGE_SERBIAN) ||
|
|
||||||
(lang == wxLANGUAGE_SPANISH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs )
|
static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs )
|
||||||
{
|
{
|
||||||
if( i18n_IsLegacyLanguageId( wxLangId ) ) return;
|
if( i18n_IsLegacyLanguageId( wxLangId ) ) return;
|
||||||
|
|
||||||
// Note: wx auto-preserves the current locale for us
|
//if( !wxLocale::IsAvailable( wxLangId ) )
|
||||||
if( !wxLocale::IsAvailable( wxLangId ) ) return;
|
// return;
|
||||||
wxLocale* locale = new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING );
|
|
||||||
|
// note: wx preserves the current locale for us, so creating a new locale and deleting
|
||||||
|
// will not affect program status.
|
||||||
|
ScopedPtr<wxLocale> locale( new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING ) );
|
||||||
|
|
||||||
// Force the msgIdLanguage param to wxLANGUAGE_UNKNOWN to disable wx's automatic english
|
// Force the msgIdLanguage param to wxLANGUAGE_UNKNOWN to disable wx's automatic english
|
||||||
// matching logic, which will bypass the catalog loader for all english-based dialects, and
|
// matching logic, which will bypass the catalog loader for all english-based dialects, and
|
||||||
|
@ -71,8 +88,6 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs )
|
||||||
|
|
||||||
if( locale->IsOk() && locale->AddCatalog( L"pcsx2_Main", wxLANGUAGE_UNKNOWN, NULL ) )
|
if( locale->IsOk() && locale->AddCatalog( L"pcsx2_Main", wxLANGUAGE_UNKNOWN, NULL ) )
|
||||||
langs.push_back( LangPackEnumeration( wxLangId ) );
|
langs.push_back( LangPackEnumeration( wxLangId ) );
|
||||||
|
|
||||||
delete locale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
|
// Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
|
||||||
|
@ -111,6 +126,10 @@ void i18n_EnumeratePackages( LangPackList& langs )
|
||||||
//i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
|
//i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// warning: wxWidgets uses duplicated canonical codes for many languages, and has some bizarre
|
||||||
|
// matching heuristics. Using this function doesn't really match the language and sublanguage
|
||||||
|
// (dialect) that the user selected.
|
||||||
bool i18n_SetLanguage( const wxString& langCode )
|
bool i18n_SetLanguage( const wxString& langCode )
|
||||||
{
|
{
|
||||||
if (langCode.IsEmpty() || langCode.CmpNoCase(L"default"))
|
if (langCode.IsEmpty() || langCode.CmpNoCase(L"default"))
|
||||||
|
@ -125,32 +144,64 @@ bool i18n_SetLanguage( const wxString& langCode )
|
||||||
if (!woot) return false;
|
if (!woot) return false;
|
||||||
return i18n_SetLanguage( woot->Language );
|
return i18n_SetLanguage( woot->Language );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool i18n_SetLanguage( int wxLangId )
|
// This method sets the requested language, based on wxLanguage id and an optional 'confirmation'
|
||||||
|
// canonical code. If the canonical code is provided, it is used to confirm that the ID matches
|
||||||
|
// the intended language/dialect. If the ID and canonical do not match, this method will use
|
||||||
|
// wx's FindLAnguageInfo to provide a "best guess" canonical match (usually relying on the user's
|
||||||
|
// operating system default).
|
||||||
|
//
|
||||||
|
// Rationale: wxWidgets language IDs are just simple enums, and not especially unique. Future
|
||||||
|
// versions of PCSX2 may have language ID changes if built against new/different versions of wx.
|
||||||
|
// To prevent PCSX2 from selecting a completely wrong language when upgraded, we double-check
|
||||||
|
// the wxLanguage code against the canonical name. We can't simply use canonical names either
|
||||||
|
// because those are not unique (dialects of chinese, for example), and wx returns the generic
|
||||||
|
// form over a specific dialect, when given a choice. Thus a two-tier check is required.
|
||||||
|
//
|
||||||
|
// wxLanguage for specific dialect, and canonical as a fallback/safeguard in case the wxLanguage
|
||||||
|
// id appears to be out of date.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
bool i18n_SetLanguage( wxLanguage wxLangId, const wxString& langCode )
|
||||||
{
|
{
|
||||||
if( !wxLocale::IsAvailable( wxLangId ) )
|
const wxLanguageInfo* info = wxLocale::GetLanguageInfo(wxLangId);
|
||||||
|
|
||||||
|
// note: language canonical name mismatch probably means wxWidgets version changed since
|
||||||
|
// the user's ini file was provided. Missing/invalid ID probably means the same thing.
|
||||||
|
// If either is true, and the caller provided a canonical name, then let wx do a best
|
||||||
|
// match based on the canonical name.
|
||||||
|
|
||||||
|
if (!info || (!langCode.IsEmpty() && (langCode.CmpNoCase(info->CanonicalName) != 0)))
|
||||||
{
|
{
|
||||||
Console.Warning( "Invalid Language Identifier (wxID=%d).", wxLangId );
|
if (!info)
|
||||||
return false;
|
Console.Warning( "Invalid language identifier (wxID=%d)", wxLangId );
|
||||||
|
|
||||||
|
if (!langCode.IsEmpty())
|
||||||
|
{
|
||||||
|
info = wxLocale::FindLanguageInfo(langCode);
|
||||||
|
if (!info)
|
||||||
|
Console.Warning( "Unrecognized language canonical name '%ls'", langCode.c_str() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedPtr<wxLocale> locale( new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING ) );
|
if (!info) return false;
|
||||||
|
ScopedPtr<wxLocale> locale( new wxLocale(info->Language) );
|
||||||
|
|
||||||
if( !locale->IsOk() )
|
if( !locale->IsOk() )
|
||||||
{
|
{
|
||||||
Console.Warning( L"SetLanguage: '%s' [%s] is not supported by the operating system",
|
Console.Warning( L"SetLanguage: '%s' [%s] is not supported by the operating system",
|
||||||
wxLocale::GetLanguageName( locale->GetLanguage() ).c_str(), locale->GetCanonicalName().c_str()
|
locale->GetLocale(), locale->GetCanonicalName().c_str()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLangId = locale->GetLanguage();
|
wxLangId = (wxLanguage)locale->GetLanguage();
|
||||||
|
|
||||||
if (wxLangId == wxLANGUAGE_UNKNOWN)
|
if (wxLangId == wxLANGUAGE_UNKNOWN)
|
||||||
{
|
{
|
||||||
Console.WriteLn("System-default language is unknown? Defaulting back to English/US.");
|
Console.WriteLn("System-default language is unknown? Defaulting back to English/US.");
|
||||||
wxLangId = wxLANGUAGE_ENGLISH;
|
wxLangId = wxLANGUAGE_ENGLISH_US;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// English/US is built in, so no need to load MO/PO files.
|
// English/US is built in, so no need to load MO/PO files.
|
||||||
|
|
|
@ -35,8 +35,7 @@ public:
|
||||||
|
|
||||||
typedef std::vector<LangPackEnumeration> LangPackList;
|
typedef std::vector<LangPackEnumeration> LangPackList;
|
||||||
|
|
||||||
extern bool i18n_SetLanguage( const wxString& langCode );
|
extern bool i18n_SetLanguage( wxLanguage wxLangId, const wxString& langCode=wxEmptyString );
|
||||||
extern bool i18n_SetLanguage( int wxLangId );
|
|
||||||
extern void i18n_EnumeratePackages( LangPackList& langs );
|
extern void i18n_EnumeratePackages( LangPackList& langs );
|
||||||
extern bool i18n_IsLegacyLanguageId( wxLanguage lang );
|
extern bool i18n_IsLegacyLanguageId( wxLanguage lang );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue