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