-/* Common.cs $\r
+/* Main.cs $\r
\r
This file is part of the HandBrake source code.\r
Homepage: <http://handbrake.fr>.\r
It may be used under the terms of the GNU General Public License. */\r
\r
using System;\r
-using System.Collections;\r
using System.Windows.Forms;\r
using System.IO;\r
using System.Diagnostics;\r
using System.Text.RegularExpressions;\r
using System.Collections.Generic;\r
using System.Xml.Serialization;\r
+using System.Threading;\r
+using Handbrake.EncodeQueue;\r
+using System.Net;\r
\r
namespace Handbrake.Functions\r
{\r
- class Main\r
+ static class Main\r
{\r
// Private Variables\r
- private static XmlSerializer ser = new XmlSerializer(typeof(List<Queue.QueueItem>));\r
+ private static readonly XmlSerializer ser = new XmlSerializer(typeof(List<Job>));\r
\r
/// <summary>\r
/// Calculate the duration of the selected title and chapters\r
/// </summary>\r
- public TimeSpan calculateDuration(string chapter_start, string chapter_end, Parsing.Title selectedTitle)\r
+ public static TimeSpan calculateDuration(string chapter_start, string chapter_end, Parsing.Title selectedTitle)\r
{\r
TimeSpan Duration = TimeSpan.FromSeconds(0.0);\r
\r
// Get the durations between the 2 chapter points and add them together.\r
if (chapter_start != "Auto" && chapter_end != "Auto")\r
{\r
- int start_chapter, end_chapter = 0;\r
+ int start_chapter, end_chapter;\r
int.TryParse(chapter_start, out start_chapter);\r
int.TryParse(chapter_end, out end_chapter);\r
\r
}\r
\r
/// <summary>\r
- /// Calculate the non-anamorphic resoltuion of the source\r
- /// </summary>\r
- /// <param name="width"></param>\r
- /// <returns></returns>\r
- public int cacluateNonAnamorphicHeight(int width, decimal top, decimal bottom, decimal left, decimal right, Parsing.Title selectedTitle)\r
- {\r
- float aspect = selectedTitle.AspectRatio;\r
- int aw = 0;\r
- int ah = 0;\r
- if (aspect.ToString() == "1.78")\r
- {\r
- aw = 16;\r
- ah = 9;\r
- }\r
- else if (aspect.ToString() == "1.33")\r
- {\r
- aw = 4;\r
- ah = 3;\r
- }\r
-\r
- if (aw != 0)\r
- {\r
- double a = width * selectedTitle.Resolution.Width * ah * (selectedTitle.Resolution.Height - (double)top - (double)bottom);\r
- double b = selectedTitle.Resolution.Height * aw * (selectedTitle.Resolution.Width - (double)left - (double)right);\r
-\r
- double y = a / b;\r
-\r
- // If it's not Mod 16, make it mod 16\r
- if ((y % 16) != 0)\r
- {\r
- double mod16 = y % 16;\r
- if (mod16 >= 8)\r
- {\r
- mod16 = 16 - mod16;\r
- y = y + mod16;\r
- }\r
- else\r
- {\r
- y = y - mod16;\r
- }\r
- }\r
-\r
- //16 * (421 / 16)\r
- //double z = ( 16 * (( y + 8 ) / 16 ) );\r
- int x = int.Parse(y.ToString());\r
- return x;\r
- }\r
- return 0;\r
- }\r
-\r
- /// <summary>\r
/// Select the longest title in the DVD title dropdown menu on frmMain\r
/// </summary>\r
- public Handbrake.Parsing.Title selectLongestTitle(ComboBox drp_dvdtitle)\r
+ public static Parsing.Title selectLongestTitle(ComboBox drp_dvdtitle)\r
{\r
int current_largest = 0;\r
- Handbrake.Parsing.Title title2Select;\r
+ Parsing.Title title2Select;\r
\r
// Check if there are titles in the DVD title dropdown menu and make sure, it's not just "Automatic"\r
if (drp_dvdtitle.Items[0].ToString() != "Automatic")\r
- title2Select = (Handbrake.Parsing.Title)drp_dvdtitle.Items[0];\r
+ title2Select = (Parsing.Title)drp_dvdtitle.Items[0];\r
else\r
title2Select = null;\r
\r
// So, If there are titles in the DVD Title dropdown menu, lets select the longest.\r
if (title2Select != null)\r
{\r
- foreach (Handbrake.Parsing.Title x in drp_dvdtitle.Items)\r
+ foreach (Parsing.Title x in drp_dvdtitle.Items)\r
{\r
string title = x.ToString();\r
if (title != "Automatic")\r
/// <summary>\r
/// Set's up the DataGridView on the Chapters tab (frmMain)\r
/// </summary>\r
- /// <param name="mainWindow"></param>\r
- public DataGridView chapterNaming(DataGridView data_chpt, string chapter_start, string chapter_end)\r
+ public static DataGridView chapterNaming(DataGridView data_chpt, string chapter_end)\r
{\r
- int i = 0, rowCount = 0, start = 0, finish = 0;\r
+ int i = 0, finish = 0;\r
\r
if (chapter_end != "Auto")\r
int.TryParse(chapter_end, out finish);\r
\r
- if (chapter_start != "Auto")\r
- int.TryParse(chapter_start, out start);\r
-\r
- rowCount = finish - (start - 1);\r
-\r
- while (i < rowCount)\r
+ while (i < finish)\r
{\r
- DataGridViewRow row = new DataGridViewRow();\r
-\r
- data_chpt.Rows.Insert(i, row);\r
- data_chpt.Rows[i].Cells[0].Value = (i + 1);\r
- data_chpt.Rows[i].Cells[1].Value = "Chapter " + (i + 1);\r
+ int n = data_chpt.Rows.Add();\r
+ data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
+ data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
+ data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
+ data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
i++;\r
}\r
+\r
return data_chpt;\r
}\r
\r
/// Function which generates the filename and path automatically based on \r
/// the Source Name, DVD title and DVD Chapters\r
/// </summary>\r
- /// <param name="mainWindow"></param>\r
- public string autoName(ComboBox drp_dvdtitle, string chapter_start, string chatper_end, string source, string dest, int format)\r
+ public static string autoName(ComboBox drp_dvdtitle, string chapter_start, string chatper_end, string source, string dest, int format)\r
{\r
string AutoNamePath = string.Empty;\r
if (drp_dvdtitle.Text != "Automatic")\r
{\r
- // Get the Source Name - THIS NEEDS FIXED\r
- string[] sourceName = source.Split('\\');\r
- source = sourceName[sourceName.Length - 1].Replace(".iso", "").Replace(".mpg", "").Replace(".ts", "").Replace(".ps", "");\r
- source.Replace(".wmv", "").Replace(".mp4", "").Replace(".m4v", "").Replace(".avi", "").Replace(".ogm", "").Replace(".tivo", "").Replace(".img", "");\r
- source.Replace(".mov", "").Replace(".rm", "");\r
+ // Get the Source Name \r
+ string sourceName = Path.GetFileNameWithoutExtension(source);\r
\r
// Get the Selected Title Number\r
string[] titlesplit = drp_dvdtitle.Text.Split(' ');\r
combinedChapterTag = chapterStart + "-" + chapterFinish;\r
\r
// Get the destination filename.\r
- string destination_filename = "";\r
+ string destination_filename;\r
if (Properties.Settings.Default.autoNameFormat != "")\r
{\r
destination_filename = Properties.Settings.Default.autoNameFormat;\r
- destination_filename = destination_filename.Replace("{source}", source).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);\r
+ destination_filename = destination_filename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);\r
}\r
else\r
- destination_filename = source + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
+ destination_filename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
+\r
+ // Add the appropriate file extension\r
+ if (format == 0)\r
+ {\r
+ if (Properties.Settings.Default.useM4v)\r
+ destination_filename += ".m4v";\r
+ else\r
+ destination_filename += ".mp4";\r
+ }\r
+ else if (format == 1)\r
+ destination_filename += ".mkv";\r
\r
// Now work out the path where the file will be stored.\r
// First case: If the destination box doesn't already contain a path, make one.\r
- if (!dest.Contains("\\"))\r
+ if (!dest.Contains(Path.DirectorySeparatorChar.ToString()))\r
{\r
- string filePath = "";\r
- if (Properties.Settings.Default.autoNamePath.Trim() != "")\r
- {\r
- if (Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
- filePath = Properties.Settings.Default.autoNamePath + "\\";\r
- }\r
-\r
- if (format == 0)\r
- AutoNamePath = filePath + destination_filename + ".mp4";\r
- else if (format == 1)\r
- AutoNamePath = filePath + destination_filename + ".m4v";\r
- else if (format == 2)\r
- AutoNamePath = filePath + destination_filename + ".mkv";\r
- else if (format == 3)\r
- AutoNamePath = filePath + destination_filename + ".avi";\r
- else if (format == 4)\r
- AutoNamePath = filePath + destination_filename + ".ogm";\r
+ // If there is an auto name path, use it...\r
+ if (Properties.Settings.Default.autoNamePath.Trim() != "" && Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
+ AutoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destination_filename);\r
+ else // ...otherwise, output to the source directory\r
+ AutoNamePath = null;\r
}\r
else // Otherwise, use the path that is already there.\r
{\r
- string destination = AutoNamePath;\r
- string[] destName = dest.Split('\\');\r
- string[] extension = dest.Split('.');\r
- string ext = extension[extension.Length - 1];\r
-\r
- destName[destName.Length - 1] = destination_filename + "." + ext;\r
-\r
- string fullDest = "";\r
- foreach (string part in destName)\r
- {\r
- if (fullDest != "")\r
- fullDest = fullDest + "\\" + part;\r
- else\r
- fullDest = fullDest + part;\r
- }\r
- return fullDest;\r
+ // Use the path and change the file extension to match the previous destination\r
+ AutoNamePath = Path.Combine(Path.GetDirectoryName(dest), destination_filename);\r
+ AutoNamePath = Path.ChangeExtension(AutoNamePath, Path.GetExtension(dest));\r
}\r
}\r
\r
}\r
\r
/// <summary>\r
- /// Checks for updates and returns true if an update is available.\r
- /// </summary>\r
- /// <param name="debug">Turns on debug mode. Don't use on program startup</param>\r
- /// <returns>Boolean True = Update available</returns>\r
- public Boolean updateCheck(Boolean debug)\r
- {\r
- try\r
- {\r
- Functions.AppcastReader rssRead = new Functions.AppcastReader();\r
- rssRead.getInfo(); // Initializes the class.\r
- string build = rssRead.build();\r
-\r
- int latest = int.Parse(build);\r
- int current = Properties.Settings.Default.hb_build;\r
- int skip = Properties.Settings.Default.skipversion;\r
-\r
- if (latest == skip)\r
- return false;\r
- else\r
- {\r
- Boolean update = (latest > current);\r
- return update;\r
- }\r
- }\r
- catch (Exception exc)\r
- {\r
- if (debug == true)\r
- MessageBox.Show("Unable to check for updates, Please try again later. \n" + exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
- return false;\r
- }\r
- }\r
-\r
- /// <summary>\r
/// Get's HandBrakes version data from the CLI.\r
/// </summary>\r
/// <returns>Arraylist of Version Data. 0 = hb_version 1 = hb_build</returns>\r
- public ArrayList getCliVersionData()\r
+ public static void setCliVersionData()\r
{\r
- ArrayList cliVersionData = new ArrayList();\r
String line;\r
\r
// 0 = SVN Build / Version\r
// 1 = Build Date\r
Process cliProcess = new Process();\r
- ProcessStartInfo handBrakeCLI = new ProcessStartInfo("HandBrakeCLI.exe", " -u");\r
- handBrakeCLI.UseShellExecute = false;\r
- handBrakeCLI.RedirectStandardError = true;\r
- handBrakeCLI.RedirectStandardOutput = true;\r
- handBrakeCLI.CreateNoWindow = true;\r
+ ProcessStartInfo handBrakeCLI = new ProcessStartInfo("HandBrakeCLI.exe", " -u")\r
+ {\r
+ UseShellExecute = false,\r
+ RedirectStandardError = true,\r
+ RedirectStandardOutput = true,\r
+ CreateNoWindow = true\r
+ };\r
cliProcess.StartInfo = handBrakeCLI;\r
\r
try\r
\r
while (!cliProcess.HasExited)\r
{\r
- line = stdOutput.ReadLine();\r
- if (line == null) line = "";\r
- Match m = Regex.Match(line, @"HandBrake ([0-9\.]*)*(svn[0-9]*[M]*)* \([0-9]*\)");\r
+ line = stdOutput.ReadLine() ?? "";\r
+ Match m = Regex.Match(line, @"HandBrake ([0-9.]*)(svn[0-9M]*) \([0-9]*\)");\r
\r
- if (m.Success != false)\r
+ if (m.Success)\r
{\r
string data = line.Replace("(", "").Replace(")", "").Replace("HandBrake ", "");\r
string[] arr = data.Split(' ');\r
- cliVersionData.Add(arr[0]);\r
- cliVersionData.Add(arr[1]);\r
- return cliVersionData;\r
+\r
+ Properties.Settings.Default.hb_build = int.Parse(arr[1]);\r
+ Properties.Settings.Default.hb_version = arr[0];\r
+ }\r
+ if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.\r
+ {\r
+ Process cli = Process.GetProcessById(cliProcess.Id);\r
+ if (!cli.HasExited)\r
+ cli.Kill();\r
}\r
}\r
}\r
{\r
MessageBox.Show("Unable to retrieve version information from the CLI. \nError:\n" + e);\r
}\r
-\r
- cliVersionData.Add(0);\r
- cliVersionData.Add("0");\r
- return cliVersionData;\r
}\r
\r
/// <summary>\r
/// If it does, it means the last queue did not complete before HandBrake closed.\r
/// So, return a boolean if true. \r
/// </summary>\r
- public Boolean check_queue_recovery()\r
+ public static Boolean check_queue_recovery()\r
{\r
try\r
{\r
{\r
using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
{\r
- List<Queue.QueueItem> list = ser.Deserialize(strm) as List<Queue.QueueItem>;\r
- if (list.Count != 0)\r
- return true;\r
+ List<Job> list = ser.Deserialize(strm) as List<Job>;\r
+ if (list != null)\r
+ if (list.Count != 0)\r
+ return true;\r
}\r
}\r
return false;\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Get the Process ID of HandBrakeCLI for the current instance.\r
+ /// </summary>\r
+ /// <param name="before">List of processes before the new process was started</param>\r
+ /// <returns>Int - Process ID</returns>\r
+ public static int getCliProcess(Process[] before)\r
+ {\r
+ // This is a bit of a cludge. Maybe someone has a better idea on how to impliment this.\r
+ // Since we used CMD to start HandBrakeCLI, we don't get the process ID from hbProc.\r
+ // Instead we take the processes before and after, and get the ID of HandBrakeCLI.exe\r
+ // avoiding any previous instances of HandBrakeCLI.exe in before.\r
+ // Kill the current process.\r
+\r
+ Process[] hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
+\r
+ // Another hack. We maybe need to wait a few seconds for HandBrakeCLI to launch\r
+ if (hbProcesses.Length == 0)\r
+ {\r
+ Thread.Sleep(2000);\r
+ hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
+ }\r
+\r
+ Process hbProcess = null;\r
+ if (hbProcesses.Length > 0)\r
+ foreach (Process process in hbProcesses)\r
+ {\r
+ Boolean found = false;\r
+ // Check if the current CLI instance was running before we started the current one\r
+ foreach (Process bprocess in before)\r
+ {\r
+ if (process.Id == bprocess.Id)\r
+ found = true;\r
+ }\r
+\r
+ // If it wasn't running before, we found the process we want.\r
+ if (!found)\r
+ {\r
+ hbProcess = process;\r
+ break;\r
+ }\r
+ }\r
+ if (hbProcess != null)\r
+ return hbProcess.Id;\r
+\r
+ return -1;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Clear all the encode log files.\r
+ /// </summary>\r
+ public static void clearLogs()\r
+ {\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ if (Directory.Exists(logDir))\r
+ {\r
+ DirectoryInfo info = new DirectoryInfo(logDir);\r
+ FileInfo[] logFiles = info.GetFiles("*.txt");\r
+ foreach (FileInfo file in logFiles)\r
+ {\r
+ if (!file.Name.Contains("last_scan_log") && !file.Name.Contains("last_encode_log") && !file.Name.Contains("tmp_appReadable_log.txt"))\r
+ {\r
+ File.Delete(file.FullName);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Begins checking for an update to HandBrake.\r
+ /// </summary>\r
+ /// <param name="callback">The method that will be called when the check is finished.</param>\r
+ /// <param name="debug">Whether or not to execute this in debug mode.</param>\r
+ public static void BeginCheckForUpdates(AsyncCallback callback, bool debug)\r
+ {\r
+ ThreadPool.QueueUserWorkItem(new WaitCallback(delegate\r
+ {\r
+ try\r
+ {\r
+ // Is this a stable or unstable build?\r
+ string url = Properties.Settings.Default.hb_build.ToString().EndsWith("1") ? Properties.Settings.Default.appcast_unstable : Properties.Settings.Default.appcast;\r
+\r
+ // Initialize variables\r
+ WebRequest request = WebRequest.Create(url);\r
+ WebResponse response = request.GetResponse();\r
+ AppcastReader reader = new AppcastReader();\r
+\r
+ // Get the data, convert it to a string, and parse it into the AppcastReader\r
+ reader.getInfo(new StreamReader(response.GetResponseStream()).ReadToEnd());\r
+\r
+ // Further parse the information\r
+ string build = reader.build;\r
+\r
+ int latest = int.Parse(build);\r
+ int current = Properties.Settings.Default.hb_build;\r
+ int skip = Properties.Settings.Default.skipversion;\r
+\r
+ // If the user wanted to skip this version, don't report the update\r
+ if (latest == skip)\r
+ {\r
+ UpdateCheckInformation info = new UpdateCheckInformation() { NewVersionAvailable = false, BuildInformation = null };\r
+ callback(new UpdateCheckResult(debug, info));\r
+ return;\r
+ }\r
+\r
+ // Set when the last update was\r
+ Properties.Settings.Default.lastUpdateCheckDate = DateTime.Now;\r
+ Properties.Settings.Default.Save();\r
+\r
+ UpdateCheckInformation info2 = new UpdateCheckInformation() { NewVersionAvailable = latest > current, BuildInformation = reader };\r
+ callback(new UpdateCheckResult(debug, info2));\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ callback(new UpdateCheckResult(debug, new UpdateCheckInformation() { Error = exc }));\r
+ }\r
+ }));\r
+ }\r
+\r
+ /// <summary>\r
+ /// \r
+ /// </summary>\r
+ /// <param name="result"></param>\r
+ /// <returns></returns>\r
+ public static UpdateCheckInformation EndCheckForUpdates(IAsyncResult result)\r
+ {\r
+ UpdateCheckResult checkResult = (UpdateCheckResult)result;\r
+ return checkResult.Result;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Used in EndUpdateCheck() for update checking and the IAsyncResult design pattern.\r
+ /// </summary>\r
+ private class UpdateCheckResult : IAsyncResult\r
+ {\r
+ public UpdateCheckResult(object asyncState, UpdateCheckInformation info)\r
+ {\r
+ AsyncState = asyncState;\r
+ Result = info;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets whether the check was executed in debug mode.\r
+ /// </summary>\r
+ public object AsyncState { get; private set; }\r
+\r
+ /// <summary>\r
+ /// Gets the result of the update check.\r
+ /// </summary>\r
+ public UpdateCheckInformation Result { get; private set; }\r
+\r
+ public WaitHandle AsyncWaitHandle { get { throw new NotImplementedException(); } }\r
+ public bool CompletedSynchronously { get { throw new NotImplementedException(); } }\r
+ public bool IsCompleted { get { throw new NotImplementedException(); } }\r
+ }\r
}\r
-}
\ No newline at end of file
+}\r