/[pcsx2_0.9.7]/trunk/pcsx2/gui/i18n.cpp
ViewVC logotype

Contents of /trunk/pcsx2/gui/i18n.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File size: 9390 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "i18n.h"
18 #include "AppConfig.h"
19
20 #include "Utilities/SafeArray.h"
21
22 // Some of the codes provided by wxWidgets are 'obsolete' -- effectively replaced by more specific
23 // region-qualified language codes. This function can be used to filter them out.
24 bool i18n_IsLegacyLanguageId( wxLanguage lang )
25 {
26 return
27 (lang == wxLANGUAGE_ENGLISH) ||
28 (lang == wxLANGUAGE_CHINESE) ||
29 (lang == wxLANGUAGE_CHINESE_TRADITIONAL) ||
30 (lang == wxLANGUAGE_SERBIAN) ||
31 (lang == wxLANGUAGE_SPANISH);
32 }
33
34 static wxString i18n_GetBetterLanguageName( const wxLanguageInfo* info )
35 {
36 switch (info->Language)
37 {
38 case wxLANGUAGE_CHINESE: return L"Chinese (Traditional)";
39 case wxLANGUAGE_CHINESE_TRADITIONAL: return L"Chinese (Traditional)";
40 case wxLANGUAGE_CHINESE_TAIWAN: return L"Chinese (Traditional, Taiwan)";
41 case wxLANGUAGE_CHINESE_HONGKONG: return L"Chinese (Traditional, Hong Kong)";
42 case wxLANGUAGE_CHINESE_MACAU: return L"Chinese (Traditional, Macau)";
43 }
44
45 return info->Description;
46 }
47
48 LangPackEnumeration::LangPackEnumeration( wxLanguage langId )
49 {
50 wxLangId = langId;
51
52 if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( wxLangId ))
53 {
54 canonicalName = info->CanonicalName;
55 englishName = i18n_GetBetterLanguageName(info);
56 }
57 }
58
59 LangPackEnumeration::LangPackEnumeration()
60 {
61 wxLangId = wxLANGUAGE_DEFAULT;
62 englishName = L" System Default"; // left-side space forces it to sort to the front of the lists
63 canonicalName = L"default";
64
65 int sysLang = wxLocale::GetSystemLanguage();
66
67 if (sysLang == wxLANGUAGE_UNKNOWN)
68 sysLang = wxLANGUAGE_ENGLISH_US;
69
70 //if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( sysLang ))
71 // englishName += L" [" + i18n_GetBetterLanguageName(info) + L"]";
72 }
73
74 static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs )
75 {
76 if( i18n_IsLegacyLanguageId( wxLangId ) ) return;
77
78 // note: wx preserves the current locale for us, so creating a new locale and deleting
79 // will not affect program status.
80 ScopedPtr<wxLocale> locale( new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING ) );
81
82 // Force the msgIdLanguage param to wxLANGUAGE_UNKNOWN to disable wx's automatic english
83 // matching logic, which will bypass the catalog loader for all english-based dialects, and
84 // (wrongly) enumerate a bunch of locales that don't actually exist.
85
86 if ((locale->GetLanguage() == wxLANGUAGE_ENGLISH_US) ||
87 (locale->IsOk() && locale->AddCatalog( L"pcsx2_Main", wxLANGUAGE_UNKNOWN, NULL )) )
88 langs.push_back( LangPackEnumeration( wxLangId ) );
89 }
90
91 // Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
92 // Note: On linux there's no easy way to reliably enumerate language packs, since every distro
93 // could use its own location for installing pcsx2.mo files (wtcrap?). Furthermore wxWidgets
94 // doesn't give us a public API for checking what the language search paths are. So the only
95 // safe way to enumerate the languages is by forcibly loading every possible locale in the wx
96 // database. Anything which hasn't been installed will fail to load.
97 //
98 // Because loading and hashing the entire pcsx2 translation for every possible language would be
99 // asinine and slow, I've decided to use a file dedicated to being a translation detection anchor.
100 // This file is named pcsx2ident.mo, and contains only the name of the language in the language
101 // native form. Additional translation files are only loaded if the user picks the language (or
102 // if it's the default language of the user's OS installation).
103 //
104 void i18n_EnumeratePackages( LangPackList& langs )
105 {
106 wxDoNotLogInThisScope here; // wx generates verbose errors if languages don't exist, so disable them here.
107 langs.push_back( LangPackEnumeration() );
108
109 for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li )
110 {
111 i18n_DoPackageCheck( (wxLanguage)li, langs );
112 }
113
114 // Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED
115 // to a place where it wasn't butt right up against the main languages (like, say, start user
116 // defined values at 4000 or something?), they had to add new languages in at some arbitrary
117 // value instead. Let's handle them here:
118 // fixme: these won't show up in alphabetical order if they're actually present (however
119 // horribly unlikely that is)... do we care? Probably not.
120
121 // Note: These aren't even available in some packaged Linux distros anyway. >_<
122
123 //i18n_DoPackageCheck( wxLANGUAGE_VALENCIAN, englishNames, xlatedNames );
124 //i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
125 }
126
127 #if 0
128 // warning: wxWidgets uses duplicated canonical codes for many languages, and has some bizarre
129 // matching heuristics. Using this function doesn't really match the language and sublanguage
130 // (dialect) that the user selected.
131 bool i18n_SetLanguage( const wxString& langCode )
132 {
133 if (langCode.IsEmpty() || langCode.CmpNoCase(L"default"))
134 {
135 wxLanguage sysLang = (wxLanguage)wxLocale::GetSystemLanguage();
136
137 if (sysLang == wxLANGUAGE_UNKNOWN)
138 sysLang = wxLANGUAGE_ENGLISH;
139 }
140
141 const wxLanguageInfo* woot = wxLocale::FindLanguageInfo( langCode );
142 if (!woot) return false;
143 return i18n_SetLanguage( woot->Language );
144 }
145 #endif
146
147 // This method sets the requested language, based on wxLanguage id and an optional 'confirmation'
148 // canonical code. If the canonical code is provided, it is used to confirm that the ID matches
149 // the intended language/dialect. If the ID and canonical do not match, this method will use
150 // wx's FindLAnguageInfo to provide a "best guess" canonical match (usually relying on the user's
151 // operating system default).
152 //
153 // Rationale: wxWidgets language IDs are just simple enums, and not especially unique. Future
154 // versions of PCSX2 may have language ID changes if built against new/different versions of wx.
155 // To prevent PCSX2 from selecting a completely wrong language when upgraded, we double-check
156 // the wxLanguage code against the canonical name. We can't simply use canonical names either
157 // because those are not unique (dialects of chinese, for example), and wx returns the generic
158 // form over a specific dialect, when given a choice. Thus a two-tier check is required.
159 //
160 // wxLanguage for specific dialect, and canonical as a fallback/safeguard in case the wxLanguage
161 // id appears to be out of date.
162 //
163 //
164 bool i18n_SetLanguage( wxLanguage wxLangId, const wxString& langCode )
165 {
166 const wxLanguageInfo* info = wxLocale::GetLanguageInfo(wxLangId);
167
168 // note: language canonical name mismatch probably means wxWidgets version changed since
169 // the user's ini file was provided. Missing/invalid ID probably means the same thing.
170 // If either is true, and the caller provided a canonical name, then let wx do a best
171 // match based on the canonical name.
172
173 if (!info || (!langCode.IsEmpty() && (langCode.CmpNoCase(info->CanonicalName) != 0)))
174 {
175 if (!info)
176 Console.Warning( "Invalid language identifier (wxID=%d)", wxLangId );
177
178 if (!langCode.IsEmpty() && (langCode.CmpNoCase(L"default")!=0))
179 {
180 info = wxLocale::FindLanguageInfo(langCode);
181 if (!info)
182 Console.Warning( "Unrecognized language canonical name '%ls'", langCode.c_str() );
183 }
184 }
185
186 if (!info) return false;
187 if (wxGetLocale() && (info->Language == wxGetLocale()->GetLanguage())) return true;
188
189 ScopedPtr<wxLocale> locale( new wxLocale(info->Language) );
190
191 if( !locale->IsOk() )
192 {
193 Console.Warning( L"SetLanguage: '%s' [%s] is not supported by the operating system",
194 i18n_GetBetterLanguageName(info).c_str(), locale->GetCanonicalName().c_str()
195 );
196 return false;
197 }
198
199 wxLangId = (wxLanguage)locale->GetLanguage();
200
201 if (wxLangId == wxLANGUAGE_UNKNOWN)
202 {
203 Console.WriteLn("System-default language is unknown? Defaulting back to English/US.");
204 wxLangId = wxLANGUAGE_ENGLISH_US;
205 }
206
207 // English/US is built in, so no need to load MO/PO files.
208 if( pxIsEnglish(wxLangId) )
209 {
210 locale.DetachPtr();
211 return true;
212 }
213
214 Console.WriteLn( L"Loading language translation databases for '%s' [%s]",
215 i18n_GetBetterLanguageName(info).c_str(), locale->GetCanonicalName().c_str()
216 );
217
218 static const wxChar* dictFiles[] =
219 {
220 L"pcsx2_Main",
221 L"pcsx2_Iconized",
222 L"pcsx2_Tertiary"
223 };
224
225 bool foundone = false;
226 for (uint i=0; i<ArraySize(dictFiles); ++i)
227 {
228 if (!dictFiles[i]) continue;
229
230 if (!locale->AddCatalog(dictFiles[i]))
231 Console.Indent().WriteLn(Color_StrongYellow, "%ls not found -- translation dictionary may be incomplete.", dictFiles[i]);
232 else
233 foundone = true;
234 }
235
236 if (!foundone)
237 {
238 Console.Warning("SetLanguage: Requested translation is not implemented yet.");
239 return false;
240 }
241
242 locale.DetachPtr();
243 return true;
244 }

  ViewVC Help
Powered by ViewVC 1.1.22