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
13 using System.Windows.Forms;
\r
16 using HandBrake.ApplicationServices.Model;
\r
17 using HandBrake.ApplicationServices.Services;
\r
18 using HandBrake.ApplicationServices.Services.Interfaces;
\r
23 /// The Queue Window
\r
25 public partial class frmQueue : Form
\r
28 /// Update Handler Delegate
\r
30 private delegate void UpdateHandler();
\r
33 /// An instance of the Queue service
\r
35 private readonly IQueue queue;
\r
38 /// A reference to the main application window
\r
40 private readonly frmMain mainWindow;
\r
43 /// Initializes a new instance of the <see cref="frmQueue"/> class.
\r
45 /// <param name="q">
\r
46 /// An instance of the queue service.
\r
48 /// <param name="mw">
\r
49 /// The main window.
\r
51 public frmQueue(IQueue q, frmMain mw)
\r
53 InitializeComponent();
\r
55 this.mainWindow = mw;
\r
58 queue.EncodeStarted += new EventHandler(QueueOnEncodeStart);
\r
59 queue.QueueCompleted += new EventHandler(QueueOnQueueFinished);
\r
60 queue.QueuePauseRequested += new EventHandler(QueueOnPaused);
\r
61 queue.QueueListChanged += new EventHandler(queue_QueueListChanged);
\r
63 queue.EncodeStarted += new EventHandler(queue_EncodeStarted);
\r
64 queue.EncodeEnded += new EventHandler(queue_EncodeEnded);
\r
66 drp_completeOption.Text = Properties.Settings.Default.CompletionOption;
\r
72 /// <param name="sender">
\r
75 /// <param name="e">
\r
78 private void queue_QueueListChanged(object sender, EventArgs e)
\r
80 UpdateUiElementsOnQueueChange();
\r
86 /// <param name="sender">
\r
89 /// <param name="e">
\r
92 private void queue_EncodeEnded(object sender, EventArgs e)
\r
94 queue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
101 /// <param name="sender">
\r
104 /// <param name="e">
\r
107 private void queue_EncodeStarted(object sender, EventArgs e)
\r
109 this.SetCurrentEncodeInformation();
\r
110 queue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
114 /// Display the Encode Status
\r
116 /// <param name="sender">
\r
119 /// <param name="e">
\r
122 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
124 if (this.InvokeRequired)
\r
126 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
130 lbl_encodeStatus.Text =
\r
132 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",
\r
136 e.EstimatedTimeLeft);
\r
140 /// Handle the Queue Paused event
\r
142 /// <param name="sender">
\r
145 /// <param name="e">
\r
148 private void QueueOnPaused(object sender, EventArgs e)
\r
150 SetUiEncodeFinished();
\r
151 UpdateUiElementsOnQueueChange();
\r
155 /// Handle the Queue Finished event.
\r
157 /// <param name="sender">
\r
160 /// <param name="e">
\r
163 private void QueueOnQueueFinished(object sender, EventArgs e)
\r
165 SetUiEncodeFinished();
\r
166 ResetQueue(); // Reset the Queue Window
\r
170 /// Handle the Encode Started event
\r
172 /// <param name="sender">
\r
175 /// <param name="e">
\r
178 private void QueueOnEncodeStart(object sender, EventArgs e)
\r
180 SetUiEncodeStarted(); // make sure the UI is set correctly
\r
181 UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.
\r
185 /// Initializes the Queue list with the Arraylist from the Queue class
\r
187 public void SetQueue()
\r
189 UpdateUiElementsOnQueueChange();
\r
193 /// Initializes the Queue list, then shows and activates the window
\r
195 public new void Show()
\r
201 /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window
\r
203 /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>
\r
204 public void Show(bool doSetQueue)
\r
206 if (doSetQueue) SetQueue();
\r
211 /// Handle the Encode button Click event
\r
213 /// <param name="sender">The sender</param>
\r
214 /// <param name="e">the EventArgs</param>
\r
215 private void BtnEncodeClick(object sender, EventArgs e)
\r
219 SetUiEncodeStarted();
\r
222 lbl_encodeStatus.Text = "Encoding ...";
\r
227 /// Handle the Pause button click event.
\r
229 /// <param name="sender">
\r
232 /// <param name="e">
\r
235 private void BtnPauseClick(object sender, EventArgs e)
\r
239 "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
240 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
246 /// Setup the UI to show that an encode has started
\r
248 private void SetUiEncodeStarted()
\r
250 if (InvokeRequired)
\r
252 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));
\r
255 btn_encode.Enabled = false;
\r
256 btn_pause.Visible = true;
\r
260 /// Setup the UI to indicate that an encode has finished.
\r
262 private void SetUiEncodeFinished()
\r
264 if (InvokeRequired)
\r
266 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));
\r
269 btn_pause.Visible = false;
\r
270 btn_encode.Enabled = true;
\r
274 /// Reset the Queue Window display
\r
276 private void ResetQueue()
\r
278 if (InvokeRequired)
\r
280 BeginInvoke(new UpdateHandler(ResetQueue));
\r
283 btn_pause.Visible = false;
\r
284 btn_encode.Enabled = true;
\r
290 /// Reset the current job text
\r
292 private void ResetEncodeText()
\r
294 if (InvokeRequired)
\r
296 BeginInvoke(new UpdateHandler(ResetEncodeText));
\r
299 lbl_encodeStatus.Text = "Ready";
\r
301 lbl_source.Text = "-";
\r
302 lbl_dest.Text = "-";
\r
303 lbl_encodeOptions.Text = "-";
\r
305 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
309 /// Redraw the Queue window with the latest information about HandBrakes status
\r
311 private void RedrawQueue()
\r
313 if (InvokeRequired)
\r
315 BeginInvoke(new UpdateHandler(RedrawQueue));
\r
319 list_queue.Items.Clear();
\r
320 ReadOnlyCollection<Job> theQueue = queue.CurrentQueue;
\r
321 foreach (Job queueItem in theQueue)
\r
323 string qItem = queueItem.Query;
\r
324 QueryParser parsed = Functions.QueryParser.Parse(qItem);
\r
326 // Get the DVD Title
\r
327 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
329 // Get the DVD Chapters
\r
331 if (parsed.ChapterStart == 0)
\r
335 chapters = parsed.ChapterStart.ToString();
\r
336 if (parsed.ChapterFinish != 0)
\r
337 chapters = chapters + " - " + parsed.ChapterFinish;
\r
340 ListViewItem item = new ListViewItem();
\r
341 item.Text = title; // Title
\r
342 item.SubItems.Add(chapters); // Chapters
\r
343 item.SubItems.Add(queueItem.Source); // Source
\r
344 item.SubItems.Add(queueItem.Destination); // Destination
\r
345 item.SubItems.Add(parsed.VideoEncoder); // Video
\r
347 // Display The Audio Track Information
\r
348 string audio = string.Empty;
\r
349 foreach (AudioTrack track in parsed.AudioInformation)
\r
351 if (audio != string.Empty)
\r
352 audio += ", " + track.Encoder;
\r
354 audio = track.Encoder;
\r
356 item.SubItems.Add(audio); // Audio
\r
358 list_queue.Items.Add(item);
\r
363 /// Update the UI elements
\r
365 private void UpdateUiElementsOnQueueChange()
\r
367 if (InvokeRequired)
\r
369 BeginInvoke(new UpdateHandler(UpdateUiElementsOnQueueChange));
\r
374 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
378 /// Set the window up with the current encode information
\r
380 private void SetCurrentEncodeInformation()
\r
384 if (InvokeRequired)
\r
386 BeginInvoke(new UpdateHandler(SetCurrentEncodeInformation));
\r
389 QueryParser parsed = QueryParser.Parse(queue.LastEncode.Query);
\r
391 // Get title and chapters
\r
392 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
394 if (Equals(parsed.ChapterStart, 0))
\r
395 chapterlbl = "Auto";
\r
398 string chapters = parsed.ChapterStart.ToString();
\r
399 if (parsed.ChapterFinish != 0)
\r
400 chapters = chapters + " - " + parsed.ChapterFinish;
\r
401 chapterlbl = chapters;
\r
404 // Get audio information
\r
405 string audio = string.Empty;
\r
406 foreach (AudioTrack track in parsed.AudioInformation)
\r
408 if (audio != string.Empty)
\r
409 audio += ", " + track.Encoder;
\r
411 audio = track.Encoder;
\r
414 // found query is a global varible
\r
415 lbl_encodeStatus.Text = "Encoding ...";
\r
416 lbl_source.Text = queue.LastEncode.Source + "(Title: " + title + " Chapters: " + chapterlbl + ")";
\r
417 lbl_dest.Text = queue.LastEncode.Destination;
\r
418 lbl_encodeOptions.Text = "Video: " + parsed.VideoEncoder + " Audio: " + audio + Environment.NewLine +
\r
419 "x264 Options: " + parsed.H264Query;
\r
427 /* Right Click Menu */
\r
430 /// Handle the Move Up Menu Item
\r
432 /// <param name="sender">
\r
435 /// <param name="e">
\r
438 private void MnuUpClick(object sender, EventArgs e)
\r
444 /// Handle the Move down Menu Item
\r
446 /// <param name="sender">
\r
449 /// <param name="e">
\r
452 private void MnuDownClick(object sender, EventArgs e)
\r
460 /// <param name="sender">
\r
463 /// <param name="e">
\r
466 private void MnuEditClick(object sender, EventArgs e)
\r
468 if (list_queue.SelectedIndices != null && list_queue.SelectedIndices.Count != 0)
\r
474 int index = list_queue.SelectedIndices[0];
\r
475 mainWindow.RecievingJob(queue.GetJob(index));
\r
476 queue.Remove(index);
\r
484 /// Handle the delete Menu Item
\r
486 /// <param name="sender">
\r
489 /// <param name="e">
\r
492 private void MnuDeleteClick(object sender, EventArgs e)
\r
494 DeleteSelectedItems();
\r
497 /* Keyboard Shortcuts */
\r
500 /// Handle the delete keyboard press
\r
502 /// <param name="sender">
\r
505 /// <param name="e">
\r
508 private void ListQueueDeleteKey(object sender, KeyEventArgs e)
\r
510 if (e.KeyCode == Keys.Delete && e.Modifiers == Keys.None)
\r
511 DeleteSelectedItems();
\r
514 /* Queue Management */
\r
517 /// Move items up in the queue
\r
519 private void MoveUp()
\r
521 // If there are selected items and the first item is not selected
\r
522 if (list_queue.SelectedIndices.Count > 0 && !list_queue.SelectedIndices.Contains(0))
\r
524 // Copy the selected indices to preserve them during the movement
\r
525 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
526 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
527 selectedIndices.Add(selectedIndex);
\r
529 // Move up each selected item
\r
530 foreach (int selectedIndex in selectedIndices)
\r
531 queue.MoveUp(selectedIndex);
\r
533 // Keep the selected item(s) selected, now moved up one index
\r
534 foreach (int selectedIndex in selectedIndices)
\r
535 if (selectedIndex - 1 > -1) // Defensive programming: ensure index is good
\r
536 list_queue.Items[selectedIndex - 1].Selected = true;
\r
539 list_queue.Select(); // Activate the control to show the selected items
\r
543 /// Move items down in the queue
\r
545 private void MoveDown()
\r
547 // If there are selected items and the last item is not selected
\r
548 if (list_queue.SelectedIndices.Count > 0 &&
\r
549 !list_queue.SelectedIndices.Contains(list_queue.Items[list_queue.Items.Count - 1].Index))
\r
551 // Copy the selected indices to preserve them during the movement
\r
552 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
553 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
554 selectedIndices.Add(selectedIndex);
\r
556 // Reverse the indices to move the items down from last to first (preserves indices)
\r
557 selectedIndices.Reverse();
\r
559 // Move down each selected item
\r
560 foreach (int selectedIndex in selectedIndices)
\r
561 queue.MoveDown(selectedIndex);
\r
563 // Keep the selected item(s) selected, now moved down one index
\r
564 foreach (int selectedIndex in selectedIndices)
\r
565 if (selectedIndex + 1 < list_queue.Items.Count) // Defensive programming: ensure index is good
\r
566 list_queue.Items[selectedIndex + 1].Selected = true;
\r
569 list_queue.Select(); // Activate the control to show the selected items
\r
573 /// Delete the currently selected items on the queue
\r
575 private void DeleteSelectedItems()
\r
577 // If there are selected items
\r
578 if (list_queue.SelectedIndices.Count > 0)
\r
580 // Save the selected indices to select them after the move
\r
581 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
582 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
583 selectedIndices.Add(selectedIndex);
\r
585 int firstSelectedIndex = selectedIndices[0];
\r
587 // Reverse the list to delete the items from last to first (preserves indices)
\r
588 selectedIndices.Reverse();
\r
590 // Remove each selected item
\r
591 foreach (int selectedIndex in selectedIndices)
\r
592 queue.Remove(selectedIndex);
\r
594 // Select the item where the first deleted item was previously
\r
595 if (firstSelectedIndex < list_queue.Items.Count)
\r
596 list_queue.Items[firstSelectedIndex].Selected = true;
\r
599 list_queue.Select(); // Activate the control to show the selected items
\r
602 /* Queue Import / Export features */
\r
605 /// Create a batch script
\r
607 /// <param name="sender">
\r
610 /// <param name="e">
\r
613 private void MnuBatchClick(object sender, EventArgs e)
\r
615 SaveFile.FileName = string.Empty;
\r
616 SaveFile.Filter = "Batch|.bat";
\r
617 SaveFile.ShowDialog();
\r
618 if (SaveFile.FileName != String.Empty)
\r
619 queue.WriteBatchScriptToFile(SaveFile.FileName);
\r
625 /// <param name="sender">
\r
628 /// <param name="e">
\r
631 private void MnuExportClick(object sender, EventArgs e)
\r
633 SaveFile.FileName = string.Empty;
\r
634 SaveFile.Filter = "HandBrake Queue|*.queue";
\r
635 SaveFile.ShowDialog();
\r
636 if (SaveFile.FileName != String.Empty)
\r
637 queue.WriteQueueStateToFile(SaveFile.FileName);
\r
643 /// <param name="sender">
\r
646 /// <param name="e">
\r
649 private void MnuImportClick(object sender, EventArgs e)
\r
651 OpenFile.FileName = string.Empty;
\r
652 OpenFile.ShowDialog();
\r
653 if (OpenFile.FileName != String.Empty)
\r
654 queue.LoadQueueFromFile(OpenFile.FileName);
\r
658 /// Readd current job to queue
\r
660 /// <param name="sender">
\r
663 /// <param name="e">
\r
666 private void MnuReaddClick(object sender, EventArgs e)
\r
668 if (queue.LastEncode != null && !queue.LastEncode.IsEmpty)
\r
671 queue.LastEncode.Query,
\r
672 queue.LastEncode.Title,
\r
673 queue.LastEncode.Source,
\r
674 queue.LastEncode.Destination,
\r
675 queue.LastEncode.CustomQuery);
\r
682 /// Hide's the window when the user tries to "x" out of the window instead of closing it.
\r
684 /// <param name="e">
\r
687 protected override void OnClosing(CancelEventArgs e)
\r
695 /// Change the OnComplete option setting.
\r
697 /// <param name="sender">
\r
700 /// <param name="e">
\r
703 private void CompleteOptionChanged(object sender, EventArgs e)
\r
705 Properties.Settings.Default.CompletionOption = drp_completeOption.Text;
\r
706 HandBrake.ApplicationServices.Init.CompletionOption = drp_completeOption.Text;
\r
707 Properties.Settings.Default.Save();
\r