Files
easy7zip/CPP/7zip/UI/FileManager/LangUtils.cpp
Igor Pavlov f08f4dcc3c 9.34
2016-05-28 00:16:51 +01:00

252 lines
5.3 KiB
C++

// LangUtils.cpp
#include "StdAfx.h"
#include "../../../Common/Lang.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Window.h"
#include "LangUtils.h"
#include "RegistryUtils.h"
using namespace NWindows;
#ifndef _UNICODE
extern bool g_IsNT;
#endif
UString g_LangID;
static CLang g_Lang;
static bool g_Loaded = false;
static NSynchronization::CCriticalSection g_CriticalSection;
bool LangOpen(CLang &lang, CFSTR fileName)
{
return lang.Open(fileName, L"7-Zip");
}
FString GetLangDirPrefix()
{
return NDLL::GetModuleDirPrefix() + FTEXT("Lang") FSTRING_PATH_SEPARATOR;
}
void LoadLangOneTime()
{
NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
if (g_Loaded)
return;
g_Loaded = true;
ReloadLang();
}
void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID)
{
const wchar_t *s = g_Lang.Get(langID);
if (s)
{
CWindow window(GetDlgItem(dialog, controlID));
window.SetText(s);
}
}
static const CIDLangPair kLangPairs[] =
{
{ IDOK, 401 },
{ IDCANCEL, 402 },
{ IDYES, 406 },
{ IDNO, 407 },
{ IDHELP, 409 }
};
void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(kLangPairs); i++)
{
const CIDLangPair &pair = kLangPairs[i];
CWindow window(GetDlgItem(dialog, pair.ControlID));
if (window)
{
const wchar_t *s = g_Lang.Get(pair.LangID);
if (s)
window.SetText(s);
}
}
for (i = 0; i < numItems; i++)
{
UInt32 id = ids[i];
LangSetDlgItemText(dialog, id, id);
}
}
void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems)
{
for (unsigned i = 0; i < numItems; i++)
{
UInt32 id = ids[i];
const wchar_t *s = g_Lang.Get(id);
if (s)
{
CWindow window(GetDlgItem(dialog, id));
UString s2 = s;
s2 += L':';
window.SetText(s2);
}
}
}
void LangSetWindowText(HWND window, UInt32 langID)
{
const wchar_t *s = g_Lang.Get(langID);
if (s)
MySetWindowText(window, s);
}
UString LangString(UInt32 langID)
{
const wchar_t *s = g_Lang.Get(langID);
if (s)
return s;
return MyLoadString(langID);
}
void LangString(UInt32 langID, UString &dest)
{
const wchar_t *s = g_Lang.Get(langID);
if (s)
{
dest = s;
return;
}
MyLoadString(langID, dest);
}
void LangString_OnlyFromLangFile(UInt32 langID, UString &dest)
{
dest.Empty();
const wchar_t *s = g_Lang.Get(langID);
if (s)
dest = s;
}
static const char *kLangs =
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is.it.ja.ko.nl.no.=nb.=nn."
"pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr.ur.id.uk.be.sl.et.lv.lt.tg."
"fa.vi.hy.az.eu.hsb.mk...tn..xh.zu.af.ka.fo.hi.mt.se.ga."
".ms.kk.ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa.mn.=mn.=mng"
"bo.cy.kh.lo..gl.kok..sd.syr.si..iu.am.tzm.ks.ne.fy.ps.fil."
"dv...ha..yo.quz.nso.ba.lb.kl.ig...ti.....ii."
".arn..moh..br..ug.mi.oc.co.gsw.sah.qut.rw.wo....prs.";
static void FindShortNames(UInt32 primeLang, UStringVector &names)
{
UInt32 index = 0;
for (const char *p = kLangs; *p != 0;)
{
const char *p2 = p;
for (; *p2 != '.'; p2++);
bool isSub = (p[0] == '-' || p[0] == '=');
if (!isSub)
index++;
if (index > primeLang)
break;
if (index == primeLang)
{
UString s;
if (isSub)
{
if (p[0] == '-')
s = names[0];
else
p++;
}
while (p != p2)
s += (wchar_t)*p++;
names.Add(s);
}
p = p2 + 1;
}
}
// typedef LANGID (WINAPI *GetUserDefaultUILanguageP)();
static void OpenDefaultLang()
{
LANGID sysLang = GetSystemDefaultLangID(); // "Language for non-Unicode programs" in XP64
LANGID userLang = GetUserDefaultLangID(); // "Standards and formats" language in XP64
if (sysLang != userLang)
return;
LANGID langID = userLang;
/*
LANGID sysUILang; // english in XP64
LANGID userUILang; // english in XP64
GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress(
GetModuleHandle("kernel32"), "GetUserDefaultUILanguage");
if (fn)
userUILang = fn();
fn = (GetUserDefaultUILanguageP)GetProcAddress(
GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage");
if (fn)
sysUILang = fn();
*/
WORD primLang = (WORD)(PRIMARYLANGID(langID));
WORD subLang = (WORD)(SUBLANGID(langID));
{
UStringVector names;
FindShortNames(primLang, names);
const FString dirPrefix = GetLangDirPrefix();
for (unsigned i = 0; i < 2; i++)
{
unsigned index = (i == 0 ? subLang : 0);
if (index < names.Size())
{
const UString &name = names[index];
if (!name.IsEmpty())
{
if (LangOpen(g_Lang, dirPrefix + us2fs(name) + FTEXT(".txt")))
{
g_LangID = name;
return;
}
}
}
}
}
}
void ReloadLang()
{
g_Lang.Clear();
ReadRegLang(g_LangID);
#ifndef _UNICODE
if (g_IsNT)
#endif
{
if (g_LangID.IsEmpty())
{
OpenDefaultLang();
return;
}
}
if (g_LangID.Len() > 1 || g_LangID[0] != L'-')
{
FString s = us2fs(g_LangID);
if (s.Find(FCHAR_PATH_SEPARATOR) < 0)
{
if (s.Find(FTEXT('.')) < 0)
s += FTEXT(".txt");
s.Insert(0, GetLangDirPrefix());
}
LangOpen(g_Lang, s);
}
}