]> granicus.if.org Git - handbrake/commitdiff
WinGui: Change the Queue to work in the same way as the Mac/Lin Queue. Retain Complet...
authorsr55 <sr55.hb@outlook.com>
Sun, 7 Aug 2011 21:31:14 +0000 (21:31 +0000)
committersr55 <sr55.hb@outlook.com>
Sun, 7 Aug 2011 21:31:14 +0000 (21:31 +0000)
- Added option to clear completed jobs.
- Added option to re-encode a completed/errored job.
- In-progress/Waiting jobs get saved into queue recovery.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4161 b64f7644-9d1e-0410-96f1-a4d463321fa5

win/CS/Functions/Main.cs
win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
win/CS/HandBrake.ApplicationServices/Model/QueueItemStatus.cs [new file with mode: 0644]
win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs
win/CS/HandBrake.ApplicationServices/Services/Encode.cs
win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueManager.cs
win/CS/HandBrake.ApplicationServices/Services/QueueManager.cs
win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs
win/CS/frmQueue.Designer.cs
win/CS/frmQueue.cs

index 2775b80646cec658c8266f18da74cf11184252c9..9aa5afdc48b7889e1bd94d4b99e36203a845f594 100644 (file)
@@ -412,7 +412,7 @@ namespace Handbrake.Functions
 \r
                 return queueFiles;\r
             }\r
-            catch (Exception)\r
+            catch (Exception exc)\r
             {\r
                 return new List<string>(); // Keep quiet about the error.\r
             }\r
index 55fa4a380f25e36704abd8ece35a1c0911607483..52906af73f68eb7db435403f741dfd65135b9498 100644 (file)
     <Compile Include="Model\General\UpdateCheckResult.cs" />\r
     <Compile Include="Model\ModelBase.cs" />\r
     <Compile Include="Model\Preset.cs" />\r
+    <Compile Include="Model\QueueItemStatus.cs" />\r
     <Compile Include="Model\QueueTask.cs" />\r
     <Compile Include="Model\Encoding\SubtitleType.cs" />\r
     <Compile Include="Parsing\Audio.cs" />\r
