OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmQueue.cs
1 /*  frmQueue.cs $\r
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
5 \r
6 namespace Handbrake\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.Collections.ObjectModel;\r
11     using System.ComponentModel;\r
12     using System.IO;\r
13     using System.Windows.Forms;\r
14     using Functions;\r
15 \r
16     using HandBrake.ApplicationServices.Model;\r
17     using HandBrake.ApplicationServices.Services;\r
18     using HandBrake.ApplicationServices.Services.Interfaces;\r
19 \r
20     using Model;\r
21 \r
22     /// <summary>\r
23     /// The Queue Window\r
24     /// </summary>\r
25     public partial class frmQueue : Form\r
26     {\r
27         /// <summary>\r
28         /// Update Handler Delegate\r
29         /// </summary>\r
30         private delegate void UpdateHandler();\r
31 \r
32         /// <summary>\r
33         /// An instance of the Queue service\r
34         /// </summary>\r
35         private readonly IQueue queue;\r
36 \r
37         /// <summary>\r
38         /// A reference to the main application window\r
39         /// </summary>\r
40         private readonly frmMain mainWindow;\r
41 \r
42         /// <summary>\r
43         /// Initializes a new instance of the <see cref="frmQueue"/> class.\r
44         /// </summary>\r
45         /// <param name="q">\r
46         /// An instance of the queue service.\r
47         /// </param>\r
48         /// <param name="mw">\r
49         /// The main window.\r
50         /// </param>\r
51         public frmQueue(IQueue q, frmMain mw)\r
52         {\r
53             InitializeComponent();\r
54 \r
55             this.mainWindow = mw;\r
56 \r
57             this.queue = q;\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
62 \r
63             queue.EncodeStarted += new EventHandler(queue_EncodeStarted);\r
64             queue.EncodeEnded += new EventHandler(queue_EncodeEnded);\r
65         }\r
66 \r
67         /// <summary>\r
68         /// Queue Changed\r
69         /// </summary>\r
70         /// <param name="sender">\r
71         /// The sender.\r
72         /// </param>\r
73         /// <param name="e">\r
74         /// The e.\r
75         /// </param>\r
76         private void queue_QueueListChanged(object sender, EventArgs e)\r
77         {\r
78             UpdateUiElementsOnQueueChange();\r
79         }\r
80 \r
81         /// <summary>\r
82         /// Encode Ended\r
83         /// </summary>\r
84         /// <param name="sender">\r
85         /// The sender.\r
86         /// </param>\r
87         /// <param name="e">\r
88         /// The e.\r
89         /// </param>\r
90         private void queue_EncodeEnded(object sender, EventArgs e)\r
91         {\r
92             queue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;\r
93             ResetEncodeText();\r
94         }\r
95 \r
96         /// <summary>\r
97         /// Queue Started\r
98         /// </summary>\r
99         /// <param name="sender">\r
100         /// The sender.\r
101         /// </param>\r
102         /// <param name="e">\r
103         /// The e.\r
104         /// </param>\r
105         private void queue_EncodeStarted(object sender, EventArgs e)\r
106         {\r
107             this.SetCurrentEncodeInformation();\r
108             queue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;        \r
109         }\r
110 \r
111         /// <summary>\r
112         /// Display the Encode Status\r
113         /// </summary>\r
114         /// <param name="sender">\r
115         /// The sender.\r
116         /// </param>\r
117         /// <param name="e">\r
118         /// The e.\r
119         /// </param>\r
120         private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)\r
121         {\r
122             if (this.InvokeRequired)\r
123             {\r
124                 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });\r
125                 return;\r
126             }\r
127 \r
128             lbl_encodeStatus.Text =\r
129                 string.Format(\r
130                 "Encoding: Pass {0} of {1}, {2:00.00}% Time Remaining: {3}",\r
131                 e.Task,\r
132                 e.Task,\r
133                 e.PercentComplete,\r
134                 e.EstimatedTimeLeft);\r
135         }\r
136 \r
137         /// <summary>\r
138         /// Handle the Queue Paused event\r
139         /// </summary>\r
140         /// <param name="sender">\r
141         /// The sender.\r
142         /// </param>\r
143         /// <param name="e">\r
144         /// The EventArgs.\r
145         /// </param>\r
146         private void QueueOnPaused(object sender, EventArgs e)\r
147         {\r
148             SetUiEncodeFinished();\r
149             UpdateUiElementsOnQueueChange();\r
150         }\r
151 \r
152         /// <summary>\r
153         /// Handle the Queue Finished event.\r
154         /// </summary>\r
155         /// <param name="sender">\r
156         /// The sender.\r
157         /// </param>\r
158         /// <param name="e">\r
159         /// The EventArgs.\r
160         /// </param>\r
161         private void QueueOnQueueFinished(object sender, EventArgs e)\r
162         {\r
163             SetUiEncodeFinished();\r
164             ResetQueue(); // Reset the Queue Window\r
165         }\r
166 \r
167         /// <summary>\r
168         /// Handle the Encode Started event\r
169         /// </summary>\r
170         /// <param name="sender">\r
171         /// The sender.\r
172         /// </param>\r
173         /// <param name="e">\r
174         /// The e.\r
175         /// </param>\r
176         private void QueueOnEncodeStart(object sender, EventArgs e)\r
177         {\r
178             SetUiEncodeStarted(); // make sure the UI is set correctly\r
179             UpdateUiElementsOnQueueChange(); // Redraw the Queue, a new encode has started.\r
180         }\r
181 \r
182         /// <summary>\r
183         /// Initializes the Queue list with the Arraylist from the Queue class\r
184         /// </summary>\r
185         public void SetQueue()\r
186         {\r
187             UpdateUiElementsOnQueueChange();\r
188         }\r
189 \r
190         /// <summary>\r
191         /// Initializes the Queue list, then shows and activates the window\r
192         /// </summary>\r
193         public new void Show()\r
194         {\r
195             Show(true);\r
196         }\r
197 \r
198         /// <summary>\r
199         /// Initializes the Queue list only if doSetQueue is true, then shows and activates the window\r
200         /// </summary>\r
201         /// <param name="doSetQueue">Indicates whether to call setQueue() before showing the window</param>\r
202         public void Show(bool doSetQueue)\r
203         {\r
204             if (doSetQueue) SetQueue();\r
205             base.Show();\r
206         }\r
207 \r
208         /// <summary>\r
209         /// Handle the Encode button Click event\r
210         /// </summary>\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
214         {\r
215             if (queue.Paused)\r
216             {\r
217                 SetUiEncodeStarted();\r
218             }\r
219 \r
220             lbl_encodeStatus.Text = "Encoding ...";\r
221             queue.Start();\r
222         }\r
223 \r
224         /// <summary>\r
225         /// Handle the Pause button click event.\r
226         /// </summary>\r
227         /// <param name="sender">\r
228         /// The sender.\r
229         /// </param>\r
230         /// <param name="e">\r
231         /// The EventArgs.\r
232         /// </param>\r
233         private void BtnPauseClick(object sender, EventArgs e)\r
234         {\r
235             queue.Pause();\r
236             MessageBox.Show(\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
239         }\r
240 \r
241         // UI Work\r
242 \r
243         /// <summary>\r
244         /// Setup the UI to show that an encode has started\r
245         /// </summary>\r
246         private void SetUiEncodeStarted()\r
247         {\r
248             if (InvokeRequired)\r
249             {\r
250                 BeginInvoke(new UpdateHandler(SetUiEncodeStarted));\r
251                 return;\r
252             }\r
253             btn_encode.Enabled = false;\r
254             btn_pause.Visible = true;\r
255         }\r
256 \r
257         /// <summary>\r
258         /// Setup the UI to indicate that an encode has finished.\r
259         /// </summary>\r
260         private void SetUiEncodeFinished()\r
261         {\r
262             if (InvokeRequired)\r
263             {\r
264                 BeginInvoke(new UpdateHandler(SetUiEncodeFinished));\r
265                 return;\r
266             }\r
267             btn_pause.Visible = false;\r
268             btn_encode.Enabled = true;\r
269         }\r
270 \r
271         /// <summary>\r
272         /// Reset the Queue Window display\r
273         /// </summary>\r
274         private void ResetQueue()\r
275         {\r
276             if (InvokeRequired)\r
277             {\r
278                 BeginInvoke(new UpdateHandler(ResetQueue));\r
279                 return;\r
280             }\r
281             btn_pause.Visible = false;\r
282             btn_encode.Enabled = true;\r
283 \r
284             ResetEncodeText();\r
285         }\r
286 \r
287         /// <summary>\r
288         /// Reset the current job text\r
289         /// </summary>\r
290         private void ResetEncodeText()\r
291         {\r
292             if (InvokeRequired)\r
293             {\r
294                 BeginInvoke(new UpdateHandler(ResetEncodeText));\r
295                 return;\r
296             }\r
297             lbl_encodeStatus.Text = "Ready";\r
298 \r
299             lbl_source.Text = "-";\r
300             lbl_dest.Text = "-";\r
301             lbl_encodeOptions.Text = "-";\r
302 \r
303             lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";\r
304         }\r
305 \r
306         /// <summary>\r
307         /// Redraw the Queue window with the latest information about HandBrakes status\r
308         /// </summary>\r
309         private void RedrawQueue()\r
310         {\r
311             if (InvokeRequired)\r
312             {\r
313                 BeginInvoke(new UpdateHandler(RedrawQueue));\r
314                 return;\r
315             }\r
316 \r
317             list_queue.Items.Clear();\r
318             ReadOnlyCollection<Job> theQueue = queue.CurrentQueue;\r
319             foreach (Job queueItem in theQueue)\r
320             {\r
321                 string qItem = queueItem.Query;\r
322                 QueryParser parsed = Functions.QueryParser.Parse(qItem);\r
323 \r
324                 // Get the DVD Title\r
325                 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();\r
326 \r
327                 // Get the DVD Chapters\r
328                 string chapters;\r
329                 if (parsed.ChapterStart == 0)\r
330                     chapters = "Auto";\r
331                 else\r
332                 {\r
333                     chapters = parsed.ChapterStart.ToString();\r
334                     if (parsed.ChapterFinish != 0)\r
335                         chapters = chapters + " - " + parsed.ChapterFinish;\r
336                 }\r
337 \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
344 \r
345                 // Display The Audio Track Information\r
346                 string audio = string.Empty;\r
347                 foreach (AudioTrack track in parsed.AudioInformation)\r
348                 {\r
349                     if (audio != string.Empty)\r
350                         audio += ", " + track.Encoder;\r
351                     else\r
352                         audio = track.Encoder;\r
353                 }\r
354                 item.SubItems.Add(audio); // Audio\r
355 \r
356                 list_queue.Items.Add(item);\r
357             }\r
358         }\r
359 \r
360         /// <summary>\r
361         /// Update the UI elements\r
362         /// </summary>\r
363         private void UpdateUiElementsOnQueueChange()\r
364         {\r
365             if (InvokeRequired)\r
366             {\r
367                 BeginInvoke(new UpdateHandler(UpdateUiElementsOnQueueChange));\r
368                 return;\r
369             }\r
370 \r
371             RedrawQueue();\r
372             lbl_encodesPending.Text = list_queue.Items.Count + " encode(s) pending";\r
373         }\r
374 \r
375         /// <summary>\r
376         /// Set the window up with the current encode information\r
377         /// </summary>\r
378         private void SetCurrentEncodeInformation()\r
379         {\r
380             try\r
381             {\r
382                 if (InvokeRequired)\r
383                 {\r
384                     BeginInvoke(new UpdateHandler(SetCurrentEncodeInformation));\r
385                 }\r
386 \r
387                 QueryParser parsed = QueryParser.Parse(queue.LastEncode.Query);\r
388 \r
389                 // Get title and chapters\r
390                 string title = parsed.Title == 0 ? "Auto" : parsed.Title.ToString();\r
391                 string chapterlbl;\r
392                 if (Equals(parsed.ChapterStart, 0))\r
393                     chapterlbl = "Auto";\r
394                 else\r
395                 {\r
396                     string chapters = parsed.ChapterStart.ToString();\r
397                     if (parsed.ChapterFinish != 0)\r
398                         chapters = chapters + " - " + parsed.ChapterFinish;\r
399                     chapterlbl = chapters;\r
400                 }\r
401 \r
402                 // Get audio information\r
403                 string audio = string.Empty;\r
404                 foreach (AudioTrack track in parsed.AudioInformation)\r
405                 {\r
406                     if (audio != string.Empty) \r
407                         audio += ", " + track.Encoder;\r
408                     else\r
409                         audio = track.Encoder;\r
410                 }\r
411 \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
418                }\r
419             catch (Exception)\r
420             {\r
421                 // Do Nothing\r
422             }\r
423         }\r
424 \r
425         /* Right Click Menu */\r
426         /// <summary>\r
427         /// Handle the Move Up Menu Item\r
428         /// </summary>\r
429         /// <param name="sender">\r
430         /// The sender.\r
431         /// </param>\r
432         /// <param name="e">\r
433         /// The e.\r
434         /// </param>\r
435         private void MnuUpClick(object sender, EventArgs e)\r
436         {\r
437             MoveUp();\r
438         }\r
439 \r
440         /// <summary>\r
441         /// Handle the Move down Menu Item\r
442         /// </summary>\r
443         /// <param name="sender">\r
444         /// The sender.\r
445         /// </param>\r
446         /// <param name="e">\r
447         /// The e.\r
448         /// </param>\r
449         private void MnuDownClick(object sender, EventArgs e)\r
450         {\r
451             MoveDown();\r
452         }\r
453 \r
454         /// <summary>\r
455         /// Edit a job\r
456         /// </summary>\r
457         /// <param name="sender">\r
458         /// The sender.\r
459         /// </param>\r
460         /// <param name="e">\r
461         /// The e.\r
462         /// </param>\r
463         private void MnuEditClick(object sender, EventArgs e)\r
464         {\r
465             if (list_queue.SelectedIndices != null && list_queue.SelectedIndices.Count != 0)\r
466             {\r
467                 lock (queue)\r
468                 {\r
469                     lock (list_queue)\r
470                     {\r
471                         int index = list_queue.SelectedIndices[0];\r
472                         mainWindow.RecievingJob(queue.GetJob(index));\r
473                         queue.Remove(index);\r
474                         RedrawQueue();\r
475                     }\r
476                 }\r
477             }\r
478         }\r
479 \r
480         /// <summary>\r
481         /// Handle the delete Menu Item\r
482         /// </summary>\r
483         /// <param name="sender">\r
484         /// The sender.\r
485         /// </param>\r
486         /// <param name="e">\r
487         /// The e.\r
488         /// </param>\r
489         private void MnuDeleteClick(object sender, EventArgs e)\r
490         {\r
491             DeleteSelectedItems();\r
492         }\r
493 \r
494         /* Keyboard Shortcuts */\r
495 \r
496         /// <summary>\r
497         /// Handle the delete keyboard press\r
498         /// </summary>\r
499         /// <param name="sender">\r
500         /// The sender.\r
501         /// </param>\r
502         /// <param name="e">\r
503         /// The e.\r
504         /// </param>\r
505         private void ListQueueDeleteKey(object sender, KeyEventArgs e)\r
506         {\r
507             if (e.KeyCode == Keys.Delete)\r
508                 DeleteSelectedItems();\r
509         }\r
510 \r
511         /* Queue Management */\r
512 \r
513         /// <summary>\r
514         /// Move items up in the queue\r
515         /// </summary>\r
516         private void MoveUp()\r
517         {\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
520             {\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
525 \r
526                 // Move up each selected item\r
527                 foreach (int selectedIndex in selectedIndices)\r
528                     queue.MoveUp(selectedIndex);\r
529 \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
534             }\r
535 \r
536             list_queue.Select(); // Activate the control to show the selected items\r
537         }\r
538 \r
539         /// <summary>\r
540         /// Move items down in the queue\r
541         /// </summary>\r
542         private void MoveDown()\r
543         {\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
547             {\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
552 \r
553                 // Reverse the indices to move the items down from last to first (preserves indices)\r
554                 selectedIndices.Reverse();\r
555 \r
556                 // Move down each selected item\r
557                 foreach (int selectedIndex in selectedIndices)\r
558                     queue.MoveDown(selectedIndex);\r
559 \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
564             }\r
565 \r
566             list_queue.Select(); // Activate the control to show the selected items\r
567         }\r
568 \r
569         /// <summary>\r
570         /// Delete the currently selected items on the queue\r
571         /// </summary>\r
572         private void DeleteSelectedItems()\r
573         {\r
574             // If there are selected items\r
575             if (list_queue.SelectedIndices.Count > 0)\r
576             {\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
581 \r
582                 int firstSelectedIndex = selectedIndices[0];\r
583 \r
584                 // Reverse the list to delete the items from last to first (preserves indices)\r
585                 selectedIndices.Reverse();\r
586 \r
587                 // Remove each selected item\r
588                 foreach (int selectedIndex in selectedIndices)\r
589                     queue.Remove(selectedIndex);\r
590 \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
594             }\r
595 \r
596             list_queue.Select(); // Activate the control to show the selected items\r
597         }\r
598 \r
599         /* Queue Import / Export features */\r
600 \r
601         /// <summary>\r
602         /// Create a batch script\r
603         /// </summary>\r
604         /// <param name="sender">\r
605         /// The sender.\r
606         /// </param>\r
607         /// <param name="e">\r
608         /// The e.\r
609         /// </param>\r
610         private void MnuBatchClick(object sender, EventArgs e)\r
611         {\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
617         }\r
618 \r
619         /// <summary>\r
620         /// Export Queue\r
621         /// </summary>\r
622         /// <param name="sender">\r
623         /// The sender.\r
624         /// </param>\r
625         /// <param name="e">\r
626         /// The e.\r
627         /// </param>\r
628         private void MnuExportClick(object sender, EventArgs e)\r
629         {\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
635         }\r
636 \r
637         /// <summary>\r
638         /// Import Queue\r
639         /// </summary>\r
640         /// <param name="sender">\r
641         /// The sender.\r
642         /// </param>\r
643         /// <param name="e">\r
644         /// The e.\r
645         /// </param>\r
646         private void MnuImportClick(object sender, EventArgs e)\r
647         {\r
648             OpenFile.FileName = string.Empty;\r
649             OpenFile.ShowDialog();\r
650             if (OpenFile.FileName != String.Empty)\r
651                 queue.LoadQueueFromFile(OpenFile.FileName);\r
652         }\r
653 \r
654         /// <summary>\r
655         /// Readd current job to queue\r
656         /// </summary>\r
657         /// <param name="sender">\r
658         /// The sender.\r
659         /// </param>\r
660         /// <param name="e">\r
661         /// The e.\r
662         /// </param>\r
663         private void MnuReaddClick(object sender, EventArgs e)\r
664         {\r
665             if (!queue.LastEncode.IsEmpty)\r
666             {\r
667                 queue.Add(\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
673             }\r
674         }\r
675 \r
676         /* Overrides */\r
677 \r
678         /// <summary>\r
679         /// Hide's the window when the user tries to "x" out of the window instead of closing it.\r
680         /// </summary>\r
681         /// <param name="e">\r
682         /// The e.\r
683         /// </param>\r
684         protected override void OnClosing(CancelEventArgs e)\r
685         {\r
686             e.Cancel = true;\r
687             this.Hide();\r
688             base.OnClosing(e);\r
689         }\r
690     }\r
691 }