OnlineLibrary

Форк
0
125 строк · 2.7 Кб
1
package lang
2

3
import (
4
	"errors"
5
	"os"
6
	"path/filepath"
7
	"unsafe"
8

9
	"OnlineLibrary/internal/config"
10
	"github.com/leonelquinteros/gotext"
11
	"golang.org/x/sys/windows"
12
)
13

14
const (
15
	LOCALE_SNATIVELANGUAGENAME = 0x00000004
16
)
17

18
var kernel32 = windows.NewLazySystemDLL("kernel32.dll")
19

20
var (
21
	procGetUserDefaultUILanguage = kernel32.NewProc("GetUserDefaultUILanguage")
22
	procGetLocaleInfoW           = kernel32.NewProc("GetLocaleInfoW")
23
	procLocaleNameToLCID         = kernel32.NewProc("LocaleNameToLCID")
24
	procLCIDToLocaleName         = kernel32.NewProc("LCIDToLocaleName")
25
)
26

27
type Language struct {
28
	ID          string
29
	Description string
30
}
31

32
type LCID uint
33

34
func GetUserDefaultUILanguage() LCID {
35
	lcid, _, _ := procGetUserDefaultUILanguage.Call()
36
	return LCID(lcid)
37
}
38

39
func GetLocaleDescription(lcid LCID) (string, error) {
40
	buf := make([]uint16, 1024)
41
	r, _, _ := procGetLocaleInfoW.Call(uintptr(lcid), LOCALE_SNATIVELANGUAGENAME, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
42
	if r == 0 {
43
		return "", errors.New("invalid lcid")
44
	}
45
	return windows.UTF16ToString(buf), nil
46
}
47

48
func LocaleNameToLCID(localeName string) (LCID, error) {
49
	buf, err := windows.UTF16FromString(localeName)
50
	if err != nil {
51
		return 0, err
52
	}
53
	lcid, _, _ := procLocaleNameToLCID.Call(uintptr(unsafe.Pointer(&buf[0])), 0)
54
	if lcid == 0 {
55
		return 0, errors.New("invalid locale name")
56
	}
57
	return LCID(lcid), nil
58
}
59

60
func LCIDToLocaleName(lcid LCID) (string, error) {
61
	buf := make([]uint16, 128)
62
	r, _, _ := procLCIDToLocaleName.Call(uintptr(lcid), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
63
	if r == 0 {
64
		return "", errors.New("invalid lcid")
65
	}
66
	return windows.UTF16ToString(buf), nil
67
}
68

69
func availableLanguages(lib string) []Language {
70
	langs := make([]Language, 0)
71
	path, err := filepath.Abs(lib)
72
	if err != nil {
73
		return langs
74
	}
75

76
	entrys, err := os.ReadDir(path)
77
	if err != nil {
78
		return langs
79
	}
80

81
	locales := []string{"en"}
82
	for _, e := range entrys {
83
		if e.IsDir() && e.Name() != "en" {
84
			locales = append(locales, e.Name())
85
		}
86
	}
87

88
	for _, locale := range locales {
89
		lcid, err := LocaleNameToLCID(locale)
90
		if err != nil {
91
			continue
92
		}
93
		description, err := GetLocaleDescription(lcid)
94
		if err != nil {
95
			continue
96
		}
97
		l := Language{ID: locale, Description: description}
98
		langs = append(langs, l)
99
	}
100
	return langs
101
}
102

103
func Init(lang string) ([]Language, bool) {
104
	lib := "locale"
105
	langs := availableLanguages(lib)
106

107
	langIsAvailable := false
108
	for _, l := range langs {
109
		if lang == l.ID {
110
			langIsAvailable = true
111
			break
112
		}
113
	}
114

115
	if !langIsAvailable {
116
		lang = "en"
117
		lcid := GetUserDefaultUILanguage()
118
		if locale, err := LCIDToLocaleName(lcid); err == nil {
119
			lang = locale
120
		}
121
	}
122

123
	gotext.Configure(lib, lang, config.ProgramName)
124
	return langs, langIsAvailable
125
}
126

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.