<Compile Include="ViewModels\Interfaces\IAddPresetViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IAudioViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IQueueViewModel.cs" />\r
- <Compile Include="ViewModels\Interfaces\IPreviewViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IErrorViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\ILogViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IAboutViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IOptionsViewModel.cs" />\r
<Compile Include="ViewModels\Interfaces\IViewModelBase.cs" />\r
<Compile Include="ViewModels\LogViewModel.cs" />\r
- <Compile Include="ViewModels\PreviewViewModel.cs" />\r
<Compile Include="ViewModels\QueueViewModel.cs" />\r
<Compile Include="ViewModels\OptionsViewModel.cs" />\r
<Compile Include="ViewModels\ViewModelBase.cs" />\r
<Compile Include="Views\LogView.xaml.cs">\r
<DependentUpon>LogView.xaml</DependentUpon>\r
</Compile>\r
- <Compile Include="Views\PreviewView.xaml.cs">\r
- <DependentUpon>PreviewView.xaml</DependentUpon>\r
- </Compile>\r
<Compile Include="Views\QueueView.xaml.cs">\r
<DependentUpon>QueueView.xaml</DependentUpon>\r
</Compile>\r
<SubType>Designer</SubType>\r
<Generator>MSBuild:Compile</Generator>\r
</Page>\r
- <Page Include="Views\PreviewView.xaml">\r
- <Generator>MSBuild:Compile</Generator>\r
- <SubType>Designer</SubType>\r
- </Page>\r
<Page Include="Views\QueueView.xaml">\r
<Generator>MSBuild:Compile</Generator>\r
<SubType>Designer</SubType>\r
}\r
\r
/// <summary>\r
- /// Looks up a localized string similar to *** EXPERIMENTAL *** Still Preview.\r
+ /// Looks up a localized string similar to Preview.\r
/// </summary>\r
public static string Preview {\r
get {\r
}\r
\r
/// <summary>\r
- /// Looks up a localized string similar to *** EXPERIMENTAL *** Still Preview (Scaled).\r
+ /// Looks up a localized string similar to Preview (Scaled).\r
/// </summary>\r
public static string Preview_Scaled {\r
get {\r
<value>The entered destination contained illegal characters. You must fix the path and filename before continuing.</value>\r
</data>\r
<data name="Preview" xml:space="preserve">\r
- <value>*** EXPERIMENTAL *** Still Preview</value>\r
+ <value>Preview</value>\r
</data>\r
<data name="Preview_Scaled" xml:space="preserve">\r
- <value> *** EXPERIMENTAL *** Still Preview (Scaled)</value>\r
+ <value>Preview (Scaled)</value>\r
</data>\r
<data name="PictureSettings_OutputResolution" xml:space="preserve">\r
<value>Output: {0}</value>\r
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
// </copyright>\r
// <summary>\r
-// We have multiple implementations of IEncode. This is a wrapper class for the GUI so that the \r
+// We have multiple implementations of IEncode. This is a wrapper class for the GUI so that the\r
// implementation used is controllable via user settings.\r
// Over time, this class will go away when the LibHB and process isolation code matures.\r
// </summary>\r
using HandBrake.ApplicationServices.Services.Encode;\r
using HandBrake.ApplicationServices.Services.Encode.EventArgs;\r
using HandBrake.ApplicationServices.Services.Encode.Interfaces;\r
- using HandBrake.ApplicationServices.Services.Interfaces;\r
\r
using HandBrakeWPF.Services.Interfaces;\r
\r
{\r
// Try to recover from errors.\r
throw new GeneralApplicationException(\r
- "Unable to initialise LibHB or Background worker service",\r
- "Falling back to using HandBrakeCLI.exe. Setting has been reset",\r
+ "Unable to initialise LibHB or Background worker service", \r
+ "Falling back to using HandBrakeCLI.exe. Setting has been reset", \r
exc);\r
}\r
}\r
this.windsorContainer.Register(Component.For<IShellViewModel>().ImplementedBy<ShellViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IQueueViewModel>().ImplementedBy<QueueViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IAddPresetViewModel>().ImplementedBy<AddPresetViewModel>().LifeStyle.Is(LifestyleType.Transient));\r
- this.windsorContainer.Register(Component.For<IPreviewViewModel>().ImplementedBy<PreviewViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<ILogViewModel>().ImplementedBy<LogViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IAboutViewModel>().ImplementedBy<AboutViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IOptionsViewModel>().ImplementedBy<OptionsViewModel>().LifeStyle.Is(LifestyleType.Singleton));\r
+++ /dev/null
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="IPreviewViewModel.cs" company="HandBrake Project (http://handbrake.fr)">\r
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
-// </copyright>\r
-// <summary>\r
-// The Preview View Model Interface\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrakeWPF.ViewModels.Interfaces\r
-{\r
- using HandBrake.ApplicationServices.Model;\r
- using HandBrake.ApplicationServices.Services.Encode.Model;\r
-\r
- /// <summary>\r
- /// The Preview View Model Interface\r
- /// </summary>\r
- public interface IPreviewViewModel\r
- {\r
- /// <summary>\r
- /// Sets Task.\r
- /// </summary>\r
- EncodeTask Task { set; }\r
- }\r
-}
\ No newline at end of file
}\r
}\r
\r
+ /// <summary>\r
+ /// Gets or sets the static preview view model.\r
+ /// </summary>\r
+ public IStaticPreviewViewModel StaticPreviewViewModel { get; set; }\r
+\r
#endregion\r
\r
#region Load and Shutdown Handling\r
/// </summary>\r
public void OpenPreviewWindow()\r
{\r
- Window window = Application.Current.Windows.Cast<Window>().FirstOrDefault(x => x.GetType() == typeof(PreviewView));\r
- IPreviewViewModel viewModel = IoC.Get<IPreviewViewModel>();\r
-\r
- if (window != null)\r
+ if (!string.IsNullOrEmpty(this.CurrentTask.Source))\r
{\r
- viewModel.Task = this.CurrentTask;\r
- window.Activate();\r
- }\r
- else\r
- {\r
- viewModel.Task = this.CurrentTask;\r
- this.WindowManager.ShowWindow(viewModel);\r
+ this.StaticPreviewViewModel.IsOpen = true;\r
+ this.StaticPreviewViewModel.UpdatePreviewFrame(this.CurrentTask);\r
+ this.WindowManager.ShowWindow(this.StaticPreviewViewModel);\r
}\r
}\r
\r
this.ChaptersViewModel.UpdateTask(this.CurrentTask);\r
this.AdvancedViewModel.UpdateTask(this.CurrentTask);\r
\r
- // Tell the Preivew Window\r
- IPreviewViewModel viewModel = IoC.Get<IPreviewViewModel>();\r
- viewModel.Task = this.CurrentTask;\r
-\r
// Cleanup\r
this.ShowStatusWindow = false;\r
this.SourceLabel = this.SourceName;\r
this.NotifyOfPropertyChange(() => this.Task);\r
}\r
\r
- /// <summary>\r
- /// The preview image.\r
- /// Experimental Feature => In-Progress\r
- /// </summary>\r
- public void PreviewImage()\r
- {\r
- if (!string.IsNullOrEmpty(this.Task.Source))\r
- {\r
- this.StaticPreviewViewModel.IsOpen = true;\r
- this.StaticPreviewViewModel.UpdatePreviewFrame(this.Task);\r
- this.WindowManager.ShowWindow(this.StaticPreviewViewModel);\r
- }\r
- }\r
-\r
#endregion\r
\r
#region Methods\r
+++ /dev/null
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="PreviewViewModel.cs" company="HandBrake Project (http://handbrake.fr)">\r
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
-// </copyright>\r
-// <summary>\r
-// The About View Model\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrakeWPF.ViewModels\r
-{\r
- using System;\r
- using System.Collections.Generic;\r
- using System.Diagnostics;\r
- using System.Globalization;\r
- using System.IO;\r
- using System.Threading;\r
- using System.Windows;\r
-\r
- using HandBrake.ApplicationServices.Model;\r
- using HandBrake.ApplicationServices.Services.Encode.EventArgs;\r
- using HandBrake.ApplicationServices.Services.Encode.Interfaces;\r
- using HandBrake.ApplicationServices.Services.Encode.Model;\r
- using HandBrake.ApplicationServices.Services.Encode.Model.Models;\r
- using HandBrake.ApplicationServices.Services.Interfaces;\r
-\r
- using HandBrakeWPF.Factories;\r
- using HandBrakeWPF.Properties;\r
- using HandBrakeWPF.Services;\r
- using HandBrakeWPF.Services.Interfaces;\r
- using HandBrakeWPF.ViewModels.Interfaces;\r
-\r
- /// <summary>\r
- /// The About View Model\r
- /// </summary>\r
- public class PreviewViewModel : ViewModelBase, IPreviewViewModel\r
- {\r
- #region Constants and Fields\r
-\r
- /// <summary>\r
- /// Backing field for the encode service.\r
- /// </summary>\r
- private readonly IEncodeServiceWrapper encodeService;\r
-\r
- /// <summary>\r
- /// The error service\r
- /// </summary>\r
- private readonly IErrorService errorService;\r
-\r
- /// <summary>\r
- /// The user Setting Service\r
- /// </summary>\r
- private readonly IUserSettingService userSettingService;\r
-\r
- /// <summary>\r
- /// The percentage.\r
- /// </summary>\r
- private string percentage;\r
-\r
- /// <summary>\r
- /// The percentage value.\r
- /// </summary>\r
- private double percentageValue;\r
-\r
- /// <summary>\r
- /// The Backing field for IsEncoding\r
- /// </summary>\r
- private bool isEncoding;\r
-\r
- /// <summary>\r
- /// Backing field for use system default player\r
- /// </summary>\r
- private bool useSystemDefaultPlayer;\r
-\r
- #endregion\r
-\r
- #region Constructors and Destructors\r
-\r
- /// <summary>\r
- /// Initializes a new instance of the <see cref="PreviewViewModel"/> class.\r
- /// </summary>\r
- /// <param name="errorService">\r
- /// The error Service.\r
- /// </param>\r
- /// <param name="userSettingService">\r
- /// The user Setting Service.\r
- /// </param>\r
- public PreviewViewModel(IErrorService errorService, IUserSettingService userSettingService)\r
- {\r
- // Preview needs a seperate instance rather than the shared singleton. This could maybe do with being refactored at some point\r
- this.encodeService = new EncodeServiceWrapper(userSettingService);\r
-\r
- this.errorService = errorService;\r
- this.userSettingService = userSettingService;\r
- this.Title = "Preview";\r
- this.Percentage = "0.00%";\r
- this.PercentageValue = 0;\r
- this.StartAt = 1;\r
- this.Duration = 30;\r
- this.CanPlay = true;\r
-\r
- UseSystemDefaultPlayer = userSettingService.GetUserSetting<bool>(UserSettingConstants.DefaultPlayer);\r
- this.Duration = userSettingService.GetUserSetting<int>(UserSettingConstants.LastPreviewDuration);\r
- }\r
-\r
- #endregion\r
-\r
- #region Properties\r
-\r
- /// <summary>\r
- /// Gets or sets Task.\r
- /// </summary>\r
- public EncodeTask Task { get; set; }\r
-\r
- /// <summary>\r
- /// Gets AvailableDurations.\r
- /// </summary>\r
- public IEnumerable<int> AvailableDurations\r
- {\r
- get\r
- {\r
- return new List<int> { 5, 10, 30, 45, 60, 75, 90, 105, 120, 150, 180, 210, 240 };\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets Duration.\r
- /// </summary>\r
- public int Duration { get; set; }\r
-\r
- /// <summary>\r
- /// Gets or sets Percentage.\r
- /// </summary>\r
- public string Percentage\r
- {\r
- get\r
- {\r
- return this.percentage;\r
- }\r
-\r
- set\r
- {\r
- this.percentage = value;\r
- this.NotifyOfPropertyChange(() => this.Percentage);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets PercentageValue.\r
- /// </summary>\r
- public double PercentageValue\r
- {\r
- get\r
- {\r
- return this.percentageValue;\r
- }\r
-\r
- set\r
- {\r
- this.percentageValue = value;\r
- this.NotifyOfPropertyChange(() => this.PercentageValue);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets StartAt.\r
- /// </summary>\r
- public int StartAt { get; set; }\r
-\r
- /// <summary>\r
- /// Gets StartPoints.\r
- /// </summary>\r
- public IEnumerable<int> StartPoints\r
- {\r
- get\r
- {\r
- List<int> startPoints = new List<int>();\r
- for (int i = 1;\r
- i <= this.UserSettingService.GetUserSetting<int>(UserSettingConstants.PreviewScanCount);\r
- i++)\r
- {\r
- startPoints.Add(i);\r
- }\r
-\r
- return startPoints;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets a value indicating whether UseSystemDefaultPlayer.\r
- /// </summary>\r
- public bool UseSystemDefaultPlayer\r
- {\r
- get\r
- {\r
- return this.useSystemDefaultPlayer;\r
- }\r
- set\r
- {\r
- this.useSystemDefaultPlayer = value;\r
- this.NotifyOfPropertyChange(() => UseSystemDefaultPlayer);\r
- this.userSettingService.SetUserSetting(UserSettingConstants.DefaultPlayer, value);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets a value indicating whether IsEncoding.\r
- /// </summary>\r
- public bool IsEncoding\r
- {\r
- get\r
- {\r
- return this.isEncoding;\r
- }\r
- set\r
- {\r
- this.isEncoding = value;\r
- this.CanPlay = !value;\r
- this.NotifyOfPropertyChange(() => this.CanPlay);\r
- this.NotifyOfPropertyChange(() => this.IsEncoding);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Gets or sets the Currently Playing / Encoding Filename.\r
- /// </summary>\r
- public string CurrentlyPlaying { get; set; }\r
-\r
- /// <summary>\r
- /// Gets or sets a value indicating whether can play.\r
- /// </summary>\r
- public bool CanPlay { get; set; }\r
-\r
- #endregion\r
-\r
- #region Public Methods\r
-\r
- /// <summary>\r
- /// Close this window.\r
- /// </summary>\r
- public void Close()\r
- {\r
- this.TryClose();\r
- }\r
-\r
- /// <summary>\r
- /// Handle The Initialisation \r
- /// </summary>\r
- public override void OnLoad()\r
- {\r
- }\r
-\r
- /// <summary>\r
- /// Encode and play a sample\r
- /// </summary>\r
- public void Play()\r
- {\r
- try\r
- {\r
- this.IsEncoding = true;\r
- if (File.Exists(this.CurrentlyPlaying))\r
- File.Delete(this.CurrentlyPlaying);\r
- }\r
- catch (Exception)\r
- {\r
- this.IsEncoding = false;\r
- this.errorService.ShowMessageBox("Unable to delete previous preview file. You may need to restart the application.",\r
- Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
- }\r
-\r
- if (this.Task == null || string.IsNullOrEmpty(Task.Source))\r
- {\r
- this.errorService.ShowMessageBox("You must first scan a source and setup your encode before creating a preview.",\r
- Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
- return;\r
- }\r
-\r
- EncodeTask encodeTask = new EncodeTask(this.Task)\r
- {\r
- PreviewDuration = this.Duration,\r
- PreviewStartAt = this.StartAt,\r
- PointToPointMode = PointToPointMode.Preview\r
- };\r
-\r
- // Filename handling.\r
- if (string.IsNullOrEmpty(encodeTask.Destination))\r
- {\r
- string filename = Path.ChangeExtension(Path.GetTempFileName(), encodeTask.OutputFormat == OutputFormat.Mkv ? "m4v" : "mkv");\r
- encodeTask.Destination = filename;\r
- this.CurrentlyPlaying = filename;\r
- }\r
- else\r
- {\r
- string directory = Path.GetDirectoryName(encodeTask.Destination) ?? string.Empty;\r
- string filename = Path.GetFileNameWithoutExtension(encodeTask.Destination);\r
- string extension = Path.GetExtension(encodeTask.Destination);\r
- string previewFilename = string.Format("{0}_preview{1}", filename, extension);\r
- string previewFullPath = Path.Combine(directory, previewFilename);\r
- encodeTask.Destination = previewFullPath;\r
- this.CurrentlyPlaying = previewFullPath;\r
- }\r
-\r
- // Setup the encode task as a preview encode\r
- encodeTask.IsPreviewEncode = true;\r
- encodeTask.PreviewEncodeStartAt = this.StartAt;\r
- encodeTask.PreviewEncodeDuration = this.Duration;\r
- QueueTask task = new QueueTask(encodeTask, HBConfigurationFactory.Create());\r
- ThreadPool.QueueUserWorkItem(this.CreatePreview, task);\r
- }\r
-\r
- #endregion\r
-\r
- #region Private Methods\r
- /// <summary>\r
- /// Play the Encoded file\r
- /// </summary>\r
- private void PlayFile()\r
- {\r
- // Launch VLC and Play video.\r
- if (this.CurrentlyPlaying != string.Empty)\r
- {\r
- if (File.Exists(this.CurrentlyPlaying))\r
- {\r
- string args = "\"" + this.CurrentlyPlaying + "\"";\r
-\r
- if (this.UseSystemDefaultPlayer)\r
- {\r
- Process.Start(args);\r
- }\r
- else\r
- {\r
- if (!File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath)))\r
- {\r
- // Attempt to find VLC if it doesn't exist in the default set location.\r
- string vlcPath;\r
-\r
- if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"))))\r
- vlcPath = Environment.GetEnvironmentVariable("ProgramFiles(x86)");\r
- else\r
- vlcPath = Environment.GetEnvironmentVariable("ProgramFiles");\r
-\r
- if (!string.IsNullOrEmpty(vlcPath))\r
- {\r
- vlcPath = Path.Combine(vlcPath, "VideoLAN\\VLC\\vlc.exe");\r
- }\r
-\r
- if (File.Exists(vlcPath))\r
- {\r
- UserSettingService.SetUserSetting(UserSettingConstants.VLCPath, vlcPath);\r
- }\r
- else\r
- {\r
- 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\")",\r
- Resources.Error, MessageBoxButton.OK, MessageBoxImage.Warning);\r
- }\r
- }\r
-\r
- if (File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath)))\r
- {\r
- ProcessStartInfo vlc = new ProcessStartInfo(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath), args);\r
- Process.Start(vlc);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- this.errorService.ShowMessageBox("Unable to find the preview file. Either the file was deleted or the encode failed. Check the activity log for details.",\r
- Resources.Error, MessageBoxButton.OK, MessageBoxImage.Warning);\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Create the Preview.\r
- /// </summary>\r
- /// <param name="state">\r
- /// The state.\r
- /// </param>\r
- private void CreatePreview(object state)\r
- {\r
- // Make sure we are not already encoding and if we are then display an error.\r
- if (encodeService.IsEncoding)\r
- {\r
- this.errorService.ShowMessageBox("Handbrake is already encoding a video! Only one file can be encoded at any one time.",\r
- Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
- return;\r
- }\r
-\r
- this.encodeService.EncodeCompleted += this.encodeService_EncodeCompleted;\r
- this.encodeService.EncodeStatusChanged += this.encodeService_EncodeStatusChanged;\r
-\r
- this.encodeService.Start((QueueTask)state);\r
- this.userSettingService.SetUserSetting(UserSettingConstants.LastPreviewDuration, this.Duration);\r
- }\r
- #endregion\r
-\r
- #region Event Handlers\r
- /// <summary>\r
- /// Handle Encode Progress Events\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The sender.\r
- /// </param>\r
- /// <param name="e">\r
- /// The EncodeProgressEventArgs.\r
- /// </param>\r
- private void encodeService_EncodeStatusChanged(object sender, EncodeProgressEventArgs e)\r
- {\r
- this.Percentage = string.Format("{0} %", Math.Round(e.PercentComplete, 2).ToString(CultureInfo.InvariantCulture));\r
- this.PercentageValue = e.PercentComplete;\r
- }\r
-\r
- /// <summary>\r
- /// Handle the Encode Completed Event\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The sender.\r
- /// </param>\r
- /// <param name="e">\r
- /// The EncodeCompletedEventArgs.\r
- /// </param>\r
- private void encodeService_EncodeCompleted(object sender, EncodeCompletedEventArgs e)\r
- {\r
- this.Percentage = "0.00%";\r
- this.PercentageValue = 0;\r
- this.IsEncoding = false;\r
-\r
- this.encodeService.EncodeCompleted -= this.encodeService_EncodeCompleted;\r
- this.encodeService.EncodeStatusChanged -= this.encodeService_EncodeStatusChanged;\r
-\r
- this.PlayFile();\r
- }\r
- #endregion\r
- }\r
-}
\ No newline at end of file
namespace HandBrakeWPF.ViewModels\r
{\r
using System;\r
+ using System.Collections.Generic;\r
+ using System.Diagnostics;\r
+ using System.Globalization;\r
+ using System.IO;\r
using System.Runtime.ExceptionServices;\r
+ using System.Threading;\r
using System.Windows;\r
using System.Windows.Media.Imaging;\r
\r
using HandBrake.ApplicationServices.Model;\r
+ using HandBrake.ApplicationServices.Services.Encode.EventArgs;\r
+ using HandBrake.ApplicationServices.Services.Encode.Interfaces;\r
using HandBrake.ApplicationServices.Services.Encode.Model;\r
+ using HandBrake.ApplicationServices.Services.Encode.Model.Models;\r
using HandBrake.ApplicationServices.Services.Interfaces;\r
using HandBrake.ApplicationServices.Services.Scan.Interfaces;\r
using HandBrake.Interop.Model.Encoding;\r
\r
using HandBrakeWPF.Factories;\r
+ using HandBrakeWPF.Properties;\r
+ using HandBrakeWPF.Services;\r
+ using HandBrakeWPF.Services.Interfaces;\r
using HandBrakeWPF.ViewModels.Interfaces;\r
\r
/// <summary>\r
{\r
/*\r
* TODO\r
- * - Integrate Video Preview panel.\r
+ * - Window Size / Scale to screen etc.\r
*/\r
\r
#region Fields\r
/// </summary>\r
private readonly IScan scanService;\r
\r
+ /// <summary>\r
+ /// Backing field for the encode service.\r
+ /// </summary>\r
+ private readonly IEncodeServiceWrapper encodeService;\r
+\r
+ /// <summary>\r
+ /// The error service\r
+ /// </summary>\r
+ private readonly IErrorService errorService;\r
+\r
+ /// <summary>\r
+ /// The user Setting Service\r
+ /// </summary>\r
+ private readonly IUserSettingService userSettingService;\r
+\r
/// <summary>\r
/// The height.\r
/// </summary>\r
/// </summary>\r
private bool previewNotAvailable;\r
\r
+ /// <summary>\r
+ /// The percentage.\r
+ /// </summary>\r
+ private string percentage;\r
+\r
+ /// <summary>\r
+ /// The percentage value.\r
+ /// </summary>\r
+ private double percentageValue;\r
+\r
+ /// <summary>\r
+ /// The Backing field for IsEncoding\r
+ /// </summary>\r
+ private bool isEncoding;\r
+\r
+ /// <summary>\r
+ /// Backing field for use system default player\r
+ /// </summary>\r
+ private bool useSystemDefaultPlayer;\r
+\r
#endregion\r
\r
#region Constructors and Destructors\r
/// <param name="scanService">\r
/// The scan service.\r
/// </param>\r
- public StaticPreviewViewModel(IScan scanService)\r
+ /// <param name="userSettingService">\r
+ /// The user Setting Service.\r
+ /// </param>\r
+ public StaticPreviewViewModel(IScan scanService, IUserSettingService userSettingService)\r
{\r
this.scanService = scanService;\r
this.selectedPreviewImage = 1;\r
this.Title = Properties.Resources.Preview;\r
this.PreviewNotAvailable = true;\r
+\r
+ // Live Preview\r
+ this.userSettingService = userSettingService;\r
+ this.encodeService = new EncodeServiceWrapper(userSettingService); // Preview needs a seperate instance rather than the shared singleton. This could maybe do with being refactored at some point\r
+\r
+ this.Title = "Preview";\r
+ this.Percentage = "0.00%";\r
+ this.PercentageValue = 0;\r
+ this.StartAt = 1;\r
+ this.Duration = 30;\r
+ this.CanPlay = true;\r
+\r
+ UseSystemDefaultPlayer = userSettingService.GetUserSetting<bool>(UserSettingConstants.DefaultPlayer);\r
+ this.Duration = userSettingService.GetUserSetting<int>(UserSettingConstants.LastPreviewDuration);\r
}\r
\r
#endregion\r
\r
#endregion\r
\r
+ #region LivePreviewProperties\r
+\r
+ /// <summary>\r
+ /// Gets AvailableDurations.\r
+ /// </summary>\r
+ public IEnumerable<int> AvailableDurations\r
+ {\r
+ get\r
+ {\r
+ return new List<int> { 5, 10, 30, 45, 60, 75, 90, 105, 120, 150, 180, 210, 240 };\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets Duration.\r
+ /// </summary>\r
+ public int Duration { get; set; }\r
+\r
+ /// <summary>\r
+ /// Gets or sets Percentage.\r
+ /// </summary>\r
+ public string Percentage\r
+ {\r
+ get\r
+ {\r
+ return this.percentage;\r
+ }\r
+\r
+ set\r
+ {\r
+ this.percentage = value;\r
+ this.NotifyOfPropertyChange(() => this.Percentage);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets PercentageValue.\r
+ /// </summary>\r
+ public double PercentageValue\r
+ {\r
+ get\r
+ {\r
+ return this.percentageValue;\r
+ }\r
+\r
+ set\r
+ {\r
+ this.percentageValue = value;\r
+ this.NotifyOfPropertyChange(() => this.PercentageValue);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets StartAt.\r
+ /// </summary>\r
+ public int StartAt { get; set; }\r
+\r
+ /// <summary>\r
+ /// Gets StartPoints.\r
+ /// </summary>\r
+ public IEnumerable<int> StartPoints\r
+ {\r
+ get\r
+ {\r
+ List<int> startPoints = new List<int>();\r
+ for (int i = 1;\r
+ i <= this.UserSettingService.GetUserSetting<int>(UserSettingConstants.PreviewScanCount);\r
+ i++)\r
+ {\r
+ startPoints.Add(i);\r
+ }\r
+\r
+ return startPoints;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets a value indicating whether UseSystemDefaultPlayer.\r
+ /// </summary>\r
+ public bool UseSystemDefaultPlayer\r
+ {\r
+ get\r
+ {\r
+ return this.useSystemDefaultPlayer;\r
+ }\r
+ set\r
+ {\r
+ this.useSystemDefaultPlayer = value;\r
+ this.NotifyOfPropertyChange(() => UseSystemDefaultPlayer);\r
+ this.userSettingService.SetUserSetting(UserSettingConstants.DefaultPlayer, value);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets a value indicating whether IsEncoding.\r
+ /// </summary>\r
+ public bool IsEncoding\r
+ {\r
+ get\r
+ {\r
+ return this.isEncoding;\r
+ }\r
+ set\r
+ {\r
+ this.isEncoding = value;\r
+ this.CanPlay = !value;\r
+ this.NotifyOfPropertyChange(() => this.CanPlay);\r
+ this.NotifyOfPropertyChange(() => this.IsEncoding);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets or sets the Currently Playing / Encoding Filename.\r
+ /// </summary>\r
+ public string CurrentlyPlaying { get; set; }\r
+\r
+ /// <summary>\r
+ /// Gets or sets a value indicating whether can play.\r
+ /// </summary>\r
+ public bool CanPlay { get; set; }\r
+ #endregion\r
+\r
#region Public Methods and Operators\r
\r
/// <summary>\r
/// </param>\r
public void PreviewSizeChanged(SizeChangedEventArgs ea)\r
{\r
+ // TODO implement window size scaling here.\r
Rect workArea = SystemParameters.WorkArea;\r
if (ea.NewSize.Width > workArea.Width)\r
{\r
}\r
}\r
#endregion\r
+\r
+ #region Public Method - Live Preview \r
+ \r
+ #region Public Methods\r
+\r
+ /// <summary>\r
+ /// Close this window.\r
+ /// </summary>\r
+ public void Close()\r
+ {\r
+ this.TryClose();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Handle The Initialisation \r
+ /// </summary>\r
+ public override void OnLoad()\r
+ {\r
+ }\r
+\r
+ /// <summary>\r
+ /// Encode and play a sample\r
+ /// </summary>\r
+ public void Play()\r
+ {\r
+ try\r
+ {\r
+ this.IsEncoding = true;\r
+ if (File.Exists(this.CurrentlyPlaying))\r
+ File.Delete(this.CurrentlyPlaying);\r
+ }\r
+ catch (Exception)\r
+ {\r
+ this.IsEncoding = false;\r
+ this.errorService.ShowMessageBox("Unable to delete previous preview file. You may need to restart the application.",\r
+ Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
+ }\r
+\r
+ if (this.Task == null || string.IsNullOrEmpty(Task.Source))\r
+ {\r
+ this.errorService.ShowMessageBox("You must first scan a source and setup your encode before creating a preview.",\r
+ Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
+ return;\r
+ }\r
+\r
+ EncodeTask encodeTask = new EncodeTask(this.Task)\r
+ {\r
+ PreviewDuration = this.Duration,\r
+ PreviewStartAt = this.StartAt,\r
+ PointToPointMode = PointToPointMode.Preview\r
+ };\r
+\r
+ // Filename handling.\r
+ if (string.IsNullOrEmpty(encodeTask.Destination))\r
+ {\r
+ string filename = Path.ChangeExtension(Path.GetTempFileName(), encodeTask.OutputFormat == OutputFormat.Mkv ? "m4v" : "mkv");\r
+ encodeTask.Destination = filename;\r
+ this.CurrentlyPlaying = filename;\r
+ }\r
+ else\r
+ {\r
+ string directory = Path.GetDirectoryName(encodeTask.Destination) ?? string.Empty;\r
+ string filename = Path.GetFileNameWithoutExtension(encodeTask.Destination);\r
+ string extension = Path.GetExtension(encodeTask.Destination);\r
+ string previewFilename = string.Format("{0}_preview{1}", filename, extension);\r
+ string previewFullPath = Path.Combine(directory, previewFilename);\r
+ encodeTask.Destination = previewFullPath;\r
+ this.CurrentlyPlaying = previewFullPath;\r
+ }\r
+\r
+ // Setup the encode task as a preview encode\r
+ encodeTask.IsPreviewEncode = true;\r
+ encodeTask.PreviewEncodeStartAt = this.StartAt;\r
+ encodeTask.PreviewEncodeDuration = this.Duration;\r
+ QueueTask task = new QueueTask(encodeTask, HBConfigurationFactory.Create());\r
+ ThreadPool.QueueUserWorkItem(this.CreatePreview, task);\r
+ }\r
+\r
+ #endregion\r
+\r
+ #region Private Methods\r
+ /// <summary>\r
+ /// Play the Encoded file\r
+ /// </summary>\r
+ private void PlayFile()\r
+ {\r
+ // Launch VLC and Play video.\r
+ if (this.CurrentlyPlaying != string.Empty)\r
+ {\r
+ if (File.Exists(this.CurrentlyPlaying))\r
+ {\r
+ string args = "\"" + this.CurrentlyPlaying + "\"";\r
+\r
+ if (this.UseSystemDefaultPlayer)\r
+ {\r
+ Process.Start(args);\r
+ }\r
+ else\r
+ {\r
+ if (!File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath)))\r
+ {\r
+ // Attempt to find VLC if it doesn't exist in the default set location.\r
+ string vlcPath;\r
+\r
+ if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"))))\r
+ vlcPath = Environment.GetEnvironmentVariable("ProgramFiles(x86)");\r
+ else\r
+ vlcPath = Environment.GetEnvironmentVariable("ProgramFiles");\r
+\r
+ if (!string.IsNullOrEmpty(vlcPath))\r
+ {\r
+ vlcPath = Path.Combine(vlcPath, "VideoLAN\\VLC\\vlc.exe");\r
+ }\r
+\r
+ if (File.Exists(vlcPath))\r
+ {\r
+ UserSettingService.SetUserSetting(UserSettingConstants.VLCPath, vlcPath);\r
+ }\r
+ else\r
+ {\r
+ 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\")",\r
+ Resources.Error, MessageBoxButton.OK, MessageBoxImage.Warning);\r
+ }\r
+ }\r
+\r
+ if (File.Exists(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath)))\r
+ {\r
+ ProcessStartInfo vlc = new ProcessStartInfo(UserSettingService.GetUserSetting<string>(UserSettingConstants.VLCPath), args);\r
+ Process.Start(vlc);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ this.errorService.ShowMessageBox("Unable to find the preview file. Either the file was deleted or the encode failed. Check the activity log for details.",\r
+ Resources.Error, MessageBoxButton.OK, MessageBoxImage.Warning);\r
+ }\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Create the Preview.\r
+ /// </summary>\r
+ /// <param name="state">\r
+ /// The state.\r
+ /// </param>\r
+ private void CreatePreview(object state)\r
+ {\r
+ // Make sure we are not already encoding and if we are then display an error.\r
+ if (encodeService.IsEncoding)\r
+ {\r
+ this.errorService.ShowMessageBox("Handbrake is already encoding a video! Only one file can be encoded at any one time.",\r
+ Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);\r
+ return;\r
+ }\r
+\r
+ this.encodeService.EncodeCompleted += this.encodeService_EncodeCompleted;\r
+ this.encodeService.EncodeStatusChanged += this.encodeService_EncodeStatusChanged;\r
+\r
+ this.encodeService.Start((QueueTask)state);\r
+ this.userSettingService.SetUserSetting(UserSettingConstants.LastPreviewDuration, this.Duration);\r
+ }\r
+ #endregion\r
+\r
+ #region Event Handlers\r
+ /// <summary>\r
+ /// Handle Encode Progress Events\r
+ /// </summary>\r
+ /// <param name="sender">\r
+ /// The sender.\r
+ /// </param>\r
+ /// <param name="e">\r
+ /// The EncodeProgressEventArgs.\r
+ /// </param>\r
+ private void encodeService_EncodeStatusChanged(object sender, EncodeProgressEventArgs e)\r
+ {\r
+ this.Percentage = string.Format("{0} %", Math.Round(e.PercentComplete, 2).ToString(CultureInfo.InvariantCulture));\r
+ this.PercentageValue = e.PercentComplete;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Handle the Encode Completed Event\r
+ /// </summary>\r
+ /// <param name="sender">\r
+ /// The sender.\r
+ /// </param>\r
+ /// <param name="e">\r
+ /// The EncodeCompletedEventArgs.\r
+ /// </param>\r
+ private void encodeService_EncodeCompleted(object sender, EncodeCompletedEventArgs e)\r
+ {\r
+ this.Percentage = "0.00%";\r
+ this.PercentageValue = 0;\r
+ this.IsEncoding = false;\r
+\r
+ this.encodeService.EncodeCompleted -= this.encodeService_EncodeCompleted;\r
+ this.encodeService.EncodeStatusChanged -= this.encodeService_EncodeStatusChanged;\r
+\r
+ this.PlayFile();\r
+ }\r
+ #endregion\r
+ #endregion\r
}\r
}
\ No newline at end of file
\r
<Label Content="{Binding DisplaySize}" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Margin="0,0,0,5"\r
Visibility="{Binding ShowDisplaySize, Converter={StaticResource boolToVisConverter}}" />\r
-\r
- <Button Content="Preview" Grid.Row="1" Margin="5,0,0,0"\r
- cal:Message.Attach="[Event Click] = [Action PreviewImage]" HorizontalAlignment="Left" />\r
</Grid>\r
\r
</StackPanel>\r
+++ /dev/null
-<Window x:Class="HandBrakeWPF.Views.PreviewView"\r
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"\r
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\r
- xmlns:cal="http://www.caliburnproject.org"\r
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"\r
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\r
- Title="{Binding Title}"\r
- Width="390"\r
- Style="{StaticResource windowStyle}"\r
- ResizeMode="NoResize"\r
- SizeToContent="Height"\r
- WindowStartupLocation="CenterScreen"\r
- TextOptions.TextFormattingMode="Display"\r
- mc:Ignorable="d">\r
-\r
- <Window.Resources>\r
- <Style TargetType="Button">\r
- <Setter Property="FontWeight" Value="Bold" />\r
- <Setter Property="Padding" Value="5,1" />\r
- <Setter Property="FontSize" Value="11.5" />\r
- <Setter Property="VerticalAlignment" Value="Center" />\r
- </Style>\r
- </Window.Resources>\r
-\r
- <StackPanel Orientation="Vertical">\r
-\r
- <StackPanel Height="34"\r
- Margin="0,0,0,10"\r
- Orientation="Horizontal">\r
-\r
- <StackPanel.Style>\r
- <Style TargetType="StackPanel">\r
- <Style.Triggers>\r
- <DataTrigger Binding="{Binding UseSystemColours}" Value="False">\r
- <Setter Property="Background" Value="White" />\r
- </DataTrigger>\r
- </Style.Triggers>\r
- </Style>\r
- </StackPanel.Style>\r
-\r
- <Image Width="32"\r
- Height="32"\r
- Margin="10,0,5,0"\r
- VerticalAlignment="Center"\r
- Source="Images/picture_small.png" />\r
- <StackPanel VerticalAlignment="Center" Orientation="Vertical">\r
- <TextBlock FontWeight="Bold" Text="Create a video preview" />\r
- </StackPanel>\r
- </StackPanel>\r
-\r
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">\r
- <TextBlock Margin="0,0,5,0"\r
- VerticalAlignment="Center"\r
- Text="Start at Preview:" />\r
- <ComboBox Width="60"\r
- ItemsSource="{Binding StartPoints}"\r
- SelectedItem="{Binding StartAt}" />\r
-\r
- <TextBlock Margin="10,0,5,0"\r
- VerticalAlignment="Center"\r
- Text="Duration:" />\r
- <ComboBox Width="60"\r
- ItemsSource="{Binding AvailableDurations}"\r
- SelectedItem="{Binding Duration}" />\r
- </StackPanel>\r
-\r
- <Grid Margin="10,10,10,0">\r
- <Grid.ColumnDefinitions>\r
- <ColumnDefinition Width="*" />\r
- <ColumnDefinition Width="Auto" MinWidth="50" />\r
- </Grid.ColumnDefinitions>\r
- <ProgressBar MinHeight="22" Maximum="100" Minimum="0" Value="{Binding PercentageValue}" Grid.Column="0" />\r
- <TextBlock Margin="5,0,0,0" Text="{Binding Percentage}" Grid.Column="1" />\r
- </Grid>\r
-\r
- <StackPanel Margin="10,10,0,10" Orientation="Horizontal">\r
- <CheckBox VerticalAlignment="Center"\r
- Content="Use system default player"\r
- IsChecked="{Binding UseSystemDefaultPlayer}" />\r
- <Button Margin="10,0,0,0"\r
- HorizontalAlignment="Right"\r
- VerticalAlignment="Center"\r
- cal:Message.Attach="[Event Click] = [Action Play]"\r
- Content="Play"\r
- IsDefault="True"\r
- Padding="8,2" />\r
- </StackPanel>\r
- </StackPanel>\r
-</Window>\r
+++ /dev/null
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="PreviewView.xaml.cs" company="HandBrake Project (http://handbrake.fr)">\r
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
-// </copyright>\r
-// <summary>\r
-// Interaction logic for VideoView.xaml\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrakeWPF.Views\r
-{\r
- using System.Windows;\r
-\r
- /// <summary>\r
- /// Interaction logic for VideoView.xaml\r
- /// </summary>\r
- public partial class PreviewView : Window\r
- {\r
- /// <summary>\r
- /// Initializes a new instance of the <see cref="PreviewView"/> class.\r
- /// </summary>\r
- public PreviewView()\r
- {\r
- InitializeComponent();\r
- }\r
- }\r
-}\r
WindowStartupLocation="CenterScreen"\r
cal:Message.Attach="[Event SizeChanged] = [Action PreviewSizeChanged($eventArgs)]" \r
Title="{Binding Title}">\r
- \r
+\r
<Window.Resources>\r
<converters:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />\r
</Window.Resources>\r
</StackPanel>\r
\r
<Image Source="{Binding PreviewImage}" MaxWidth="{Binding Width}" MaxHeight="{Binding Height}" />\r
- <Slider Maximum="{Binding TotalPreviews}" Minimum="0" \r
+\r
+\r
+ <Border BorderBrush="WhiteSmoke" BorderThickness="1,1,1,1" CornerRadius="8,8,8,8" Padding="8"\r
+ VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="20" MinWidth="400" Background="Black" Opacity="0.70">\r
+ <Grid>\r
+ <Grid.RowDefinitions>\r
+ <RowDefinition Height="Auto" />\r
+ <RowDefinition Height="Auto" />\r
+ <RowDefinition Height="Auto" />\r
+ </Grid.RowDefinitions>\r
+ <Grid.ColumnDefinitions></Grid.ColumnDefinitions>\r
+ <Slider Maximum="{Binding TotalPreviews}" Minimum="0" \r
Value="{Binding SelectedPreviewImage}"\r
- VerticalAlignment="Bottom"\r
- HorizontalAlignment="Center"\r
- Margin="0,0,0,20" Width="150" \r
- Background="Transparent" \r
+ VerticalAlignment="Center"\r
+ HorizontalAlignment="Stretch"\r
+ Background="Transparent" TickPlacement="TopLeft"\r
+ Margin="0,0,0,5"\r
/>\r
+\r
+ <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Left">\r
+ <Button Content="Live Preview" Padding="8,2" cal:Message.Attach="[Event Click] = [Action Play]" />\r
+ <TextBlock Margin="10,0,5,0" VerticalAlignment="Center" Foreground="White" Text="Duration:" />\r
+ <ComboBox Width="60"\r
+ ItemsSource="{Binding AvailableDurations}"\r
+ SelectedItem="{Binding Duration}" />\r
+\r
+ <CheckBox VerticalAlignment="Center" Content="Use system default player" Foreground="White" Margin="10,0,0,0" IsChecked="{Binding UseSystemDefaultPlayer}" />\r
+ </StackPanel>\r
+\r
+ <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,5,0,0">\r
+\r
+ </StackPanel>\r
+\r
+ <Grid Margin="0,10,10,0" Grid.Row="2" Visibility="{Binding IsEncoding, Converter={StaticResource booleanToVisibilityConverter}}">\r
+ <Grid.ColumnDefinitions>\r
+ <ColumnDefinition Width="23*" />\r
+ <ColumnDefinition Width="289*"/>\r
+ <ColumnDefinition Width="Auto" MinWidth="50" />\r
+ </Grid.ColumnDefinitions>\r
+ <ProgressBar MinHeight="5" Maximum="100" Minimum="0" Value="{Binding PercentageValue}" Grid.Column="0" Grid.ColumnSpan="2" />\r
+ <TextBlock Margin="5,0,0,0" Text="{Binding Percentage}" Grid.Column="2" HorizontalAlignment="Right" Foreground="White" />\r
+ </Grid>\r
+\r
+\r
+\r
+\r
+ </Grid>\r
+\r
+ </Border>\r
+\r
</Grid>\r
</Window>\r