From 9e7294fa6aa7356c9420d1c046ef3c5f9539b4fa Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Mon, 15 Jun 2026 05:29:17 +0200 Subject: [PATCH] Show subtitle count below the right grid in track pickers Add a "Number of subtitles: X" label under the cue grid in the Matroska, MP4 and TS track picker windows. The label lives in its own row so both grids keep the same height. For pickers that cap the preview at 20 rows (BluRay/TextSt/Teletext/DVB), the label reports the true total, not the displayed count. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../PickMatroskaTrackViewModel.cs | 19 ++++++++++++++----- .../PickMatroskaTrackWindow.cs | 6 +++++- .../PickMp4Track/PickMp4TrackViewModel.cs | 5 +++++ .../Shared/PickMp4Track/PickMp4TrackWindow.cs | 6 +++++- .../PickTsTrack/PickTsTrackViewModel.cs | 8 +++++++- .../Shared/PickTsTrack/PickTsTrackWindow.cs | 6 +++++- 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackViewModel.cs b/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackViewModel.cs index f9a335ac0ee..4243a6a3324 100644 --- a/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackViewModel.cs +++ b/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackViewModel.cs @@ -28,6 +28,7 @@ public partial class PickMatroskaTrackViewModel : ObservableObject [ObservableProperty] private ObservableCollection _tracks; [ObservableProperty] private MatroskaTrackInfoDisplay? _selectedTrack; [ObservableProperty] private ObservableCollection _rows; + [ObservableProperty] private string _subtitleCountText; public Window? Window { get; set; } public DataGrid TracksGrid { get; set; } @@ -49,6 +50,7 @@ public PickMatroskaTrackViewModel(IFileHelper fileHelper, IWindowService windowS Tracks = new ObservableCollection(); TracksGrid = new DataGrid(); WindowTitle = string.Empty; + SubtitleCountText = string.Empty; Rows = new ObservableCollection(); _matroskaTracks = new List(); _fileName = string.Empty; @@ -219,31 +221,34 @@ private bool TrackChanged() var selectedTrack = SelectedTrack; if (selectedTrack == null || selectedTrack.MatroskaTrackInfo == null) { + SubtitleCountText = string.Empty; return false; } Rows.Clear(); + var count = 0; var trackInfo = selectedTrack.MatroskaTrackInfo!; var subtitles = _matroskaFile?.GetSubtitle(trackInfo.TrackNumber, null); if (trackInfo.CodecId == MatroskaTrackType.SubRip && subtitles != null) { - AddTextContent(trackInfo, subtitles, new SubRip()); + count = AddTextContent(trackInfo, subtitles, new SubRip()); } else if (trackInfo.CodecId is MatroskaTrackType.SubStationAlpha or MatroskaTrackType.SubStationAlpha2 && subtitles != null) { - AddTextContent(trackInfo, subtitles, new SubStationAlpha()); + count = AddTextContent(trackInfo, subtitles, new SubStationAlpha()); } else if (trackInfo.CodecId is MatroskaTrackType.AdvancedSubStationAlpha or MatroskaTrackType.AdvancedSubStationAlpha2 && subtitles != null) { - AddTextContent(trackInfo, subtitles, new AdvancedSubStationAlpha()); + count = AddTextContent(trackInfo, subtitles, new AdvancedSubStationAlpha()); } else if (trackInfo.CodecId is MatroskaTrackType.WebVTT or MatroskaTrackType.WebVTT2 && subtitles != null) { - AddTextContent(trackInfo, subtitles, new WebVTT()); + count = AddTextContent(trackInfo, subtitles, new WebVTT()); } else if (trackInfo.CodecId == MatroskaTrackType.BluRay && subtitles != null && _matroskaFile != null) { var pcsData = BluRaySupParser.ParseBluRaySupFromMatroska(trackInfo, _matroskaFile); + count = pcsData.Count; for (var i = 0; i < 20 && i < pcsData.Count; i++) { var item = pcsData[i]; @@ -265,6 +270,7 @@ private bool TrackChanged() Utilities.LoadMatroskaTextSubtitle(trackInfo, _matroskaFile, sub, subtitle); Utilities.ParseMatroskaTextSt(trackInfo, sub, subtitle); + count = subtitle.Paragraphs.Count; for (var i = 0; i < 20 && i < subtitle.Paragraphs.Count; i++) { var item = subtitle.Paragraphs[i]; @@ -279,10 +285,11 @@ private bool TrackChanged() } } + SubtitleCountText = string.Format(Se.Language.File.Import.NumberOfSubtitlesX, count); return true; } - private void AddTextContent(MatroskaTrackInfo trackInfo, List subtitles, SubtitleFormat format) + private int AddTextContent(MatroskaTrackInfo trackInfo, List subtitles, SubtitleFormat format) { var sub = new Subtitle(); Utilities.LoadMatroskaTextSubtitle(trackInfo, _matroskaFile, subtitles, sub); @@ -299,6 +306,8 @@ private void AddTextContent(MatroskaTrackInfo trackInfo, List }; Rows.Add(cue); } + + return sub.Paragraphs.Count; } internal void SelectAndScrollToRow(int index) diff --git a/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackWindow.cs b/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackWindow.cs index 9f20985283d..10f76dacfc9 100644 --- a/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackWindow.cs +++ b/src/ui/Features/Shared/PickMatroskaTrack/PickMatroskaTrackWindow.cs @@ -33,12 +33,15 @@ public PickMatroskaTrackWindow(PickMatroskaTrackViewModel vm) var buttonCancel = UiUtil.MakeButtonCancel(vm.CancelCommand); var panelButtons = UiUtil.MakeButtonBar(buttonExport, buttonOk, buttonCancel); + var labelSubtitleCount = UiUtil.MakeLabel(new Binding(nameof(vm.SubtitleCountText))); + var grid = new Grid { RowDefinitions = { new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }, new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, }, ColumnDefinitions = { @@ -53,7 +56,8 @@ public PickMatroskaTrackWindow(PickMatroskaTrackViewModel vm) grid.Add(tracksView, 0); grid.Add(subtitleView, 0, 1); - grid.Add(panelButtons, 1, 0, 1, 2); + grid.Add(labelSubtitleCount, 1, 1); + grid.Add(panelButtons, 2, 0, 1, 2); Content = grid; diff --git a/src/ui/Features/Shared/PickMp4Track/PickMp4TrackViewModel.cs b/src/ui/Features/Shared/PickMp4Track/PickMp4TrackViewModel.cs index 5bafe3f4a47..f4d8b7c9e78 100644 --- a/src/ui/Features/Shared/PickMp4Track/PickMp4TrackViewModel.cs +++ b/src/ui/Features/Shared/PickMp4Track/PickMp4TrackViewModel.cs @@ -5,6 +5,7 @@ using CommunityToolkit.Mvvm.Input; using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes; using Nikse.SubtitleEdit.Logic; +using Nikse.SubtitleEdit.Logic.Config; using SkiaSharp; using System; using System.Collections.Generic; @@ -17,6 +18,7 @@ public partial class PickMp4TrackViewModel : ObservableObject [ObservableProperty] private ObservableCollection _tracks; [ObservableProperty] private Mp4TrackInfoDisplay? _selectedTrack; [ObservableProperty] private ObservableCollection _rows; + [ObservableProperty] private string _subtitleCountText; public Window? Window { get; set; } public DataGrid TracksGrid { get; set; } @@ -31,6 +33,7 @@ public PickMp4TrackViewModel() Tracks = new ObservableCollection(); TracksGrid = new DataGrid(); WindowTitle = string.Empty; + SubtitleCountText = string.Empty; Rows = new ObservableCollection(); _mp4Tracks = new List(); } @@ -103,12 +106,14 @@ private bool TrackChanged() var selectedTrack = SelectedTrack; if (selectedTrack == null || selectedTrack.Track == null) { + SubtitleCountText = string.Empty; return false; } Rows.Clear(); var trackinfo = selectedTrack.Track!; var subtitles = trackinfo.Mdia.Minf.Stbl.GetParagraphs(); + SubtitleCountText = string.Format(Se.Language.File.Import.NumberOfSubtitlesX, subtitles.Count); var i = 0; foreach (var item in subtitles) { diff --git a/src/ui/Features/Shared/PickMp4Track/PickMp4TrackWindow.cs b/src/ui/Features/Shared/PickMp4Track/PickMp4TrackWindow.cs index 8b52459a181..1fc98704196 100644 --- a/src/ui/Features/Shared/PickMp4Track/PickMp4TrackWindow.cs +++ b/src/ui/Features/Shared/PickMp4Track/PickMp4TrackWindow.cs @@ -36,12 +36,15 @@ public PickMp4TrackWindow(PickMp4TrackViewModel vm) var buttonCancel = UiUtil.MakeButtonCancel(vm.CancelCommand); var panelButtons = UiUtil.MakeButtonBar(buttonExport, buttonOk, buttonCancel); + var labelSubtitleCount = UiUtil.MakeLabel(new Binding(nameof(vm.SubtitleCountText))); + var grid = new Grid { RowDefinitions = { new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }, new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, }, ColumnDefinitions = { @@ -56,7 +59,8 @@ public PickMp4TrackWindow(PickMp4TrackViewModel vm) grid.Add(tracksView, 0, 0); grid.Add(subtitleView, 0, 1); - grid.Add(panelButtons, 1, 0, 1, 2); + grid.Add(labelSubtitleCount, 1, 1); + grid.Add(panelButtons, 2, 0, 1, 2); Content = grid; diff --git a/src/ui/Features/Shared/PickTsTrack/PickTsTrackViewModel.cs b/src/ui/Features/Shared/PickTsTrack/PickTsTrackViewModel.cs index 7129c2d3df4..dee43fd6121 100644 --- a/src/ui/Features/Shared/PickTsTrack/PickTsTrackViewModel.cs +++ b/src/ui/Features/Shared/PickTsTrack/PickTsTrackViewModel.cs @@ -7,6 +7,7 @@ using Nikse.SubtitleEdit.Core.ContainerFormats.TransportStream; using Nikse.SubtitleEdit.Features.Ocr; using Nikse.SubtitleEdit.Logic; +using Nikse.SubtitleEdit.Logic.Config; using System; using System.Collections.ObjectModel; using System.Linq; @@ -18,6 +19,7 @@ public partial class PickTsTrackViewModel : ObservableObject [ObservableProperty] private ObservableCollection _tracks; [ObservableProperty] private TsTrackInfoDisplay? _selectedTrack; [ObservableProperty] private ObservableCollection _rows; + [ObservableProperty] private string _subtitleCountText; public Window? Window { get; set; } public DataGrid TracksGrid { get; set; } @@ -33,6 +35,7 @@ public PickTsTrackViewModel() Tracks = new ObservableCollection(); TracksGrid = new DataGrid(); WindowTitle = string.Empty; + SubtitleCountText = string.Empty; Rows = new ObservableCollection(); TeletextSubtitle = new Subtitle(); } @@ -130,6 +133,7 @@ private bool TrackChanged() var selectedTrack = SelectedTrack; if (selectedTrack == null || _tsParser == null) { + SubtitleCountText = string.Empty; return false; } @@ -137,9 +141,10 @@ private bool TrackChanged() if (selectedTrack.IsTeletext) { - var subtitle = new Subtitle(selectedTrack.Teletext); + var subtitle = new Subtitle(selectedTrack.Teletext); subtitle.Renumber(); TeletextSubtitle = subtitle; + SubtitleCountText = string.Format(Se.Language.File.Import.NumberOfSubtitlesX, subtitle.Paragraphs.Count); foreach (var p in subtitle.Paragraphs.Take(20)) { var cue = new TsSubtitleCueDisplay() @@ -157,6 +162,7 @@ private bool TrackChanged() } var subtitles = _tsParser.GetDvbSubtitles(selectedTrack.TrackNumber); + SubtitleCountText = string.Format(Se.Language.File.Import.NumberOfSubtitlesX, subtitles.Count); for (var i = 0; i < 20 && i < subtitles.Count; i++) { var item = subtitles[i]; diff --git a/src/ui/Features/Shared/PickTsTrack/PickTsTrackWindow.cs b/src/ui/Features/Shared/PickTsTrack/PickTsTrackWindow.cs index 21ab7678c63..407928135ff 100644 --- a/src/ui/Features/Shared/PickTsTrack/PickTsTrackWindow.cs +++ b/src/ui/Features/Shared/PickTsTrack/PickTsTrackWindow.cs @@ -31,12 +31,15 @@ public PickTsTrackWindow(PickTsTrackViewModel vm) var buttonCancel = UiUtil.MakeButtonCancel(vm.CancelCommand); var panelButtons = UiUtil.MakeButtonBar(buttonExport, buttonOk, buttonCancel); + var labelSubtitleCount = UiUtil.MakeLabel(new Binding(nameof(vm.SubtitleCountText))); + var grid = new Grid { RowDefinitions = { new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }, new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, }, ColumnDefinitions = { @@ -51,7 +54,8 @@ public PickTsTrackWindow(PickTsTrackViewModel vm) grid.Add(tracksView, 0, 0); grid.Add(subtitleView, 0, 1); - grid.Add(panelButtons, 1, 0, 1, 2); + grid.Add(labelSubtitleCount, 1, 1); + grid.Add(panelButtons, 2, 0, 1, 2); Content = grid;