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
70 /// <param name="sender">
\r
73 /// <param name="e">
\r
76 private void queue_QueueListChanged(object sender, EventArgs e)
\r
78 UpdateUiElementsOnQueueChange();
\r
84 /// <param name="sender">
\r
87 /// <param name="e">
\r
90 private void queue_EncodeEnded(object sender, EventArgs e)
\r
92 queue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
99 /// <param name="sender">
\r
102 /// <param name="e">
\r
105 private void queue_EncodeStarted(object sender, EventArgs e)
\r
107 this.SetCurrentEncodeInformation();
\r
108 queue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
112 /// Display the Encode Status
\r
114 /// <param name="sender">
\r
117 /// <param name="e">
\r
120 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
122 if (this.InvokeRequired)
\r
124 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
128 lbl_encodeStatus.Text =
\r
130 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",
\r
134 e.EstimatedTimeLeft);
\r
138 /// Handle the Queue Paused event
\r
140 /// <param name="sender">
\r
143 /// <param name="e">
\r
146 private void QueueOnPaused(object sender, EventArgs e)
\r
148 SetUiEncodeFinished();
\r
149 UpdateUiElementsOnQueueChange();
\r
153 /// Handle the Queue Finished event.
\r
155 /// <param name="sender">
\r
158 /// <param name="e">
\r
161 private void QueueOnQueueFinished(object sender, EventArgs e)
\r
163 SetUiEncodeFinished();
\r
164 ResetQueue(); // Reset the Queue Window
\r
168 /// Handle the Encode Started event
\r
170 /// <param name="sender">
\r
173 /// <param name="e">
\r
176 private void QueueOnEncodeStart(object sender, EventArgs e)
\r
178 SetUiEncodeStarted(); // make sure the UI is set correctly
\r
179 UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.
\r
183 /// Initializes the Queue list with the Arraylist from the Queue class
\r
185 public void SetQueue()
\r
187 UpdateUiElementsOnQueueChange();
\r
191 /// Initializes the Queue list, then shows and activates the window
\r
193 public new void Show()
\r
199 /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window
\r
201 /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>
\r
202 public void Show(bool doSetQueue)
\r
204 if (doSetQueue) SetQueue();
\r
209 /// Handle the Encode button Click event
\r
211 /// <param name="sender">The sender</param>
\r
212 /// <param name="e">the EventArgs</param>
\r
213 private void BtnEncodeClick(object sender, EventArgs e)
\r
217 SetUiEncodeStarted();
\r
220 lbl_encodeStatus.Text = "Encoding ...";
\r
225 /// Handle the Pause button click event.
\r
227 /// <param name="sender">
\r
230 /// <param name="e">
\r
233 private void BtnPauseClick(object sender, EventArgs e)
\r
237 "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
238 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
244 /// Setup the UI to show that an encode has started
\r
246 private void SetUiEncodeStarted()
\r
248 if (InvokeRequired)
\r
250 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));
\r
253 btn_encode.Enabled = false;
\r
254 btn_pause.Visible = true;
\r
258 /// Setup the UI to indicate that an encode has finished.
\r
260 private void SetUiEncodeFinished()
\r
262 if (InvokeRequired)
\r
264 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));
\r
267 btn_pause.Visible = false;
\r
268 btn_encode.Enabled = true;
\r
272 /// Reset the Queue Window display
\r
274 private void ResetQueue()
\r
276 if (InvokeRequired)
\r
278 BeginInvoke(new UpdateHandler(ResetQueue));
\r
281 btn_pause.Visible = false;
\r
282 btn_encode.Enabled = true;
\r
288 /// Reset the current job text
\r
290 private void ResetEncodeText()
\r
292 if (InvokeRequired)
\r
294 BeginInvoke(new UpdateHandler(ResetEncodeText));
\r
297 lbl_encodeStatus.Text = "Ready";
\r
299 lbl_source.Text = "-";
\r
300 lbl_dest.Text = "-";
\r
301 lbl_encodeOptions.Text = "-";
\r
303 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
307 /// Redraw the Queue window with the latest information about HandBrakes status
\r
309 private void RedrawQueue()
\r
311 if (InvokeRequired)
\r
313 BeginInvoke(new UpdateHandler(RedrawQueue));
\r
317 list_queue.Items.Clear();
\r
318 ReadOnlyCollection<Job> theQueue = queue.CurrentQueue;
\r
319 foreach (Job queueItem in theQueue)
\r
321 string qItem = queueItem.Query;
\r
322 QueryParser parsed = Functions.QueryParser.Parse(qItem);
\r
324 // Get the DVD Title
\r
325 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
327 // Get the DVD Chapters
\r
329 if (parsed.ChapterStart == 0)
\r
333 chapters = parsed.ChapterStart.ToString();
\r
334 if (parsed.ChapterFinish != 0)
\r
335 chapters = chapters + " - " + parsed.ChapterFinish;
\r
338 ListViewItem item = new ListViewItem();
\r
339 item.Text = title; // Title
\r
340 item.SubItems.Add(chapters); // Chapters
\r
341 item.SubItems.Add(queueItem.Source); // Source
\r
342 item.SubItems.Add(queueItem.Destination); // Destination
\r
343 item.SubItems.Add(parsed.VideoEncoder); // Video
\r
345 // Display The Audio Track Information
\r
346 string audio = string.Empty;
\r
347 foreach (AudioTrack track in parsed.AudioInformation)
\r
349 if (audio != string.Empty)
\r
350 audio += ", " + track.Encoder;
\r
352 audio = track.Encoder;
\r
354 item.SubItems.Add(audio); // Audio
\r
356 list_queue.Items.Add(item);
\r
361 /// Update the UI elements
\r
363 private void UpdateUiElementsOnQueueChange()
\r
365 if (InvokeRequired)
\r
367 BeginInvoke(new UpdateHandler(UpdateUiElementsOnQueueChange));
\r
372 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
376 /// Set the window up with the current encode information
\r
378 private void SetCurrentEncodeInformation()
\r
382 if (InvokeRequired)
\r
384 BeginInvoke(new UpdateHandler(SetCurrentEncodeInformation));
\r
387 QueryParser parsed = QueryParser.Parse(queue.LastEncode.Query);
\r
389 // Get title and chapters
\r
390 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
392 if (Equals(parsed.ChapterStart, 0))
\r
393 chapterlbl = "Auto";
\r
396 string chapters = parsed.ChapterStart.ToString();
\r
397 if (parsed.ChapterFinish != 0)
\r
398 chapters = chapters + " - " + parsed.ChapterFinish;
\r
399 chapterlbl = chapters;
\r
402 // Get audio information
\r
403 string audio = string.Empty;
\r
404 foreach (AudioTrack track in parsed.AudioInformation)
\r
406 if (audio != string.Empty)
\r
407 audio += ", " + track.Encoder;
\r
409 audio = track.Encoder;
\r
412 // found query is a global varible
\r
413 lbl_encodeStatus.Text = "Encoding ...";
\r
414 lbl_source.Text = queue.LastEncode.Source + "(Title: " + title + " Chapters: " + chapterlbl + ")";
\r
415 lbl_dest.Text = queue.LastEncode.Destination;
\r
416 lbl_encodeOptions.Text = "Video: " + parsed.VideoEncoder + " Audio: " + audio + Environment.NewLine +
\r
417 "x264 Options: " + parsed.H264Query;
\r
425 /* Right Click Menu */
\r
427 /// Handle the Move Up Menu Item
\r
429 /// <param name="sender">
\r
432 /// <param name="e">
\r
435 private void MnuUpClick(object sender, EventArgs e)
\r
441 /// Handle the Move down Menu Item
\r
443 /// <param name="sender">
\r
446 /// <param name="e">
\r
449 private void MnuDownClick(object sender, EventArgs e)
\r
457 /// <param name="sender">
\r
460 /// <param name="e">
\r
463 private void MnuEditClick(object sender, EventArgs e)
\r
465 if (list_queue.SelectedIndices != null && list_queue.SelectedIndices.Count != 0)
\r
471 int index = list_queue.SelectedIndices[0];
\r
472 mainWindow.RecievingJob(queue.GetJob(index));
\r
473 queue.Remove(index);
\r
481 /// Handle the delete Menu Item
\r
483 /// <param name="sender">
\r
486 /// <param name="e">
\r
489 private void MnuDeleteClick(object sender, EventArgs e)
\r
491 DeleteSelectedItems();
\r
494 /* Keyboard Shortcuts */
\r
497 /// Handle the delete keyboard press
\r
499 /// <param name="sender">
\r
502 /// <param name="e">
\r
505 private void ListQueueDeleteKey(object sender, KeyEventArgs e)
\r
507 if (e.KeyCode == Keys.Delete)
\r
508 DeleteSelectedItems();
\r
511 /* Queue Management */
\r
514 /// Move items up in the queue
\r
516 private void MoveUp()
\r
518 // If there are selected items and the first item is not selected
\r
519 if (list_queue.SelectedIndices.Count > 0 && !list_queue.SelectedIndices.Contains(0))
\r
521 // Copy the selected indices to preserve them during the movement
\r
522 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
523 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
524 selectedIndices.Add(selectedIndex);
\r
526 // Move up each selected item
\r
527 foreach (int selectedIndex in selectedIndices)
\r
528 queue.MoveUp(selectedIndex);
\r
530 // Keep the selected item(s) selected, now moved up one index
\r
531 foreach (int selectedIndex in selectedIndices)
\r
532 if (selectedIndex - 1 > -1) // Defensive programming: ensure index is good
\r
533 list_queue.Items[selectedIndex - 1].Selected = true;
\r
536 list_queue.Select(); // Activate the control to show the selected items
\r
540 /// Move items down in the queue
\r
542 private void MoveDown()
\r
544 // If there are selected items and the last item is not selected
\r
545 if (list_queue.SelectedIndices.Count > 0 &&
\r
546 !list_queue.SelectedIndices.Contains(list_queue.Items[list_queue.Items.Count - 1].Index))
\r
548 // Copy the selected indices to preserve them during the movement
\r
549 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
550 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
551 selectedIndices.Add(selectedIndex);
\r
553 // Reverse the indices to move the items down from last to first (preserves indices)
\r
554 selectedIndices.Reverse();
\r
556 // Move down each selected item
\r
557 foreach (int selectedIndex in selectedIndices)
\r
558 queue.MoveDown(selectedIndex);
\r
560 // Keep the selected item(s) selected, now moved down one index
\r
561 foreach (int selectedIndex in selectedIndices)
\r
562 if (selectedIndex + 1 < list_queue.Items.Count) // Defensive programming: ensure index is good
\r
563 list_queue.Items[selectedIndex + 1].Selected = true;
\r
566 list_queue.Select(); // Activate the control to show the selected items
\r
570 /// Delete the currently selected items on the queue
\r
572 private void DeleteSelectedItems()
\r
574 // If there are selected items
\r
575 if (list_queue.SelectedIndices.Count > 0)
\r
577 // Save the selected indices to select them after the move
\r
578 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
579 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
580 selectedIndices.Add(selectedIndex);
\r
582 int firstSelectedIndex = selectedIndices[0];
\r
584 // Reverse the list to delete the items from last to first (preserves indices)
\r
585 selectedIndices.Reverse();
\r
587 // Remove each selected item
\r
588 foreach (int selectedIndex in selectedIndices)
\r
589 queue.Remove(selectedIndex);
\r
591 // Select the item where the first deleted item was previously
\r
592 if (firstSelectedIndex < list_queue.Items.Count)
\r
593 list_queue.Items[firstSelectedIndex].Selected = true;
\r
596 list_queue.Select(); // Activate the control to show the selected items
\r
599 /* Queue Import / Export features */
\r
602 /// Create a batch script
\r
604 /// <param name="sender">
\r
607 /// <param name="e">
\r
610 private void MnuBatchClick(object sender, EventArgs e)
\r
612 SaveFile.FileName = string.Empty;
\r
613 SaveFile.Filter = "Batch|.bat";
\r
614 SaveFile.ShowDialog();
\r
615 if (SaveFile.FileName != String.Empty)
\r
616 queue.WriteBatchScriptToFile(SaveFile.FileName);
\r
622 /// <param name="sender">
\r
625 /// <param name="e">
\r
628 private void MnuExportClick(object sender, EventArgs e)
\r
630 SaveFile.FileName = string.Empty;
\r
631 SaveFile.Filter = "HandBrake Queue|*.queue";
\r
632 SaveFile.ShowDialog();
\r
633 if (SaveFile.FileName != String.Empty)
\r
634 queue.WriteQueueStateToFile(SaveFile.FileName);
\r
640 /// <param name="sender">
\r
643 /// <param name="e">
\r
646 private void MnuImportClick(object sender, EventArgs e)
\r
648 OpenFile.FileName = string.Empty;
\r
649 OpenFile.ShowDialog();
\r
650 if (OpenFile.FileName != String.Empty)
\r
651 queue.LoadQueueFromFile(OpenFile.FileName);
\r
655 /// Readd current job to queue
\r
657 /// <param name="sender">
\r
660 /// <param name="e">
\r
663 private void MnuReaddClick(object sender, EventArgs e)
\r
665 if (!queue.LastEncode.IsEmpty)
\r
668 queue.LastEncode.Query,
\r
669 queue.LastEncode.Title,
\r
670 queue.LastEncode.Source,
\r
671 queue.LastEncode.Destination,
\r
672 queue.LastEncode.CustomQuery);
\r
679 /// Hide's the window when the user tries to "x" out of the window instead of closing it.
\r
681 /// <param name="e">
\r
684 protected override void OnClosing(CancelEventArgs e)
\r