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
429 /// Handle the Move Up Menu Item
\r
431 /// <param name="sender">
\r
434 /// <param name="e">
\r
437 private void MnuUpClick(object sender, EventArgs e)
\r
443 /// Handle the Move down Menu Item
\r
445 /// <param name="sender">
\r
448 /// <param name="e">
\r
451 private void MnuDownClick(object sender, EventArgs e)
\r
459 /// <param name="sender">
\r
462 /// <param name="e">
\r
465 private void MnuEditClick(object sender, EventArgs e)
\r
467 if (list_queue.SelectedIndices != null && list_queue.SelectedIndices.Count != 0)
\r
473 int index = list_queue.SelectedIndices[0];
\r
474 mainWindow.RecievingJob(queue.GetJob(index));
\r
475 queue.Remove(index);
\r
483 /// Handle the delete Menu Item
\r
485 /// <param name="sender">
\r
488 /// <param name="e">
\r
491 private void MnuDeleteClick(object sender, EventArgs e)
\r
493 DeleteSelectedItems();
\r
496 /* Keyboard Shortcuts */
\r
499 /// Handle the delete keyboard press
\r
501 /// <param name="sender">
\r
504 /// <param name="e">
\r
507 private void ListQueueDeleteKey(object sender, KeyEventArgs e)
\r
509 if (e.KeyCode == Keys.Delete)
\r
510 DeleteSelectedItems();
\r
513 /* Queue Management */
\r
516 /// Move items up in the queue
\r
518 private void MoveUp()
\r
520 // If there are selected items and the first item is not selected
\r
521 if (list_queue.SelectedIndices.Count > 0 && !list_queue.SelectedIndices.Contains(0))
\r
523 // Copy the selected indices to preserve them during the movement
\r
524 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
525 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
526 selectedIndices.Add(selectedIndex);
\r
528 // Move up each selected item
\r
529 foreach (int selectedIndex in selectedIndices)
\r
530 queue.MoveUp(selectedIndex);
\r
532 // Keep the selected item(s) selected, now moved up one index
\r
533 foreach (int selectedIndex in selectedIndices)
\r
534 if (selectedIndex - 1 > -1) // Defensive programming: ensure index is good
\r
535 list_queue.Items[selectedIndex - 1].Selected = true;
\r
538 list_queue.Select(); // Activate the control to show the selected items
\r
542 /// Move items down in the queue
\r
544 private void MoveDown()
\r
546 // If there are selected items and the last item is not selected
\r
547 if (list_queue.SelectedIndices.Count > 0 &&
\r
548 !list_queue.SelectedIndices.Contains(list_queue.Items[list_queue.Items.Count - 1].Index))
\r
550 // Copy the selected indices to preserve them during the movement
\r
551 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
552 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
553 selectedIndices.Add(selectedIndex);
\r
555 // Reverse the indices to move the items down from last to first (preserves indices)
\r
556 selectedIndices.Reverse();
\r
558 // Move down each selected item
\r
559 foreach (int selectedIndex in selectedIndices)
\r
560 queue.MoveDown(selectedIndex);
\r
562 // Keep the selected item(s) selected, now moved down one index
\r
563 foreach (int selectedIndex in selectedIndices)
\r
564 if (selectedIndex + 1 < list_queue.Items.Count) // Defensive programming: ensure index is good
\r
565 list_queue.Items[selectedIndex + 1].Selected = true;
\r
568 list_queue.Select(); // Activate the control to show the selected items
\r
572 /// Delete the currently selected items on the queue
\r
574 private void DeleteSelectedItems()
\r
576 // If there are selected items
\r
577 if (list_queue.SelectedIndices.Count > 0)
\r
579 // Save the selected indices to select them after the move
\r
580 List<int> selectedIndices = new List<int>(list_queue.SelectedIndices.Count);
\r
581 foreach (int selectedIndex in list_queue.SelectedIndices)
\r
582 selectedIndices.Add(selectedIndex);
\r
584 int firstSelectedIndex = selectedIndices[0];
\r
586 // Reverse the list to delete the items from last to first (preserves indices)
\r
587 selectedIndices.Reverse();
\r
589 // Remove each selected item
\r
590 foreach (int selectedIndex in selectedIndices)
\r
591 queue.Remove(selectedIndex);
\r
593 // Select the item where the first deleted item was previously
\r
594 if (firstSelectedIndex < list_queue.Items.Count)
\r
595 list_queue.Items[firstSelectedIndex].Selected = true;
\r
598 list_queue.Select(); // Activate the control to show the selected items
\r
601 /* Queue Import / Export features */
\r
604 /// Create a batch script
\r
606 /// <param name="sender">
\r
609 /// <param name="e">
\r
612 private void MnuBatchClick(object sender, EventArgs e)
\r
614 SaveFile.FileName = string.Empty;
\r
615 SaveFile.Filter = "Batch|.bat";
\r
616 SaveFile.ShowDialog();
\r
617 if (SaveFile.FileName != String.Empty)
\r
618 queue.WriteBatchScriptToFile(SaveFile.FileName);
\r
624 /// <param name="sender">
\r
627 /// <param name="e">
\r
630 private void MnuExportClick(object sender, EventArgs e)
\r
632 SaveFile.FileName = string.Empty;
\r
633 SaveFile.Filter = "HandBrake Queue|*.queue";
\r
634 SaveFile.ShowDialog();
\r
635 if (SaveFile.FileName != String.Empty)
\r
636 queue.WriteQueueStateToFile(SaveFile.FileName);
\r
642 /// <param name="sender">
\r
645 /// <param name="e">
\r
648 private void MnuImportClick(object sender, EventArgs e)
\r
650 OpenFile.FileName = string.Empty;
\r
651 OpenFile.ShowDialog();
\r
652 if (OpenFile.FileName != String.Empty)
\r
653 queue.LoadQueueFromFile(OpenFile.FileName);
\r
657 /// Readd current job to queue
\r
659 /// <param name="sender">
\r
662 /// <param name="e">
\r
665 private void MnuReaddClick(object sender, EventArgs e)
\r
667 if (!queue.LastEncode.IsEmpty)
\r
670 queue.LastEncode.Query,
\r
671 queue.LastEncode.Title,
\r
672 queue.LastEncode.Source,
\r
673 queue.LastEncode.Destination,
\r
674 queue.LastEncode.CustomQuery);
\r
681 /// Hide's the window when the user tries to "x" out of the window instead of closing it.
\r
683 /// <param name="e">
\r
686 protected override void OnClosing(CancelEventArgs e)
\r
694 /// Change the OnComplete option setting.
\r
696 /// <param name="sender">
\r
699 /// <param name="e">
\r
702 private void CompleteOptionChanged(object sender, EventArgs e)
\r
704 Properties.Settings.Default.CompletionOption = drp_completeOption.Text;
\r
705 Properties.Settings.Default.Save();
\r