diff options
author | sr55 <[email protected]> | 2012-03-04 16:27:56 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2012-03-04 16:27:56 +0000 |
commit | 376eae49e2c14f4acdbd644908e162ac6a2c5c3e (patch) | |
tree | 1093c1625c7a1c4399b9d114eb7bbecba9c4b65c | |
parent | 24bbf1b361a7b9cb78208b43cfec59173757ae24 (diff) |
WinGui: (WPF) Add basic Preview window.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4495 b64f7644-9d1e-0410-96f1-a4d463321fa5
6 files changed, 437 insertions, 13 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs index 16d8d1694..6e2d59667 100644 --- a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs +++ b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs @@ -32,8 +32,6 @@ namespace HandBrake.ApplicationServices.Model this.AllowedPassthruOptions = new AllowedPassthru();
}
- #region Source
-
/// <summary>
/// Initializes a new instance of the <see cref="EncodeTask"/> class.
/// Copy Constructor
@@ -121,8 +119,13 @@ namespace HandBrake.ApplicationServices.Model this.x264Preset = task.x264Preset;
this.x264Profile = task.x264Profile;
this.X264Tune = task.X264Tune;
+
+ this.PreviewStartAt = task.PreviewStartAt;
+ this.PreviewDuration = task.PreviewDuration;
}
+ #region Source
+
/// <summary>
/// Gets or sets Source.
/// </summary>
@@ -421,6 +424,19 @@ namespace HandBrake.ApplicationServices.Model #endregion
+ #region Preview
+
+ /// <summary>
+ /// Gets or sets StartAt.
+ /// </summary>
+ public int? PreviewStartAt { get; set; }
+
+ /// <summary>
+ /// Gets or sets Duration.
+ /// </summary>
+ public int? PreviewDuration { get; set; }
+ #endregion
+
#region Preset Information (TODO This should probably be dropped)
/// <summary>
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs index 84c6252a2..e2eacce72 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs @@ -366,7 +366,7 @@ namespace HandBrake.ApplicationServices.Services.Base // Make sure the path exists, attempt to create it if it doesn't
try
{
- string path = Directory.GetParent(task.Destination).ToString();
+ string path = Directory.GetParent(task.Destination ?? task.Task.Destination).ToString();
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPreviewViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPreviewViewModel.cs index f0a7bb660..ba20434e5 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPreviewViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPreviewViewModel.cs @@ -9,10 +9,16 @@ namespace HandBrakeWPF.ViewModels.Interfaces
{
+ using HandBrake.ApplicationServices.Model;
+
/// <summary>
/// The Preview View Model Interface
/// </summary>
public interface IPreviewViewModel
{
+ /// <summary>
+ /// Sets Task.
+ /// </summary>
+ EncodeTask Task { set; }
}
}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index e8e584f60..a0d1ee15c 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -704,7 +704,9 @@ namespace HandBrakeWPF.ViewModels /// </summary>
public void OpenPreviewWindow()
{
- this.WindowManager.ShowWindow(IoC.Get<IPreviewViewModel>());
+ IPreviewViewModel viewModel = IoC.Get<IPreviewViewModel>();
+ this.WindowManager.ShowWindow(viewModel);
+ viewModel.Task = this.CurrentTask;
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs index 0f9c7a213..e2efe673f 100644 --- a/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs @@ -9,31 +9,403 @@ namespace HandBrakeWPF.ViewModels
{
- using Interfaces;
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using System.Threading;
+ using System.Windows;
+
using Caliburn.Micro;
+ using HandBrake.ApplicationServices;
+ using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Model.Encoding;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrake.ApplicationServices.Utilities;
+
+ using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.ViewModels.Interfaces;
+
/// <summary>
/// The About View Model
/// </summary>
public class PreviewViewModel : ViewModelBase, IPreviewViewModel
{
+ #region Constants and Fields
+
+ /// <summary>
+ /// Backing field for the encode service.
+ /// </summary>
+ private readonly IEncode encodeService;
+
+ /// <summary>
+ /// The error service
+ /// </summary>
+ private readonly IErrorService errorService;
+
+ /// <summary>
+ /// The user Setting Service
+ /// </summary>
+ private readonly IUserSettingService userSettingService;
+
+ /// <summary>
+ /// The percentage.
+ /// </summary>
+ private string percentage;
+
+ /// <summary>
+ /// The percentage value.
+ /// </summary>
+ private double percentageValue;
+
+ /// <summary>
+ /// The Backing field for IsEncoding
+ /// </summary>
+ private bool isEncoding;
+
+ /// <summary>
+ /// Backing field for use system default player
+ /// </summary>
+ private bool useSystemDefaultPlayer;
+
+ #endregion
+
+ #region Constructors and Destructors
+
/// <summary>
/// Initializes a new instance of the <see cref="PreviewViewModel"/> class.
/// </summary>
/// <param name="windowManager">
/// The window manager.
/// </param>
- public PreviewViewModel(IWindowManager windowManager)
+ /// <param name="encodeService">
+ /// The encode Service.
+ /// </param>
+ /// <param name="errorService">
+ /// The error Service.
+ /// </param>
+ /// <param name="userSettingService">
+ /// The user Setting Service.
+ /// </param>
+ public PreviewViewModel(IWindowManager windowManager, IEncode encodeService, IErrorService errorService, IUserSettingService userSettingService)
{
+ this.encodeService = encodeService;
+ this.errorService = errorService;
+ this.userSettingService = userSettingService;
this.Title = "Preview";
+ this.Percentage = "0.00%";
+ this.PercentageValue = 0;
+ this.StartAt = 1;
+ this.Duration = 30;
+
+ UseSystemDefaultPlayer = userSettingService.GetUserSetting<bool>(UserSettingConstants.DefaultPlayer);
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets Task.
+ /// </summary>
+ public EncodeTask Task { get; set; }
+
+ /// <summary>
+ /// Gets AvailableDurations.
+ /// </summary>
+ public IEnumerable<int> AvailableDurations
+ {
+ get
+ {
+ return new List<int> { 10, 30, 45, 60, 75, 90, 105, 120 };
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Duration.
+ /// </summary>
+ public int Duration { get; set; }
+
+ /// <summary>
+ /// Gets or sets Percentage.
+ /// </summary>
+ public string Percentage
+ {
+ get
+ {
+ return this.percentage;
+ }
+
+ set
+ {
+ this.percentage = value;
+ this.NotifyOfPropertyChange(() => this.Percentage);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets PercentageValue.
+ /// </summary>
+ public double PercentageValue
+ {
+ get
+ {
+ return this.percentageValue;
+ }
+
+ set
+ {
+ this.percentageValue = value;
+ this.NotifyOfPropertyChange(() => this.PercentageValue);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets StartAt.
+ /// </summary>
+ public int StartAt { get; set; }
+
+ /// <summary>
+ /// Gets StartPoints.
+ /// </summary>
+ public IEnumerable<int> StartPoints
+ {
+ get
+ {
+ List<int> startPoints = new List<int>();
+ for (int i = 1;
+ i <= this.UserSettingService.GetUserSetting<int>(ASUserSettingConstants.PreviewScanCount);
+ i++)
+ {
+ startPoints.Add(i);
+ }
+
+ return startPoints;
+ }
}
/// <summary>
+ /// Gets or sets a value indicating whether UseSystemDefaultPlayer.
+ /// </summary>
+ public bool UseSystemDefaultPlayer
+ {
+ get
+ {
+ return this.useSystemDefaultPlayer;
+ }
+ set
+ {
+ this.useSystemDefaultPlayer = value;
+ this.NotifyOfPropertyChange(() => UseSystemDefaultPlayer);
+ this.userSettingService.SetUserSetting(UserSettingConstants.DefaultPlayer, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IsEncoding.
+ /// </summary>
+ public bool IsEncoding
+ {
+ get
+ {
+ return this.isEncoding;
+ }
+ set
+ {
+ this.isEncoding = value;
+ this.NotifyOfPropertyChange(() => this.IsEncoding);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the Currently Playing / Encoding Filename.
+ /// </summary>
+ public string CurrentlyPlaying { get; set; }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
/// Close this window.
/// </summary>
public void Close()
{
this.TryClose();
}
+
+ /// <summary>
+ /// Handle The Initialisation
+ /// </summary>
+ public override void OnLoad()
+ {
+ }
+
+ /// <summary>
+ /// Encode and play a sample
+ /// </summary>
+ public void Play()
+ {
+ try
+ {
+ this.IsEncoding = true;
+ if (File.Exists(this.CurrentlyPlaying))
+ File.Delete(this.CurrentlyPlaying);
+ }
+ catch (Exception)
+ {
+ this.IsEncoding = false;
+ this.errorService.ShowMessageBox("Unable to delete previous preview file. You may need to restart the application.",
+ "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+
+ if (this.Task == null || string.IsNullOrEmpty(Task.Source))
+ {
+ this.errorService.ShowMessageBox("You must first scan a source and setup your encode before creating a perview.",
+ "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ EncodeTask encodeTask = new EncodeTask(this.Task)
+ {
+ PreviewDuration = this.Duration,
+ PreviewStartAt = this.StartAt,
+ PointToPointMode = PointToPointMode.Preview
+ };
+
+ this.CurrentlyPlaying = encodeTask.Destination.Replace(".m", "_sample.m");
+
+ QueueTask task = new QueueTask
+ {
+ Task = encodeTask,
+ Query = QueryGeneratorUtility.GeneratePreviewQuery(encodeTask, this.Duration, this.StartAt.ToString(CultureInfo.InvariantCulture)),
+ };
+
+ ThreadPool.QueueUserWorkItem(this.CreatePreview, task);
+ }
+
+ #endregion
+
+ #region Private Methods
+ /// <summary>
+ /// Play the Encoded file
+ /// </summary>
+ private void PlayFile()
+ {
+ // Launch VLC and Play video.
+ if (this.CurrentlyPlaying != string.Empty)
+ {
+ if (File.Exists(this.CurrentlyPlaying))
+ {
+ string args = "\"" + this.CurrentlyPlaying + "\"";
+
+ if (this.UseSystemDefaultPlayer)
+ {
+ Process.Start(args);
+ }
+ else
+ {
+ if (!File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLC_Path)))
+ {
+ // Attempt to find VLC if it doesn't exist in the default set location.
+ string vlcPath;
+
+ if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"))))
+ vlcPath = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
+ else
+ vlcPath = Environment.GetEnvironmentVariable("ProgramFiles");
+
+ if (!string.IsNullOrEmpty(vlcPath))
+ {
+ vlcPath = Path.Combine(vlcPath, "VideoLAN\\VLC\\vlc.exe");
+ }
+
+ if (File.Exists(vlcPath))
+ {
+ UserSettingService.SetUserSetting(UserSettingConstants.VLC_Path, vlcPath);
+ }
+ else
+ {
+ this.errorService.ShowMessageBox("Unable to detect VLC Player. \nPlease make sure VLC is installed and the directory specified in HandBrake's options is correct. (See: \"Tools Menu > Options > Picture Tab\")",
+ "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+
+ if (File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLC_Path)))
+ {
+ ProcessStartInfo vlc = new ProcessStartInfo(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLC_Path), args);
+ Process.Start(vlc);
+ }
+ }
+ }
+ else
+ {
+ this.errorService.ShowMessageBox("Unable to find the preview file. Either the file was deleted or the encode failed. Check the activity log for details.",
+ "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Create the Preview.
+ /// </summary>
+ /// <param name="state">
+ /// The state.
+ /// </param>
+ private void CreatePreview(object state)
+ {
+ // Make sure we are not already encoding and if we are then display an error.
+ if (encodeService.IsEncoding)
+ {
+ this.errorService.ShowMessageBox("Handbrake is already encoding a video! Only one file can be encoded at any one time.",
+ "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ this.encodeService.EncodeCompleted += this.encodeService_EncodeCompleted;
+ this.encodeService.EncodeStatusChanged += this.encodeService_EncodeStatusChanged;
+
+ this.encodeService.Start((QueueTask)state, false);
+ }
+ #endregion
+
+ #region Event Handlers
+ /// <summary>
+ /// Handle Encode Progress Events
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EncodeProgressEventArgs.
+ /// </param>
+ private void encodeService_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs e)
+ {
+ this.Percentage = string.Format("{0} %", e.PercentComplete.ToString(CultureInfo.InvariantCulture));
+ this.PercentageValue = e.PercentComplete;
+ }
+
+ /// <summary>
+ /// Handle the Encode Completed Event
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EncodeCompletedEventArgs.
+ /// </param>
+ private void encodeService_EncodeCompleted(object sender, HandBrake.ApplicationServices.EventArgs.EncodeCompletedEventArgs e)
+ {
+ this.Percentage = "0.00%";
+ this.PercentageValue = 0;
+
+ this.encodeService.EncodeCompleted -= this.encodeService_EncodeCompleted;
+ this.encodeService.EncodeStatusChanged -= this.encodeService_EncodeStatusChanged;
+
+ this.PlayFile();
+ }
+ #endregion
}
-}
+}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Views/PreviewView.xaml b/win/CS/HandBrakeWPF/Views/PreviewView.xaml index caf0aaca8..4a5399b69 100644 --- a/win/CS/HandBrakeWPF/Views/PreviewView.xaml +++ b/win/CS/HandBrakeWPF/Views/PreviewView.xaml @@ -2,11 +2,39 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- mc:Ignorable="d"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:cal="http://www.caliburnproject.org"
+ mc:Ignorable="d"
Title="{Binding Title}"
- Width="300" Height="300">
- <Grid Background="Beige">
-
- </Grid>
+ Width="380" Height="140">
+
+ <Window.Resources>
+ <Style TargetType="Button">
+ <Setter Property="Foreground" Value="DarkOrange" />
+ <Setter Property="FontWeight" Value="Bold" />
+ <Setter Property="Padding" Value="5,1" />
+ <Setter Property="FontSize" Value="11.5" />
+ <Setter Property="VerticalAlignment" Value="Center" />
+ </Style>
+ </Window.Resources>
+
+ <StackPanel Orientation="Vertical" Margin="10,10,0,0">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="Start at Preview:" Margin="0,0,5,0" VerticalAlignment="Center" />
+ <ComboBox ItemsSource="{Binding StartPoints}" Width="60" SelectedItem="{Binding StartAt}" />
+
+ <TextBlock Text="Duration:" VerticalAlignment="Center" Margin="10,0,5,0" />
+ <ComboBox ItemsSource="{Binding AvailableDurations}" Width="60" SelectedItem="{Binding Duration}" />
+ </StackPanel>
+
+ <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
+ <ProgressBar Minimum="0" Maximum="100" Width="310" Height="22" Value="{Binding PercentageValue}" />
+ <TextBlock Text="{Binding Percentage}" Margin="5,0,0,0" />
+ </StackPanel>
+
+ <StackPanel Orientation="Horizontal" Margin="0,10,0,0" Width="360">
+ <CheckBox Content="Use system default player" IsChecked="{Binding UseSystemDefaultPlayer}" />
+ <Button Content="Play" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10,0,0,0"
+ cal:Message.Attach="[Event Click] = [Action Play]" />
+ </StackPanel>
+ </StackPanel>
</Window>
|