LenovoLegionToolkit

Форк
0
177 строк · 5.1 Кб
1
using System;
2
using System.Globalization;
3
using System.IO;
4
using System.Linq;
5
using System.Runtime.InteropServices;
6
using System.Threading;
7
using System.Threading.Tasks;
8
using System.Windows;
9
using Humanizer;
10
using LenovoLegionToolkit.Lib.Utils;
11
using LenovoLegionToolkit.WPF.Resources;
12
using LenovoLegionToolkit.WPF.Windows.Utils;
13
using Windows.Win32;
14
using Windows.Win32.Foundation;
15

16
namespace LenovoLegionToolkit.WPF.Utils;
17

18
public static class LocalizationHelper
19
{
20
    private static readonly string LanguagePath = Path.Combine(Folders.AppData, "lang");
21

22
    private static readonly CultureInfo DefaultLanguage = new("en");
23

24
    public static readonly CultureInfo[] Languages = {
25
        DefaultLanguage,
26
        new("ar"),
27
        new("bg"),
28
        new("cs"),
29
        new("de"),
30
        new("el"),
31
        new("es"),
32
        new("fr"),
33
        new("it"),
34
        new("lv"),
35
        new("nl-nl"),
36
        new("pt"),
37
        new("pt-br"),
38
        new("ro"),
39
        new("ru"),
40
        new("sk"),
41
        new("tr"),
42
        new("uk"),
43
        new("vi"),
44
        new("zh-hans"),
45
        new("zh-hant"),
46
        // HACK: Karakalpak is not a recognized culture by msbuild, so we use this one as workaround instead.
47
        new("uz-latn-uz")
48
    };
49

50
    public static FlowDirection Direction => Resource.Culture?.TextInfo.IsRightToLeft ?? false
51
        ? FlowDirection.RightToLeft
52
        : FlowDirection.LeftToRight;
53

54
    private static string? _dateFormat;
55

56
    public static string ShortDateFormat
57
    {
58
        get
59
        {
60
            if (_dateFormat is not null)
61
                return _dateFormat;
62

63
            _dateFormat = GetSystemShortDateFormat() ?? "dd/M/yyyy";
64
            return _dateFormat;
65
        }
66
    }
67

68
    public static string LanguageDisplayName(CultureInfo culture)
69
    {
70
        var name = culture.NativeName.Transform(culture, To.TitleCase);
71

72
        if (culture.IetfLanguageTag.Equals("uz-latn-uz", StringComparison.InvariantCultureIgnoreCase))
73
            name = "Karakalpak";
74

75
        return ForceLeftToRight(name);
76
    }
77

78
    public static string ForceLeftToRight(string str)
79
    {
80
        if (Resource.Culture?.TextInfo.IsRightToLeft ?? false)
81
            return "\u200e" + str + "\u200e";
82
        return str;
83
    }
84

85
    public static async Task SetLanguageAsync(bool interactive = false)
86
    {
87
        CultureInfo? cultureInfo = null;
88

89
        if (interactive && await GetLanguageFromFile() is null)
90
        {
91
            var window = new LanguageSelectorWindow(Languages, DefaultLanguage);
92
            window.Show();
93
            cultureInfo = await window.ShouldContinue;
94
            if (cultureInfo is not null)
95
                await SaveLanguageToFileAsync(cultureInfo);
96
        }
97

98
        cultureInfo ??= await GetLanguageAsync();
99

100
        SetLanguageInternal(cultureInfo);
101
    }
102

103
    public static async Task SetLanguageAsync(CultureInfo cultureInfo)
104
    {
105
        await SaveLanguageToFileAsync(cultureInfo);
106
        SetLanguageInternal(cultureInfo);
107
    }
108

109
    public static async Task<CultureInfo> GetLanguageAsync()
110
    {
111
        var cultureInfo = await GetLanguageFromFile();
112
        if (cultureInfo is null)
113
        {
114
            cultureInfo = DefaultLanguage;
115
            await SaveLanguageToFileAsync(cultureInfo);
116
        }
117
        return cultureInfo;
118
    }
119

120
    private static async Task<CultureInfo?> GetLanguageFromFile()
121
    {
122
        try
123
        {
124
            var name = await File.ReadAllTextAsync(LanguagePath);
125
            var cultureInfo = new CultureInfo(name);
126
            if (!Languages.Contains(cultureInfo))
127
                throw new InvalidOperationException("Unknown language.");
128
            return cultureInfo;
129
        }
130
        catch
131
        {
132
            return null;
133
        }
134
    }
135

136
    private static Task SaveLanguageToFileAsync(CultureInfo cultureInfo) => File.WriteAllTextAsync(LanguagePath, cultureInfo.Name);
137

138
    private static void SetLanguageInternal(CultureInfo cultureInfo)
139
    {
140
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
141
        CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en");
142

143
        Thread.CurrentThread.CurrentUICulture = cultureInfo;
144
        CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
145

146
        Resource.Culture = cultureInfo;
147
        Lib.Resources.Resource.Culture = cultureInfo;
148
        Lib.Automation.Resources.Resource.Culture = cultureInfo;
149

150
        if (Log.Instance.IsTraceEnabled)
151
            Log.Instance.Trace($"Applied culture: {cultureInfo.Name}");
152
    }
153

154
    private static unsafe string? GetSystemShortDateFormat()
155
    {
156
        var ptr = IntPtr.Zero;
157
        try
158
        {
159
            var length = PInvoke.GetLocaleInfoEx((string?)null, PInvoke.LOCALE_SSHORTDATE, null, 0);
160
            if (length == 0)
161
                return null;
162

163
            ptr = Marshal.AllocHGlobal(sizeof(char) * length);
164
            var charPtr = new PWSTR((char*)ptr.ToPointer());
165

166
            length = PInvoke.GetLocaleInfoEx((string?)null, PInvoke.LOCALE_SSHORTDATE, charPtr, length);
167
            if (length == 0)
168
                return null;
169

170
            return charPtr.ToString();
171
        }
172
        finally
173
        {
174
            Marshal.FreeHGlobal(ptr);
175
        }
176
    }
177
}
178

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

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

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

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