Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/CI-CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
- name: Build and Pack
run: dotnet build --configuration Release

- name: Test (Windows only, Framework 4.6.1)
run: dotnet test --configuration Release --no-build output\Release\net461\*Tests.dll -- NUnit.TestOutputXml=TestResults
- name: Test (Windows only, Framework 4.6.2)
run: dotnet test --configuration Release --no-build output\Release\net462\*Tests.dll -- NUnit.TestOutputXml=TestResults
if: matrix.os == 'windows-latest'

- name: Test (Windows only, all TFMs)
Expand Down
30 changes: 21 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [11.0.0] - 2026-09-03

### Added

- [L10NSharp] Added pseudolocalization support: lookups for the standard `qps-ploc` pseudo-locale (`LocalizationManager.PseudoLocalizationLanguageId`) return the English text pseudolocalized at runtime (e.g. `[Tîitlée Mîissîing]`), so testers can spot non-internationalized strings and layout problems. Set `LocalizationManager.OfferPseudoLocalization = true` to include it in the offered UI languages; `LocalizationManager.PseudoLocalize(string)` exposes the transform directly. The SampleApp turns this on, so you can see it in action. See `src/L10NSharp/Pseudo/README.md`.

### Changed

- BREAKING CHANGE: [L10NSharp] [L10NSharp.Windows.Forms] [SampleApp] [CheckOrFixXliff] [ExtractXliff] Replaced the `net461` target framework with `net462`. The `System.Resources.Extensions` version raised transitively by the `SIL.ReleaseTasks` upgrade (above) no longer ships a `net461`-specific assembly, so `net461` is no longer a supported or tested target. Projects that still need to target `net461` should continue using the last release built for it, or upgrade to at least `net462`.

### Security

- [L10NSharp] [L10NSharp.Windows.Forms] [CheckOrFixXliff] [ExtractXliff] Upgraded `SIL.ReleaseTasks` from 2.5.0 to 3.3.0. This also raises the resolved version of `System.Resources.Extensions` (a transitive dependency of `SIL.ReleaseTasks`) from 6.0.0 to 10.0.11. Note: `SIL.ReleaseTasks` 3.3.0 has a known, build-time-only dependency on a vulnerable `Newtonsoft.Json` (via a temporary revert of its own `SIL.Core` dependency, pending an upstream `Mono.Unix` packaging issue) — per the upstream maintainers this is not an exploitable runtime risk, since the package is build-tool-only and never ships in L10nSharp's own output, and no L10nSharp or SIL.ReleaseTasks build step feeds it untrusted JSON. See [sillsdev/SIL.BuildTasks#88](https://github.com/sillsdev/SIL.BuildTasks/pull/88) for details.
- [L10NSharp.Windows.Forms] Upgraded `System.ServiceModel.Http` and `System.ServiceModel.Primitives` from 6.2.0 to 8.1.2, and added a direct `System.Security.Cryptography.Xml` reference pinned to 8.0.4. `System.ServiceModel.Primitives` 8.1.2 resolves a vulnerable 8.0.2 of `System.Security.Cryptography.Xml` transitively on `net8.0-windows`; the direct reference overrides it with the latest patched 8.0.x release.

## [10.0.0] - 2026-08-27

