Add chapters display, gray out fixed tracks, spacebar preview
This commit is contained in:
+8
-1
@@ -233,6 +233,12 @@
|
|||||||
<Trigger Property="IsSelected" Value="True">
|
<Trigger Property="IsSelected" Value="True">
|
||||||
<Setter Property="Background" Value="{DynamicResource AccentFillColorSecondaryBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource AccentFillColorSecondaryBrush}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
|
<DataTrigger Binding="{Binding Type}" Value="video">
|
||||||
|
<Setter Property="Opacity" Value="0.5"/>
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Type}" Value="chapters">
|
||||||
|
<Setter Property="Opacity" Value="0.5"/>
|
||||||
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGrid.RowStyle>
|
</DataGrid.RowStyle>
|
||||||
@@ -259,13 +265,14 @@
|
|||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<CheckBox IsChecked="{Binding Copy, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<CheckBox IsChecked="{Binding Copy, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
IsEnabled="{Binding IsEditable}"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
|
||||||
<DataGridTextColumn Header="ID"
|
<DataGridTextColumn Header="ID"
|
||||||
Binding="{Binding Id}" Width="45" IsReadOnly="True"/>
|
Binding="{Binding IdDisplay}" Width="45" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn Header="Codec"
|
<DataGridTextColumn Header="Codec"
|
||||||
Binding="{Binding Codec}" Width="185" IsReadOnly="True"/>
|
Binding="{Binding Codec}" Width="185" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn Header="Language"
|
<DataGridTextColumn Header="Language"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@@ -357,6 +358,13 @@ public partial class MainWindow : FluentWindow
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void FileQueueList_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
private void FileQueueList_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (e.Key == System.Windows.Input.Key.Space)
|
||||||
|
{
|
||||||
|
OpenSelectedFileInDefaultPlayer();
|
||||||
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.Key != System.Windows.Input.Key.Delete) return;
|
if (e.Key != System.Windows.Input.Key.Delete) return;
|
||||||
|
|
||||||
var selected = FileQueueList.SelectedItems.Cast<QueuedFileItem>().ToList();
|
var selected = FileQueueList.SelectedItems.Cast<QueuedFileItem>().ToList();
|
||||||
@@ -371,6 +379,25 @@ public partial class MainWindow : FluentWindow
|
|||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the currently-selected queue item with whatever application
|
||||||
|
/// Windows has associated with .mkv files (typically the default video
|
||||||
|
/// player), so the user can quickly preview a file without leaving the app.
|
||||||
|
/// </summary>
|
||||||
|
private void OpenSelectedFileInDefaultPlayer()
|
||||||
|
{
|
||||||
|
if (FileQueueList.SelectedItem is not QueuedFileItem item) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo(item.FilePath) { UseShellExecute = true });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatusText.Text = $"Couldn't open {item.FileName}: {ex.Message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearQueueButton_Click(object sender, RoutedEventArgs e)
|
private void ClearQueueButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
foreach (var item in _fileQueue)
|
foreach (var item in _fileQueue)
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ public class MkvIdentifyResult
|
|||||||
|
|
||||||
[JsonPropertyName("tracks")]
|
[JsonPropertyName("tracks")]
|
||||||
public List<MkvTrack> Tracks { get; set; } = new();
|
public List<MkvTrack> Tracks { get; set; } = new();
|
||||||
|
|
||||||
|
[JsonPropertyName("chapters")]
|
||||||
|
public List<MkvChapters> Chapters { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MkvChapters
|
||||||
|
{
|
||||||
|
[JsonPropertyName("num_entries")]
|
||||||
|
public int NumEntries { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MkvTrack
|
public class MkvTrack
|
||||||
|
|||||||
@@ -44,6 +44,20 @@ public class TrackItem : INotifyPropertyChanged
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string DisplayName => Type == "subtitles" ? $"{Codec}/{Name}" : Name;
|
public string DisplayName => Type == "subtitles" ? $"{Codec}/{Name}" : Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Video is always kept, and chapters (a synthetic pseudo-track, not a
|
||||||
|
/// real mkvmerge track) are always kept too — neither is user-selectable,
|
||||||
|
/// so their Copy checkbox is shown checked but disabled.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEditable => Type is "audio" or "subtitles";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chapters aren't a real track and have no track ID; show a dash
|
||||||
|
/// instead of a meaningless number.
|
||||||
|
/// </summary>
|
||||||
|
public string IdDisplay => Type == "chapters" ? "—" : Id.ToString();
|
||||||
|
|
||||||
|
|
||||||
public bool Copy
|
public bool Copy
|
||||||
{
|
{
|
||||||
get => _copy;
|
get => _copy;
|
||||||
|
|||||||
+17
-1
@@ -110,7 +110,7 @@ public class MkvService
|
|||||||
MkvTrack? preferredAudio = eligibleAudio.FirstOrDefault(t => t.Properties?.AudioChannels == 2)
|
MkvTrack? preferredAudio = eligibleAudio.FirstOrDefault(t => t.Properties?.AudioChannels == 2)
|
||||||
?? eligibleAudio.FirstOrDefault();
|
?? eligibleAudio.FirstOrDefault();
|
||||||
|
|
||||||
return info.Tracks.Select(t =>
|
var items = info.Tracks.Select(t =>
|
||||||
{
|
{
|
||||||
bool copy = t.Type switch
|
bool copy = t.Type switch
|
||||||
{
|
{
|
||||||
@@ -136,6 +136,22 @@ public class MkvService
|
|||||||
Copy = copy,
|
Copy = copy,
|
||||||
};
|
};
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
|
int chapterCount = info.Chapters.Sum(c => c.NumEntries);
|
||||||
|
if (chapterCount > 0)
|
||||||
|
{
|
||||||
|
items.Add(new TrackItem
|
||||||
|
{
|
||||||
|
Id = -1,
|
||||||
|
Type = "chapters",
|
||||||
|
Codec = string.Empty,
|
||||||
|
Language = string.Empty,
|
||||||
|
Name = $"Chapters ({chapterCount})",
|
||||||
|
Copy = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user