Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- [L10NSharp] Added UiLanguageChanged event to ILocalizationManager. This provides a way for clients to deal with changes now that (in Windows) LocalizeItemDlg<XLiffDocument>.StringsLocalized no longer exists.

### Changed

- [L10NSharp] Removed CanCustomizeLocalizations and PrepareToCustomizeLocalizations from ILocalizationManager since L10nSharp no longer provides a mechanism by which users may customize localizations.
- [L10NSharp] Removed the following members from from ILocalizationManager since they are really only needed internally and serve no purpose in the public API:
- AppVersion
- NamespaceBeginnings (no longer used even internally)
- FilenamesToAddToCache
- [L10NSharp] Removed emailForSubmissions parameter from LocalizationManager.Create. Since the localization dialog was jettisoned, it no longer makes sense to store this information on the localization manager.
- [L10NSharp.Windows.Forms] Removed emailForSubmissions parameter (8th parameter) from LocalizationManagerWinforms.Create. Since the localization dialog was jettisoned, it no longer makes sense to store this information on the localization manager.

### Removed

- [L10NSharp] Removed EnableClickingOnControlToBringUpLocalizationDialog. Since the localization dialog was jettisoned, this is meaningless (and wouldn't belong in the Winforms agnostic namespace anyway).
- [L10NSharp] Removed EmailForSubmissions. Since the localization dialog was jettisoned, it no longer makes sense to store this information on the localization manager.
- [L10NSharp.Windows.Forms] Removed LmGrid, LmButtonColumn, LmButtonCell, TipDialog.
- [L10NSharp.Windows.Forms] Removed the version of LocalizationManagerWinforms.Create that did not take an icon. The mere absence of a usable icon does not preclude the possibility of displaying the dialog for the user to choose a fallback language. Callers that do not wish to provide an icon can safely pass null for that parameter.

## [9.0.0] - 2026-02-02

### Changed
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ See full changelog at https://github.com/sillsdev/l10nsharp/blob/master/CHANGELO
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
<UseWindowsForms>true</UseWindowsForms>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<!-- Without this line some projects fail to build on TC with "error : SourceRoot items
Expand Down
11 changes: 11 additions & 0 deletions L10NSharp.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ISO/@EntryIndexedValue">ISO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JSON/@EntryIndexedValue">JSON</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TMX/@EntryIndexedValue">TMX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=appdata/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=bldr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ctrls/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ctype/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DOCTYPE/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Filenames/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=langs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Liff/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lingobit/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Marlett/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Palaso/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=performant/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=pretranslated/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=recursing/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winforms/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xliff/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
43 changes: 43 additions & 0 deletions LocalizationFilesFromInstaller/SampleApp.es.xlf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:sil="http://sil.org/software/XLiff" xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" product-version="1.0.0" original="SampleApp.exe" datatype="plaintext" target-language="es-ES">
<body>
<trans-unit id="Form1.WindowTitle">
<source xml:lang="en">Localization Sample App</source>
<target xml:lang="es-ES" state="final">App de muestra para la localización {0}</target>
<note>ID: Form1.WindowTitle</note>
</trans-unit>
<trans-unit id="TheSampleForm.ASubHeading.Label">
<source xml:lang="en">A Static Label</source>
<target xml:lang="es-ES" state="final">Una etiqueta estática</target>
<note>ID: TheSampleForm.ASubHeading.Label</note>
</trans-unit>
<trans-unit id="TheSampleForm.SampleDataGridView.ColumnHeadings.FirstColumn">
<source xml:lang="en">First</source>
<note>ID: TheSampleForm.SampleDataGridView.ColumnHeadings.FirstColumn</note>
</trans-unit>
<trans-unit id="TheSampleForm.button1">
<source xml:lang="en">Get Name Dynamically</source>
<note>ID: TheSampleForm.button1</note>
</trans-unit>
<trans-unit id="TheSampleForm.columnHeader1">
<source xml:lang="en">One</source>
<target xml:lang="es-ES" state="final">Uno</target>
<note>ID: TheSampleForm.columnHeader1</note>
</trans-unit>
<trans-unit id="TheSampleForm.columnHeader2">
<source xml:lang="en">Two</source>
<note>ID: TheSampleForm.columnHeader2</note>
</trans-unit>
<trans-unit id="accessed.before.setting.up.lm">
<source xml:lang="en">Localization is not yet set up, so this will always be in English. It should not cause anything bad to happen even if the current culture is some other variant of a localized language (e.g., es-MX). By the way, the current locale is {0}</source>
<note>ID: accessed.before.setting.up.lm</note>
</trans-unit>
<trans-unit id="TheSampleForm.Form1.label2">
<source xml:lang="en">The UI language was last changed at {0} on {1}.</source>
<target xml:lang="es-ES" state="final">El idioma de la interfaz de usuario se cambió por última vez a las {0} el {1}.</target>
<note>ID: TheSampleForm.Form1.label2</note>
</trans-unit>
</body>
</file>
</xliff>
3 changes: 3 additions & 0 deletions src/ExtractXliff/ExtractXliff.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="all" />
</ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion src/L10NSharp.Tests/CodeReaderTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.ComponentModel;
using System.Linq;
using L10NSharp.CodeReader;
using L10NSharp.Tests;
using L10NSharp.XLiffUtils;
Expand Down
11 changes: 10 additions & 1 deletion src/L10NSharp.Tests/L10NCultureInfoTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;
using System.Linq;
using NUnit.Framework;
Expand Down Expand Up @@ -46,6 +46,15 @@ public void L10NCultureInfo_TestPbu()
}
}

