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
6 changes: 5 additions & 1 deletion src/ui/Assets/Languages/English.json
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,11 @@
"unbreakShortLine": "Unbreak short line",
"fixText": "Fix text",
"removeSpaceBetweenNumbers": "Remove space between numbers",
"fixDialogsOnOneLine": "Fix dialogs on one line"
"fixDialogsOnOneLine": "Fix dialogs on one line",
"fixTypeFormatting": "Formatting",
"fixTypeDialog": "Dialog",
"fixTypePunctuation": "Punctuation",
"fixTypeOcr": "OCR"
},
"adjustDurations": {
"title": "Adjust durations",
Expand Down
37 changes: 35 additions & 2 deletions src/ui/Features/Tools/FixCommonErrors/FixCommonErrorsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public partial class FixCommonErrorsViewModel : ObservableObject, IFixCallbacks
private const int AnalysingPaintDelayMilliseconds = 20;

[ObservableProperty] private string _searchText;
[ObservableProperty] private ObservableCollection<FixTypeDisplayItem> _fixTypes;
[ObservableProperty] private FixTypeDisplayItem? _selectedFixType;
[ObservableProperty] private ObservableCollection<LanguageDisplayItem> _languages;
[ObservableProperty] private LanguageDisplayItem? _selectedLanguage;
[ObservableProperty] private ObservableCollection<FixDisplayItem> _fixes;
Expand Down Expand Up @@ -116,6 +118,13 @@ public FixCommonErrorsViewModel(INamesList namesList, IWindowService windowServi

GridSubtitles = new TableView();
SearchText = string.Empty;
FixTypes = new ObservableCollection<FixTypeDisplayItem> { new() };
foreach (var fixType in Enum.GetValues<FixType>())
{
FixTypes.Add(new FixTypeDisplayItem(fixType));
}

SelectedFixType = FixTypes[0];
Languages = new ObservableCollection<LanguageDisplayItem>();
Language = new string(' ', 0);
Fixes = new ObservableCollection<FixDisplayItem>();
Expand Down Expand Up @@ -961,7 +970,28 @@ internal void OnKeyDown(KeyEventArgs e)
}
}

internal void TextBoxSearch_TextChanged(object? sender, TextChangedEventArgs e)
partial void OnSearchTextChanged(string value)
{
RebuildVisibleRules();
}

partial void OnSelectedFixTypeChanged(FixTypeDisplayItem? value)
{
RebuildVisibleRules();
}

// Runs before PropertyChanged is raised, so the grid rebinds to an already filtered
// collection - a search text or type filter carries over to the newly picked profile.
partial void OnSelectedProfileChanged(ProfileDisplayItem? value)
{
RebuildVisibleRules();
}

