summaryrefslogtreecommitdiffstats
path: root/win/CS
diff options
context:
space:
mode:
authorsr55 <[email protected]>2019-05-10 22:37:25 +0100
committersr55 <[email protected]>2019-05-10 22:37:25 +0100
commitd66c23d4a81c6165965114e855a4f361c9481649 (patch)
tree650f51b9ef6308582394f6316ecff58f7776bf6f /win/CS
parent38af1c5f6595fd7ab01f1672197aabe9f87aa5b4 (diff)
WinGui: Switch the GUI over to using JSON for the queue. (Note, this is not the same format as the CLI and thus cannot be imported. This may happen in the future)
Please finish existing queue before installing new version.
Diffstat (limited to 'win/CS')
-rw-r--r--win/CS/HandBrake.Interop/Model/HBConfiguration.cs7
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj4
-rw-r--r--win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs45
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.Designer.cs27
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.resx9
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs2
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs4
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs6
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs6
-rw-r--r--win/CS/HandBrakeWPF/Services/PrePostActionService.cs4
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueService.cs (renamed from win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs)432
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/Model/QueueStats.cs3
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs58
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/QueueService.cs (renamed from win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs)1399
-rw-r--r--win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs2
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs4
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs4
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs4
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs4
19 files changed, 1019 insertions, 1005 deletions
diff --git a/win/CS/HandBrake.Interop/Model/HBConfiguration.cs b/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
index 2ec9f8302..06362dd14 100644
--- a/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
+++ b/win/CS/HandBrake.Interop/Model/HBConfiguration.cs
@@ -9,11 +9,12 @@
namespace HandBrake.Interop.Model
{
- /// <summary>
- /// HandBrakes configuration options
- /// </summary>
public class HBConfiguration
{
+ public HBConfiguration()
+ {
+ }
+
/// <summary>
/// Gets or sets a value indicating whether is dvd nav disabled.
/// </summary>
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index 53235d092..b81e5fce7 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -223,7 +223,7 @@
<Compile Include="Services\Presets\Factories\JsonPresetFactory.cs" />
<Compile Include="Services\Presets\Interfaces\IPresetObject.cs" />
<Compile Include="Services\Presets\Model\PresetDisplayCategory.cs" />
- <Compile Include="Services\Queue\Interfaces\IQueueProcessor.cs" />
+ <Compile Include="Services\Queue\Interfaces\IQueueService.cs" />
<Compile Include="Helpers\FileHelper.cs" />
<Compile Include="Services\Presets\Model\Preset.cs" />
<Compile Include="Model\ScanMode.cs" />
@@ -233,7 +233,7 @@
<Compile Include="Services\Presets\PresetService.cs" />
<Compile Include="Services\Queue\Model\QueueStats.cs" />
<Compile Include="Services\Queue\Model\QueueTaskContainer.cs" />
- <Compile Include="Services\Queue\QueueProcessor.cs" />
+ <Compile Include="Services\Queue\QueueService.cs" />
<Compile Include="Services\Queue\Model\QueueItemStatus.cs" />
<Compile Include="Services\Queue\Model\QueueTask.cs" />
<Compile Include="Services\Scan\EventArgs\ScanCompletedEventArgs.cs" />
diff --git a/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs b/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
index 2a7318814..072baafc7 100644
--- a/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
+++ b/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
@@ -16,7 +16,6 @@ namespace HandBrakeWPF.Helpers
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
- using System.Xml.Serialization;
using HandBrake.Interop.Utilities;
@@ -24,13 +23,14 @@ namespace HandBrakeWPF.Helpers
using HandBrakeWPF.Services.Queue.Model;
using HandBrakeWPF.Utilities;
- using IQueueProcessor = HandBrakeWPF.Services.Queue.Interfaces.IQueueProcessor;
+ using Newtonsoft.Json;
+
+ using IQueueService = HandBrakeWPF.Services.Queue.Interfaces.IQueueService;
- /// <summary>
- /// Queue Recovery Helper
- /// </summary>
public class QueueRecoveryHelper
{
+ public static string QueueFileName = "hb_queue";
+
/// <summary>
/// Check if the queue recovery file contains records.
/// If it does, it means the last queue did not complete before HandBrake closed.
@@ -48,7 +48,7 @@ namespace HandBrakeWPF.Helpers
{
string tempPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
DirectoryInfo info = new DirectoryInfo(tempPath);
- IEnumerable<FileInfo> foundFiles = info.GetFiles("*.xml").Where(f => f.Name.StartsWith("hb_queue_recovery"));
+ IEnumerable<FileInfo> foundFiles = info.GetFiles("*.json").Where(f => f.Name.StartsWith(QueueFileName));
var queueFiles = GetFilesExcludingActiveProcesses(foundFiles, filterQueueFiles);
if (!queueFiles.Any())
@@ -59,14 +59,14 @@ namespace HandBrakeWPF.Helpers
List<string> removeFiles = new List<string>();
List<string> acceptedFiles = new List<string>();
- XmlSerializer ser = new XmlSerializer(typeof(List<QueueTask>));
+
foreach (string file in queueFiles)
{
try
{
- using (FileStream strm = new FileStream(file, FileMode.Open, FileAccess.Read))
+ using (StreamReader stream = new StreamReader(file))
{
- List<QueueTask> list = ser.Deserialize(strm) as List<QueueTask>;
+ List<QueueTask> list = list = JsonConvert.DeserializeObject<List<QueueTask>>(stream.ReadToEnd());
if (list != null && list.Count == 0)
{
removeFiles.Add(file);
@@ -115,10 +115,13 @@ namespace HandBrakeWPF.Helpers
/// <param name="silentRecovery">
/// The silent Recovery.
/// </param>
+ /// <param name="queueFilter">
+ /// The queue Filter.
+ /// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
- public static bool RecoverQueue(IQueueProcessor encodeQueue, IErrorService errorService, bool silentRecovery, List<string> queueFilter)
+ public static bool RecoverQueue(IQueueService encodeQueue, IErrorService errorService, bool silentRecovery, List<string> queueFilter)
{
string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
List<string> queueFiles = CheckQueueRecovery(queueFilter);
@@ -129,8 +132,8 @@ namespace HandBrakeWPF.Helpers
{
result =
errorService.ShowMessageBox(
- "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",
- "Queue Recovery Possible",
+ Properties.Resources.Queue_RecoverQueueQuestionSingular,
+ Properties.Resources.Queue_RecoveryPossible,
MessageBoxButton.YesNo,
MessageBoxImage.Question);
}
@@ -138,8 +141,8 @@ namespace HandBrakeWPF.Helpers
{
result =
errorService.ShowMessageBox(
- "HandBrake has detected multiple unfinished queue files. These will be from multiple instances of HandBrake running. Would you like to recover all unfinished jobs?",
- "Queue Recovery Possible",
+ Properties.Resources.Queue_RecoverQueueQuestionPlural,
+ Properties.Resources.Queue_RecoveryPossible,
MessageBoxButton.YesNo,
MessageBoxImage.Question);
}
@@ -173,7 +176,7 @@ namespace HandBrakeWPF.Helpers
{
string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
DirectoryInfo info = new DirectoryInfo(appDataPath);
- IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith("hb_queue_recovery"));
+ IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName));
return foundFiles.Any();
}
@@ -185,7 +188,7 @@ namespace HandBrakeWPF.Helpers
// Remove any files where we have an active instnace.
foreach (FileInfo file in foundFiles)
{
- string fileProcessId = file.Name.Replace("hb_queue_recovery", string.Empty).Replace(".xml", string.Empty);
+ string fileProcessId = file.Name.Replace(QueueFileName, string.Empty).Replace(".json", string.Empty);
int processId;
if (!string.IsNullOrEmpty(fileProcessId) && int.TryParse(fileProcessId, out processId))
{
@@ -216,7 +219,7 @@ namespace HandBrakeWPF.Helpers
// Cleanup old/unused queue files for now.
foreach (string file in removeFiles)
{
- Match m = Regex.Match(file, @"([0-9]+).xml");
+ Match m = Regex.Match(file, @"([0-9]+).json");
if (m.Success)
{
int processId = int.Parse(m.Groups[1].ToString());
@@ -249,13 +252,13 @@ namespace HandBrakeWPF.Helpers
{
string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
DirectoryInfo info = new DirectoryInfo(appDataPath);
- IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith("hb_queue_recovery"));
+ IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName));
- DateTime LastWeek = DateTime.Now.AddDays(-7);
+ DateTime lastWeek = DateTime.Now.AddDays(-7);
foreach (FileInfo file in foundFiles)
{
- if (file.CreationTime < LastWeek)
+ if (file.CreationTime < lastWeek)
{
string fullPath = Path.Combine(appDataPath, file.Name);
File.Delete(fullPath);
@@ -267,7 +270,7 @@ namespace HandBrakeWPF.Helpers
{
string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
DirectoryInfo info = new DirectoryInfo(appDataPath);
- IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith("hb_queue_recovery"));
+ IEnumerable<FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName));
foreach (FileInfo file in foundFiles)
{
string fullPath = Path.Combine(appDataPath, file.Name);
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
index 3e04f632c..a3583ef4a 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
+++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
@@ -3814,6 +3814,33 @@ namespace HandBrakeWPF.Properties {
}
/// <summary>
+ /// Looks up a localized string similar to HandBrake has detected multiple unfinished queue files. These will be from multiple instances of HandBrake running. Would you like to recover all unfinished jobs?.
+ /// </summary>
+ public static string Queue_RecoverQueueQuestionPlural {
+ get {
+ return ResourceManager.GetString("Queue_RecoverQueueQuestionPlural", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?.
+ /// </summary>
+ public static string Queue_RecoverQueueQuestionSingular {
+ get {
+ return ResourceManager.GetString("Queue_RecoverQueueQuestionSingular", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Queue Recovery Possible.
+ /// </summary>
+ public static string Queue_RecoveryPossible {
+ get {
+ return ResourceManager.GetString("Queue_RecoveryPossible", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Unable to reset job status as it is not in an Error or Completed state.
/// </summary>
public static string Queue_UnableToResetJob {
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx
index 3f2b0a0b8..66a4cf97f 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.resx
+++ b/win/CS/HandBrakeWPF/Properties/Resources.resx
@@ -1987,4 +1987,13 @@ Non-Live Options: {date} {time} {creation-date} {creation-time} {quality} {bitra
<data name="OptionsView_ChoiceOfEncoderHint" xml:space="preserve">
<value>Choice of encoder will be made available on the 'Video' tab.</value>
</data>
+ <data name="Queue_RecoverQueueQuestionPlural" xml:space="preserve">
+ <value>HandBrake has detected multiple unfinished queue files. These will be from multiple instances of HandBrake running. Would you like to recover all unfinished jobs?</value>
+ </data>
+ <data name="Queue_RecoverQueueQuestionSingular" xml:space="preserve">
+ <value>HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?</value>
+ </data>
+ <data name="Queue_RecoveryPossible" xml:space="preserve">
+ <value>Queue Recovery Possible</value>
+ </data>
</root> \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs
index 5272810cd..a61cd0bf0 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs
@@ -18,6 +18,8 @@ namespace HandBrakeWPF.Services.Encode.Model
using HandBrakeWPF.Model.Filters;
using HandBrakeWPF.Services.Encode.Model.Models;
+ using Newtonsoft.Json;
+
using AllowedPassthru = Models.AllowedPassthru;
using AudioTrack = Models.AudioTrack;
using ChapterMarker = Models.ChapterMarker;
diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs
index cda397929..bab9d242a 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs
@@ -27,9 +27,7 @@ namespace HandBrakeWPF.Services.Encode.Model.Models
using Newtonsoft.Json;
- /// <summary>
- /// Model of a HandBrake Audio Track and it's associated behaviours.
- /// </summary>
+ [JsonObject(MemberSerialization.OptOut)]
public class AudioTrack : PropertyChangedBase
{
private int bitrate;
diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs
index c699ec39c..4e4e84e0e 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs
@@ -13,9 +13,9 @@ namespace HandBrakeWPF.Services.Encode.Model.Models
using Caliburn.Micro;
- /// <summary>
- /// A Movie Chapter
- /// </summary>
+ using Newtonsoft.Json;
+
+ [JsonObject(MemberSerialization.OptOut)]
public class ChapterMarker : PropertyChangedBase
{
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs
index 3eef3bc4f..79ea7a8b6 100644
--- a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs
+++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs
@@ -17,9 +17,9 @@ namespace HandBrakeWPF.Services.Encode.Model.Models
using HandBrakeWPF.Services.Scan.Model;
- /// <summary>
- /// Subtitle Information
- /// </summary>
+ using Newtonsoft.Json;
+
+ [JsonObject(MemberSerialization.OptOut)]
public class SubtitleTrack : PropertyChangedBase
{
#region Constants and Fields
diff --git a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
index 4cbd4c82a..20a6c39a8 100644
--- a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
+++ b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
@@ -36,7 +36,7 @@ namespace HandBrakeWPF.Services
/// </summary>
public class PrePostActionService : IPrePostActionService
{
- private readonly IQueueProcessor queueProcessor;
+ private readonly IQueueService queueProcessor;
private readonly IUserSettingService userSettingService;
private readonly IWindowManager windowManager;
private readonly IScan scanService;
@@ -53,7 +53,7 @@ namespace HandBrakeWPF.Services
/// <param name="windowManager">
/// The window Manager.
/// </param>
- public PrePostActionService(IQueueProcessor queueProcessor, IUserSettingService userSettingService, IWindowManager windowManager, IScan scanService)
+ public PrePostActionService(IQueueService queueProcessor, IUserSettingService userSettingService, IWindowManager windowManager, IScan scanService)
{
this.queueProcessor = queueProcessor;
this.userSettingService = userSettingService;
diff --git a/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs b/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueService.cs
index 90723c7a8..add20a27d 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueService.cs
@@ -1,217 +1,217 @@
-// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="IQueueProcessor.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// The Queue Processor
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrakeWPF.Services.Queue.Interfaces
-{
- using System;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
-
- using HandBrakeWPF.Services.Queue.Model;
-
- using IEncode = Encode.Interfaces.IEncode;
-
- /// <summary>
- /// The Queue Processor
- /// </summary>
- public interface IQueueProcessor
- {
- #region Events
-
- /// <summary>
- /// Fires when the Queue has started
- /// </summary>
- event QueueProcessor.QueueProgressStatus JobProcessingStarted;
-
- /// <summary>
- /// Fires when a job is Added, Removed or Re-Ordered.
- /// Should be used for triggering an update of the Queue Window.
- /// </summary>
- event EventHandler QueueChanged;
-
- /// <summary>
- /// Fires when the entire encode queue has completed.
- /// </summary>
- event QueueProcessor.QueueCompletedEventDelegate QueueCompleted;
-
- /// <summary>
- /// Fires when a pause to the encode queue has been requested.
- /// </summary>
- event EventHandler QueuePaused;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets the number of jobs in the queue
- /// </summary>
- int Count { get; }
-
- /// <summary>
- /// Gets the number of errors detected in the queue.
- /// </summary>
- int ErrorCount { get; }
-
- /// <summary>
- /// Gets the IEncodeService instance.
- /// </summary>
- IEncode EncodeService { get; }
-
- /// <summary>
- /// Gets a value indicating whether IsProcessing.
- /// </summary>
- bool IsProcessing { get; }
-
- /// <summary>
- /// Gets or sets Last Processed Job.
- /// This is set when the job is poped of the queue by GetNextJobForProcessing();
- /// </summary>
- QueueTask LastProcessedJob { get; set; }
-
- /// <summary>
- /// Gets The current queue.
- /// </summary>
- ObservableCollection<QueueTask> Queue { get; }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Add a job to the Queue.
- /// This method is Thread Safe.
- /// </summary>
- /// <param name="job">
- /// The encode Job object.
- /// </param>
- void Add(QueueTask job);
-
- /// <summary>
- /// Backup any changes to the queue file
- /// </summary>
- /// <param name="exportPath">
- /// If this is not null or empty, this will be used instead of the standard backup location.
- /// </param>
- void BackupQueue(string exportPath);
-
- /// <summary>
- /// Export the Queue the standardised JSON format.
- /// </summary>
- /// <param name="exportPath">
- /// The export path.
- /// </param>
- void ExportJson(string exportPath);
-
- /// <summary>
- /// Restore a JSON queue file.
- /// </summary>
- /// <param name="path">
- /// Path to the file the user wishes to import.
- /// </param>
- void ImportJson(string path);
-
- /// <summary>
- /// Checks the current queue for an existing instance of the specified destination.
- /// </summary>
- /// <param name="destination">
- /// The destination of the encode.
- /// </param>
- /// <returns>
- /// Whether or not the supplied destination is already in the queue.
- /// </returns>
- bool CheckForDestinationPathDuplicates(string destination);
-
- /// <summary>
- /// Clear down all Queue Items
- /// </summary>
- void Clear();
-
- /// <summary>
- /// Clear down the Queue�s completed items
- /// </summary>
- void ClearCompleted();
-
- /// <summary>
- /// Get the first job on the queue for processing.
- /// This also removes the job from the Queue and sets the LastProcessedJob
- /// </summary>
- /// <returns>
- /// An encode Job object.
- /// </returns>
- QueueTask GetNextJobForProcessing();
-
- /// <summary>
- /// Moves an item down one position in the queue.
- /// </summary>
- /// <param name="index">
- /// The zero-based location of the job in the queue.
- /// </param>
- void MoveDown(int index);
-
- /// <summary>
- /// Moves an item up one position in the queue.
- /// </summary>
- /// <param name="index">
- /// The zero-based location of the job in the queue.
- /// </param>
- void MoveUp(int index);
-
- /// <summary>
- /// Remove a job from the Queue.
- /// This method is Thread Safe
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- void Remove(QueueTask job);
-
- /// <summary>
- /// Reset a Queued Item from Error or Completed to Waiting
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- void ResetJobStatusToWaiting(QueueTask job);
-
- /// <summary>
- /// Restore a Queue from file or from the queue backup file.
- /// </summary>
- /// <param name="importPath">
- /// The import path. String.Empty or null will result in the default file being loaded.
- /// </param>
- void RestoreQueue(string importPath);
-
- /// <summary>
- /// Starts encoding the first job in the queue and continues encoding until all jobs
- /// have been encoded.
- /// </summary>
- /// <param name="clearCompleted">
- /// The clear Completed.
- /// </param>
- void Start(bool clearCompleted);
-
- /// <summary>
- /// Stop the current encode and pause the queue.
- /// </summary>
- void Stop();
-
- /// <summary>
- /// Pause the queue but allow the current encode to complete.
- /// </summary>
- void Pause();
-
- /// <summary>
- /// Pause and Encode and the Queue.
- /// </summary>
- void PauseEncode();
-
- #endregion
- }
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IQueueService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Queue Processor
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Queue.Interfaces
+{
+ using System;
+ using System.Collections.ObjectModel;
+ using System.ComponentModel;
+
+ using HandBrakeWPF.Services.Queue.Model;
+
+ using IEncode = Encode.Interfaces.IEncode;
+
+ /// <summary>
+ /// The Queue Processor
+ /// </summary>
+ public interface IQueueService
+ {
+ #region Events
+
+ /// <summary>
+ /// Fires when the Queue has started
+ /// </summary>
+ event QueueService.QueueProgressStatus JobProcessingStarted;
+
+ /// <summary>
+ /// Fires when a job is Added, Removed or Re-Ordered.
+ /// Should be used for triggering an update of the Queue Window.
+ /// </summary>
+ event EventHandler QueueChanged;
+
+ /// <summary>
+ /// Fires when the entire encode queue has completed.
+ /// </summary>
+ event QueueService.QueueCompletedEventDelegate QueueCompleted;
+
+ /// <summary>
+ /// Fires when a pause to the encode queue has been requested.
+ /// </summary>
+ event EventHandler QueuePaused;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the number of jobs in the queue
+ /// </summary>
+ int Count { get; }
+
+ /// <summary>
+ /// Gets the number of errors detected in the queue.
+ /// </summary>
+ int ErrorCount { get; }
+
+ /// <summary>
+ /// Gets the IEncodeService instance.
+ /// </summary>
+ IEncode EncodeService { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether IsProcessing.
+ /// </summary>
+ bool IsProcessing { get; }
+
+ /// <summary>
+ /// Gets or sets Last Processed Job.
+ /// This is set when the job is poped of the queue by GetNextJobForProcessing();
+ /// </summary>
+ QueueTask LastProcessedJob { get; set; }
+
+ /// <summary>
+ /// Gets The current queue.
+ /// </summary>
+ ObservableCollection<QueueTask> Queue { get; }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Add a job to the Queue.
+ /// This method is Thread Safe.
+ /// </summary>
+ /// <param name="job">
+ /// The encode Job object.
+ /// </param>
+ void Add(QueueTask job);
+
+ /// <summary>
+ /// Backup any changes to the queue file
+ /// </summary>
+ /// <param name="exportPath">
+ /// If this is not null or empty, this will be used instead of the standard backup location.
+ /// </param>
+ void BackupQueue(string exportPath);
+
+ /// <summary>
+ /// Export the Queue the standardised JSON format.
+ /// </summary>
+ /// <param name="exportPath">
+ /// The export path.
+ /// </param>
+ void ExportJson(string exportPath);
+
+ /// <summary>
+ /// Restore a JSON queue file.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the file the user wishes to import.
+ /// </param>
+ void ImportJson(string path);
+
+ /// <summary>
+ /// Checks the current queue for an existing instance of the specified destination.
+ /// </summary>
+ /// <param name="destination">
+ /// The destination of the encode.
+ /// </param>
+ /// <returns>
+ /// Whether or not the supplied destination is already in the queue.
+ /// </returns>
+ bool CheckForDestinationPathDuplicates(string destination);
+
+ /// <summary>
+ /// Clear down all Queue Items
+ /// </summary>
+ void Clear();
+
+ /// <summary>
+ /// Clear down the Queue�s completed items
+ /// </summary>
+ void ClearCompleted();
+
+ /// <summary>
+ /// Get the first job on the queue for processing.
+ /// This also removes the job from the Queue and sets the LastProcessedJob
+ /// </summary>
+ /// <returns>
+ /// An encode Job object.
+ /// </returns>
+ QueueTask GetNextJobForProcessing();
+
+ /// <summary>
+ /// Moves an item down one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ void MoveDown(int index);
+
+ /// <summary>
+ /// Moves an item up one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ void MoveUp(int index);
+
+ /// <summary>
+ /// Remove a job from the Queue.
+ /// This method is Thread Safe
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ void Remove(QueueTask job);
+
+ /// <summary>
+ /// Reset a Queued Item from Error or Completed to Waiting
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ void ResetJobStatusToWaiting(QueueTask job);
+
+ /// <summary>
+ /// Restore a Queue from file or from the queue backup file.
+ /// </summary>
+ /// <param name="importPath">
+ /// The import path. String.Empty or null will result in the default file being loaded.
+ /// </param>
+ void RestoreQueue(string importPath);
+
+ /// <summary>
+ /// Starts encoding the first job in the queue and continues encoding until all jobs
+ /// have been encoded.
+ /// </summary>
+ /// <param name="clearCompleted">
+ /// The clear Completed.
+ /// </param>
+ void Start(bool clearCompleted);
+
+ /// <summary>
+ /// Stop the current encode and pause the queue.
+ /// </summary>
+ void Stop();
+
+ /// <summary>
+ /// Pause the queue but allow the current encode to complete.
+ /// </summary>
+ void Pause();
+
+ /// <summary>
+ /// Pause and Encode and the Queue.
+ /// </summary>
+ void PauseEncode();
+
+ #endregion
+ }
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueStats.cs b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueStats.cs
index 77454c4ad..3378bd6aa 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueStats.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueStats.cs
@@ -13,6 +13,9 @@ namespace HandBrakeWPF.Services.Queue.Model
using Caliburn.Micro;
+ using Newtonsoft.Json;
+
+ [JsonObject(MemberSerialization.OptOut)]
public class QueueStats : PropertyChangedBase
{
private DateTime startTime;
diff --git a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs
index 77c9b66ad..f3d7bb6e4 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs
@@ -18,22 +18,17 @@ namespace HandBrakeWPF.Services.Queue.Model
using HandBrakeWPF.Services.Presets.Model;
using HandBrakeWPF.Utilities;
+ using Newtonsoft.Json;
+
using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask;
- /// <summary>
- /// The QueueTask.
- /// </summary>
+
public class QueueTask : PropertyChangedBase
{
private static int id;
private QueueItemStatus status;
private string presetKey;
- #region Properties
-
- /// <summary>
- /// Initializes a new instance of the <see cref="QueueTask"/> class.
- /// </summary>
public QueueTask()
{
this.Status = QueueItemStatus.Waiting;
@@ -42,21 +37,6 @@ namespace HandBrakeWPF.Services.Queue.Model
this.Statistics = new QueueStats();
}
- /// <summary>
- /// Initializes a new instance of the <see cref="QueueTask"/> class.
- /// </summary>
- /// <param name="task">
- /// The task.
- /// </param>
- /// <param name="configuration">
- /// The configuration.
- /// </param>
- /// <param name="scannedSourcePath">
- /// The scanned Source Path.
- /// </param>
- /// <param name="currentPreset">
- /// The currently active preset.
- /// </param>
public QueueTask(EncodeTask task, HBConfiguration configuration, string scannedSourcePath, Preset currentPreset)
{
this.Task = task;
@@ -74,16 +54,13 @@ namespace HandBrakeWPF.Services.Queue.Model
this.Statistics = new QueueStats();
}
+ [JsonIgnore]
public string Id { get; }
- /// <summary>
- /// Gets or sets ScannedSource.
- /// </summary>
+ [JsonProperty]
public string ScannedSourcePath { get; set; }
- /// <summary>
- /// Gets or sets Status.
- /// </summary>
+ [JsonProperty]
public QueueItemStatus Status
{
get
@@ -99,18 +76,16 @@ namespace HandBrakeWPF.Services.Queue.Model
}
}
- /// <summary>
- /// Gets or sets the task.
- /// </summary>
+ [JsonProperty]
public EncodeTask Task { get; set; }
- /// <summary>
- /// Gets or sets the configuration.
- /// </summary>
+ [JsonProperty]
public HBConfiguration Configuration { get; set; }
+ [JsonProperty]
public QueueStats Statistics { get; set; }
+ [JsonIgnore]
public string SelectedPresetKey
{
get
@@ -119,15 +94,9 @@ namespace HandBrakeWPF.Services.Queue.Model
}
}
+ [JsonIgnore]
public bool ShowEncodeProgress => this.Status == QueueItemStatus.InProgress && SystemInfo.IsWindows10();
- #endregion
-
- protected bool Equals(QueueTask other)
- {
- return this.Id == other.Id;
- }
-
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
@@ -145,5 +114,10 @@ namespace HandBrakeWPF.Services.Queue.Model
{
return string.Format("Encode Task. Title: {0}, Source: {1}, Destination: {2}", this.Task.Title, this.Task.Source, this.Task.Destination);
}
+
+ protected bool Equals(QueueTask other)
+ {
+ return this.Id == other.Id;
+ }
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs b/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs
index ec0867f2a..0a9c6e8e9 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs
@@ -1,702 +1,699 @@
-// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="QueueProcessor.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// The HandBrake Queue
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrakeWPF.Services.Queue
-{
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.IO;
- using System.Linq;
- using System.Xml.Serialization;
-
- using HandBrake.Interop.Interop.Json.Queue;
- using HandBrake.Interop.Model;
- using HandBrake.Interop.Utilities;
-
- using HandBrakeWPF.Factories;
- using HandBrakeWPF.Properties;
- using HandBrakeWPF.Services.Encode.Factories;
- using HandBrakeWPF.Services.Encode.Model;
- using HandBrakeWPF.Services.Interfaces;
- using HandBrakeWPF.Services.Queue.Model;
- using HandBrakeWPF.Utilities;
-
- using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs;
- using Execute = Caliburn.Micro.Execute;
- using GeneralApplicationException = HandBrakeWPF.Exceptions.GeneralApplicationException;
- using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode;
- using LogLevel = HandBrakeWPF.Services.Logging.Model.LogLevel;
- using LogMessageType = HandBrakeWPF.Services.Logging.Model.LogMessageType;
- using LogService = HandBrakeWPF.Services.Logging.LogService;
- using QueueCompletedEventArgs = HandBrakeWPF.EventArgs.QueueCompletedEventArgs;
- using QueueProgressEventArgs = HandBrakeWPF.EventArgs.QueueProgressEventArgs;
-
- /// <summary>
- /// The HandBrake Queue
- /// </summary>
- public class QueueProcessor : Interfaces.IQueueProcessor
- {
- #region Constants and Fields
- private static readonly object QueueLock = new object();
- private readonly IUserSettingService userSettingService;
- private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
- private readonly string queueFile;
- private bool clearCompleted;
-
- #endregion
-
- #region Constructors and Destructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="QueueProcessor"/> class.
- /// </summary>
- /// <param name="encodeService">
- /// The encode Service.
- /// </param>
- /// <param name="userSettingService">
- /// The user settings service.
- /// </param>
- /// <param name="errorService">
- /// The Error Service.
- /// </param>
- /// <exception cref="ArgumentNullException">
- /// Services are not setup
- /// </exception>
- public QueueProcessor(IEncode encodeService, IUserSettingService userSettingService)
- {
- this.userSettingService = userSettingService;
- this.EncodeService = encodeService;
-
- // If this is the first instance, just use the main queue file, otherwise add the instance id to the filename.
- this.queueFile = string.Format("hb_queue_recovery{0}.xml", GeneralUtilities.ProcessId);
- }
-
- #endregion
-
- #region Delegates
-
- /// <summary>
- /// Queue Progress Status
- /// </summary>
- /// <param name="sender">
- /// The sender.
- /// </param>
- /// <param name="e">
- /// The QueueProgressEventArgs.
- /// </param>
- public delegate void QueueProgressStatus(object sender, QueueProgressEventArgs e);
-
- /// <summary>
- /// The queue completed.
- /// </summary>
- /// <param name="sender">
- /// The sender.
- /// </param>
- /// <param name="e">
- /// The e.
- /// </param>
- public delegate void QueueCompletedEventDelegate(object sender, QueueCompletedEventArgs e);
-
- #endregion
-
- #region Events
-
- /// <summary>
- /// Fires when the Queue has started
- /// </summary>
- public event QueueProgressStatus JobProcessingStarted;
-
- /// <summary>
- /// Fires when a job is Added, Removed or Re-Ordered.
- /// Should be used for triggering an update of the Queue Window.
- /// </summary>
- public event EventHandler QueueChanged;
-
- /// <summary>
- /// Fires when the entire encode queue has completed.
- /// </summary>
- public event QueueCompletedEventDelegate QueueCompleted;
-
- /// <summary>
- /// Fires when a pause to the encode queue has been requested.
- /// </summary>
- public event EventHandler QueuePaused;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets the number of jobs in the queue;
- /// </summary>
- public int Count
- {
- get
- {
- return this.queue.Count(item => item.Status == QueueItemStatus.Waiting);
- }
- }
-
- /// <summary>
- /// The number of errors detected.
- /// </summary>
- public int ErrorCount
- {
- get
- {
- return this.queue.Count(item => item.Status == QueueItemStatus.Error);
- }
- }
-
- /// <summary>
- /// Gets the IEncodeService instance.
- /// </summary>
- public IEncode EncodeService { get; private set; }
-
- /// <summary>
- /// Gets a value indicating whether IsProcessing.
- /// </summary>
- public bool IsProcessing { get; private set; }
-
- /// <summary>
- /// Gets or sets Last Processed Job.
- /// This is set when the job is poped of the queue by GetNextJobForProcessing();
- /// </summary>
- public QueueTask LastProcessedJob { get; set; }
-
- /// <summary>
- /// Gets The current queue.
- /// </summary>
- public ObservableCollection<QueueTask> Queue
- {
- get
- {
- return this.queue;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Add a job to the Queue.
- /// This method is Thread Safe.
- /// </summary>
- /// <param name="job">
- /// The encode Job object.
- /// </param>
- public void Add(QueueTask job)
- {
- lock (QueueLock)
- {
- this.queue.Add(job);
- this.InvokeQueueChanged(EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Backup any changes to the queue file
- /// </summary>
- /// <param name="exportPath">
- /// If this is not null or empty, this will be used instead of the standard backup location.
- /// </param>
- public void BackupQueue(string exportPath)
- {
- string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
- string tempPath = !string.IsNullOrEmpty(exportPath)
- ? exportPath
- : Path.Combine(appDataPath, string.Format(this.queueFile, string.Empty));
-
- using (var strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
- {
- List<QueueTask> tasks = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
- var serializer = new XmlSerializer(typeof(List<QueueTask>));
- serializer.Serialize(strm, tasks);
- strm.Close();
- strm.Dispose();
- }
- }
-
- public void ExportJson(string exportPath)
- {
- List<QueueTask> jobs = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
- List<EncodeTask> workUnits = jobs.Select(job => job.Task).ToList();
- HBConfiguration config = HBConfigurationFactory.Create(); // Default to current settings for now. These will hopefully go away in the future.
-
- string json = QueueFactory.GetQueueJson(workUnits, config);
-
- using (var strm = new StreamWriter(exportPath, false))
- {
- strm.Write(json);
- strm.Close();
- strm.Dispose();
- }
- }
-
- public void ImportJson(string path)
- {
- List<Task> tasks;
- using (StreamReader reader = new StreamReader(path))
- {
- string fileContent = reader.ReadToEnd();
- tasks = QueueFactory.GetQueue(fileContent);
-
- if (tasks != null)
- {
- foreach (Task task in tasks)
- {
- // TODO flesh out.
- EncodeTask encodeTask = EncodeTaskImportFactory.Create(task.Job);
- QueueTask queueTask = new QueueTask();
- queueTask.Task = encodeTask;
-
- this.queue.Add(queueTask);
- }
- }
- }
- }
-
- /// <summary>
- /// Checks the current queue for an existing instance of the specified destination.
- /// </summary>
- /// <param name="destination">
- /// The destination of the encode.
- /// </param>
- /// <returns>
- /// Whether or not the supplied destination is already in the queue.
- /// </returns>
- public bool CheckForDestinationPathDuplicates(string destination)
- {
- foreach (QueueTask job in this.queue)
- {
- if (string.Equals(
- job.Task.Destination,
- destination.Replace("\\\\", "\\"),
- StringComparison.OrdinalIgnoreCase) && (job.Status == QueueItemStatus.Waiting || job.Status == QueueItemStatus.InProgress))
- {
- return true;
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// Clear down all Queue Items
- /// </summary>
- public void Clear()
- {
- List<QueueTask> deleteList = this.queue.ToList();
- foreach (QueueTask item in deleteList)
- {
- this.queue.Remove(item);
- }
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Clear down the Queue´s completed items
- /// </summary>
- public void ClearCompleted()
- {
- Execute.OnUIThread(
- () =>
- {
- List<QueueTask> deleteList =
- this.queue.Where(task => task.Status == QueueItemStatus.Completed).ToList();
- foreach (QueueTask item in deleteList)
- {
- this.queue.Remove(item);
- }
- this.InvokeQueueChanged(EventArgs.Empty);
- });
- }
-
- /// <summary>
- /// Get the first job on the queue for processing.
- /// This also removes the job from the Queue and sets the LastProcessedJob
- /// </summary>
- /// <returns>
- /// An encode Job object.
- /// </returns>
- public QueueTask GetNextJobForProcessing()
- {
- if (this.queue.Count > 0)
- {
- return this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);
- }
-
- return null;
- }
-
- /// <summary>
- /// Moves an item down one position in the queue.
- /// </summary>
- /// <param name="index">
- /// The zero-based location of the job in the queue.
- /// </param>
- public void MoveDown(int index)
- {
- if (index < this.queue.Count - 1)
- {
- QueueTask item = this.queue[index];
-
- this.queue.RemoveAt(index);
- this.queue.Insert((index + 1), item);
- }
-
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Moves an item up one position in the queue.
- /// </summary>
- /// <param name="index">
- /// The zero-based location of the job in the queue.
- /// </param>
- public void MoveUp(int index)
- {
- if (index > 0)
- {
- QueueTask item = this.queue[index];
-
- this.queue.RemoveAt(index);
- this.queue.Insert((index - 1), item);
- }
-
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Remove a job from the Queue.
- /// This method is Thread Safe
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- public void Remove(QueueTask job)
- {
- lock (QueueLock)
- {
- this.queue.Remove(job);
- this.InvokeQueueChanged(EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Reset a Queued Item from Error or Completed to Waiting
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- public void ResetJobStatusToWaiting(QueueTask job)
- {
- if (job.Status != QueueItemStatus.Error && job.Status != QueueItemStatus.Completed)
- {
- throw new GeneralApplicationException(
- Resources.Error, Resources.Queue_UnableToResetJob, null);
- }
-
- job.Status = QueueItemStatus.Waiting;
- }
-
- /// <summary>
- /// Restore a Queue from file or from the queue backup file.
- /// </summary>
- /// <param name="importPath">
- /// The import path. String.Empty or null will result in the default file being loaded.
- /// </param>
- public void RestoreQueue(string importPath)
- {
- string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
- string tempPath = !string.IsNullOrEmpty(importPath)
- ? importPath
- : (appDataPath + string.Format(this.queueFile, string.Empty));
-
- if (File.Exists(tempPath))
- {
- bool invokeUpdate = false;
- using (
- var strm = new FileStream(
- (!string.IsNullOrEmpty(importPath) ? importPath : tempPath), FileMode.Open, FileAccess.Read))
- {
- if (strm.Length != 0)
- {
- var serializer = new XmlSerializer(typeof(List<QueueTask>));
-
- List<QueueTask> list;
-
- try
- {
- list = serializer.Deserialize(strm) as List<QueueTask>;
- }
- catch (Exception exc)
- {
- throw new GeneralApplicationException(Resources.Queue_UnableToRestoreFile, Resources.Queue_UnableToRestoreFileExtended, exc);
- }
-
- if (list != null)
- {
- foreach (QueueTask item in list)
- {
- if (item.Status != QueueItemStatus.Completed)
- {
- // Reset InProgress/Error to Waiting so it can be processed
- if (item.Status == QueueItemStatus.InProgress)
- {
- item.Status = QueueItemStatus.Error;
- }
-
- this.queue.Add(item);
- }
- }
- }
-
- invokeUpdate = true;
- }
- }
-
- if (invokeUpdate)
- {
- this.InvokeQueueChanged(EventArgs.Empty);
- }
- }
- }
-
- /// <summary>
- /// Requests a pause of the encode queue.
- /// </summary>
- public void Pause()
- {
- this.IsProcessing = false;
- this.InvokeQueuePaused(EventArgs.Empty);
- }
-
- public void PauseEncode()
- {
- if (this.EncodeService.IsEncoding && !this.EncodeService.IsPasued)
- {
- this.EncodeService.Pause();
- this.LastProcessedJob.Statistics.SetPaused(true);
- }
-
- this.Pause();
- }
-
- /// <summary>
- /// Starts encoding the first job in the queue and continues encoding until all jobs
- /// have been encoded.
- /// </summary>
- /// <param name="isClearCompleted">
- /// The is Clear Completed.
- /// </param>
- public void Start(bool isClearCompleted)
- {
- if (this.IsProcessing)
- {
- return;
- }
-
- this.clearCompleted = isClearCompleted;
-
- this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
- this.EncodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted;
-
- if (this.EncodeService.IsPasued)
- {
- this.EncodeService.Resume();
- this.IsProcessing = true;
- this.InvokeJobProcessingStarted(new QueueProgressEventArgs(this.LastProcessedJob));
- this.LastProcessedJob.Statistics.SetPaused(false);
- }
-
- if (!this.EncodeService.IsEncoding)
- {
- this.ProcessNextJob();
- }
- }
-
- public void Stop()
- {
- if (this.EncodeService.IsEncoding)
- {
- this.EncodeService.Stop();
- }
- this.IsProcessing = false;
- this.InvokeQueuePaused(EventArgs.Empty);
- }
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// The on queue completed.
- /// </summary>
- /// <param name="e">
- /// The e.
- /// </param>
- protected virtual void OnQueueCompleted(QueueCompletedEventArgs e)
- {
- QueueCompletedEventDelegate handler = this.QueueCompleted;
- if (handler != null)
- {
- handler(this, e);
- }
-
- this.IsProcessing = false;
- }
-
- /// <summary>
- /// After an encode is complete, move onto the next job.
- /// </summary>
- /// <param name="sender">
- /// The sender.
- /// </param>
- /// <param name="e">
- /// The EncodeCompletedEventArgs.
- /// </param>
- private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)
- {
- this.LastProcessedJob.Status = QueueItemStatus.Completed;
- this.LastProcessedJob.Statistics.EndTime = DateTime.Now;
- this.LastProcessedJob.Statistics.CompletedActivityLogPath = e.ActivityLogPath;
- this.LastProcessedJob.Statistics.FinalFileSize = e.FinalFilesizeInBytes;
-
- // Clear the completed item of the queue if the setting is set.
- if (this.clearCompleted)
- {
- this.ClearCompleted();
- }
-
- if (!e.Successful)
- {
- this.LastProcessedJob.Status = QueueItemStatus.Error;
- }
-
- // Move onto the next job.
- if (this.IsProcessing)
- {
- this.ProcessNextJob();
- }
- else
- {
- this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
- this.BackupQueue(string.Empty);
- this.OnQueueCompleted(new QueueCompletedEventArgs(true));
- }
- }
-
- /// <summary>
- /// Invoke the JobProcessingStarted event
- /// </summary>
- /// <param name="e">
- /// The QueueProgressEventArgs.
- /// </param>
- private void InvokeJobProcessingStarted(QueueProgressEventArgs e)
- {
- QueueProgressStatus handler = this.JobProcessingStarted;
- if (handler != null)
- {
- handler(this, e);
- }
- }
-
- /// <summary>
- /// Invoke the Queue Changed Event
- /// </summary>
- /// <param name="e">
- /// The e.
- /// </param>
- private void InvokeQueueChanged(EventArgs e)
- {
- try
- {
- this.BackupQueue(string.Empty);
- }
- catch (Exception)
- {
- // Do Nothing.
- }
-
- EventHandler handler = this.QueueChanged;
- if (handler != null)
- {
- handler(this, e);
- }
- }
-
- /// <summary>
- /// Invoke the QueuePaused event
- /// </summary>
- /// <param name="e">
- /// The EventArgs.
- /// </param>
- private void InvokeQueuePaused(EventArgs e)
- {
- this.IsProcessing = false;
-
- EventHandler handler = this.QueuePaused;
- if (handler != null)
- {
- handler(this, e);
- }
- }
-
- /// <summary>
- /// Run through all the jobs on the queue.
- /// </summary>
- private void ProcessNextJob()
- {
- QueueTask job = this.GetNextJobForProcessing();
- if (job != null)
- {
- if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.PauseOnLowDiskspace) && !DriveUtilities.HasMinimumDiskSpace(job.Task.Destination, this.userSettingService.GetUserSetting<long>(UserSettingConstants.PauseOnLowDiskspaceLevel)))
- {
- LogService.GetLogger().LogMessage(Resources.PauseOnLowDiskspace, LogMessageType.ScanOrEncode, LogLevel.Info);
- job.Status = QueueItemStatus.Waiting;
- this.Pause();
- this.BackupQueue(string.Empty);
- return; // Don't start the next job.
- }
-
- job.Status = QueueItemStatus.InProgress;
- job.Statistics.StartTime = DateTime.Now;
- this.LastProcessedJob = job;
- this.IsProcessing = true;
- this.InvokeQueueChanged(EventArgs.Empty);
- this.InvokeJobProcessingStarted(new QueueProgressEventArgs(job));
-
- if (!Directory.Exists(Path.GetDirectoryName(job.Task.Destination)))
- {
- this.EncodeServiceEncodeCompleted(null, new EncodeCompletedEventArgs(false, null, "Destination Directory Missing", null, null, 0));
- this.BackupQueue(string.Empty);
- return;
- }
- this.EncodeService.Start(job.Task, job.Configuration);
- this.BackupQueue(string.Empty);
- }
- else
- {
- // No more jobs to process, so unsubscribe the event
- this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
-
- this.BackupQueue(string.Empty);
-
- // Fire the event to tell connected services.
- this.OnQueueCompleted(new QueueCompletedEventArgs(false));
- }
- }
-
- #endregion
- }
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="QueueService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The HandBrake Queue
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Queue
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.IO;
+ using System.Linq;
+
+ using HandBrake.Interop.Interop.Json.Queue;
+ using HandBrake.Interop.Model;
+ using HandBrake.Interop.Utilities;
+
+ using HandBrakeWPF.Factories;
+ using HandBrakeWPF.Helpers;
+ using HandBrakeWPF.Properties;
+ using HandBrakeWPF.Services.Encode.Factories;
+ using HandBrakeWPF.Services.Encode.Model;
+ using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.Services.Queue.Model;
+ using HandBrakeWPF.Utilities;
+
+ using Newtonsoft.Json;
+
+ using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs;
+ using Execute = Caliburn.Micro.Execute;
+ using GeneralApplicationException = HandBrakeWPF.Exceptions.GeneralApplicationException;
+ using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode;
+ using LogLevel = HandBrakeWPF.Services.Logging.Model.LogLevel;
+ using LogMessageType = HandBrakeWPF.Services.Logging.Model.LogMessageType;
+ using LogService = HandBrakeWPF.Services.Logging.LogService;
+ using QueueCompletedEventArgs = HandBrakeWPF.EventArgs.QueueCompletedEventArgs;
+ using QueueProgressEventArgs = HandBrakeWPF.EventArgs.QueueProgressEventArgs;
+
+ /// <summary>
+ /// The HandBrake Queue
+ /// </summary>
+ public class QueueService : Interfaces.IQueueService
+ {
+ #region Constants and Fields
+ private static readonly object QueueLock = new object();
+ private readonly IUserSettingService userSettingService;
+ private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
+ private readonly string queueFile;
+ private bool clearCompleted;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QueueService"/> class.
+ /// </summary>
+ /// <param name="encodeService">
+ /// The encode Service.
+ /// </param>
+ /// <param name="userSettingService">
+ /// The user settings service.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// Services are not setup
+ /// </exception>
+ public QueueService(IEncode encodeService, IUserSettingService userSettingService)
+ {
+ this.userSettingService = userSettingService;
+ this.EncodeService = encodeService;
+
+ // If this is the first instance, just use the main queue file, otherwise add the instance id to the filename.
+ this.queueFile = string.Format("{0}{1}.json", QueueRecoveryHelper.QueueFileName, GeneralUtilities.ProcessId);
+ }
+
+ #endregion
+
+ #region Delegates
+
+ /// <summary>
+ /// Queue Progress Status
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The QueueProgressEventArgs.
+ /// </param>
+ public delegate void QueueProgressStatus(object sender, QueueProgressEventArgs e);
+
+ /// <summary>
+ /// The queue completed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ public delegate void QueueCompletedEventDelegate(object sender, QueueCompletedEventArgs e);
+
+ #endregion
+
+ #region Events
+
+ /// <summary>
+ /// Fires when the Queue has started
+ /// </summary>
+ public event QueueProgressStatus JobProcessingStarted;
+
+ /// <summary>
+ /// Fires when a job is Added, Removed or Re-Ordered.
+ /// Should be used for triggering an update of the Queue Window.
+ /// </summary>
+ public event EventHandler QueueChanged;
+
+ /// <summary>
+ /// Fires when the entire encode queue has completed.
+ /// </summary>
+ public event QueueCompletedEventDelegate QueueCompleted;
+
+ /// <summary>
+ /// Fires when a pause to the encode queue has been requested.
+ /// </summary>
+ public event EventHandler QueuePaused;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the number of jobs in the queue;
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ return this.queue.Count(item => item.Status == QueueItemStatus.Waiting);
+ }
+ }
+
+ /// <summary>
+ /// The number of errors detected.
+ /// </summary>
+ public int ErrorCount
+ {
+ get
+ {
+ return this.queue.Count(item => item.Status == QueueItemStatus.Error);
+ }
+ }
+
+ /// <summary>
+ /// Gets the IEncodeService instance.
+ /// </summary>
+ public IEncode EncodeService { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether IsProcessing.
+ /// </summary>
+ public bool IsProcessing { get; private set; }
+
+ /// <summary>
+ /// Gets or sets Last Processed Job.
+ /// This is set when the job is poped of the queue by GetNextJobForProcessing();
+ /// </summary>
+ public QueueTask LastProcessedJob { get; set; }
+
+ /// <summary>
+ /// Gets The current queue.
+ /// </summary>
+ public ObservableCollection<QueueTask> Queue
+ {
+ get
+ {
+ return this.queue;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Add a job to the Queue.
+ /// This method is Thread Safe.
+ /// </summary>
+ /// <param name="job">
+ /// The encode Job object.
+ /// </param>
+ public void Add(QueueTask job)
+ {
+ lock (QueueLock)
+ {
+ this.queue.Add(job);
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Backup any changes to the queue file
+ /// </summary>
+ /// <param name="exportPath">
+ /// If this is not null or empty, this will be used instead of the standard backup location.
+ /// </param>
+ public void BackupQueue(string exportPath)
+ {
+ Stopwatch watch = Stopwatch.StartNew();
+
+ string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
+ string tempPath = !string.IsNullOrEmpty(exportPath)
+ ? exportPath
+ : Path.Combine(appDataPath, string.Format(this.queueFile, string.Empty));
+
+ using (StreamWriter writer = new StreamWriter(tempPath))
+ {
+ List<QueueTask> tasks = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
+ string queueJson = JsonConvert.SerializeObject(tasks, Formatting.Indented);
+ writer.Write(queueJson);
+ }
+
+ watch.Stop();
+ Debug.WriteLine("Queue Save (ms): " + watch.ElapsedMilliseconds);
+ }
+
+ public void ExportJson(string exportPath)
+ {
+ List<QueueTask> jobs = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
+ List<EncodeTask> workUnits = jobs.Select(job => job.Task).ToList();
+ HBConfiguration config = HBConfigurationFactory.Create(); // Default to current settings for now. These will hopefully go away in the future.
+
+ string json = QueueFactory.GetQueueJson(workUnits, config);
+
+ using (var strm = new StreamWriter(exportPath, false))
+ {
+ strm.Write(json);
+ strm.Close();
+ strm.Dispose();
+ }
+ }
+
+ public void ImportJson(string path)
+ {
+ List<Task> tasks;
+ using (StreamReader reader = new StreamReader(path))
+ {
+ string fileContent = reader.ReadToEnd();
+ tasks = QueueFactory.GetQueue(fileContent);
+
+ if (tasks != null)
+ {
+ foreach (Task task in tasks)
+ {
+ // TODO flesh out.
+ EncodeTask encodeTask = EncodeTaskImportFactory.Create(task.Job);
+ QueueTask queueTask = new QueueTask();
+ queueTask.Task = encodeTask;
+
+ this.queue.Add(queueTask);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks the current queue for an existing instance of the specified destination.
+ /// </summary>
+ /// <param name="destination">
+ /// The destination of the encode.
+ /// </param>
+ /// <returns>
+ /// Whether or not the supplied destination is already in the queue.
+ /// </returns>
+ public bool CheckForDestinationPathDuplicates(string destination)
+ {
+ foreach (QueueTask job in this.queue)
+ {
+ if (string.Equals(
+ job.Task.Destination,
+ destination.Replace("\\\\", "\\"),
+ StringComparison.OrdinalIgnoreCase) && (job.Status == QueueItemStatus.Waiting || job.Status == QueueItemStatus.InProgress))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Clear down all Queue Items
+ /// </summary>
+ public void Clear()
+ {
+ List<QueueTask> deleteList = this.queue.ToList();
+ foreach (QueueTask item in deleteList)
+ {
+ this.queue.Remove(item);
+ }
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Clear down the Queue´s completed items
+ /// </summary>
+ public void ClearCompleted()
+ {
+ Execute.OnUIThread(
+ () =>
+ {
+ List<QueueTask> deleteList =
+ this.queue.Where(task => task.Status == QueueItemStatus.Completed).ToList();
+ foreach (QueueTask item in deleteList)
+ {
+ this.queue.Remove(item);
+ }
+ this.InvokeQueueChanged(EventArgs.Empty);
+ });
+ }
+
+ /// <summary>
+ /// Get the first job on the queue for processing.
+ /// This also removes the job from the Queue and sets the LastProcessedJob
+ /// </summary>
+ /// <returns>
+ /// An encode Job object.
+ /// </returns>
+ public QueueTask GetNextJobForProcessing()
+ {
+ if (this.queue.Count > 0)
+ {
+ return this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Moves an item down one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ public void MoveDown(int index)
+ {
+ if (index < this.queue.Count - 1)
+ {
+ QueueTask item = this.queue[index];
+
+ this.queue.RemoveAt(index);
+ this.queue.Insert((index + 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Moves an item up one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ public void MoveUp(int index)
+ {
+ if (index > 0)
+ {
+ QueueTask item = this.queue[index];
+
+ this.queue.RemoveAt(index);
+ this.queue.Insert((index - 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Remove a job from the Queue.
+ /// This method is Thread Safe
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ public void Remove(QueueTask job)
+ {
+ lock (QueueLock)
+ {
+ this.queue.Remove(job);
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Reset a Queued Item from Error or Completed to Waiting
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ public void ResetJobStatusToWaiting(QueueTask job)
+ {
+ if (job.Status != QueueItemStatus.Error && job.Status != QueueItemStatus.Completed)
+ {
+ throw new GeneralApplicationException(
+ Resources.Error, Resources.Queue_UnableToResetJob, null);
+ }
+
+ job.Status = QueueItemStatus.Waiting;
+ }
+
+ /// <summary>
+ /// Restore a Queue from file or from the queue backup file.
+ /// </summary>
+ /// <param name="importPath">
+ /// The import path. String.Empty or null will result in the default file being loaded.
+ /// </param>
+ public void RestoreQueue(string importPath)
+ {
+ string appDataPath = DirectoryUtilities.GetUserStoragePath(VersionHelper.IsNightly());
+ string tempPath = !string.IsNullOrEmpty(importPath)
+ ? importPath
+ : (appDataPath + string.Format(this.queueFile, string.Empty));
+
+ if (File.Exists(tempPath))
+ {
+ bool invokeUpdate = false;
+ using (StreamReader stream = new StreamReader(!string.IsNullOrEmpty(importPath) ? importPath : tempPath))
+ {
+ string queueJson = stream.ReadToEnd();
+ List<QueueTask> list;
+
+ try
+ {
+ list = JsonConvert.DeserializeObject<List<QueueTask>>(queueJson);
+ }
+ catch (Exception exc)
+ {
+ throw new GeneralApplicationException(Resources.Queue_UnableToRestoreFile, Resources.Queue_UnableToRestoreFileExtended, exc);
+ }
+
+ if (list != null)
+ {
+ foreach (QueueTask item in list)
+ {
+ if (item.Status != QueueItemStatus.Completed)
+ {
+ // Reset InProgress/Error to Waiting so it can be processed
+ if (item.Status == QueueItemStatus.InProgress)
+ {
+ item.Status = QueueItemStatus.Error;
+ }
+
+ this.queue.Add(item);
+ }
+ }
+ }
+
+ invokeUpdate = true;
+ }
+
+ if (invokeUpdate)
+ {
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Requests a pause of the encode queue.
+ /// </summary>
+ public void Pause()
+ {
+ this.IsProcessing = false;
+ this.InvokeQueuePaused(EventArgs.Empty);
+ }
+
+ public void PauseEncode()
+ {
+ if (this.EncodeService.IsEncoding && !this.EncodeService.IsPasued)
+ {
+ this.EncodeService.Pause();
+ this.LastProcessedJob.Statistics.SetPaused(true);
+ }
+
+ this.Pause();
+ }
+
+ /// <summary>
+ /// Starts encoding the first job in the queue and continues encoding until all jobs
+ /// have been encoded.
+ /// </summary>
+ /// <param name="isClearCompleted">
+ /// The is Clear Completed.
+ /// </param>
+ public void Start(bool isClearCompleted)
+ {
+ if (this.IsProcessing)
+ {
+ return;
+ }
+
+ this.clearCompleted = isClearCompleted;
+
+ this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
+ this.EncodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted;
+
+ if (this.EncodeService.IsPasued)
+ {
+ this.EncodeService.Resume();
+ this.IsProcessing = true;
+ this.InvokeJobProcessingStarted(new QueueProgressEventArgs(this.LastProcessedJob));
+ this.LastProcessedJob.Statistics.SetPaused(false);
+ }
+
+ if (!this.EncodeService.IsEncoding)
+ {
+ this.ProcessNextJob();
+ }
+ }
+
+ public void Stop()
+ {
+ if (this.EncodeService.IsEncoding)
+ {
+ this.EncodeService.Stop();
+ }
+ this.IsProcessing = false;
+ this.InvokeQueuePaused(EventArgs.Empty);
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// The on queue completed.
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ protected virtual void OnQueueCompleted(QueueCompletedEventArgs e)
+ {
+ QueueCompletedEventDelegate handler = this.QueueCompleted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+
+ this.IsProcessing = false;
+ }
+
+ /// <summary>
+ /// After an encode is complete, move onto the next job.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EncodeCompletedEventArgs.
+ /// </param>
+ private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)
+ {
+ this.LastProcessedJob.Status = QueueItemStatus.Completed;
+ this.LastProcessedJob.Statistics.EndTime = DateTime.Now;
+ this.LastProcessedJob.Statistics.CompletedActivityLogPath = e.ActivityLogPath;
+ this.LastProcessedJob.Statistics.FinalFileSize = e.FinalFilesizeInBytes;
+
+ // Clear the completed item of the queue if the setting is set.
+ if (this.clearCompleted)
+ {
+ this.ClearCompleted();
+ }
+
+ if (!e.Successful)
+ {
+ this.LastProcessedJob.Status = QueueItemStatus.Error;
+ }
+
+ // Move onto the next job.
+ if (this.IsProcessing)
+ {
+ this.ProcessNextJob();
+ }
+ else
+ {
+ this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
+ this.BackupQueue(string.Empty);
+ this.OnQueueCompleted(new QueueCompletedEventArgs(true));
+ }
+ }
+
+ /// <summary>
+ /// Invoke the JobProcessingStarted event
+ /// </summary>
+ /// <param name="e">
+ /// The QueueProgressEventArgs.
+ /// </param>
+ private void InvokeJobProcessingStarted(QueueProgressEventArgs e)
+ {
+ QueueProgressStatus handler = this.JobProcessingStarted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the Queue Changed Event
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void InvokeQueueChanged(EventArgs e)
+ {
+ try
+ {
+ this.BackupQueue(string.Empty);
+ }
+ catch (Exception)
+ {
+ // Do Nothing.
+ }
+
+ EventHandler handler = this.QueueChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the QueuePaused event
+ /// </summary>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ private void InvokeQueuePaused(EventArgs e)
+ {
+ this.IsProcessing = false;
+
+ EventHandler handler = this.QueuePaused;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Run through all the jobs on the queue.
+ /// </summary>
+ private void ProcessNextJob()
+ {
+ QueueTask job = this.GetNextJobForProcessing();
+ if (job != null)
+ {
+ if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.PauseOnLowDiskspace) && !DriveUtilities.HasMinimumDiskSpace(job.Task.Destination, this.userSettingService.GetUserSetting<long>(UserSettingConstants.PauseOnLowDiskspaceLevel)))
+ {
+ LogService.GetLogger().LogMessage(Resources.PauseOnLowDiskspace, LogMessageType.ScanOrEncode, LogLevel.Info);
+ job.Status = QueueItemStatus.Waiting;
+ this.Pause();
+ this.BackupQueue(string.Empty);
+ return; // Don't start the next job.
+ }
+
+ job.Status = QueueItemStatus.InProgress;
+ job.Statistics.StartTime = DateTime.Now;
+ this.LastProcessedJob = job;
+ this.IsProcessing = true;
+ this.InvokeQueueChanged(EventArgs.Empty);
+ this.InvokeJobProcessingStarted(new QueueProgressEventArgs(job));
+
+ if (!Directory.Exists(Path.GetDirectoryName(job.Task.Destination)))
+ {
+ this.EncodeServiceEncodeCompleted(null, new EncodeCompletedEventArgs(false, null, "Destination Directory Missing", null, null, 0));
+ this.BackupQueue(string.Empty);
+ return;
+ }
+ this.EncodeService.Start(job.Task, job.Configuration);
+ this.BackupQueue(string.Empty);
+ }
+ else
+ {
+ // No more jobs to process, so unsubscribe the event
+ this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
+
+ this.BackupQueue(string.Empty);
+
+ // Fire the event to tell connected services.
+ this.OnQueueCompleted(new QueueCompletedEventArgs(false));
+ }
+ }
+
+ #endregion
+ }
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
index 458c071c3..4f1f6c159 100644
--- a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
+++ b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
@@ -60,7 +60,7 @@ namespace HandBrakeWPF.Startup
this.container.Singleton<IPrePostActionService, PrePostActionService>();
this.container.Singleton<IUserSettingService, UserSettingService>();
this.container.Singleton<IPresetService, PresetService>();
- this.container.Singleton<IQueueProcessor, QueueProcessor>();
+ this.container.Singleton<IQueueService, QueueService>();
// Commands
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index d39975244..c93a005d3 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -70,7 +70,7 @@ namespace HandBrakeWPF.ViewModels
{
#region Private Variables and Services
- private readonly IQueueProcessor queueProcessor;
+ private readonly IQueueService queueProcessor;
private readonly IPresetService presetService;
private readonly IErrorService errorService;
private readonly IUpdateService updateService;
@@ -126,7 +126,7 @@ namespace HandBrakeWPF.ViewModels
this.notifyIconService = notifyIconService;
this.QueueViewModel = queueViewModel;
this.userSettingService = userSettingService;
- this.queueProcessor = IoC.Get<IQueueProcessor>();
+ this.queueProcessor = IoC.Get<IQueueService>();
this.SummaryViewModel = summaryViewModel;
this.PictureSettingsViewModel = pictureSettingsViewModel;
diff --git a/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs
index 3e5fb83c1..59de994df 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs
@@ -25,7 +25,7 @@ namespace HandBrakeWPF.ViewModels
public class MiniViewModel : ViewModelBase, IMiniViewModel
{
private readonly IEncode encodeService;
- private readonly IQueueProcessor queueProcessor;
+ private readonly IQueueService queueProcessor;
private string queueStatus;
private string progress;
private string task;
@@ -40,7 +40,7 @@ namespace HandBrakeWPF.ViewModels
/// <param name="queueProcessor">
/// The queue Processor.
/// </param>
- public MiniViewModel(IEncode encodeService, IQueueProcessor queueProcessor)
+ public MiniViewModel(IEncode encodeService, IQueueService queueProcessor)
{
this.encodeService = encodeService;
this.queueProcessor = queueProcessor;
diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
index a5df085b0..15602f79d 100644
--- a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
@@ -44,7 +44,7 @@ namespace HandBrakeWPF.ViewModels
private readonly IErrorService errorService;
private readonly IUserSettingService userSettingService;
- private readonly IQueueProcessor queueProcessor;
+ private readonly IQueueService queueProcessor;
private string jobStatus;
private string jobsPending;
private string whenDoneAction;
@@ -70,7 +70,7 @@ namespace HandBrakeWPF.ViewModels
/// <param name="errorService">
/// The Error Service
/// </param>
- public QueueViewModel(IUserSettingService userSettingService, IQueueProcessor queueProcessor, IErrorService errorService)
+ public QueueViewModel(IUserSettingService userSettingService, IQueueService queueProcessor, IErrorService errorService)
{
this.userSettingService = userSettingService;
this.queueProcessor = queueProcessor;
diff --git a/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
index 60706c3fd..c75981ef2 100644
--- a/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
@@ -18,7 +18,7 @@ namespace HandBrakeWPF.ViewModels
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.ViewModels.Interfaces;
- using IQueueProcessor = HandBrakeWPF.Services.Queue.Interfaces.IQueueProcessor;
+ using IQueueService = HandBrakeWPF.Services.Queue.Interfaces.IQueueService;
/// <summary>
/// The Shell View Model
@@ -189,7 +189,7 @@ namespace HandBrakeWPF.ViewModels
/// </returns>
public bool CanClose()
{
- IQueueProcessor processor = IoC.Get<IQueueProcessor>();
+ IQueueService processor = IoC.Get<IQueueService>();
if (processor != null && processor.EncodeService.IsEncoding)
{
MessageBoxResult result =