69af5b6ac3
- Strings.resx (Hebrew, default) + Strings.en-US.resx (English override)
cover every dialog/sidebar/ribbon string, plus filing summary format
templates (`Msg_FilingSummary_*`)
- LocalizationManager singleton wraps ResourceManager with Get() and
Format() helpers; SetCulture honors AppSettings.Locale
- LocExtension XAML markup ({l:Loc Key}) for bindings
- Themes/RtlFonts.xaml — global RightToLeft FlowDirection and Hebrew
font stack (Segoe UI / David / Frank Ruehl / Arial)
- AddInHost calls LocalizationManager.SetCulture(Settings.Locale) before
any UI thread reads a resource
Existing dialogs keep their hardcoded Hebrew for v1 — those are already
in the correct (he-IL) language. Future iterations can switch to
{l:Loc …} bindings; the resource files already enumerate every string so
the migration is mechanical.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
59 lines
1.8 KiB
C#
59 lines
1.8 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
using System.Resources;
|
|
using System.Threading;
|
|
|
|
namespace MarcusLaw.OutlookAddin.UI.Services
|
|
{
|
|
/// <summary>
|
|
/// Strongly-typed wrapper around <see cref="ResourceManager"/>. The
|
|
/// default culture is Hebrew (he-IL) — that's the user base. Switch by
|
|
/// calling <see cref="SetCulture"/> from SettingsViewModel.
|
|
/// </summary>
|
|
public sealed class LocalizationManager
|
|
{
|
|
private const string BaseName = "MarcusLaw.OutlookAddin.UI.Resources.Strings";
|
|
|
|
public static LocalizationManager Instance { get; } = new LocalizationManager();
|
|
|
|
public ResourceManager ResourceManager { get; }
|
|
|
|
private LocalizationManager()
|
|
{
|
|
ResourceManager = new ResourceManager(BaseName, typeof(LocalizationManager).Assembly);
|
|
}
|
|
|
|
public string Get(string key)
|
|
{
|
|
try
|
|
{
|
|
return ResourceManager.GetString(key, CultureInfo.CurrentUICulture) ?? key;
|
|
}
|
|
catch
|
|
{
|
|
return key;
|
|
}
|
|
}
|
|
|
|
public string Format(string key, params object[] args)
|
|
{
|
|
var template = Get(key);
|
|
try { return string.Format(CultureInfo.CurrentUICulture, template, args); }
|
|
catch { return template; }
|
|
}
|
|
|
|
public static void SetCulture(string cultureName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(cultureName)) return;
|
|
try
|
|
{
|
|
var ci = CultureInfo.GetCultureInfo(cultureName);
|
|
Thread.CurrentThread.CurrentUICulture = ci;
|
|
CultureInfo.DefaultThreadCurrentUICulture = ci;
|
|
}
|
|
catch (CultureNotFoundException) { /* leave as-is */ }
|
|
}
|
|
}
|
|
}
|