diff --git a/win/CS/HandBrake.ApplicationServices/Model/QueueItemStatus.cs b/win/CS/HandBrake.ApplicationServices/Model/QueueItemStatus.cs
new file mode 100644 (file)
index 0000000..774d0a7
--- /dev/null
@@ -0,0 +1,30 @@
+/*  QueueItemStatus.cs $\r
+    This file is part of the HandBrake source code.\r
+    Homepage: <http://handbrake.fr>.\r
+    It may be used under the terms of the GNU General Public License. */\r
+\r
+namespace HandBrake.ApplicationServices.Model\r
+{\r
+    using System.ComponentModel;\r
+\r
+    using HandBrake.ApplicationServices.Converters;\r
+\r
+    /// <summary>\r
+    /// Queue Item Status\r
+    /// </summary>\r
+    [TypeConverter(typeof(EnumToDescConveter))]\r
+    public enum QueueItemStatus\r
+    {\r
+        [Description("Waiting")]\r
+        Waiting = 0,\r
+\r
+        [Description("In Progress")]\r
+        InProgress,\r
+\r
+        [Description("Completed")]\r
+        Completed,\r
+\r
+        [Description("Error")]\r
+        Error,\r
+    }\r
+}\r
index 83948a1f398f94212dad61faa870b72dfcdadc90..aa71a28194dc8749e28ac95c3e30b4d936b37394 100644 (file)
@@ -5,6 +5,8 @@
 \r
 namespace HandBrake.ApplicationServices.Model\r
 {\r
+    using System;\r
+\r
     /// <summary>\r
     /// The QueueTask.\r
     /// </summary>\r
@@ -64,6 +66,21 @@ namespace HandBrake.ApplicationServices.Model
         /// </summary>\r
         public bool CustomQuery { get; set; }\r
 \r
+        /// <summary>\r
+        /// Gets or sets Status.\r
+        /// </summary>\r
+        public QueueItemStatus Status { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets or sets StartTime.\r
+        /// </summary>\r
+        public DateTime StartTime { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets or sets ElaspedEncodeTime.\r
+        /// </summary>\r
+        public TimeSpan ElaspedEncodeTime { get; set; }\r
+\r
         /// <summary>\r
         /// Gets or sets the Encode Task.\r
         /// </summary>\r
index 26708434fc322945220a63351e9513fe7ecfafe4..953831732ba2bf308e58f50a0a34db7848cadf46 100644 (file)
@@ -40,6 +40,11 @@ namespace HandBrake.ApplicationServices.Services
         /// </summary>\r
         private DateTime startTime;\r
 \r
+        /// <summary>\r
+        /// The Current Task\r
+        /// </summary>\r
+        private QueueTask currentTask;\r
+\r
         #endregion\r
 \r
         /// <summary>\r
@@ -75,7 +80,7 @@ namespace HandBrake.ApplicationServices.Services
         {\r
             try\r
             {\r
-                QueueTask queueTask = encodeQueueTask;\r
+                this.currentTask = encodeQueueTask;\r
 \r
                 if (this.IsEncoding)\r
                 {\r
@@ -88,7 +93,7 @@ namespace HandBrake.ApplicationServices.Services
                 {\r
                     try\r
                     {\r
-                        this.SetupLogging(queueTask);\r
+                        this.SetupLogging(currentTask);\r
                     }\r
                     catch (Exception)\r
                     {\r
@@ -103,10 +108,10 @@ namespace HandBrake.ApplicationServices.Services
                 }\r
 \r
                 // Make sure the path exists, attempt to create it if it doesn't\r
-                this.VerifyEncodeDestinationPath(queueTask);\r
+                this.VerifyEncodeDestinationPath(currentTask);\r
 \r
                 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
-                ProcessStartInfo cliStart = new ProcessStartInfo(handbrakeCLIPath, queueTask.Query)\r
+                ProcessStartInfo cliStart = new ProcessStartInfo(handbrakeCLIPath, currentTask.Query)\r
                 {\r
                     RedirectStandardOutput = true,\r
                     RedirectStandardError = enableLogging ? true : false,\r
@@ -164,7 +169,10 @@ namespace HandBrake.ApplicationServices.Services
             }\r
             catch (Exception exc)\r
             {\r
-                this.Invoke_encodeCompleted(new EncodeCompletedEventArgs(false, exc, "An Error occured when trying to encode this source. "));\r
+                TimeSpan time = DateTime.Now.Subtract(this.currentTask.StartTime);\r
+                this.Invoke_encodeCompleted(\r
+                    new EncodeCompletedEventArgs(\r
+                        false, exc, "An Error occured when trying to encode this source. "));\r
             }\r
         }\r
 \r
@@ -266,6 +274,7 @@ namespace HandBrake.ApplicationServices.Services
                 // This exception doesn't warrent user interaction, but it should be logged (TODO)\r
             }\r
 \r
+            this.currentTask.Status = QueueItemStatus.Completed;\r
             this.Invoke_encodeCompleted(new EncodeCompletedEventArgs(true, null, string.Empty));\r
         }\r
 \r
index 2c9005cfb1e40b19c8d8a29573b72d47f53d2421..be87b370546fdd6a89e4ca4bb56accf5b9495f8b 100644 (file)
@@ -55,6 +55,19 @@ namespace HandBrake.ApplicationServices.Services.Interfaces
         /// </param>\r
         void Remove(QueueTask job);\r
 \r
+        /// <summary>\r
+        /// Reset a Queued Item from Error or Completed to Waiting\r
+        /// </summary>\r
+        /// <param name="job">\r
+        /// The job.\r
+        /// </param>\r
+        void ResetJobStatusToWaiting(QueueTask job);\r
+\r
+        /// <summary>\r
+        /// Clear down the Queue´s completed items\r
+        /// </summary>\r
+        void ClearCompleted();\r
+\r
         /// <summary>\r
         /// Get the first job on the queue for processing.\r
         /// This also removes the job from the Queue and sets the LastProcessedJob\r
index ad56043ac0639e1dbd79279af7da051e6f5b8a49..d8ebbf31ed194b34832db5929efb3eb11dbc7555 100644 (file)
@@ -13,6 +13,7 @@ namespace HandBrake.ApplicationServices.Services
     using System.Windows.Forms;\r
     using System.Xml.Serialization;\r
 \r
+    using HandBrake.ApplicationServices.Exceptions;\r
     using HandBrake.ApplicationServices.Model;\r
     using HandBrake.ApplicationServices.Services.Interfaces;\r
 \r
@@ -114,7 +115,7 @@ namespace HandBrake.ApplicationServices.Services
         {\r
             get\r
             {\r
-                return this.queue.Count;\r
+                return this.queue.Where(item => item.Status == QueueItemStatus.Waiting).Count();\r
             }\r
         }\r
 \r
@@ -167,6 +168,35 @@ namespace HandBrake.ApplicationServices.Services
             }\r
         }\r
 \r
+        /// <summary>\r
+        /// Reset a Queued Item from Error or Completed to Waiting\r
+        /// </summary>\r
+        /// <param name="job">\r
+        /// The job.\r
+        /// </param>\r
+        public void ResetJobStatusToWaiting(QueueTask job)\r
+        {\r
+            if (job.Status != QueueItemStatus.Error && job.Status != QueueItemStatus.Completed)\r
+            {\r
+                throw new GeneralApplicationException("Job Error", "Unable to reset job status as it is not in an Error or Completed state", null);\r
+            }\r
+\r
+            job.Status = QueueItemStatus.Waiting;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Clear down the Queue´s completed items\r
+        /// </summary>\r
+        public void ClearCompleted()\r
+        {\r
+            List<QueueTask> deleteList = this.queue.Where(task => task.Status == QueueItemStatus.Completed).ToList();\r
+            foreach (QueueTask item in deleteList)\r
+            {\r
+                this.queue.Remove(item);\r
+            }\r
+            this.InvokeQueueChanged(EventArgs.Empty);\r
+        }\r
+\r
         /// <summary>\r
         /// Get the first job on the queue for processing.\r
         /// This also removes the job from the Queue and sets the LastProcessedJob\r
@@ -178,9 +208,14 @@ namespace HandBrake.ApplicationServices.Services
         {\r
             if (this.queue.Count > 0)\r
             {\r
-                QueueTask job = this.queue[0];\r
-                this.LastProcessedJob = job;\r
-                this.Remove(job); // Remove the item which we are about to pass out.\r
+                QueueTask job = this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);\r
+                if (job != null)\r
+                {\r
+                    job.Status = QueueItemStatus.InProgress;\r
+                    job.StartTime = DateTime.Now;\r
+                    this.LastProcessedJob = job;\r
+                    InvokeQueueChanged(EventArgs.Empty);\r
+                }\r
 \r
                 return job;\r
             }\r
@@ -233,10 +268,12 @@ namespace HandBrake.ApplicationServices.Services
             string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");\r
             string tempPath = !string.IsNullOrEmpty(exportPath) ? exportPath : appDataPath + string.Format(this.queueFile, string.Empty);\r
 \r
+\r
             using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))\r
             {\r
+                List<QueueTask> tasks = queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();\r
                 XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));\r
