OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / EncodeQueue / Queue.cs
1 /*  Queue.cs $\r
2         \r
3            This file is part of the HandBrake source code.\r
4            Homepage: <http://handbrake.fr/>.\r
5            It may be used under the terms of the GNU General Public License. */\r
6 \r
7 using System;\r
8 using System.Collections.Generic;\r
9 using System.Collections.ObjectModel;\r
10 using System.IO;\r
11 using System.Threading;\r
12 using System.Windows.Forms;\r
13 using System.Xml.Serialization;\r
14 using Handbrake.Functions;\r
15 \r
16 namespace Handbrake.EncodeQueue\r
17 {\r
18     public class Queue : Encode\r
19     {\r
20         private static XmlSerializer serializer;\r
21         private readonly List<Job> queue = new List<Job>();\r
22         private int NextJobId;\r
23 \r
24         /// <summary>\r
25         /// Fires when a pause to the encode queue has been requested.\r
26         /// </summary>\r
27         public event EventHandler QueuePauseRequested;\r
28 \r
29         /// <summary>\r
30         /// Fires when the entire encode queue has completed.\r
31         /// </summary>\r
32         public event EventHandler QueueCompleted;\r
33 \r
34         #region Queue\r
35         /// <summary>\r
36         /// Gets and removes the next job in the queue.\r
37         /// </summary>\r
38         /// <returns>The job that was removed from the queue.</returns>\r
39         private Job GetNextJob()\r
40         {\r
41             Job job = queue[0];\r
42             LastEncode = job;\r
43             Remove(0); // Remove the item which we are about to pass out.\r
44 \r
45             WriteQueueStateToFile("hb_queue_recovery.xml");\r
46 \r
47             return job;\r
48         }\r
49 \r
50         /// <summary>\r
51         /// Gets the current state of the encode queue.\r
52         /// </summary>\r
53         public ReadOnlyCollection<Job> CurrentQueue\r
54         {\r
55             get { return queue.AsReadOnly(); }\r
56         }\r
57 \r
58         /// <summary>\r
59         /// Gets the number of items in the queue.\r
60         /// </summary>\r
61         public int Count\r
62         {\r
63             get { return queue.Count; }\r
64         }\r
65 \r
66         /// <summary>\r
67         /// Adds an item to the queue.\r
68         /// </summary>\r
69         /// <param name="query">The query that will be passed to the HandBrake CLI.</param>\r
70         /// <param name="source">The location of the source video.</param>\r
71         /// <param name="destination">The location where the encoded video will be.</param>\r
72         /// <param name="customJob">Custom job</param>\r
73         /// <param name="scanInfo">The Scan</param>\r
74         public void Add(string query, string source, string destination, bool customJob)\r
75         {\r
76             Job newJob = new Job { Id = NextJobId++, Query = query, Source = source, Destination = destination, CustomQuery = customJob };\r
77 \r
78             queue.Add(newJob);\r
79             WriteQueueStateToFile("hb_queue_recovery.xml");\r
80         }\r
81 \r
82         /// <summary>\r
83         /// Removes an item from the queue.\r
84         /// </summary>\r
85         /// <param name="index">The zero-based location of the job in the queue.</param>\r
86         public void Remove(int index)\r
87         {\r
88             queue.RemoveAt(index);\r
89             WriteQueueStateToFile("hb_queue_recovery.xml");\r
90         }\r
91 \r
92         /// <summary>\r
93         /// Retrieve a job from the queue\r
94         /// </summary>\r
95         /// <param name="index"></param>\r
96         /// <returns></returns>\r
97         public Job GetJob(int index)\r
98         {\r
99             if (queue.Count >= (index +1))\r
100                 return queue[index];\r
101 \r
102             return new Job();\r
103         }\r
104 \r
105         /// <summary>\r
106         /// Moves an item up one position in the queue.\r
107         /// </summary>\r
108         /// <param name="index">The zero-based location of the job in the queue.</param>\r
109         public void MoveUp(int index)\r
110         {\r
111             if (index > 0)\r
112             {\r
113                 Job item = queue[index];\r
114 \r
115                 queue.RemoveAt(index);\r
116                 queue.Insert((index - 1), item);\r
117             }\r
118 \r
119             WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file\r
120         }\r
121 \r
122         /// <summary>\r
123         /// Moves an item down one position in the queue.\r
124         /// </summary>\r
125         /// <param name="index">The zero-based location of the job in the queue.</param>\r
126         public void MoveDown(int index)\r
127         {\r
128             if (index < queue.Count - 1)\r
129             {\r
130                 Job item = queue[index];\r
131 \r
132                 queue.RemoveAt(index);\r
133                 queue.Insert((index + 1), item);\r
134             }\r
135 \r
136             WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file\r
137         }\r
138 \r
139         /// <summary>\r
140         /// Writes the current state of the queue to a file.\r
141         /// </summary>\r
142         /// <param name="file">The location of the file to write the queue to.</param>\r
143         public void WriteQueueStateToFile(string file)\r
144         {\r
145             string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\hb_queue_recovery.xml");\r
146             string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;\r
147 \r
148             try\r
149             {\r
150                 using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))\r
151                 {\r
152                     if (serializer == null)\r
153                         serializer = new XmlSerializer(typeof(List<Job>));\r
154                     serializer.Serialize(strm, queue);\r
155                     strm.Close();\r
156                     strm.Dispose();\r
157                 }\r
158             }\r
159             catch (Exception)\r
160             {\r
161                 return;\r
162             }\r
163         }\r
164 \r
165         /// <summary>\r
166         /// Writes the current state of the queue in the form of a batch (.bat) file.\r
167         /// </summary>\r
168         /// <param name="file">The location of the file to write the batch file to.</param>\r
169         public void WriteBatchScriptToFile(string file)\r
170         {\r
171             string queries = "";\r
172             foreach (Job queue_item in queue)\r
173             {\r
174                 string q_item = queue_item.Query;\r
175                 string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item;\r
176 \r
177                 if (queries == string.Empty)\r
178                     queries = queries + fullQuery;\r
179                 else\r
180                     queries = queries + " && " + fullQuery;\r
181             }\r
182             string strCmdLine = queries;\r
183 \r
184             if (file != "")\r
185             {\r
186                 try\r
187                 {\r
188                     // Create a StreamWriter and open the file, Write the batch file query to the file and \r
189                     // Close the stream\r
190                     using (StreamWriter line = new StreamWriter(file))\r
191                     {\r
192                         line.WriteLine(strCmdLine);\r
193                     }\r
194 \r
195                     MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\r
196                 }\r
197                 catch (Exception)\r
198                 {\r
199                     MessageBox.Show("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
200                 }\r
201 \r
202             }\r
203         }\r
204 \r
205         /// <summary>\r
206         /// Reads a serialized XML file that represents a queue of encoding jobs.\r
207         /// </summary>\r
208         /// <param name="file">The location of the file to read the queue from.</param>\r
209         public void LoadQueueFromFile(string file)\r
210         {\r
211             string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\hb_queue_recovery.xml");\r
212             string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file;\r
213 \r
214             if (File.Exists(tempPath))\r
215             {\r
216                 using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
217                 {\r
218                     if (strm.Length != 0)\r
219                     {\r
220                         if (serializer == null)\r
221                             serializer = new XmlSerializer(typeof(List<Job>));\r
222 \r
223                         List<Job> list = serializer.Deserialize(strm) as List<Job>;\r
224 \r
225                         if (list != null)\r
226                             foreach (Job item in list)\r
227                                 queue.Add(item);\r
228 \r
229                         if (file != "hb_queue_recovery.xml")\r
230                             WriteQueueStateToFile("hb_queue_recovery.xml");\r
231                     }\r
232                 }\r
233             }\r
234         }\r
235 \r
236         /// <summary>\r
237         /// Checks the current queue for an existing instance of the specified destination.\r
238         /// </summary>\r
239         /// <param name="destination">The destination of the encode.</param>\r
240         /// <returns>Whether or not the supplied destination is already in the queue.</returns>\r
241         public bool CheckForDestinationDuplicate(string destination)\r
242         {\r
243             foreach (Job checkItem in queue)\r
244             {\r
245                 if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))\r
246                     return true;\r
247             }\r
248 \r
249             return false;\r
250         }\r
251 \r
252         #endregion\r
253 \r
254         #region Encoding\r
255 \r
256         /// <summary>\r
257         /// Gets the last encode that was processed.\r
258         /// </summary>\r
259         /// <returns></returns> \r
260         public Job LastEncode { get; set; }\r
261 \r
262         /// <summary>\r
263         /// Request Pause\r
264         /// </summary>\r
265         public Boolean PauseRequested { get; private set; }\r
266 \r
267         /// <summary>\r
268         /// Starts encoding the first job in the queue and continues encoding until all jobs\r
269         /// have been encoded.\r
270         /// </summary>\r
271         public void Start()\r
272         {\r
273             if (this.Count != 0)\r
274             {\r
275                 if (PauseRequested)\r
276                     PauseRequested = false;\r
277                 else\r
278                 {\r
279                     PauseRequested = false;\r
280                     try\r
281                     {\r
282                         Thread theQueue = new Thread(StartQueue) { IsBackground = true };\r
283                         theQueue.Start();\r
284                     }\r
285                     catch (Exception exc)\r
286                     {\r
287                         MessageBox.Show(exc.ToString());\r
288                     }\r
289                 }\r
290             }\r
291         }\r
292 \r
293         /// <summary>\r
294         /// Requests a pause of the encode queue.\r
295         /// </summary>\r
296         public void Pause()\r
297         {\r
298             PauseRequested = true;\r
299 \r
300             if (QueuePauseRequested != null)\r
301                 QueuePauseRequested(this, new EventArgs());\r
302         }\r
303 \r
304         /// <summary>\r
305         /// Run through all the jobs on the queue.\r
306         /// </summary>\r
307         /// <param name="state"></param>\r
308         private void StartQueue(object state)\r
309         {\r
310             // Run through each item on the queue\r
311             while (this.Count != 0)\r
312             {\r
313                 Job encJob = GetNextJob();\r
314                 string query = encJob.Query;\r
315                 WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file\r
316 \r
317                 Run(query);\r
318 \r
319                 HbProcess.WaitForExit();\r
320 \r
321                 AddCLIQueryToLog(encJob);\r
322                 CopyLog(LastEncode.Destination);\r
323 \r
324                 HbProcess.Close();\r
325                 HbProcess.Dispose();\r
326 \r
327                 IsEncoding = false;\r
328 \r
329                 //Growl\r
330                 if (Properties.Settings.Default.growlEncode)\r
331                     GrowlCommunicator.Notify("Encode Completed", "Put down that cocktail...\nyour Handbrake encode is done.");\r
332 \r
333                 while (PauseRequested) // Need to find a better way of doing this.\r
334                 {\r
335                     Thread.Sleep(2000);\r
336                 }\r
337             }\r
338             LastEncode = new Job();\r
339 \r
340             if (QueueCompleted != null)\r
341                 QueueCompleted(this, new EventArgs());\r
342 \r
343             // After the encode is done, we may want to shutdown, suspend etc.\r
344             Finish();\r
345         }\r
346 \r
347         #endregion\r
348     }\r
349 }