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.Model.Encoding;
\r
18 using HandBrake.ApplicationServices.Services;
\r
19 using HandBrake.ApplicationServices.Services.Interfaces;
\r
24 /// The Queue Window
\r
26 public partial class frmQueue : Form
\r
29 /// Update Handler Delegate
\r
31 private delegate void UpdateHandler();
\r
34 /// An instance of the Queue service
\r
36 private readonly IQueue queue;
\r
39 /// A reference to the main application window
\r
41 private readonly frmMain mainWindow;
\r
44 /// Initializes a new instance of the <see cref="frmQueue"/> class.
\r
46 /// <param name="q">
\r
47 /// An instance of the queue service.
\r
49 /// <param name="mw">
\r
50 /// The main window.
\r
52 public frmQueue(IQueue q, frmMain mw)
\r
54 InitializeComponent();
\r
56 this.mainWindow = mw;
\r
59 queue.EncodeStarted += new EventHandler(QueueOnEncodeStart);
\r
60 queue.QueueCompleted += new EventHandler(QueueOnQueueFinished);
\r
61 queue.QueuePauseRequested += new EventHandler(QueueOnPaused);
\r
62 queue.QueueListChanged += new EventHandler(queue_QueueListChanged);
\r
64 queue.EncodeStarted += new EventHandler(queue_EncodeStarted);
\r
65 queue.EncodeEnded += new EventHandler(queue_EncodeEnded);
\r
67 drp_completeOption.Text = Properties.Settings.Default.CompletionOption;
\r
73 /// <param name="sender">
\r
76 /// <param name="e">
\r
79 private void queue_QueueListChanged(object sender, EventArgs e)
\r
81 UpdateUiElementsOnQueueChange();
\r
87 /// <param name="sender">
\r
90 /// <param name="e">
\r
93 private void queue_EncodeEnded(object sender, EventArgs e)
\r
95 queue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
102 /// <param name="sender">
\r
105 /// <param name="e">
\r
108 private void queue_EncodeStarted(object sender, EventArgs e)
\r
110 this.SetCurrentEncodeInformation();
\r
111 queue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
115 /// Display the Encode Status
\r
117 /// <param name="sender">
\r
120 /// <param name="e">
\r
123 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs e)
\r
125 if (this.InvokeRequired)
\r
127 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
131 lbl_encodeStatus.Text =
\r
133 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",
\r
137 e.EstimatedTimeLeft);
\r
141 /// Handle the Queue Paused event
\r
143 /// <param name="sender">
\r
146 /// <param name="e">
\r
149 private void QueueOnPaused(object sender, EventArgs e)
\r
151 SetUiEncodeFinished();
\r
152 UpdateUiElementsOnQueueChange();
\r
156 /// Handle the Queue Finished event.
\r
158 /// <param name="sender">
\r
161 /// <param name="e">
\r
164 private void QueueOnQueueFinished(object sender, EventArgs e)
\r
166 SetUiEncodeFinished();
\r
167 ResetQueue(); // Reset the Queue Window
\r
171 /// Handle the Encode Started event
\r
173 /// <param name="sender">
\r
176 /// <param name="e">
\r
179 private void QueueOnEncodeStart(object sender, EventArgs e)
\r
181 SetUiEncodeStarted(); // make sure the UI is set correctly
\r
182 UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.
\r
186 /// Initializes the Queue list with the Arraylist from the Queue class
\r
188 public void SetQueue()
\r
190 UpdateUiElementsOnQueueChange();
\r
194 /// Initializes the Queue list, then shows and activates the window
\r
196 public new void Show()
\r
202 /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window
\r
204 /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>
\r
205 public void Show(bool doSetQueue)
\r
207 if (doSetQueue) SetQueue();
\r
212 /// Handle the Encode button Click event
\r
214 /// <param name="sender">The sender</param>
\r
215 /// <param name="e">the EventArgs</param>
\r
216 private void BtnEncodeClick(object sender, EventArgs e)
\r
220 SetUiEncodeStarted();
\r
223 lbl_encodeStatus.Text = "Encoding ...";
\r
228 /// Handle the Pause button click event.
\r
230 /// <param name="sender">
\r
233 /// <param name="e">
\r
236 private void BtnPauseClick(object sender, EventArgs e)
\r
240 "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
241 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
247 /// Setup the UI to show that an encode has started
\r
249 private void SetUiEncodeStarted()
\r
251 if (InvokeRequired)
\r
253 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));
\r
256 btn_encode.Enabled = false;
\r
257 btn_pause.Visible = true;
\r
261 /// Setup the UI to indicate that an encode has finished.
\r
263 private void SetUiEncodeFinished()
\r
265 if (InvokeRequired)
\r
267 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));
\r
270 btn_pause.Visible = false;
\r
271 btn_encode.Enabled = true;
\r
275 /// Reset the Queue Window display
\r
277 private void ResetQueue()
\r
279 if (InvokeRequired)
\r
281 BeginInvoke(new UpdateHandler(ResetQueue));
\r
284 btn_pause.Visible = false;
\r
285 btn_encode.Enabled = true;
\r
291 /// Reset the current job text
\r
293 private void ResetEncodeText()
\r
295 if (InvokeRequired)
\r
297 BeginInvoke(new UpdateHandler(ResetEncodeText));
\r
300 lbl_encodeStatus.Text = "Ready";
\r
302 lbl_source.Text = "-";
\r
303 lbl_dest.Text = "-";
\r
304 lbl_encodeOptions.Text = "-";
\r
306 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
310 /// Redraw the Queue window with the latest information about HandBrakes status
\r
312 private void RedrawQueue()
\r
314 if (InvokeRequired)
\r
316 BeginInvoke(new UpdateHandler(RedrawQueue));
\r
320 list_queue.Items.Clear();
\r
321 ReadOnlyCollection<QueueTask> theQueue = queue.CurrentQueue;
\r
322 foreach (QueueTask queueItem in theQueue)
\r
324 string qItem = queueItem.Query;
\r
325 QueryParser parsed = Functions.QueryParser.Parse(qItem);
\r
327 // Get the DVD Title
\r
328 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
330 // Get the DVD Chapters
\r
332 if (parsed.ChapterStart == 0)
\r
336 chapters = parsed.ChapterStart.ToString();
\r
337 if (parsed.ChapterFinish != 0)
\r
338 chapters = chapters + " - " + parsed.ChapterFinish;
\r
341 ListViewItem item = new ListViewItem();
\r
342 item.Text = title; // 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.LastEncode.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.LastEncode.Source + "(Title: " + title + " Chapters: " + chapterlbl + ")";
\r
418 lbl_dest.Text = queue.LastEncode.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 int index = list_queue.SelectedIndices[0];
\r
476 mainWindow.RecievingJob(queue.GetJob(index));
\r
477 queue.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.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.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 // Save the selected indices to select them after the move
\r
582 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
583 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
584 selectedIndices.Add(selectedIndex);
\r
586 int firstSelectedIndex = selectedIndices[0];
\r
588 // Reverse the list to delete the items from last to first (preserves indices)
\r
589 selectedIndices.Reverse();
\r
591 // Remove each selected item
\r
592 foreach (int selectedIndex in selectedIndices)
\r
593 queue.Remove(selectedIndex);
\r
595 // Select the item where the first deleted item was previously
\r
596 if (firstSelectedIndex < list_queue.Items.Count)
\r
597 list_queue.Items[firstSelectedIndex].Selected = true;
\r
600 list_queue.Select(); // Activate the control to show the selected items
\r
603 /* Queue Import / Export features */
\r
606 /// Create a batch script
\r
608 /// <param name="sender">
\r
611 /// <param name="e">
\r
614 private void MnuBatchClick(object sender, EventArgs e)
\r
616 SaveFile.FileName = string.Empty;
\r
617 SaveFile.Filter = "Batch|.bat";
\r
618 SaveFile.ShowDialog();
\r
619 if (SaveFile.FileName != String.Empty)
\r
620 queue.WriteBatchScriptToFile(SaveFile.FileName);
\r
626 /// <param name="sender">
\r
629 /// <param name="e">
\r
632 private void MnuExportClick(object sender, EventArgs e)
\r
634 SaveFile.FileName = string.Empty;
\r
635 SaveFile.Filter = "HandBrake Queue|*.queue";
\r
636 SaveFile.ShowDialog();
\r
637 if (SaveFile.FileName != String.Empty)
\r
638 queue.WriteQueueStateToFile(SaveFile.FileName);
\r
644 /// <param name="sender">
\r
647 /// <param name="e">
\r
650 private void MnuImportClick(object sender, EventArgs e)
\r
652 OpenFile.FileName = string.Empty;
\r
653 OpenFile.ShowDialog();
\r
654 if (OpenFile.FileName != String.Empty)
\r
655 queue.LoadQueueFromFile(OpenFile.FileName);
\r
659 /// Readd current job to queue
\r
661 /// <param name="sender">
\r
664 /// <param name="e">
\r
667 private void MnuReaddClick(object sender, EventArgs e)
\r
669 if (queue.LastEncode != null && !queue.LastEncode.IsEmpty)
\r
672 queue.LastEncode.Query,
\r
673 queue.LastEncode.Title,
\r
674 queue.LastEncode.Source,
\r
675 queue.LastEncode.Destination,
\r
676 queue.LastEncode.CustomQuery);
\r
683 /// Hide's the window when the user tries to "x" out of the window instead of closing it.
\r
685 /// <param name="e">
\r
688 protected override void OnClosing(CancelEventArgs e)
\r
696 /// Change the OnComplete option setting.
\r
698 /// <param name="sender">
\r
701 /// <param name="e">
\r
704 private void CompleteOptionChanged(object sender, EventArgs e)
\r
706 Properties.Settings.Default.CompletionOption = drp_completeOption.Text;
\r
707 HandBrake.ApplicationServices.Init.CompletionOption = drp_completeOption.Text;
\r
708 Properties.Settings.Default.Save();
\r