-                serializer.Serialize(strm, queue);\r
+                serializer.Serialize(strm, tasks);\r
                 strm.Close();\r
                 strm.Dispose();\r
             }\r
@@ -265,7 +302,18 @@ namespace HandBrake.ApplicationServices.Services
 \r
                         if (list != null)\r
                             foreach (QueueTask item in list)\r
-                                this.queue.Add(item);\r
+                            {\r
+                                if (item.Status != QueueItemStatus.Completed)\r
+                                {\r
+                                    // Reset InProgress/Error to Waiting so it can be processed\r
+                                    if (item.Status == QueueItemStatus.InProgress)\r
+                                    {\r
+                                        item.Status = QueueItemStatus.Waiting;\r
+                                    }\r
+\r
+                                    this.queue.Add(item);\r
+                                }\r
+                            }\r
 \r
                         this.InvokeQueueChanged(EventArgs.Empty);\r
                     }\r
index fe3eb8549f0cdb7ea5709231ac733c83768516af..be9c46359038719ee57c377dd76687a7d1cf1260 100644 (file)
@@ -30,6 +30,7 @@ namespace HandBrake.ApplicationServices.Services
         /// The encode Service.\r
         /// </param>\r
         /// <exception cref="ArgumentNullException">\r
+        /// Services are not setup\r
         /// </exception>\r
         public QueueProcessor(IQueueManager queueManager, IEncode encodeService)\r
         {\r
@@ -177,7 +178,6 @@ namespace HandBrake.ApplicationServices.Services
         /// </summary>\r
         public void Pause()\r
         {\r
-            this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;\r
             this.InvokeQueuePaused(EventArgs.Empty);\r
             this.IsProcessing = false;\r
         }\r
@@ -193,6 +193,8 @@ namespace HandBrake.ApplicationServices.Services
         /// </param>\r
         private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)\r
         {\r
+            this.QueueManager.LastProcessedJob.Status = QueueItemStatus.Completed;\r
+\r
             // Growl\r
             if (Properties.Settings.Default.GrowlEncode)\r
                 GrowlCommunicator.Notify("Encode Completed",\r
@@ -200,6 +202,7 @@ namespace HandBrake.ApplicationServices.Services
 \r
             if (!e.Successful)\r
             {\r
+                this.QueueManager.LastProcessedJob.Status = QueueItemStatus.Error;\r
                 this.Pause();\r
                 throw new GeneralApplicationException(e.ErrorInformation, e.Exception.Message, e.Exception);\r
             }\r
@@ -214,7 +217,16 @@ namespace HandBrake.ApplicationServices.Services
             }\r
 \r
             // Move onto the next job.\r
-            this.ProcessNextJob();\r
+            if (this.IsProcessing)\r
+            {\r
+                this.ProcessNextJob();\r
+            } \r
+            else \r
+            {\r
+                this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;\r
+                this.InvokeQueueCompleted(EventArgs.Empty);\r
+                this.QueueManager.BackupQueue(string.Empty);\r
+            }\r
         }\r
 \r
         /// <summary>\r
