Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / UI / FileManager / LangUtils.cpp
1 // LangUtils.cpp\r
2 \r
3 #include "StdAfx.h"\r
4 \r
5 #include "LangUtils.h"\r
6 #include "Common/StringConvert.h"\r
7 #include "Common/StringToInt.h"\r
8 #include "Windows/Synchronization.h"\r
9 #include "Windows/Window.h"\r
10 #include "Windows/FileFind.h"\r
11 #include "RegistryUtils.h"\r
12 #include "ProgramLocation.h"\r
13 \r
14 using namespace NWindows;\r
15 \r
16 static CLang g_Lang;\r
17 UString g_LangID;\r
18 \r
19 #ifndef _UNICODE\r
20 extern bool g_IsNT;\r
21 #endif\r
22 \r
23 void ReloadLang()\r
24 {\r
25   ReadRegLang(g_LangID);\r
26   g_Lang.Clear();\r
27   if (!g_LangID.IsEmpty() && g_LangID != L"-")\r
28   {\r
29     UString langPath = g_LangID;\r
30     if (langPath.Find(WCHAR_PATH_SEPARATOR) < 0)\r
31     {\r
32       if (langPath.Find(L'.') < 0)\r
33         langPath += L".txt";\r
34       UString folderPath;\r
35       if (GetProgramFolderPath(folderPath))\r
36         langPath = folderPath + UString(L"Lang" WSTRING_PATH_SEPARATOR) + langPath;\r
37     }\r
38     g_Lang.Open(langPath);\r
39   }\r
40 }\r
41 \r
42 static bool g_Loaded = false;\r
43 static NSynchronization::CCriticalSection g_CriticalSection;\r
44 \r
45 void LoadLangOneTime()\r
46 {\r
47   NSynchronization::CCriticalSectionLock lock(g_CriticalSection);\r
48   if (g_Loaded)\r
49     return;\r
50   g_Loaded = true;\r
51   ReloadLang();\r
52 }\r
53 \r
54 void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems)\r
55 {\r
56   for (int i = 0; i < numItems; i++)\r
57   {\r
58     const CIDLangPair &idLangPair = idLangPairs[i];\r
59     UString message;\r
60     if (g_Lang.GetMessage(idLangPair.LangID, message))\r
61     {\r
62       NWindows::CWindow window(GetDlgItem(dialogWindow, idLangPair.ControlID));\r
63       window.SetText(message);\r
64     }\r
65   }\r
66 }\r
67 \r
68 void LangSetWindowText(HWND window, UInt32 langID)\r
69 {\r
70   UString message;\r
71   if (g_Lang.GetMessage(langID, message))\r
72     MySetWindowText(window, message);\r
73 }\r
74 \r
75 UString LangString(UInt32 langID)\r
76 {\r
77   UString message;\r
78   if (g_Lang.GetMessage(langID, message))\r
79     return message;\r
80   return UString();\r
81 }\r
82 \r
83 UString LangString(UINT resourceID, UInt32 langID)\r
84 {\r
85   UString message;\r
86   if (g_Lang.GetMessage(langID, message))\r
87     return message;\r
88   return NWindows::MyLoadStringW(resourceID);\r
89 }\r
90 \r
91 void LoadLangs(CObjectVector<CLangEx> &langs)\r
92 {\r
93   langs.Clear();\r
94   UString folderPath;\r
95   if (!::GetProgramFolderPath(folderPath))\r
96     return;\r
97   folderPath += L"Lang" WSTRING_PATH_SEPARATOR;\r
98   NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt");\r
99   NWindows::NFile::NFind::CFileInfoW fileInfo;\r
100   while (enumerator.Next(fileInfo))\r
101   {\r
102     if (fileInfo.IsDir())\r
103       continue;\r
104     CLangEx lang;\r
105     UString filePath = folderPath + fileInfo.Name;\r
106     const int kExtSize = 4;\r
107     const UString ext = fileInfo.Name.Right(kExtSize);\r
108     if (ext.CompareNoCase(L".txt") != 0)\r
109       continue;\r
110     lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize);\r
111     if (lang.Lang.Open(filePath))\r
112       langs.Add(lang);\r
113   }\r
114 }\r
115 \r
116 bool SplidID(const UString &id, WORD &primID, WORD &subID)\r
117 {\r
118   primID = 0;\r
119   subID = 0;\r
120   const wchar_t *start = id;\r
121   const wchar_t *end;\r
122   UInt64 value = ConvertStringToUInt64(start, &end);\r
123   if (start == end)\r
124     return false;\r
125   primID = (WORD)value;\r
126   if (*end == 0)\r
127     return true;\r
128   if (*end != L'-')\r
129     return false;\r
130   start = end + 1;\r
131   value = ConvertStringToUInt64(start, &end);\r
132   if (start == end)\r
133     return false;\r
134   subID = (WORD)value;\r
135   return (*end == 0);\r
136 }\r
137 \r
138 typedef LANGID (WINAPI *GetUserDefaultUILanguageP)();\r
139 \r
140 void FindMatchLang(UString &shortName)\r
141 {\r
142   shortName.Empty();\r
143 \r
144   LANGID SystemDefaultLangID = GetSystemDefaultLangID(); // Lang for non-Unicode in XP64\r
145   LANGID UserDefaultLangID = GetUserDefaultLangID(); // Standarts and formats in XP64\r
146 \r
147   if (SystemDefaultLangID != UserDefaultLangID)\r
148     return;\r
149   LANGID langID = UserDefaultLangID;\r
150   /*\r
151   LANGID SystemDefaultUILanguage; // english  in XP64\r
152   LANGID UserDefaultUILanguage; // english  in XP64\r
153 \r
154   GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress(\r
155       GetModuleHandle("kernel32"), "GetUserDefaultUILanguage");\r
156   if (fn != NULL)\r
157     UserDefaultUILanguage = fn();\r
158   fn = (GetUserDefaultUILanguageP)GetProcAddress(\r
159       GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage");\r
160   if (fn != NULL)\r
161     SystemDefaultUILanguage = fn();\r
162   */\r
163 \r
164   WORD primLang = (WORD)(PRIMARYLANGID(langID));\r
165   WORD subLang = (WORD)(SUBLANGID(langID));\r
166   CObjectVector<CLangEx> langs;\r
167   LoadLangs(langs);\r
168   for (int i = 0; i < langs.Size(); i++)\r
169   {\r
170     const CLangEx &lang = langs[i];\r
171     UString id;\r
172     if (lang.Lang.GetMessage(0x00000002, id))\r
173     {\r
174       WORD primID;\r
175       WORD subID;\r
176       if (SplidID(id, primID, subID))\r
177         if (primID == primLang)\r
178         {\r
179           if (subID == 0)\r
180             shortName = lang.ShortName;\r
181           if (subLang == subID)\r
182           {\r
183             shortName = lang.ShortName;\r
184             return;\r
185           }\r
186         }\r
187     }\r
188   }\r
189 }\r
190 \r
191 void ReloadLangSmart()\r
192 {\r
193   #ifndef _UNICODE\r
194   if (g_IsNT)\r
195   #endif\r
196   {\r
197     ReadRegLang(g_LangID);\r
198     if (g_LangID.IsEmpty())\r
199     {\r
200       UString shortName;\r
201       FindMatchLang(shortName);\r
202       if (shortName.IsEmpty())\r
203         shortName = L"-";\r
204       SaveRegLang(shortName);\r
205     }\r
206   }\r
207   ReloadLang();\r
208 }\r