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
12 using System.Windows.Forms;
\r
15 using HandBrake.ApplicationServices.Model;
\r
16 using HandBrake.ApplicationServices.Services;
\r
17 using HandBrake.ApplicationServices.Services.Interfaces;
\r
22 /// The Queue Window
\r
24 public partial class frmQueue : Form
\r
27 /// Update Handler Delegate
\r
29 private delegate void UpdateHandler();
\r
32 /// An instance of the Queue service
\r
34 private readonly IQueue queue;
\r
37 /// A reference to the main application window
\r
39 private readonly frmMain mainWindow;
\r
42 /// Initializes a new instance of the <see cref="frmQueue"/> class.
\r
44 /// <param name="q">
\r
45 /// An instance of the queue service.
\r
47 /// <param name="mw">
\r
48 /// The main window.
\r
50 public frmQueue(IQueue q, frmMain mw)
\r
52 InitializeComponent();
\r
54 this.mainWindow = mw;
\r
57 queue.EncodeStarted += new EventHandler(QueueOnEncodeStart);
\r
58 queue.QueueCompleted += new EventHandler(QueueOnQueueFinished);
\r
59 queue.QueuePauseRequested += new EventHandler(QueueOnPaused);
\r
60 queue.QueueListChanged += new EventHandler(queue_QueueListChanged);
\r
62 queue.EncodeStarted += new EventHandler(queue_EncodeStarted);
\r
63 queue.EncodeEnded += new EventHandler(queue_EncodeEnded);
\r
65 drp_completeOption.Text = Properties.Settings.Default.CompletionOption;
\r
71 /// <param name="sender">
\r
74 /// <param name="e">
\r
77 private void queue_QueueListChanged(object sender, EventArgs e)
\r
79 UpdateUiElementsOnQueueChange();
\r
85 /// <param name="sender">
\r
88 /// <param name="e">
\r
91 private void queue_EncodeEnded(object sender, EventArgs e)
\r
93 queue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
100 /// <param name="sender">
\r
103 /// <param name="e">
\r
106 private void queue_EncodeStarted(object sender, EventArgs e)
\r
108 this.SetCurrentEncodeInformation();
\r
109 queue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
113 /// Display the Encode Status
\r
115 /// <param name="sender">
\r
118 /// <param name="e">
\r
121 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
123 if (this.InvokeRequired)
\r
125 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
129 lbl_encodeStatus.Text =
\r
131 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",
\r
135 e.EstimatedTimeLeft);
\r
139 /// Handle the Queue Paused event
\r
141 /// <param name="sender">
\r
144 /// <param name="e">
\r
147 private void QueueOnPaused(object sender, EventArgs e)
\r
149 SetUiEncodeFinished();
\r
150 UpdateUiElementsOnQueueChange();
\r
154 /// Handle the Queue Finished event.
\r
156 /// <param name="sender">
\r
159 /// <param name="e">
\r
162 private void QueueOnQueueFinished(object sender, EventArgs e)
\r
164 SetUiEncodeFinished();
\r
165 ResetQueue(); // Reset the Queue Window
\r
169 /// Handle the Encode Started event
\r
171 /// <param name="sender">
\r
174 /// <param name="e">
\r
177 private void QueueOnEncodeStart(object sender, EventArgs e)
\r
179 SetUiEncodeStarted(); // make sure the UI is set correctly
\r
180 UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.
\r
184 /// Initializes the Queue list with the Arraylist from the Queue class
\r
186 public void SetQueue()
\r
188 UpdateUiElementsOnQueueChange();
\r
192 /// Initializes the Queue list, then shows and activates the window
\r
194 public new void Show()
\r
200 /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window
\r
202 /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>
\r
203 public void Show(bool doSetQueue)
\r
205 if (doSetQueue) SetQueue();
\r
210 /// Handle the Encode button Click event
\r
212 /// <param name="sender">The sender</param>
\r
213 /// <param name="e">the EventArgs</param>
\r
214 private void BtnEncodeClick(object sender, EventArgs e)
\r
218 SetUiEncodeStarted();
\r
221 lbl_encodeStatus.Text = "Encoding ...";
\r
226 /// Handle the Pause button click event.
\r
228 /// <param name="sender">
\r
231 /// <param name="e">
\r
234 private void BtnPauseClick(object sender, EventArgs e)
\r
238 "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
239 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
245 /// Setup the UI to show that an encode has started
\r
247 private void SetUiEncodeStarted()
\r
249 if (InvokeRequired)
\r
251 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));
\r
254 btn_encode.Enabled = false;
\r
255 btn_pause.Visible = true;
\r
259 /// Setup the UI to indicate that an encode has finished.
\r
261 private void SetUiEncodeFinished()
\r
263 if (InvokeRequired)
\r
265 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));
\r
268 btn_pause.Visible = false;
\r
269 btn_encode.Enabled = true;
\r
273 /// Reset the Queue Window display
\r
275 private void ResetQueue()
\r
277 if (InvokeRequired)
\r
279 BeginInvoke(new UpdateHandler(ResetQueue));
\r
282 btn_pause.Visible = false;
\r
283 btn_encode.Enabled = true;
\r
289 /// Reset the current job text
\r
291 private void ResetEncodeText()
\r
293 if (InvokeRequired)
\r
295 BeginInvoke(new UpdateHandler(ResetEncodeText));
\r
298 lbl_encodeStatus.Text = "Ready";
\r
300 lbl_source.Text = "-";
\r
301 lbl_dest.Text = "-";
\r
302 lbl_encodeOptions.Text = "-";
\r
304 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
308 /// Redraw the Queue window with the latest information about HandBrakes status
\r
310 private void RedrawQueue()
\r
312 if (InvokeRequired)
\r
314 BeginInvoke(new UpdateHandler(RedrawQueue));
\r
318 list_queue.Items.Clear();
\r
319 ReadOnlyCollection<Job> theQueue = queue.CurrentQueue;
\r
320 foreach (Job queueItem in theQueue)
\r
322 string qItem = queueItem.Query;
\r
323 QueryParser parsed = Functions.QueryParser.Parse(qItem);
\r
325 // Get the DVD Title
\r
326 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
328 // Get the DVD Chapters
\r
330 if (parsed.ChapterStart == 0)
\r
334 chapters = parsed.ChapterStart.ToString();
\r
335 if (parsed.ChapterFinish != 0)
\r
336 chapters = chapters + " - " + parsed.ChapterFinish;
\r
339 ListViewItem item = new ListViewItem();
\r
340 item.Text = title; // Title
\r
341 item.SubItems.Add(chapters); // Chapters
\r
342 item.SubItems.Add(queueItem.Source); // Source
\r
343 item.SubItems.Add(queueItem.Destination); // Destination
\r
344 item.SubItems.Add(parsed.VideoEncoder); // Video
\r
346 // Display The Audio Track Information
\r
347 string audio = string.Empty;
\r
348 foreach (AudioTrack track in parsed.AudioInformation)
\r
350 if (audio != string.Empty)
\r
351 audio += ", " + track.Encoder;
\r
353 audio = track.Encoder;
\r
355 item.SubItems.Add(audio); // Audio
\r
357 list_queue.Items.Add(item);
\r
362 /// Update the UI elements
\r
364 private void UpdateUiElementsOnQueueChange()
\r
366 if (InvokeRequired)
\r
368 BeginInvoke(new UpdateHandler(UpdateUiElementsOnQueueChange));
\r
373 lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";
\r
377 /// Set the window up with the current encode information
\r
379 private void SetCurrentEncodeInformation()
\r
383 if (InvokeRequired)
\r
385 BeginInvoke(new UpdateHandler(SetCurrentEncodeInformation));
\r
388 QueryParser parsed = QueryParser.Parse(queue.LastEncode.Query);
\r
390 // Get title and chapters
\r
391 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();
\r
393 if (Equals(parsed.ChapterStart, 0))
\r
394 chapterlbl = "Auto";
\r
397 string chapters = parsed.ChapterStart.ToString();
\r
398 if (parsed.ChapterFinish != 0)
\r
399 chapters = chapters + " - " + parsed.ChapterFinish;
\r
400 chapterlbl = chapters;
\r
403 // Get audio information
\r
404 string audio = string.Empty;
\r
405 foreach (AudioTrack track in parsed.AudioInformation)
\r
407 if (audio != string.Empty)
\r
408 audio += ", " + track.Encoder;
\r
410 audio = track.Encoder;
\r
413 // found query is a global varible
\r
414 lbl_encodeStatus.Text = "Encoding ...";
\r
415 lbl_source.Text = queue.LastEncode.Source + "(Title: " + title + " Chapters: " + chapterlbl + ")";
\r
416 lbl_dest.Text = queue.LastEncode.Destination;
\r
417 lbl_encodeOptions.Text = "Video: " + parsed.VideoEncoder + " Audio: " + audio + Environment.NewLine +
\r
418 "x264 Options: " + parsed.H264Query;
\r
426 /* 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