index 5a49243256348fde0d2ee8030517ac645288eaba..9beaf0a5ef76b445b6061a8b3c06ed9fc87e1d27 100644 (file)
@@ -54,6 +54,7 @@ namespace Handbrake
             this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();\r
             this.SaveFile = new System.Windows.Forms.SaveFileDialog();\r
             this.list_queue = new System.Windows.Forms.ListView();\r
+            this.Status = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\r
             this.Title = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\r
             this.Chapters = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\r
             this.Source = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\r
@@ -67,6 +68,7 @@ namespace Handbrake
             this.mnu_edit = new System.Windows.Forms.ToolStripMenuItem();\r
             this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();\r
             this.mnu_delete = new System.Windows.Forms.ToolStripMenuItem();\r
+            this.mnuClearCompleted = new System.Windows.Forms.ToolStripMenuItem();\r
             this.statusStrip1 = new System.Windows.Forms.StatusStrip();\r
             this.lbl_encodesPending = new System.Windows.Forms.ToolStripStatusLabel();\r
             this.OpenFile = new System.Windows.Forms.OpenFileDialog();\r
@@ -76,6 +78,7 @@ namespace Handbrake
             this.panel3 = new System.Windows.Forms.Panel();\r
             this.panel2 = new System.Windows.Forms.Panel();\r
             this.panel1 = new System.Windows.Forms.Panel();\r
+            this.mnu_Retry = new System.Windows.Forms.ToolStripMenuItem();\r
             this.toolStrip1.SuspendLayout();\r
             this.mnu_queue.SuspendLayout();\r
             this.statusStrip1.SuspendLayout();\r
@@ -257,6 +260,7 @@ namespace Handbrake
             // list_queue\r
             // \r
             this.list_queue.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {\r
+            this.Status,\r
             this.Title,\r
             this.Chapters,\r
             this.Source,\r
@@ -277,6 +281,11 @@ namespace Handbrake
             this.list_queue.View = System.Windows.Forms.View.Details;\r
             this.list_queue.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ListQueueDeleteKey);\r
             // \r
+            // Status\r
+            // \r
+            this.Status.Text = "Job Status";\r
+            this.Status.Width = 80;\r
+            // \r
             // Title\r
             // \r
             this.Title.Text = "Title";\r
@@ -314,49 +323,58 @@ namespace Handbrake
             this.mnu_Down,\r
             this.toolStripSeparator3,\r
             this.mnu_edit,\r
+            this.mnu_Retry,\r
             this.toolStripSeparator4,\r
+            this.mnuClearCompleted,\r
             this.mnu_delete});\r
             this.mnu_queue.Name = "mnu_queue";\r
