xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/LangPage.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // LangPage.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/Lang.h"
6 
7 #include "../../../Windows/FileFind.h"
8 #include "../../../Windows/ResourceString.h"
9 
10 #include "HelpUtils.h"
11 #include "LangPage.h"
12 #include "LangPageRes.h"
13 #include "LangUtils.h"
14 #include "RegistryUtils.h"
15 
16 using namespace NWindows;
17 
18 
19 static const unsigned k_NumLangLines_EN = 443;
20 
21 #ifdef Z7_LANG
22 static const UInt32 kLangIDs[] =
23 {
24   IDT_LANG_LANG
25 };
26 #endif
27 
28 #define kLangTopic "fm/options.htm#language"
29 
30 
31 struct CLangListRecord
32 {
33   int Order;
34   unsigned LangInfoIndex;
35   bool IsSelected;
36   UString Mark;
37   UString Name;
38 
CLangListRecordCLangListRecord39   CLangListRecord(): Order (10), IsSelected(false) {}
CompareCLangListRecord40   int Compare(const CLangListRecord &a) const
41   {
42     if (Order < a.Order) return -1;
43     if (Order > a.Order) return 1;
44     return MyStringCompareNoCase(Name, a.Name);
45   }
46 };
47 
48 
NativeLangString(UString & dest,const wchar_t * s)49 static void NativeLangString(UString &dest, const wchar_t *s)
50 {
51   dest += " (";
52   dest += s;
53   dest.Add_Char(')');
54 }
55 
56 bool LangOpen(CLang &lang, CFSTR fileName);
57 
OnInit()58 bool CLangPage::OnInit()
59 {
60 #ifdef Z7_LANG
61   LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
62 #endif
63   _langCombo.Attach(GetItem(IDC_LANG_LANG));
64 
65 
66   unsigned listRecords_SelectedIndex = 0;
67 
68   CObjectVector<CLangListRecord> listRecords;
69   {
70     CLangListRecord listRecord;
71     listRecord.Order = 0;
72     listRecord.Mark = "---";
73     listRecord.Name = MyLoadString(IDS_LANG_ENGLISH);
74     NativeLangString(listRecord.Name, MyLoadString(IDS_LANG_NATIVE));
75     listRecord.LangInfoIndex = _langs.Size();
76     listRecords.Add(listRecord);
77   }
78 
79   AStringVector names;
80   unsigned subLangIndex = 0;
81   Lang_GetShortNames_for_DefaultLang(names, subLangIndex);
82 
83   const FString dirPrefix = GetLangDirPrefix();
84   NFile::NFind::CEnumerator enumerator;
85   enumerator.SetDirPrefix(dirPrefix);
86   NFile::NFind::CFileInfo fi;
87 
88   CLang lang_en;
89   {
90     CLangInfo &langInfo = _langs.AddNew();
91     langInfo.Name = "-";
92     if (LangOpen(lang_en, dirPrefix + FTEXT("en.ttt")))
93     {
94       langInfo.NumLines = lang_en._ids.Size();
95       // langInfo.Comments = lang_en.Comments;
96     }
97     else
98       langInfo.NumLines = k_NumLangLines_EN;
99     NumLangLines_EN = langInfo.NumLines;
100   }
101 
102   CLang lang;
103   UString error;
104   UString n;
105 
106   while (enumerator.Next(fi))
107   {
108     if (fi.IsDir())
109       continue;
110     const unsigned kExtSize = 4;
111     if (fi.Name.Len() < kExtSize)
112       continue;
113     const unsigned pos = fi.Name.Len() - kExtSize;
114     if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".txt"))
115     {
116       // if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".ttt"))
117       continue;
118     }
119 
120     if (!LangOpen(lang, dirPrefix + fi.Name))
121     {
122       error.Add_Space_if_NotEmpty();
123       error += fs2us(fi.Name);
124       continue;
125     }
126 
127     const UString shortName = fs2us(fi.Name.Left(pos));
128 
129     CLangListRecord listRecord;
130     if (!names.IsEmpty())
131     {
132       for (unsigned i = 0; i < names.Size(); i++)
133         if (shortName.IsEqualTo_Ascii_NoCase(names[i]))
134         {
135           if (subLangIndex == i || names.Size() == 1)
136           {
137             listRecord.Mark = "***";
138             // listRecord.Order = 1;
139           }
140           else
141           {
142             listRecord.Mark = "+++";
143             // listRecord.Order = 2;
144           }
145           break;
146         }
147       if (listRecord.Mark.IsEmpty())
148       {
149         const int minusPos = shortName.Find(L'-');
150         if (minusPos >= 0)
151         {
152           const UString shortName2 = shortName.Left(minusPos);
153           if (shortName2.IsEqualTo_Ascii_NoCase(names[0]))
154           {
155             listRecord.Mark = "+++";
156             // listRecord.Order = 3;
157           }
158         }
159       }
160     }
161     UString s = shortName;
162     const wchar_t *eng = lang.Get(IDS_LANG_ENGLISH);
163     if (eng)
164       s = eng;
165     const wchar_t *native = lang.Get(IDS_LANG_NATIVE);
166     if (native)
167       NativeLangString(s, native);
168 
169     listRecord.Name = s;
170     listRecord.LangInfoIndex = _langs.Size();
171     listRecords.Add(listRecord);
172     if (g_LangID.IsEqualTo_NoCase(shortName))
173       listRecords_SelectedIndex = listRecords.Size() - 1;
174 
175     CLangInfo &langInfo = _langs.AddNew();
176     langInfo.Comments = lang.Comments;
177     langInfo.Name = shortName;
178     unsigned numLines = lang._ids.Size();
179     if (!lang_en.IsEmpty())
180     {
181       numLines = 0;
182       unsigned i1 = 0;
183       unsigned i2 = 0;
184       for (;;)
185       {
186         UInt32 id1 = (UInt32)0 - 1;
187         UInt32 id2 = (UInt32)0 - 1;
188         bool id1_defined = false;
189         bool id2_defined = false;
190         if (i1 < lang_en._ids.Size())
191         {
192           id1 = lang_en._ids[i1];
193           id1_defined = true;
194         }
195         if (i2 < lang._ids.Size())
196         {
197           id2 = lang._ids[i2];
198           id2_defined = true;
199         }
200 
201         bool id1_is_smaller = true;
202         if (id1_defined)
203         {
204           if (id2_defined)
205           {
206             if (id1 == id2)
207             {
208               i1++;
209               i2++;
210               numLines++;
211               continue;
212             }
213             if (id1 > id2)
214               id1_is_smaller = false;
215           }
216         }
217         else if (!id2_defined)
218           break;
219         else
220           id1_is_smaller = false;
221 
222         n.Empty();
223         if (id1_is_smaller)
224         {
225           n.Add_UInt32(id1);
226           n += " : ";
227           n += lang_en.Get_by_index(i1);
228           langInfo.MissingLines.Add(n);
229           i1++;
230         }
231         else
232         {
233           n.Add_UInt32(id2);
234           n += " : ";
235           n += lang.Get_by_index(i2);
236           langInfo.ExtraLines.Add(n);
237           i2++;
238         }
239       }
240     }
241     langInfo.NumLines = numLines + langInfo.ExtraLines.Size();
242   }
243 
244   listRecords[listRecords_SelectedIndex].IsSelected = true;
245 
246   listRecords.Sort();
247   FOR_VECTOR (i, listRecords)
248   {
249     const CLangListRecord &rec= listRecords[i];
250     UString temp = rec.Name;
251     if (!rec.Mark.IsEmpty())
252     {
253       temp += "  ";
254       temp += rec.Mark;
255     }
256     const int index = (int)_langCombo.AddString(temp);
257     _langCombo.SetItemData(index, (LPARAM)rec.LangInfoIndex);
258     if (rec.IsSelected)
259       _langCombo.SetCurSel(index);
260   }
261 
262   ShowLangInfo();
263 
264   if (!error.IsEmpty())
265     MessageBoxW(NULL, error, L"Error in Lang file", MB_ICONERROR);
266   return CPropertyPage::OnInit();
267 }
268 
OnApply()269 LONG CLangPage::OnApply()
270 {
271   if (_needSave)
272   {
273     const int pathIndex = (int)_langCombo.GetItemData_of_CurSel();
274     if ((unsigned)pathIndex < _langs.Size())
275       SaveRegLang(_langs[pathIndex].Name);
276   }
277   _needSave = false;
278   #ifdef Z7_LANG
279   ReloadLang();
280   #endif
281   LangWasChanged = true;
282   return PSNRET_NOERROR;
283 }
284 
OnNotifyHelp()285 void CLangPage::OnNotifyHelp()
286 {
287   ShowHelpWindow(kLangTopic);
288 }
289 
OnCommand(unsigned code,unsigned itemID,LPARAM param)290 bool CLangPage::OnCommand(unsigned code, unsigned itemID, LPARAM param)
291 {
292   if (code == CBN_SELCHANGE && itemID == IDC_LANG_LANG)
293   {
294     _needSave = true;
295     Changed();
296     ShowLangInfo();
297     return true;
298   }
299   return CPropertyPage::OnCommand(code, itemID, param);
300 }
301 
AddVectorToString(UString & s,const UStringVector & v)302 static void AddVectorToString(UString &s, const UStringVector &v)
303 {
304   UString a;
305   FOR_VECTOR (i, v)
306   {
307     if (i >= 50)
308       break;
309     a = v[i];
310     if (a.Len() > 1500)
311       continue;
312     if (a[0] == ';')
313     {
314       a.DeleteFrontal(1);
315       a.Trim();
316     }
317     s += a;
318     s.Add_LF();
319   }
320 }
321 
AddVectorToString2(UString & s,const char * name,const UStringVector & v)322 static void AddVectorToString2(UString &s, const char *name, const UStringVector &v)
323 {
324   if (v.IsEmpty())
325     return;
326   s.Add_LF();
327   s += "------ ";
328   s += name;
329   s += ": ";
330   s.Add_UInt32(v.Size());
331   s += " :";
332   s.Add_LF();
333   AddVectorToString(s, v);
334 }
335 
ShowLangInfo()336 void CLangPage::ShowLangInfo()
337 {
338   UString s;
339   const int pathIndex = (int)_langCombo.GetItemData_of_CurSel();
340   if ((unsigned)pathIndex < _langs.Size())
341   {
342     const CLangInfo &langInfo = _langs[pathIndex];
343     const unsigned numLines = langInfo.NumLines;
344     s += langInfo.Name;
345     s += " : ";
346     s.Add_UInt32(numLines);
347     if (NumLangLines_EN != 0)
348     {
349       s += " / ";
350       s.Add_UInt32(NumLangLines_EN);
351       s += " = ";
352       s.Add_UInt32(numLines * 100 / NumLangLines_EN);
353       s += "%";
354     }
355     s.Add_LF();
356     AddVectorToString(s, langInfo.Comments);
357     AddVectorToString2(s, "Missing lines", langInfo.MissingLines);
358     AddVectorToString2(s, "Extra lines", langInfo.ExtraLines);
359   }
360   SetItemText(IDT_LANG_INFO, s);
361 }
362