OSDN Git Service

LinGui: make Help->Guide work on windows/mingw
[handbrake-jp/handbrake-jp-git.git] / win / C# / Presets / PresetsHandler.cs
1 /*  PresetHandler.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.Presets\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.Diagnostics;\r
11     using System.Drawing;\r
12     using System.IO;\r
13     using System.Linq;\r
14     using System.Text.RegularExpressions;\r
15     using System.Windows.Forms;\r
16     using System.Xml.Serialization;\r
17 \r
18     /// <summary>\r
19     /// The Preset Handler Class\r
20     /// </summary>\r
21     public class PresetsHandler\r
22     {\r
23         /// <summary>\r
24         /// The User Preset file\r
25         /// </summary>\r
26         private readonly string userPresetFile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\user_presets.xml";\r
27 \r
28         /// <summary>\r
29         /// The Built In Presets File\r
30         /// </summary>\r
31         private readonly string hbPresetFile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\presets.xml";\r
32 \r
33         /// <summary>\r
34         /// XML Serializer\r
35         /// </summary>\r
36         private static readonly XmlSerializer Ser = new XmlSerializer(typeof(List<Preset>));\r
37 \r
38         /// <summary>\r
39         /// A List of built-in presets\r
40         /// </summary>\r
41         private List<Preset> presets = new List<Preset>();\r
42 \r
43         /// <summary>\r
44         /// A List of user presets\r
45         /// </summary>\r
46         private List<Preset> userPresets = new List<Preset>();\r
47 \r
48         /// <summary>\r
49         /// Add a new preset to the system\r
50         /// </summary>\r
51         /// <param name="presetName">\r
52         /// String, The name of the new preset\r
53         /// </param>\r
54         /// <param name="query">\r
55         /// String, the CLI query for the new preset\r
56         /// </param>\r
57         /// <param name="pictureSettings">\r
58         /// Bool, store crop/picture sizes in the Presets\r
59         /// </param>\r
60         /// <returns>\r
61         /// The add.\r
62         /// </returns>\r
63         public bool Add(string presetName, string query, bool pictureSettings)\r
64         {\r
65             if (this.CheckIfPresetExists(presetName) == false)\r
66             {\r
67                 Preset newPreset = new Preset\r
68                                        {\r
69                                            Name = presetName, \r
70                                            Query = query, \r
71                                            PictureSettings = pictureSettings, \r
72                                            Version = Properties.Settings.Default.hb_version\r
73                                        };\r
74                 this.userPresets.Add(newPreset);\r
75                 this.UpdatePresetFiles();\r
76                 return true;\r
77             }\r
78             return false;\r
79         }\r
80 \r
81         /// <summary>\r
82         /// Remove a preset with a given name from either the built in or user preset list.\r
83         /// </summary>\r
84         /// <param name="name">String, the preset name</param>\r
85         public void Remove(string name)\r
86         {\r
87             List<Preset> newPresets = new List<Preset>();\r
88             List<Preset> newUserPresets = new List<Preset>();\r
89 \r
90             // Built In Presets\r
91             foreach (Preset item in this.presets)\r
92             {\r
93                 if (item.Name != name)\r
94                 {\r
95                     newPresets.Add(item);\r
96                 }\r
97             }\r
98             this.presets = newPresets;\r
99 \r
100             // User Presets\r
101             foreach (Preset item in this.userPresets)\r
102             {\r
103                 if (item.Name != name)\r
104                 {\r
105                     newUserPresets.Add(item);\r
106                 }\r
107             }\r
108             this.userPresets = newUserPresets;\r
109 \r
110             // Rebuild the UserPresets.xml file\r
111             this.UpdatePresetFiles();\r
112             this.UpdatePresetFiles();\r
113         }\r
114 \r
115         /// <summary>\r
116         /// Remove all built in Presets;\r
117         /// </summary>\r
118         public void RemoveBuiltInPresets()\r
119         {\r
120             this.presets.Clear();\r
121             this.UpdatePresetFiles();\r
122         }\r
123 \r
124         /// <summary>\r
125         /// Save changes to a given preset in the user preset list.\r
126         /// </summary>\r
127         /// <param name="presetName">String, The name of the new preset</param>\r
128         /// <param name="query">String, the CLI query for the new preset</param>\r
129         /// <param name="pictureSettings"> Bool, store crop/picture sizes in the preset</param>\r
130         public void Update(string presetName, string query, bool pictureSettings)\r
131         {\r
132             // User Presets\r
133             foreach (Preset item in this.userPresets)\r
134             {\r
135                 if (item.Name == presetName)\r
136                 {\r
137                     item.Query = query;\r
138                     item.PictureSettings = pictureSettings;\r
139                     MessageBox.Show(\r
140                         "Changes to \"" + presetName + "\" Saved",\r
141                                     "Success",\r
142                                     MessageBoxButtons.OK, \r
143                                     MessageBoxIcon.Information);\r
144                     this.UpdatePresetFiles();\r
145                 }\r
146             }\r
147         }\r
148 \r
149         /// <summary>\r
150         /// Return the CLI query for a preset name given in name\r
151         /// </summary>\r
152         /// <param name="name">String, The preset's name</param>\r
153         /// <returns>String, the CLI query for the given preset name</returns>    not\r
154         public Preset GetPreset(string name)\r
155         {\r
156             // Built In Presets\r
157             foreach (Preset item in this.presets)\r
158             {\r
159                 if (item.Name == name)\r
160                     return item;\r
161             }\r
162 \r
163             // User Presets\r
164             return this.userPresets.FirstOrDefault(item => item.Name == name);\r
165         }\r
166 \r
167         /// <summary>\r
168         /// Reads the CLI's CLI output format and load's them into the preset List Preset\r
169         /// </summary>\r
170         public void UpdateBuiltInPresets()\r
171         {\r
172             // Create a new tempory file and execute the CLI to get the built in Presets.\r
173             string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
174             string presetsPath = Path.Combine(Path.GetTempPath(), "temp_presets.dat");\r
175             string strCmdLine = String.Format(@"cmd /c """"{0}"" --preset-list >""{1}"" 2>&1""", handbrakeCLIPath, presetsPath);\r
176 \r
177             ProcessStartInfo hbGetPresets = new ProcessStartInfo("CMD.exe", strCmdLine)\r
178                                                 {\r
179                                                    WindowStyle = ProcessWindowStyle.Hidden\r
180                                                 };\r
181             Process hbproc = Process.Start(hbGetPresets);\r
182             if (hbproc != null)\r
183             {\r
184                 hbproc.WaitForExit();\r
185                 hbproc.Dispose();\r
186                 hbproc.Close();\r
187             }\r
188 \r
189             // Clear the current built in Presets and now parse the tempory Presets file.\r
190             this.presets.Clear();\r
191 \r
192             if (File.Exists(presetsPath))\r
193             {\r
194                 StreamReader presetInput = new StreamReader(presetsPath);\r
195 \r
196                 string category = String.Empty;\r
197 \r
198                 while (!presetInput.EndOfStream)\r
199                 {\r
200                     string line = presetInput.ReadLine();\r
201                     if (line.Contains("<") && !line.Contains("<<")) // Found the beginning of a preset block \r
202                         category = line.Replace("<", string.Empty).Trim();\r
203 \r
204                     if (line.Contains("+")) // A Preset\r
205                     {\r
206                         Regex r = new Regex("(:  )"); // Split on hyphens. \r
207                         string[] presetName = r.Split(line);\r
208 \r
209                         bool pic = false;\r
210                         if (presetName[2].Contains("crop"))\r
211                             pic = true;\r
212 \r
213                         Preset newPreset = new Preset\r
214                                                {\r
215                                                    Category = category, \r
216                                                    Name = presetName[0].Replace("+", string.Empty).Trim(), \r
217                                                    Query = presetName[2], \r
218                                                    Version = Properties.Settings.Default.hb_version, \r
219                                                    PictureSettings = pic\r
220                                                };\r
221                         this.presets.Add(newPreset);\r
222                     }\r
223                 }\r
224                 presetInput.Close();\r
225                 presetInput.Dispose();\r
226             }\r
227 \r
228             // Finally, Create a new or update the current Presets.xml file\r
229             this.UpdatePresetFiles();\r
230         }\r
231 \r
232         /// <summary>\r
233         /// Setup the frmMain preset panel\r
234         /// </summary>\r
235         /// <param name="presetPanel">The Preset Panel from the Main Window</param>\r
236         public void GetPresetPanel(ref TreeView presetPanel)\r
237         {\r
238             this.LoadPresetData();\r
239             presetPanel.Nodes.Clear();\r
240             string category = string.Empty;\r
241             TreeNode rootNode = null;\r
242 \r
243             if (this.presets.Count != 0) // Built In Presets\r
244             {\r
245                 foreach (Preset preset in this.presets)\r
246                 {\r
247                     if (preset.Category != category)\r
248                     {\r
249                         rootNode = new TreeNode(preset.Category);\r
250                         presetPanel.Nodes.Add(rootNode);\r
251                         category = preset.Category;\r
252                     }\r
253 \r
254                     if (preset.Category == category && rootNode != null)\r
255                         rootNode.Nodes.Add(preset.Name);\r
256                 }\r
257             }\r
258 \r
259             rootNode = null;\r
260             category = null;\r
261             foreach (Preset preset in this.userPresets) // User Presets\r
262             {\r
263                 if (preset.Category != category && preset.Category != string.Empty)\r
264                 {\r
265                     rootNode = new TreeNode(preset.Category) {ForeColor = Color.Black};\r
266                     presetPanel.Nodes.Add(rootNode);\r
267                     category = preset.Category;\r
268                 }\r
269 \r
270                 if (preset.Category == category && rootNode != null)\r
271                     rootNode.Nodes.Add(new TreeNode(preset.Name) {ForeColor = Color.Black});\r
272                 else\r
273                     presetPanel.Nodes.Add(new TreeNode(preset.Name) {ForeColor = Color.Black});\r
274             }\r
275         }\r
276 \r
277         /// <summary>\r
278         /// Check if the user preset "name" exists in UserPresets list.\r
279         /// </summary>\r
280         /// <param name="name">Name of the preset</param>\r
281         /// <returns>true if found</returns>\r
282         public bool CheckIfUserPresetExists(string name)\r
283         {\r
284             return name != string.Empty && this.userPresets.Any(item => item.Name == name);\r
285         }\r
286 \r
287         /// <summary>\r
288         /// Check if the built in Presets stored are not out of date.\r
289         /// Update them if they are.\r
290         /// </summary>\r
291         /// <returns>true if out of date</returns>\r
292         public bool CheckIfPresetsAreOutOfDate()\r
293         {\r
294             this.LoadPresetData();\r
295             // Update built-in Presets if the built-in Presets belong to an older version.\r
296             if (this.presets.Count != 0)\r
297                 if (this.presets[0].Version != Properties.Settings.Default.hb_version)\r
298                 {\r
299                     this.UpdateBuiltInPresets();\r
300                     return true;\r
301                 }\r
302 \r
303             return false;\r
304         }\r
305 \r
306         /// <summary>\r
307         /// Load in the preset data from Presets.xml and UserPresets.xml\r
308         /// Load it into the 2 arraylist's Presets and UserPresets\r
309         /// </summary>\r
310         private void LoadPresetData()\r
311         {\r
312             // First clear the Presets arraylists\r
313             this.presets.Clear();\r
314             this.userPresets.Clear();\r
315 \r
316             try\r
317             {\r
318                 // Load in the users Presets from UserPresets.xml\r
319                 if (File.Exists(this.hbPresetFile))\r
320                 {\r
321                     using (FileStream strm = new FileStream(this.hbPresetFile, FileMode.Open, FileAccess.Read))\r
322                     {\r
323                         if (strm.Length != 0)\r
324                         {\r
325                             List<Preset> list = Ser.Deserialize(strm) as List<Preset>;\r
326 \r
327                             if (list != null)\r
328                                 foreach (Preset preset in list)\r
329                                     this.presets.Add(preset);\r
330                         }\r
331                     }\r
332                 }\r
333             }\r
334             catch (Exception)\r
335             {\r
336                 MessageBox.Show(\r
337                     "HandBrakes preset file appears to have been corrupted. This file will now be re-generated!\n" +\r
338                     "If the problem presists, please delete the file: \n\n" + this.hbPresetFile, \r
339                     "Error",\r
340                     MessageBoxButtons.OK, \r
341                     MessageBoxIcon.Error);\r
342                 this.UpdateBuiltInPresets();\r
343             }\r
344 \r
345             try\r
346             {\r
347                 // Load in the users Presets from UserPresets.xml\r
348                 if (File.Exists(this.userPresetFile))\r
349                 {\r
350                     using (FileStream strm = new FileStream(this.userPresetFile, FileMode.Open, FileAccess.Read))\r
351                     {\r
352                         if (strm.Length != 0)\r
353                         {\r
354                             List<Preset> list = Ser.Deserialize(strm) as List<Preset>;\r
355 \r
356                             if (list != null)\r
357                                 foreach (Preset preset in list)\r
358                                     this.userPresets.Add(preset);\r
359                         }\r
360                     }\r
361                 }\r
362             }\r
363             catch (Exception)\r
364             {\r
365                 MessageBox.Show(\r
366                     "Your User presets file appears to have been corrupted.\n" +\r
367                     "Your presets will not be loaded. You may need to re-create your presets.\n\n" +\r
368                     "Your user presets file has been renamed to 'user_presets.xml.old' and is located in:\n " +\r
369                     Path.GetDirectoryName(this.userPresetFile) + "\n" + \r
370                     "You may be able to recover some presets if you know the XML language.", \r
371                     "Error",\r
372                     MessageBoxButtons.OK, \r
373                     MessageBoxIcon.Error);\r
374 \r
375                 // Recover from Error.\r
376                 if (File.Exists(this.userPresetFile))\r
377                 {\r
378                     string disabledFile = this.userPresetFile + ".old";\r
379                     if (File.Exists(disabledFile))\r
380                         File.Delete(disabledFile);\r
381                     File.Move(this.userPresetFile, disabledFile);\r
382                 }\r
383             }\r
384         }\r
385 \r
386         /// <summary>\r
387         /// Update the preset files\r
388         /// </summary>\r
389         private void UpdatePresetFiles()\r
390         {\r
391             try\r
392             {\r
393                 using (FileStream strm = new FileStream(this.hbPresetFile, FileMode.Create, FileAccess.Write))\r
394                 {\r
395                     Ser.Serialize(strm, this.presets);\r
396                     strm.Close();\r
397                     strm.Dispose();\r
398                 }\r
399 \r
400                 using (FileStream strm = new FileStream(this.userPresetFile, FileMode.Create, FileAccess.Write))\r
401                 {\r
402                     Ser.Serialize(strm, this.userPresets);\r
403                     strm.Close();\r
404                     strm.Dispose();\r
405                 }\r
406             }\r
407             catch (Exception exc)\r
408             {\r
409                 MessageBox.Show(\r
410                     "Unable to write to the file. Please make sure the location has the correct permissions for file writing.\n Error Information: \n\n" +\r
411                     exc, \r
412                     "Error", \r
413                     MessageBoxButtons.OK, \r
414                     MessageBoxIcon.Hand);\r
415             }\r
416         }\r
417 \r
418         /// <summary>\r
419         /// Check if the preset "name" exists in either Presets or UserPresets lists.\r
420         /// </summary>\r
421         /// <param name="name">Name of the preset</param>\r
422         /// <returns>True if found</returns>\r
423         private bool CheckIfPresetExists(string name)\r
424         {\r
425             if (name == string.Empty)\r
426                 return true;\r
427 \r
428             // Built In Presets\r
429             foreach (Preset item in this.presets)\r
430             {\r
431                 if (item.Name == name)\r
432                     return true;\r
433             }\r
434 \r
435             // User Presets\r
436             return this.userPresets.Any(item => item.Name == name);\r
437         }\r
438     }\r
439 }