-            this.mnu_queue.Size = new System.Drawing.Size(139, 104);\r
+            this.mnu_queue.Size = new System.Drawing.Size(164, 148);\r
             // \r
             // mnu_up\r
             // \r
             this.mnu_up.Name = "mnu_up";\r
-            this.mnu_up.Size = new System.Drawing.Size(138, 22);\r
+            this.mnu_up.Size = new System.Drawing.Size(163, 22);\r
             this.mnu_up.Text = "Move Up";\r
             this.mnu_up.Click += new System.EventHandler(this.MnuUpClick);\r
             // \r
             // mnu_Down\r
             // \r
             this.mnu_Down.Name = "mnu_Down";\r
-            this.mnu_Down.Size = new System.Drawing.Size(138, 22);\r
+            this.mnu_Down.Size = new System.Drawing.Size(163, 22);\r
             this.mnu_Down.Text = "Move Down";\r
             this.mnu_Down.Click += new System.EventHandler(this.MnuDownClick);\r
             // \r
             // toolStripSeparator3\r
             // \r
             this.toolStripSeparator3.Name = "toolStripSeparator3";\r
-            this.toolStripSeparator3.Size = new System.Drawing.Size(135, 6);\r
+            this.toolStripSeparator3.Size = new System.Drawing.Size(160, 6);\r
             // \r
             // mnu_edit\r
             // \r
             this.mnu_edit.Name = "mnu_edit";\r
-            this.mnu_edit.Size = new System.Drawing.Size(138, 22);\r
+            this.mnu_edit.Size = new System.Drawing.Size(163, 22);\r
             this.mnu_edit.Text = "Edit";\r
             this.mnu_edit.Click += new System.EventHandler(this.MnuEditClick);\r
             // \r
             // toolStripSeparator4\r
             // \r
             this.toolStripSeparator4.Name = "toolStripSeparator4";\r
-            this.toolStripSeparator4.Size = new System.Drawing.Size(135, 6);\r
+            this.toolStripSeparator4.Size = new System.Drawing.Size(160, 6);\r
             // \r
             // mnu_delete\r
             // \r
             this.mnu_delete.Name = "mnu_delete";\r
-            this.mnu_delete.Size = new System.Drawing.Size(138, 22);\r
+            this.mnu_delete.Size = new System.Drawing.Size(163, 22);\r
             this.mnu_delete.Text = "Delete";\r
             this.mnu_delete.Click += new System.EventHandler(this.MnuDeleteClick);\r
             // \r
+            // mnuClearCompleted\r
+            // \r
+            this.mnuClearCompleted.Name = "mnuClearCompleted";\r
+            this.mnuClearCompleted.Size = new System.Drawing.Size(163, 22);\r
+            this.mnuClearCompleted.Text = "Clear Completed";\r
+            this.mnuClearCompleted.Click += new System.EventHandler(this.mnuClearCompleted_Click);\r
+            // \r
             // statusStrip1\r
             // \r
             this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\r
@@ -459,6 +477,13 @@ namespace Handbrake
             this.panel1.Size = new System.Drawing.Size(15, 214);\r
             this.panel1.TabIndex = 0;\r
             // \r
+            // mnu_Retry\r
+            // \r
+            this.mnu_Retry.Name = "mnu_Retry";\r
+            this.mnu_Retry.Size = new System.Drawing.Size(163, 22);\r
+            this.mnu_Retry.Text = "Retry Encode";\r
+            this.mnu_Retry.Click += new System.EventHandler(this.mnu_Retry_Click);\r
+            // \r
             // frmQueue\r
             // \r
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\r
@@ -531,5 +556,8 @@ namespace Handbrake
         private System.Windows.Forms.ToolStripComboBox drp_completeOption;\r
         private System.Windows.Forms.ToolStripButton toolStripButton1;\r
         private System.Windows.Forms.Panel panel3;\r
+        private System.Windows.Forms.ColumnHeader Status;\r
+        private System.Windows.Forms.ToolStripMenuItem mnuClearCompleted;\r
+        private System.Windows.Forms.ToolStripMenuItem mnu_Retry;\r
     }\r
 }\r
index 6bc7081f59b614af5b00941658f46a18fa0fc0d7..94c7cebd0aff38645882300e3de8a430468d75a2 100644 (file)
@@ -47,6 +47,9 @@ namespace Handbrake
         /// </summary>\r
         private readonly frmMain mainWindow;\r
 \r