### Added
Expand All @@ -39,7 +50,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [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.
- [L10NSharp] Replaced the .NET 8.0 target with .NET Standard 2.0 for broader compatibility.
- [L10NSharp] `GetDynamicString`, `GetDynamicStringOrEnglish`, and `GetString` now return the English fallback text immediately when called with a null, empty, or whitespace string ID, rather than attempting a cache lookup or write.

### Fixed

- [L10NSharp.Windows.Forms] Restored project-local Resources support for `FallbackLanguagesDlgBase` button images (`Move`, `Move_up`, and `Move_down`).
Expand All @@ -65,7 +76,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [9.0.0] - 2026-02-02

### Changed
### Changed

- BREAKING CHANGE: Move code that depends on Windows.Forms or System.Drawing into an L10NSharp.Windows.Forms namespace. Rename L10NSharp.UI as L10NSharp.Windows.Forms.UIComponents. Move L10NExtender out of UI subfolder into L10NSharp.Windows.Forms. Move Winforms related tests to L10NSharp.Windows.Forms.Tests. Change the folder for L10NSharp tests to match its namespace L10NSharp.Tests.

Expand All @@ -88,7 +99,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
CHANGED: Remove static designation from the LocalizationManager class in order for LocalizationManagerWinforms to subclass it and share its properties.

CHANGED: The Icon argument is removed from the Create methods in LocalizationManager. Create methods for LocalizationManagerWinforms are available with and without the Icon argument. (The two obsolete create methods in LocalizationManager, which included a TranslationMemory argument, are removed.)

CHANGED: SetUILanguage in LocalizationManager no longer reapplies localizations based on a reapplyLocalizationsToAllObjectsInAllManagers argument, since reapplying localizations is a Winforms method. SetUILanguage in LocalizationManagerWinforms retains this argument and reapplies localizations depending on its value.

MOVED: The methods ReapplyLocalizationsToAllObjectsInAllManagers, ReapplyLocalizationsToAllObjects, and GetLocalisedToolTipForControl are moved to LocalizationManagerWinforms.
Expand All @@ -105,7 +116,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

CHANGED: In LocalizationManagerInternalWinforms, GetLocalizationManagerForComponent and GetLocalizationManagerForString, return type ILocalizationManagerInternalWinforms\<T> instead of ILocalizationManagerInternal\<T>.

MOVED: The methods ReapplyLocalizationsToAllObjectsInAllManagers, ReapplyLocalizationsToAllObjects, GetLocalizedToolTipForControl, and GetRealTopLevelControl are moved to LocalizationManagerInternalWinforms.
MOVED: The methods ReapplyLocalizationsToAllObjectsInAllManagers, ReapplyLocalizationsToAllObjects, GetLocalizedToolTipForControl, and GetRealTopLevelControl are moved to LocalizationManagerInternalWinforms.

- Split LocalizingInfo into LocalizingInfo and LocalizingInfoWinforms.

Expand All @@ -118,7 +129,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
MOVED: The methods SendMessage, SendMessageWindows and SetWindowRedraw are moved to UtilsWinforms.

- Split XliffLocalizationManager into XliffLocalizationManager and XliffLocalizationManagerWinforms.

MOVED: The following are moved to XliffLocalizationManagerWinforms:

- The properties ApplicationIcon, ToolTipCtrls, LocalizableComponents and StringCache.
Expand All @@ -127,15 +138,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Split XliffLocalizedStringCache into XliffLocalizedStringCacheWinforms and XliffLocalizedStringCache.

MOVED: The LeafNodeList property and the methods LoadGroupNodes and GetShortcutKeys are moved to XliffLocalizedStringCacheWinforms.

### Removed

- BREAKING CHANGE: Remove code related to doing one's own localization at runtime. Also remove obsolete create methods from LocalizationManager.

In particular:

- Remove the LocalizeItemDlg designer, cs, resx, and viewmodel.
- Remove ShowLocalizationDialogBox from LocalizationManager and LocalizationManagerInternal.
- Remove the LocalizeItemDlg designer, cs, resx, and viewmodel.
- Remove ShowLocalizationDialogBox from LocalizationManager and LocalizationManagerInternal.
- Remove the following runtime-localization related methods from XliffLocalizationManager:
PrepareComponentForRuntimeLocalization, HandleToolStripItemMouseDown, DoHandleMouseDown, HandeToolStripItemDisposed, HandleControlMouseDouwn, HandleControlDisposed, HandleTabPageDisposed, HandleDataGridViewDisposed, HandleListViewColumnHeaderClicked, HandleListViewDisposed, HandleListViewColumnDisposed, HandleDataGridViewCellMouseDown, HandleColumnDisposed, and ShowLocalizationDialogBox.
- Remove obsolete Create methods from LocalizationManager. These are the two Create methods that included a TranslationMemory argument.
Expand Down Expand Up @@ -276,7 +287,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Create nuget package
- Strong-name assembly

[Unreleased]: https://github.com/sillsdev/l10nsharp/compare/v10.0.0...HEAD
[Unreleased]: https://github.com/sillsdev/l10nsharp/compare/v11.0.0...HEAD
[11.0.0]: https://github.com/sillsdev/l10nsharp/compare/v10.0.0...v11.0.0
[10.0.0]: https://github.com/sillsdev/l10nsharp/compare/v9.0.0...v10.0.0
[9.0.0]: https://github.com/sillsdev/l10nsharp/compare/v8.0.0.0...v9.0.0
[8.0.0]: https://github.com/sillsdev/l10nsharp/compare/v7.0.0...v8.0.0.0
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net461;net48</TargetFrameworks>
<TargetFrameworks>net462;net48</TargetFrameworks>
<Company>SIL</Company>
<Authors>SIL Global</Authors>
<Product>L10NSharp</Product>
Expand Down
2 changes: 1 addition & 1 deletion src/CheckOrFixXliff/App.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>
6 changes: 3 additions & 3 deletions src/CheckOrFixXliff/CheckOrFixXliff.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
<NoWarn>$(NoWarn);NU5128;NU5118</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="all" />
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="3.3.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\L10NSharp\L10NSharp.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion src/ExtractXliff/App.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>
8 changes: 4 additions & 4 deletions src/ExtractXliff/ExtractXliff.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
<NoWarn>$(NoWarn);NU5128;NU5118</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4">
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0">
<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="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="3.3.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\L10NSharp\L10NSharp.csproj" />
Expand Down
6 changes: 3 additions & 3 deletions src/L10NSharp.Tests/L10NSharp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<ProjectReference Include="..\L10NSharp\L10NSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
<ProjectReference Include="..\L10NSharp.Windows.Forms\L10NSharp.Windows.Forms.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net48' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net48' ">
<Reference Include="System.Windows.Forms" />
</ItemGroup>
</Project>
21 changes: 11 additions & 10 deletions src/L10NSharp.Windows.Forms/L10NSharp.Windows.Forms.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UseWindowsForms>true</UseWindowsForms>
<TargetFrameworks>$(TargetFrameworks);net8.0-windows</TargetFrameworks>
Expand All @@ -8,27 +8,28 @@
<PackageId>L10NSharp.Windows.Forms</PackageId>
<SignAssembly>True</SignAssembly>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net48' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net48' ">
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0-windows' ">
<PackageReference Include="System.ServiceModel.Http" Version="6.2.0" />
<PackageReference Include="System.ServiceModel.Primitives" Version="6.2.0" />
<PackageReference Include="System.ServiceModel.Http" Version="8.1.2" />
<PackageReference Include="System.ServiceModel.Primitives" Version="8.1.2" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\L10NSharp\L10NSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4">
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0">
<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" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="3.3.0" PrivateAssets="all" />
<PackageReference Include="System.Resources.Extensions" Version="10.0.11" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net48'">
<ItemGroup Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net48'">
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,30 @@ public partial class LanguageServiceClient : System.ServiceModel.ClientBase<L10N

public LanguageServiceClient() {
}

public LanguageServiceClient(string endpointConfigurationName) :

// MANUAL EDIT — NOT REGENERATED SAFE: the #if NETFRAMEWORK guard below was added by hand
// and will be silently dropped if this file is regenerated (e.g. via "Update Service
// Reference" from BingTranslatorService.svcmap). Without it, these config-name-based
// ClientBase constructors don't compile against the modern System.ServiceModel.Primitives
// package used for net8.0-windows (no config-based WCF client support), breaking the build
// exactly as it did before. If you regenerate this file, reapply this guard, or — better —
// finish the replacement of BingTranslator/this proxy with a plain REST client (see
// https://github.com/sillsdev/l10nsharp/issues/163), which removes this file entirely.
#if NETFRAMEWORK
public LanguageServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public LanguageServiceClient(string endpointConfigurationName, string remoteAddress) :

public LanguageServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public LanguageServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :

public LanguageServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}

public LanguageServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
#endif

public LanguageServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}

Expand Down
2 changes: 0 additions & 2 deletions src/L10NSharp.Windows.Forms/Translators/BingTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public BingTranslator(string srcLangId, string tgtLangId)
binding.SendTimeout = new TimeSpan(0, 1, 0);
binding.AllowCookies = false;
binding.BypassProxyOnLocal = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MaxBufferSize = 65536;
binding.MaxBufferPoolSize = 524288;
binding.MaxReceivedMessageSize = 65536;
Expand All @@ -51,7 +50,6 @@ public BingTranslator(string srcLangId, string tgtLangId)
binding.Security.Mode = BasicHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Transport.Realm = string.Empty;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;

Expand Down
10 changes: 5 additions & 5 deletions src/L10NSharp/L10NSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
<PackageProjectUrl>https://github.com/sillsdev/l10nsharp</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4">
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0" PrivateAssets="all" />
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0">
<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" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="SIL.ReleaseTasks" Version="3.3.0" PrivateAssets="all" />
<PackageReference Include="System.Resources.Extensions" Version="10.0.11" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/L10NSharp/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@
</setting>
</L10NSharp.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
Loading
Loading