2 This file is part of the HandBrake source code.
\r
3 Homepage: <http://handbrake.fr>.
\r
4 It may be used under the terms of the GNU General Public License. */
\r
9 using System.Collections.Generic;
\r
10 using System.Collections.ObjectModel;
\r
11 using System.ComponentModel;
\r
14 using System.Windows.Forms;
\r
17 using HandBrake.ApplicationServices.Model;
\r
18 using HandBrake.ApplicationServices.Model.Encoding;
\r
19 using HandBrake.ApplicationServices.Services;
\r
20 using HandBrake.ApplicationServices.Services.Interfaces;
\r
25 /// The Queue Window
\r
27 public partial class frmQueue : Form
\r
30 /// Update Handler Delegate
\r
32 private delegate void UpdateHandler();
\r
35 /// An instance of the Queue service
\r
37 private readonly IQueueProcessor queue;
\r
40 /// A reference to the main application window
\r
42 private readonly frmMain mainWindow;
\r
45 /// Initializes a new instance of the <see cref="frmQueue"/> class.
\r
47 /// <param name="q">
\r
48 /// An instance of the queue service.
\r
50 /// <param name="mw">
\r
51 /// The main window.
\r
53 public frmQueue(IQueueProcessor q, frmMain mw)
\r
55 InitializeComponent();
\r
57 this.mainWindow = mw;
\r
60 queue.EncodeService.EncodeStarted += this.QueueOnEncodeStart;
\r
61 queue.QueueCompleted += this.QueueOnQueueFinished;
\r
62 queue.QueuePaused += this.QueueOnPaused;
\r
63 queue.QueueManager.QueueChanged += new EventHandler(queue_QueueListChanged);
\r
65 queue.EncodeService.EncodeStarted += this.queue_EncodeStarted;
\r
66 queue.EncodeService.EncodeCompleted += this.queue_EncodeEnded;
\r
68 drp_completeOption.Text = Properties.Settings.Default.CompletionOption;
\r
74 /// <param name="sender">
\r
77 /// <param name="e">
\r
80 private void queue_QueueListChanged(object sender, EventArgs e)
\r
82 UpdateUiElementsOnQueueChange();
\r
88 /// <param name="sender">
\r
91 /// <param name="e">
\r
94 private void queue_EncodeEnded(object sender, EventArgs e)
\r
96 queue.EncodeService.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
103 /// <param name="sender">
\r
106 /// <param name="e">
\r
109 private void queue_EncodeStarted(object sender, EventArgs e)
\r
111 this.SetCurrentEncodeInformation();
\r
112 queue.EncodeService.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
116 /// Display the Encode Status
\r
118 /// <param name="sender">
\r
121 /// <param name="e">
\r
124 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs e)
\r
126 if (this.InvokeRequired)
\r
128 this.BeginInvoke(new EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
132 lbl_encodeStatus.Text =
\r
134 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",
\r
138 e.EstimatedTimeLeft);
\r
142 /// Handle the Queue Paused event
\r
144 /// <param name="sender">
\r
147 /// <param name="e">
\r
150 private void QueueOnPaused(object sender, EventArgs e)
\r
152 SetUiEncodeFinished();
\r
153 UpdateUiElementsOnQueueChange();
\r
157 /// Handle the Queue Finished event.
\r
159 /// <param name="sender">
\r
162 /// <param name="e">
\r
165 private void QueueOnQueueFinished(object sender, EventArgs e)
\r
167 SetUiEncodeFinished();
\r
168 ResetQueue(); // Reset the Queue Window
\r
172 /// Handle the Encode Started event
\r
174 /// <param name="sender">
\r
177 /// <param name="e">
\r
180 private void QueueOnEncodeStart(object sender, EventArgs e)
\r
182 SetUiEncodeStarted(); // make sure the UI is set correctly
\r
183 UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.
\r
187 /// Initializes the Queue list with the Arraylist from the Queue class
\r
189 public void SetQueue()
\r
191 UpdateUiElementsOnQueueChange();
\r
195 /// Initializes the Queue list, then shows and activates the window
\r
197 public new void Show()
\r
203 /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window
\r
205 /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>
\r
206 public void Show(bool doSetQueue)
\r
208 if (doSetQueue) SetQueue();
\r
213 /// Handle the Encode button Click event
\r
215 /// <param name="sender">The sender</param>
\r
216 /// <param name="e">the EventArgs</param>
\r
217 private void BtnEncodeClick(object sender, EventArgs e)
\r
219 if (!queue.IsProcessing)
\r
221 SetUiEncodeStarted();
\r
224 lbl_encodeStatus.Text = "Encoding ...";
\r
229 /// Handle the Pause button click event.
\r
231 /// <param name="sender">
\r
234 /// <param name="e">
\r
237 private void BtnPauseClick(object sender, EventArgs e)
\r
241 "No further items on the queue will start. The current encode process will continue until it is finished. \nClick 'Encode' when you wish to continue encoding the queue.",
\r
242 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
248 /// Setup the UI to show that an encode has started
\r
250 private void SetUiEncodeStarted()
\r
252 if (InvokeRequired)
\r
254 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));
\r
257 btn_encode.Enabled = false;
\r
258 btn_pause.Visible = true;
\r
262 /// Setup the UI to indicate that an encode has finished.
\r
264 private void SetUiEncodeFinished()
\r
266 if (InvokeRequired)
\r
268 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));
\r
271 btn_pause.Visible = false;
\r
272 btn_encode.Enabled = true;
\r
276 /// Reset the Queue Window display
\r
278 private void ResetQueue()
\r
280 if (InvokeRequired)
\r
282 BeginInvoke(new UpdateHandler(ResetQueue));
\r
285 btn_pause.Visible = false;
\r
286 btn_encode.Enabled = true;
\r
292 /// Reset the current job text
\r
294 private void ResetEncodeText()
\r
296 if (InvokeRequired)
\r
298 BeginInvoke(new UpdateHandler(ResetEncodeText));
\r
301 lbl_encodeStatus.Text = "Ready";
\r
303 lbl_source.Text = "-";
\r
304 lbl_dest.Text = "-";
\r
305 lbl_encodeOptions.Text = "-";
\r
307 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
311 /// Redraw the Queue window with the latest information about HandBrakes status
\r
313 private void RedrawQueue()
\r
315 if (InvokeRequired)
\r
317 BeginInvoke(new UpdateHandler(RedrawQueue));
\r
321 list_queue.Items.Clear();
\r
322 ReadOnlyCollection<QueueTask> theQueue = queue.QueueManager.Queue;
\r
323 foreach (QueueTask queueItem in theQueue)
\r
325 string qItem = queueItem.Query;
\r
326 QueryParser parsed = QueryParser.Parse(qItem);
\r
328 // Get the DVD Title
\r
329 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
331 // Get the DVD Chapters
\r
333 if (parsed.ChapterStart == 0)
\r
337 chapters = parsed.ChapterStart.ToString();
\r
338 if (parsed.ChapterFinish != 0)
\r
339 chapters = chapters + " - " + parsed.ChapterFinish;
\r
342 ListViewItem item = new ListViewItem { Tag = queueItem, Text = title };
\r
343 item.SubItems.Add(chapters); // Chapters
\r
344 item.SubItems.Add(queueItem.Source); // Source
\r
345 item.SubItems.Add(queueItem.Destination); // Destination
\r
346 item.SubItems.Add(parsed.VideoEncoder); // Video
\r
348 // Display The Audio Track Information
\r
349 string audio = string.Empty;
\r
350 foreach (AudioTrack track in parsed.AudioInformation)
\r
352 if (audio != string.Empty)
\r
353 audio += ", " + track.Encoder;
\r
355 audio = track.Encoder;
\r
357 item.SubItems.Add(audio); // Audio
\r
359 list_queue.Items.Add(item);
\r
364 /// Update the UI elements
\r
366 private void UpdateUiElementsOnQueueChange()
\r
368 if (InvokeRequired)
\r
370 BeginInvoke(new UpdateHandler(UpdateUiElementsOnQueueChange));
\r
375 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
379 /// Set the window up with the current encode information
\r
381 private void SetCurrentEncodeInformation()
\r
385 if (InvokeRequired)
\r
387 BeginInvoke(new UpdateHandler(SetCurrentEncodeInformation));
\r
390 QueryParser parsed = QueryParser.Parse(queue.QueueManager.LastProcessedJob.Query);
\r
392 // Get title and chapters
\r
393 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
395 if (Equals(parsed.ChapterStart, 0))
\r
396 chapterlbl = "Auto";
\r
399 string chapters = parsed.ChapterStart.ToString();
\r
400 if (parsed.ChapterFinish != 0)
\r
401 chapters = chapters + " - " + parsed.ChapterFinish;
\r
402 chapterlbl = chapters;
\r
405 // Get audio information
\r
406 string audio = string.Empty;
\r
407 foreach (AudioTrack track in parsed.AudioInformation)
\r
409 if (audio != string.Empty)
\r
410 audio += ", " + track.Encoder;
\r
412 audio = track.Encoder;
\r
415 // found query is a global varible
\r
416 lbl_encodeStatus.Text = "Encoding ...";
\r
417 lbl_source.Text = queue.QueueManager.LastProcessedJob.Source + "(Title: " + title + " Chapters: " + chapterlbl + ")";
\r
418 lbl_dest.Text = queue.QueueManager.LastProcessedJob.Destination;
\r
419 lbl_encodeOptions.Text = "Video: " + parsed.VideoEncoder + " Audio: " + audio + Environment.NewLine +
\r
420 "x264 Options: " + parsed.H264Query;
\r
428 /* Right Click Menu */
\r
431 /// Handle the Move Up Menu Item
\r
433 /// <param name="sender">
\r
436 /// <param name="e">
\r
439 private void MnuUpClick(object sender, EventArgs e)
\r
445 /// Handle the Move down Menu Item
\r
447 /// <param name="sender">
\r
450 /// <param name="e">
\r
453 private void MnuDownClick(object sender, EventArgs e)
\r
461 /// <param name="sender">
\r
464 /// <param name="e">
\r
467 private void MnuEditClick(object sender, EventArgs e)
\r
469 if (list_queue.SelectedIndices != null && list_queue.SelectedIndices.Count != 0)
\r
475 QueueTask index = list_queue.SelectedItems[0].Tag as QueueTask;
\r
476 mainWindow.RecievingJob(index);
\r
477 queue.QueueManager.Remove(index);
\r
485 /// Handle the delete Menu Item
\r
487 /// <param name="sender">
\r
490 /// <param name="e">
\r
493 private void MnuDeleteClick(object sender, EventArgs e)
\r
495 DeleteSelectedItems();
\r
498 /* Keyboard Shortcuts */
\r
501 /// Handle the delete keyboard press
\r
503 /// <param name="sender">
\r
506 /// <param name="e">
\r
509 private void ListQueueDeleteKey(object sender, KeyEventArgs e)
\r
511 if (e.KeyCode == Keys.Delete && e.Modifiers == Keys.None)
\r
512 DeleteSelectedItems();
\r
515 /* Queue Management */
\r
518 /// Move items up in the queue
\r
520 private void MoveUp()
\r
522 // If there are selected items and the first item is not selected
\r
523 if (list_queue.SelectedIndices.Count > 0 && !list_queue.SelectedIndices.Contains(0))
\r
525 // Copy the selected indices to preserve them during the movement
\r
526 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
527 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
528 selectedIndices.Add(selectedIndex);
\r
530 // Move up each selected item
\r
531 foreach (int selectedIndex in selectedIndices)
\r
532 queue.QueueManager.MoveUp(selectedIndex);
\r
534 // Keep the selected item(s) selected, now moved up one index
\r
535 foreach (int selectedIndex in selectedIndices)
\r
536 if (selectedIndex - 1 > -1) // Defensive programming: ensure index is good
\r
537 list_queue.Items[selectedIndex - 1].Selected = true;
\r
540 list_queue.Select(); // Activate the control to show the selected items
\r
544 /// Move items down in the queue
\r
546 private void MoveDown()
\r
548 // If there are selected items and the last item is not selected
\r
549 if (list_queue.SelectedIndices.Count > 0 &&
\r
550 !list_queue.SelectedIndices.Contains(list_queue.Items[list_queue.Items.Count - 1].Index))
\r
552 // Copy the selected indices to preserve them during the movement
\r
553 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
554 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
555 selectedIndices.Add(selectedIndex);
\r
557 // Reverse the indices to move the items down from last to first (preserves indices)
\r
558 selectedIndices.Reverse();
\r
560 // Move down each selected item
\r
561 foreach (int selectedIndex in selectedIndices)
\r
562 queue.QueueManager.MoveDown(selectedIndex);
\r
564 // Keep the selected item(s) selected, now moved down one index
\r
565 foreach (int selectedIndex in selectedIndices)
\r
566 if (selectedIndex + 1 < list_queue.Items.Count) // Defensive programming: ensure index is good
\r
567 list_queue.Items[selectedIndex + 1].Selected = true;
\r
570 list_queue.Select(); // Activate the control to show the selected items
\r
574 /// Delete the currently selected items on the queue
\r
576 private void DeleteSelectedItems()
\r
578 // If there are selected items
\r
579 if (list_queue.SelectedIndices.Count > 0)
\r
581 // Remove each selected item
\r
582 foreach (ListViewItem selectedIndex in this.list_queue.SelectedItems)
\r
583 queue.QueueManager.Remove((QueueTask)selectedIndex.Tag);
\r
585 // Select the first item after deletion.
\r
586 if (list_queue.Items.Count > 0)
\r
587 list_queue.Items[0].Selected = true;
\r
590 list_queue.Select(); // Activate the control to show the selected items
\r
593 /* Queue Import / Export features */
\r
596 /// Create a batch script
\r
598 /// <param name="sender">
\r
601 /// <param name="e">
\r
604 private void MnuBatchClick(object sender, EventArgs e)
\r
606 SaveFile.FileName = string.Empty;
\r
607 SaveFile.Filter = "Batch|.bat";
\r
608 SaveFile.ShowDialog();
\r
609 if (SaveFile.FileName != String.Empty)
\r
610 queue.QueueManager.WriteBatchScriptToFile(SaveFile.FileName);
\r
616 /// <param name="sender">
\r
619 /// <param name="e">
\r
622 private void MnuExportClick(object sender, EventArgs e)
\r
624 SaveFile.FileName = string.Empty;
\r
625 SaveFile.Filter = "HandBrake Queue|*.queue";
\r
626 SaveFile.ShowDialog();
\r
627 if (SaveFile.FileName != String.Empty)
\r
628 queue.QueueManager.BackupQueue(SaveFile.FileName);
\r
634 /// <param name="sender">
\r
637 /// <param name="e">
\r
640 private void MnuImportClick(object sender, EventArgs e)
\r
642 OpenFile.FileName = string.Empty;
\r
643 OpenFile.ShowDialog();
\r
644 if (OpenFile.FileName != String.Empty)
\r
645 queue.QueueManager.RestoreQueue(OpenFile.FileName);
\r
649 /// Readd current job to queue
\r
651 /// <param name="sender">
\r
654 /// <param name="e">
\r
657 private void MnuReaddClick(object sender, EventArgs e)
\r
659 if (queue.QueueManager.LastProcessedJob != null && !queue.QueueManager.LastProcessedJob.IsEmpty)
\r
661 queue.QueueManager.Add(queue.QueueManager.LastProcessedJob);
\r
668 /// Hide's the window when the user tries to "x" out of the window instead of closing it.
\r
670 /// <param name="e">
\r
673 protected override void OnClosing(CancelEventArgs e)
\r
681 /// Change the OnComplete option setting.
\r
683 /// <param name="sender">
\r
686 /// <param name="e">
\r
689 private void CompleteOptionChanged(object sender, EventArgs e)
\r
691 Properties.Settings.Default.CompletionOption = drp_completeOption.Text;
\r
692 HandBrake.ApplicationServices.Init.CompletionOption = drp_completeOption.Text;
\r
693 Properties.Settings.Default.Save();
\r