From a287ed83aba005afe974121e106953ff807fe84c Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 2 Apr 2026 12:16:57 +0200 Subject: [PATCH] feat(01-05): implement TranslationSource singleton + EN/FR resx files - TranslationSource singleton with INotifyPropertyChanged indexer binding - PropertyChanged fires with string.Empty on culture switch (signals all bindings refresh) - Missing key returns [key] placeholder (prevents null in WPF bindings) - Strings.resx with 27 Phase 1 UI string keys (EN) - Strings.fr.resx with same 27 keys stubbed with EN text (FR completeness Phase 5) - Strings.Designer.cs ResourceManager for dotnet build compatibility - SharepointToolbox.csproj updated with EmbeddedResource metadata --- .../Localization/Strings.Designer.cs | 60 ++++++ .../Localization/Strings.fr.resx | 178 ++++++++++++++++++ SharepointToolbox/Localization/Strings.resx | 148 +++++++++++++++ .../Localization/TranslationSource.cs | 38 ++++ SharepointToolbox/SharepointToolbox.csproj | 10 + 5 files changed, 434 insertions(+) create mode 100644 SharepointToolbox/Localization/Strings.Designer.cs create mode 100644 SharepointToolbox/Localization/Strings.fr.resx create mode 100644 SharepointToolbox/Localization/Strings.resx create mode 100644 SharepointToolbox/Localization/TranslationSource.cs diff --git a/SharepointToolbox/Localization/Strings.Designer.cs b/SharepointToolbox/Localization/Strings.Designer.cs new file mode 100644 index 0000000..d80dbc7 --- /dev/null +++ b/SharepointToolbox/Localization/Strings.Designer.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SharepointToolbox.Localization { + using System; + using System.Reflection; + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// Auto-generated designer file for Strings.resx — do not edit manually. + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SharepointToolbox.Localization.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/SharepointToolbox/Localization/Strings.fr.resx b/SharepointToolbox/Localization/Strings.fr.resx new file mode 100644 index 0000000..02b65ab --- /dev/null +++ b/SharepointToolbox/Localization/Strings.fr.resx @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + SharePoint Toolbox + + + + Connect + + + + Manage Profiles... + + + + Clear Session + + + + Permissions + + + + Storage + + + + File Search + + + + Duplicates + + + + Templates + + + + Bulk Operations + + + + Folder Structure + + + + Settings + + + + Coming soon + + + + Cancel + + + + Language + + + + English + + + + French + + + + Data output folder + + + + Browse... + + + + Profile name + + + + Tenant URL + + + + Client ID + + + + Add + + + + Rename + + + + Delete + + + + Ready + + + + Operation cancelled + + + + Authentication failed. Check tenant URL and Client ID. + + + + An error occurred. See log for details. + + + diff --git a/SharepointToolbox/Localization/Strings.resx b/SharepointToolbox/Localization/Strings.resx new file mode 100644 index 0000000..aaeebb8 --- /dev/null +++ b/SharepointToolbox/Localization/Strings.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + SharePoint Toolbox + + + Connect + + + Manage Profiles... + + + Clear Session + + + Permissions + + + Storage + + + File Search + + + Duplicates + + + Templates + + + Bulk Operations + + + Folder Structure + + + Settings + + + Coming soon + + + Cancel + + + Language + + + English + + + French + + + Data output folder + + + Browse... + + + Profile name + + + Tenant URL + + + Client ID + + + Add + + + Rename + + + Delete + + + Ready + + + Operation cancelled + + + Authentication failed. Check tenant URL and Client ID. + + + An error occurred. See log for details. + + diff --git a/SharepointToolbox/Localization/TranslationSource.cs b/SharepointToolbox/Localization/TranslationSource.cs new file mode 100644 index 0000000..deee2bd --- /dev/null +++ b/SharepointToolbox/Localization/TranslationSource.cs @@ -0,0 +1,38 @@ +using System.ComponentModel; +using System.Globalization; +using System.Resources; + +namespace SharepointToolbox.Localization; + +/// +/// Singleton INotifyPropertyChanged string lookup enabling runtime culture switching without restart. +/// WPF bindings use: Source={x:Static loc:TranslationSource.Instance}, Path=[key] +/// On CurrentCulture change, fires PropertyChanged with empty string to signal all properties changed, +/// which causes WPF to re-evaluate all bindings to this source. +/// +public class TranslationSource : INotifyPropertyChanged +{ + public static readonly TranslationSource Instance = new(); + + private ResourceManager _resourceManager = Strings.ResourceManager; + private CultureInfo _currentCulture = CultureInfo.CurrentUICulture; + + private TranslationSource() { } + + public string this[string key] => + _resourceManager.GetString(key, _currentCulture) ?? $"[{key}]"; + + public CultureInfo CurrentCulture + { + get => _currentCulture; + set + { + if (Equals(_currentCulture, value)) return; + _currentCulture = value; + Thread.CurrentThread.CurrentUICulture = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty)); + } + } + + public event PropertyChangedEventHandler? PropertyChanged; +} diff --git a/SharepointToolbox/SharepointToolbox.csproj b/SharepointToolbox/SharepointToolbox.csproj index ad202f4..24a4c99 100644 --- a/SharepointToolbox/SharepointToolbox.csproj +++ b/SharepointToolbox/SharepointToolbox.csproj @@ -15,6 +15,16 @@ + + + ResXFileCodeGenerator + Strings.Designer.cs + + + Strings.resx + + +