+        /// <summary>\r
+        /// The User setting service\r
+        /// </summary>\r
         private readonly IUserSettingService userSettingService = new UserSettingService();\r
 \r
         /// <summary>\r
@@ -137,6 +140,8 @@ namespace Handbrake
                 return;\r
             }\r
 \r
+            this.queue.QueueManager.LastProcessedJob.ElaspedEncodeTime = e.ElapsedTime;\r
+\r
             lbl_encodeStatus.Text =\r
                 string.Format(\r
                 "Encoding: Pass {0} of {1},  {2:00.00}%, FPS: {3:000.0},  Avg FPS: {4:000.0},  Time Remaining: {5},  Elapsed: {6:hh\\:mm\\:ss}",\r
@@ -299,6 +304,7 @@ namespace Handbrake
             btn_pause.Visible = false;\r
             btn_encode.Enabled = true;\r
 \r
+            this.RedrawQueue();\r
             ResetEncodeText();\r
         }\r
 \r
@@ -353,7 +359,9 @@ namespace Handbrake
                         chapters = chapters + " - " + parsed.EndPoint;\r
                 }\r
 \r
-                ListViewItem item = new ListViewItem { Tag = queueItem, Text = title };\r
+                ListViewItem item = new ListViewItem\r
+                    { Tag = queueItem, Text = EnumHelper<QueueItemStatus>.GetDescription(queueItem.Status) };\r
+                item.SubItems.Add(title);\r
                 item.SubItems.Add(chapters); // Chapters\r
                 item.SubItems.Add(queueItem.Source); // Source\r
                 item.SubItems.Add(queueItem.Destination); // Destination\r
@@ -389,6 +397,9 @@ namespace Handbrake
             UpdateStatusLabel();\r
         }\r
 \r
+        /// <summary>\r
+        /// Update the Display\r
+        /// </summary>\r
         private void UpdateStatusLabel()\r
         {\r
             if (InvokeRequired)\r
@@ -397,7 +408,7 @@ namespace Handbrake
                 return;\r
             }\r
 \r
-            lbl_encodesPending.Text = string.Format("{0} encodes(s) pending", list_queue.Items.Count);\r
+            lbl_encodesPending.Text = string.Format("{0} encodes(s) pending", this.queue.QueueManager.Count);\r
         }\r
 \r
         /// <summary>\r
@@ -718,5 +729,56 @@ namespace Handbrake
         {\r
             userSettingService.SetUserSetting(UserSettingConstants.WhenCompleteAction, drp_completeOption.Text);\r
         }\r
+\r
+        /// <summary>\r
+        /// Clear all completed items\r
+        /// </summary>\r
+        /// <param name="sender">\r
+        /// The sender.\r
+        /// </param>\r
+        /// <param name="e">\r
+        /// The e.\r
+        /// </param>\r
+        private void mnuClearCompleted_Click(object sender, EventArgs e)\r
+        {\r
+            this.queue.QueueManager.ClearCompleted();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Retry Job Menu Item\r
+        /// </summary>\r
+        /// <param name="sender">\r
+        /// The sender.\r
+        /// </param>\r
+        /// <param name="e">\r
+        /// The e.\r
+        /// </param>\r
+        private void mnu_Retry_Click(object sender, EventArgs e)\r
+        {\r
+            if (list_queue.SelectedIndices.Count != 0)\r
+            {\r
+                lock (queue)\r
+                {\r
+                    lock (list_queue)\r
+                    {\r
+                        QueueTask index = list_queue.SelectedItems[0].Tag as QueueTask;\r
+\r
+                        try\r
+                        {\r
+                            queue.QueueManager.ResetJobStatusToWaiting(index);\r
+                        } \r
+                        catch (Exception)\r
+                        {\r
+                            MessageBox.Show(\r
+                                "Can only retry a job if it is in an Error or Completed state.",\r
+                                "Notice",\r
+                                MessageBoxButtons.OK,\r
+                                MessageBoxIcon.Information);\r
+                        }\r
+                        RedrawQueue();\r
+                    }\r
+                }\r
+            }\r
+        }\r
     }\r
 }
\ No newline at end of file