[Test]
public void L10NCultureInfo_TestPTp()
{
var tpCi = L10NCultureInfo.GetCultureInfo("tp");
var tpiCi = L10NCultureInfo.GetCultureInfo("tpi");
Assert.That(tpCi.EnglishName, Is.EqualTo(tpiCi.EnglishName));
Assert.That(tpCi.NativeName, Is.EqualTo(tpiCi.NativeName));
}

[Test]
public void L10NCultureInfo_TestList()
{
Expand Down
2 changes: 1 addition & 1 deletion src/L10NSharp.Tests/LocalizationManagerTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ public void TestMappingLanguageCodesToAvailable_FindsSpecificGivenGeneric()
AddChineseOfChinaTranslation(installedFolder);
LocalizationManagerInternal<T>.ChooseFallbackLanguage();
var manager = LocalizationManager.Create("zh", AppId, AppName, AppVersion, installedFolder,
$"Temp/{Path.GetFileName(folder.Path)}/user", null, new string[] { });
$"Temp/{Path.GetFileName(folder.Path)}/user", new string[] { });
LocalizationManagerInternal<T>.LoadedManagers[AppId] = (ILocalizationManagerInternal<T>)manager;

var langs = LocalizationManager.GetAvailableLocalizedLanguages();
Expand Down
3 changes: 1 addition & 2 deletions src/L10NSharp.Tests/LocalizationManagerXliffTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -40,7 +39,7 @@ public void Create_PreferredUiLanguageIsGenericVariant_CreatesLocalizationManage
LocalizationManager.ClearLoadedManagers();
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var lm = LocalizationManager.Create(genericLocaleId, "Test", "Test", "1.0",
Path.Combine(dir, "../../../src/L10NSharp.Tests/TestXliff2"), "", "",
Path.Combine(dir, "../../../src/L10NSharp.Tests/TestXliff2"), "",
new string[] {});
Assert.AreEqual($"Protección de configuraciones ({genericLocaleId})...",
lm.GetLocalizedString("SettingsProtection.LauncherButtonLabel", "don't use this"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ protected void TestSetup(string installedTranslationDir)
var dir = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().Location).LocalPath);
m_manager = LocalizationManagerWinforms.Create("en", "LocalizableComponentTest", "LocalizableComponentTest", "1.0",
Path.Combine(dir, installedTranslationDir),
"", null, "", new string[] { })
"", null, new string[] { })
as ILocalizationManagerInternalWinforms<XLiffDocument>;
m_translationPath = m_manager.GetPathForLanguage("en", true);
m_extender = new L10NSharpExtender { LocalizationManagerId = "LocalizableComponentTest" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using L10NSharp;
using L10NSharp.Translators;
using L10NSharp.Windows.Forms.UIComponents;
using NUnit.Framework;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System.Collections.Generic;
using System.Windows.Forms;
using L10NSharp;
using L10NSharp.Windows.Forms.UIComponents;
using NUnit.Framework;
using L10NSharp.Windows.Forms;

namespace L10NSharp.Windows.Forms.Tests
{
Expand Down
2 changes: 0 additions & 2 deletions src/L10NSharp.Windows.Forms.Tests/LocalizingInfoTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Windows.Forms;
using NUnit.Framework;
using L10NSharp;
using L10NSharp.Windows.Forms;

namespace L10NSharp.Windows.Forms.Tests
{
Expand Down
3 changes: 0 additions & 3 deletions src/L10NSharp.Windows.Forms.Tests/MockLocalizableComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using L10NSharp;
using L10NSharp.Windows.Forms;
using L10NSharp.Windows.Forms.UIComponents;

namespace L10NSharp.Windows.Forms.Tests
{
Expand Down
1 change: 0 additions & 1 deletion src/L10NSharp.Windows.Forms.Tests/UtilsTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Windows.Forms;
using NUnit.Framework;
using L10NSharp;

namespace L10NSharp.Windows.Forms.Tests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public void TestMappingLanguageCodesToAvailable_AmbiguousOptions_PromptsUser([Va
return choice;
};
var manager = LocalizationManagerWinforms.Create("zh", AppId, AppName, AppVersion, installedFolder,
userRelativeFolder, null, null, new string[] { });
userRelativeFolder, null, new string[] { });
Assert.That(userPromptCount, Is.EqualTo(1));
LocalizationManagerInternal<XLiffDocument>.LoadedManagers[AppId] = (ILocalizationManagerInternal<XLiffDocument>)manager;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright © 2019-2025 SIL Global
// Copyright © 2019-2026 SIL Global
// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace L10NSharp.Windows.Forms
Expand All @@ -13,7 +12,6 @@ internal interface ILocalizationManagerInternalWinforms: ILocalizationManagerInt
{
Dictionary<Control, ToolTip> ToolTipCtrls { get; }
Dictionary<ILocalizableComponent, Dictionary<string, LocalizingInfoWinforms>> LocalizableComponents { get; }
Icon ApplicationIcon { get; set; }

void ApplyLocalization(IComponent component);
void ApplyLocalizationsToILocalizableComponent(LocalizingInfoWinforms locInfo);
Expand All @@ -23,7 +21,6 @@ void RegisterComponentForLocalizing(IComponent component, string id, string defa
string defaultTooltip, string defaultShortcutKeys, string comment);
void RegisterComponentForLocalizing(LocalizingInfoWinforms info,
Action<ILocalizationManagerInternalWinforms, LocalizingInfoWinforms> successAction);

}

internal interface ILocalizationManagerInternalWinforms<T> : ILocalizationManagerInternalWinforms, ILocalizationManagerInternal<T>
Expand Down
9 changes: 6 additions & 3 deletions src/L10NSharp.Windows.Forms/L10NExtender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public void EndInit()
/// ------------------------------------------------------------------------------------
/// <summary>
/// This method goes through the collection of the controls that have been extended
/// and adds to or udates the default values in the string files. Then each extended
/// and adds to or updates the default values in the string files. Then each extended
/// control is localized.
/// </summary>
/// ------------------------------------------------------------------------------------
Expand All @@ -258,9 +258,12 @@ private void LocalizeControls()
// Special case: the Text of a column header is "ColumnHeader" before it is ever set.
// This means that if we first processed the CH before we set its text, we have noted
// "ColumnHeader" as its default English name. Get the real one if it has since been updated.
var ch = locInfo.Component as ColumnHeader;
if (ch != null && ch.Text != "ColumnHeader" && locInfo.Text == "ColumnHeader")
if (locInfo.Component is ColumnHeader ch && ch.Text != "ColumnHeader" &&
locInfo.Text == "ColumnHeader")
{
locInfo.UpdateTextFromObject();
}

_manager.RegisterComponentForLocalizing(locInfo, (lm, info) =>
{
if (info.Category == LocalizationCategory.LocalizableComponent)
Expand Down
32 changes: 4 additions & 28 deletions src/L10NSharp.Windows.Forms/L10NSharp.Windows.Forms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="all" />
<PackageReference Include="System.Resources.Extensions" Version="6.0.0" />
Expand All @@ -32,27 +35,12 @@
<DependentUpon>Settings.settings</DependentUpon>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UIComponents\CustomDropDownComboBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="UIComponents\DontShowThisAgainButton.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="UIComponents\EditSourceBeforeTranslatingDlg.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\FallbackLanguagesDlg.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\FallbackLanguagesDlgBase.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\Grid\LmGrid.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="UIComponents\HowToDistributeDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\InitializationProgressDlg.cs">
<SubType>Form</SubType>
</Compile>
Expand All @@ -65,27 +53,15 @@
<Compile Update="UIComponents\LanguageChoosingSimpleDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\PopupControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="UIComponents\ShortcutKeysDropDown.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="UIComponents\ShortcutKeysEditor.cs">
<Compile Update="UIComponents\ShortcutKeysConverter.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="UIComponents\TipDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="UIComponents\UILanguageComboBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="UIComponents\UILanguageListBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="UIComponents\XButton.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
Expand Down
Loading
Loading