/// <summary>
/// Narrows the step 1 rules grid to the rules matching both the search text and the
/// selected fix type.
/// </summary>
internal void RebuildVisibleRules()
{
if (SelectedProfile == null)
{
Expand All @@ -975,10 +1005,13 @@ internal void TextBoxSearch_TextChanged(object? sender, TextChangedEventArgs e)
SelectedProfile.AllFixRules = SelectedProfile.FixRules.ToList();
}

var fixType = SelectedFixType?.FixType;
SelectedProfile.FixRules.Clear();
foreach (var rule in SelectedProfile.AllFixRules)
{
if (string.IsNullOrEmpty(SearchText) || rule.Name.ToLowerInvariant().Contains(SearchText.ToLowerInvariant()))
var typeMatches = fixType == null || rule.FixType == fixType;
var searchMatches = string.IsNullOrEmpty(SearchText) || rule.Name.Contains(SearchText, StringComparison.OrdinalIgnoreCase);
if (typeMatches && searchMatches)
{
SelectedProfile.FixRules.Add(rule);
}
Expand Down
16 changes: 14 additions & 2 deletions src/ui/Features/Tools/FixCommonErrors/FixCommonErrorsWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,20 @@ public FixCommonErrorsWindow(FixCommonErrorsViewModel vm)
labelStep2.Bind(Label.ContentProperty, new Binding(nameof(vm.Step2Title)));
labelStep2.Bind(IsVisibleProperty, new Binding(nameof(vm.Step2IsVisible)));

var textBoxSearch = UiUtil.MakeTextBox(250, vm, nameof(vm.SearchText)).WithMarginRight(25)
var textBoxSearch = UiUtil.MakeTextBox(200, vm, nameof(vm.SearchText)).WithMarginRight(25)
.WithAccessibleName(Se.Language.Tools.FixCommonErrors.SearchRulesDotDotDot);
textBoxSearch.PlaceholderText = Se.Language.Tools.FixCommonErrors.SearchRulesDotDotDot;
textBoxSearch.Bind(IsVisibleProperty, new Binding(nameof(vm.Step1IsVisible)));
textBoxSearch.TextChanged += vm.TextBoxSearch_TextChanged;

// Narrows the rules grid to one FixType; combined with the search text in the view model.
var labelFixType = UiUtil.MakeTextBlock(Se.Language.General.Type).WithMarginRight(5);
labelFixType.Bind(IsVisibleProperty, new Binding(nameof(vm.Step1IsVisible)));
var comboFixType = UiUtil.MakeComboBox(vm.FixTypes, vm, nameof(vm.SelectedFixType))
.WithMinWidth(120)
.WithMarginRight(25);
comboFixType.Bind(IsVisibleProperty, new Binding(nameof(vm.Step1IsVisible)));
AutomationProperties.SetLabeledBy(comboFixType, labelFixType);

// Off by default (#12441) - keep it reachable here, next to the language it depends on,
// instead of only in the OCR window where a Fix-common-errors user would never look.
var checkBoxGuessUnknownWords = UiUtil.MakeCheckBox(Se.Language.Ocr.TryToGuessUnknownWords, vm, nameof(vm.TryToGuessUnknownWords))
Expand All @@ -69,6 +78,9 @@ public FixCommonErrorsWindow(FixCommonErrorsViewModel vm)
HorizontalAlignment = HorizontalAlignment.Right,
Children =
{
textBoxSearch,
labelFixType,
comboFixType,
checkBoxGuessUnknownWords,
UiUtil.MakeTextBlock(Se.Language.General.Language).WithMarginRight(5),
UiUtil.MakeComboBox(vm.Languages, vm, nameof(vm.SelectedLanguage))
Expand Down
20 changes: 20 additions & 0 deletions src/ui/Features/Tools/FixCommonErrors/FixRuleDisplayItem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Core.Enums;
using Nikse.SubtitleEdit.Core.Forms.FixCommonErrors;
using Nikse.SubtitleEdit.Core.Interfaces;
using Nikse.SubtitleEdit.Logic.Config;
Expand All @@ -19,6 +20,23 @@ public partial class FixRuleDisplayItem : ObservableObject

public string FixCommonErrorFunctionName { get; set; }

/// <summary>
/// The kind of fix the rule performs, taken from the fix class itself so the category
/// has one source of truth. Null when <see cref="FixCommonErrorFunctionName"/> does not
/// name a known fix - such a rule is only listed under "All" in the type filter.
/// </summary>
public FixType? FixType { get; private set; }

// Built once: GetFixCommonErrorItems() news up every fix class, and the copy-ctor runs
// per rule per profile.
private static readonly Lazy<Dictionary<string, FixType>> FixTypesByFunctionName = new(() =>
GetFixCommonErrorItems().ToDictionary(p => p.GetType().Name, p => p.FixType, StringComparer.Ordinal));

public static bool TryResolveFixType(string fixCommonErrorFunctionName, out FixType fixType)
{
return FixTypesByFunctionName.Value.TryGetValue(fixCommonErrorFunctionName, out fixType);
}

public FixRuleDisplayItem()
{
Name = string.Empty;
Expand All @@ -33,6 +51,7 @@ public FixRuleDisplayItem(FixRuleDisplayItem item)
IsSelected = item.IsSelected;
SortOrder = item.SortOrder;
FixCommonErrorFunctionName = item.FixCommonErrorFunctionName;
FixType = item.FixType;
}

public FixRuleDisplayItem(string name, string example, int sortOrder, bool isSelected, string fixCommonErrorFunctionName)
Expand All @@ -42,6 +61,7 @@ public FixRuleDisplayItem(string name, string example, int sortOrder, bool isSel
SortOrder = sortOrder;
IsSelected = isSelected;
FixCommonErrorFunctionName = fixCommonErrorFunctionName;
FixType = TryResolveFixType(fixCommonErrorFunctionName, out var fixType) ? fixType : null;
}

public IFixCommonError GetFixCommonErrorFunction()
Expand Down
31 changes: 31 additions & 0 deletions src/ui/Features/Tools/FixCommonErrors/FixTypeDisplayItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Nikse.SubtitleEdit.Core.Enums;
using Nikse.SubtitleEdit.Logic.Config;

namespace Nikse.SubtitleEdit.Features.Tools.FixCommonErrors;

/// <summary>
/// One entry in the step 1 "Type" filter combo. FixType == null means "all types".
/// </summary>
public class FixTypeDisplayItem
{
public FixType? FixType { get; }
public string Name { get; }

public FixTypeDisplayItem(FixType fixType)
{
FixType = fixType;
Name = Se.Language.Tools.FixCommonErrors.GetFixTypeName(fixType);
}

public FixTypeDisplayItem() // "All" entry
{
FixType = null;
Name = Se.Language.General.All;
}

// The combo uses the default item template, which shows ToString().
public override string ToString()
{
return Name;
}
}
28 changes: 27 additions & 1 deletion src/ui/Logic/Config/Language/Tools/LanguageFixCommonErrors.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Nikse.SubtitleEdit.Logic.Config.Language.Tools;
using Nikse.SubtitleEdit.Core.Enums;

namespace Nikse.SubtitleEdit.Logic.Config.Language.Tools;

public class LanguageFixCommonErrors
{
Expand Down Expand Up @@ -125,6 +127,10 @@ public class LanguageFixCommonErrors
public string FixText { get; set; }
public string RemoveSpaceBetweenNumbers { get; set; }
public string FixDialogsOnOneLine { get; set; }
public string FixTypeFormatting { get; set; }
public string FixTypeDialog { get; set; }
public string FixTypePunctuation { get; set; }
public string FixTypeOcr { get; set; }

public LanguageFixCommonErrors()
{
Expand Down Expand Up @@ -253,5 +259,25 @@ public LanguageFixCommonErrors()
FixText = "Fix text";
RemoveSpaceBetweenNumbers = "Remove space between numbers";
FixDialogsOnOneLine = "Fix dialogs on one line";
FixTypeFormatting = "Formatting";
FixTypeDialog = "Dialog";
FixTypePunctuation = "Punctuation";
FixTypeOcr = "OCR";
}

public string GetFixTypeName(FixType fixType)
{
return fixType switch
{
Core.Enums.FixType.Time => Se.Language.General.Time,
Core.Enums.FixType.Formatting => FixTypeFormatting,
Core.Enums.FixType.Dialog => FixTypeDialog,
Core.Enums.FixType.Punctuation => FixTypePunctuation,
Core.Enums.FixType.Casing => Se.Language.General.Casing,
Core.Enums.FixType.Spacing => Se.Language.General.Spacing,
Core.Enums.FixType.Characters => Se.Language.General.Characters,
Core.Enums.FixType.Ocr => FixTypeOcr,
_ => fixType.ToString(),
};
}
}
Loading