33using System . Globalization ;
44using System . IO ;
55using System . Linq ;
6- using System . Reflection ;
76using System . Threading ;
87using System . Threading . Tasks ;
98using System . Windows ;
@@ -28,22 +27,20 @@ public class Internationalization
2827 private const string DefaultFile = "en.xaml" ;
2928 private const string Extension = ".xaml" ;
3029 private readonly Settings _settings ;
31- private readonly List < string > _languageDirectories = new ( ) ;
32- private readonly List < ResourceDictionary > _oldResources = new ( ) ;
30+ private readonly List < string > _languageDirectories = [ ] ;
31+ private readonly List < ResourceDictionary > _oldResources = [ ] ;
3332 private static string SystemLanguageCode ;
3433
3534 public Internationalization ( Settings settings )
3635 {
3736 _settings = settings ;
38- AddFlowLauncherLanguageDirectory ( ) ;
3937 }
4038
41- private void AddFlowLauncherLanguageDirectory ( )
42- {
43- var directory = Path . Combine ( Constant . ProgramDirectory , Folder ) ;
44- _languageDirectories . Add ( directory ) ;
45- }
39+ #region Initialization
4640
41+ /// <summary>
42+ /// Initialize the system language code based on the current culture.
43+ /// </summary>
4744 public static void InitSystemLanguageCode ( )
4845 {
4946 var availableLanguages = AvailableLanguages . GetAvailableLanguages ( ) ;
@@ -72,35 +69,6 @@ public static void InitSystemLanguageCode()
7269 SystemLanguageCode = DefaultLanguageCode ;
7370 }
7471
75- private void AddPluginLanguageDirectories ( )
76- {
77- foreach ( var plugin in PluginManager . GetTranslationPlugins ( ) )
78- {
79- var location = Assembly . GetAssembly ( plugin . Plugin . GetType ( ) ) . Location ;
80- var dir = Path . GetDirectoryName ( location ) ;
81- if ( dir != null )
82- {
83- var pluginThemeDirectory = Path . Combine ( dir , Folder ) ;
84- _languageDirectories . Add ( pluginThemeDirectory ) ;
85- }
86- else
87- {
88- API . LogError ( ClassName , $ "Can't find plugin path <{ location } > for <{ plugin . Metadata . Name } >") ;
89- }
90- }
91-
92- LoadDefaultLanguage ( ) ;
93- }
94-
95- private void LoadDefaultLanguage ( )
96- {
97- // Removes language files loaded before any plugins were loaded.
98- // Prevents the language Flow started in from overwriting English if the user switches back to English
99- RemoveOldLanguageFiles ( ) ;
100- LoadLanguage ( AvailableLanguages . English ) ;
101- _oldResources . Clear ( ) ;
102- }
103-
10472 /// <summary>
10573 /// Initialize language. Will change app language and plugin language based on settings.
10674 /// </summary>
@@ -116,13 +84,64 @@ public async Task InitializeLanguageAsync()
11684 // Get language by language code and change language
11785 var language = GetLanguageByLanguageCode ( languageCode ) ;
11886
87+ // Add Flow Launcher language directory
88+ AddFlowLauncherLanguageDirectory ( ) ;
89+
11990 // Add plugin language directories first so that we can load language files from plugins
12091 AddPluginLanguageDirectories ( ) ;
12192
93+ // Load default language resources
94+ LoadDefaultLanguage ( ) ;
95+
12296 // Change language
123- await ChangeLanguageAsync ( language ) ;
97+ await ChangeLanguageAsync ( language , false ) ;
12498 }
12599
100+ private void AddFlowLauncherLanguageDirectory ( )
101+ {
102+ // Check if Flow Launcher language directory exists
103+ var directory = Path . Combine ( Constant . ProgramDirectory , Folder ) ;
104+ if ( ! Directory . Exists ( directory ) )
105+ {
106+ API . LogError ( ClassName , $ "Flow Launcher language directory can't be found <{ directory } >") ;
107+ return ;
108+ }
109+
110+ _languageDirectories . Add ( directory ) ;
111+ }
112+
113+ private void AddPluginLanguageDirectories ( )
114+ {
115+ foreach ( var pluginsDir in PluginManager . Directories )
116+ {
117+ if ( ! Directory . Exists ( pluginsDir ) ) continue ;
118+
119+ // Enumerate all top directories in the plugin directory
120+ foreach ( var dir in Directory . GetDirectories ( pluginsDir ) )
121+ {
122+ // Check if the directory contains a language folder
123+ var pluginLanguageDir = Path . Combine ( dir , Folder ) ;
124+ if ( ! Directory . Exists ( pluginLanguageDir ) ) continue ;
125+
126+ // Check if the language directory contains default language file since it will be checked later
127+ _languageDirectories . Add ( pluginLanguageDir ) ;
128+ }
129+ }
130+ }
131+
132+ private void LoadDefaultLanguage ( )
133+ {
134+ // Removes language files loaded before any plugins were loaded.
135+ // Prevents the language Flow started in from overwriting English if the user switches back to English
136+ RemoveOldLanguageFiles ( ) ;
137+ LoadLanguage ( AvailableLanguages . English ) ;
138+ _oldResources . Clear ( ) ;
139+ }
140+
141+ #endregion
142+
143+ #region Change Language
144+
126145 /// <summary>
127146 /// Change language during runtime. Will change app language and plugin language & save settings.
128147 /// </summary>
@@ -151,8 +170,8 @@ public void ChangeLanguage(string languageCode)
151170
152171 private static Language GetLanguageByLanguageCode ( string languageCode )
153172 {
154- var lowercase = languageCode . ToLower ( ) ;
155- var language = AvailableLanguages . GetAvailableLanguages ( ) . FirstOrDefault ( o => o . LanguageCode . ToLower ( ) == lowercase ) ;
173+ var language = AvailableLanguages . GetAvailableLanguages ( ) .
174+ FirstOrDefault ( o => o . LanguageCode . Equals ( languageCode , StringComparison . OrdinalIgnoreCase ) ) ;
156175 if ( language == null )
157176 {
158177 API . LogError ( ClassName , $ "Language code can't be found <{ languageCode } >") ;
@@ -164,7 +183,7 @@ private static Language GetLanguageByLanguageCode(string languageCode)
164183 }
165184 }
166185
167- private async Task ChangeLanguageAsync ( Language language )
186+ private async Task ChangeLanguageAsync ( Language language , bool updateMetadata = true )
168187 {
169188 // Remove old language files and load language
170189 RemoveOldLanguageFiles ( ) ;
@@ -176,8 +195,11 @@ private async Task ChangeLanguageAsync(Language language)
176195 // Change culture info
177196 ChangeCultureInfo ( language . LanguageCode ) ;
178197
179- // Raise event for plugins after culture is set
180- await Task . Run ( UpdatePluginMetadataTranslations ) ;
198+ if ( updateMetadata )
199+ {
200+ // Raise event for plugins after culture is set
201+ await Task . Run ( UpdatePluginMetadataTranslations ) ;
202+ }
181203 }
182204
183205 public static void ChangeCultureInfo ( string languageCode )
@@ -200,6 +222,10 @@ public static void ChangeCultureInfo(string languageCode)
200222 thread . CurrentUICulture = currentCulture ;
201223 }
202224
225+ #endregion
226+
227+ #region Prompt Pinyin
228+
203229 public bool PromptShouldUsePinyin ( string languageCodeToSet )
204230 {
205231 var languageToSet = GetLanguageByLanguageCode ( languageCodeToSet ) ;
@@ -212,14 +238,18 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
212238
213239 // No other languages should show the following text so just make it hard-coded
214240 // "Do you want to search with pinyin?"
215- string text = languageToSet == AvailableLanguages . Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
241+ string text = languageToSet == AvailableLanguages . Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
216242
217243 if ( API . ShowMsgBox ( text , string . Empty , MessageBoxButton . YesNo ) == MessageBoxResult . No )
218244 return false ;
219245
220246 return true ;
221247 }
222248
249+ #endregion
250+
251+ #region Language Resources Management
252+
223253 private void RemoveOldLanguageFiles ( )
224254 {
225255 var dicts = Application . Current . Resources . MergedDictionaries ;
@@ -255,13 +285,51 @@ private void LoadLanguage(Language language)
255285 }
256286 }
257287
288+ private static string LanguageFile ( string folder , string language )
289+ {
290+ if ( Directory . Exists ( folder ) )
291+ {
292+ var path = Path . Combine ( folder , language ) ;
293+ if ( File . Exists ( path ) )
294+ {
295+ return path ;
296+ }
297+ else
298+ {
299+ API . LogError ( ClassName , $ "Language path can't be found <{ path } >") ;
300+ var english = Path . Combine ( folder , DefaultFile ) ;
301+ if ( File . Exists ( english ) )
302+ {
303+ return english ;
304+ }
305+ else
306+ {
307+ API . LogError ( ClassName , $ "Default English Language path can't be found <{ path } >") ;
308+ return string . Empty ;
309+ }
310+ }
311+ }
312+ else
313+ {
314+ return string . Empty ;
315+ }
316+ }
317+
318+ #endregion
319+
320+ #region Available Languages
321+
258322 public List < Language > LoadAvailableLanguages ( )
259323 {
260324 var list = AvailableLanguages . GetAvailableLanguages ( ) ;
261325 list . Insert ( 0 , new Language ( Constant . SystemLanguageCode , AvailableLanguages . GetSystemTranslation ( SystemLanguageCode ) ) ) ;
262326 return list ;
263327 }
264328
329+ #endregion
330+
331+ #region Get Translations
332+
265333 public static string GetTranslation ( string key )
266334 {
267335 var translation = Application . Current . TryFindResource ( key ) ;
@@ -276,7 +344,11 @@ public static string GetTranslation(string key)
276344 }
277345 }
278346
279- private void UpdatePluginMetadataTranslations ( )
347+ #endregion
348+
349+ #region Update Metadata
350+
351+ public static void UpdatePluginMetadataTranslations ( )
280352 {
281353 // Update plugin metadata name & description
282354 foreach ( var p in PluginManager . GetTranslationPlugins ( ) )
@@ -295,34 +367,6 @@ private void UpdatePluginMetadataTranslations()
295367 }
296368 }
297369
298- private static string LanguageFile ( string folder , string language )
299- {
300- if ( Directory . Exists ( folder ) )
301- {
302- var path = Path . Combine ( folder , language ) ;
303- if ( File . Exists ( path ) )
304- {
305- return path ;
306- }
307- else
308- {
309- API . LogError ( ClassName , $ "Language path can't be found <{ path } >") ;
310- var english = Path . Combine ( folder , DefaultFile ) ;
311- if ( File . Exists ( english ) )
312- {
313- return english ;
314- }
315- else
316- {
317- API . LogError ( ClassName , $ "Default English Language path can't be found <{ path } >") ;
318- return string . Empty ;
319- }
320- }
321- }
322- else
323- {
324- return string . Empty ;
325- }
326- }
370+ #endregion
327371 }
328372}
0 commit comments