mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[pollock] add automatic PO generation and update detection
* Also use Rufus application version in .loc
This commit is contained in:
		
							parent
							
								
									af9cca5fb3
								
							
						
					
					
						commit
						d9d0feadb6
					
				
					 5 changed files with 563 additions and 213 deletions
				
			
		|  | @ -12,6 +12,7 @@ skip_commits: | ||||||
|     - '**/*.cmd' |     - '**/*.cmd' | ||||||
|     - '**/*.cs' |     - '**/*.cs' | ||||||
|     - '**/*.md' |     - '**/*.md' | ||||||
|  |     - '**/*.rc' | ||||||
|     - '**/*.sh' |     - '**/*.sh' | ||||||
|     - '**/*.txt' |     - '**/*.txt' | ||||||
|     - '**/*.xml' |     - '**/*.xml' | ||||||
|  |  | ||||||
|  | @ -15,13 +15,13 @@ content. PLEASE, do not just look at this Changelog when updating your | ||||||
| translation, but always use the English section of rufus.loc as your base. | translation, but always use the English section of rufus.loc as your base. | ||||||
| For instance, MSG_114, that was introduced in v1.0.8 is MORE than one line! | For instance, MSG_114, that was introduced in v1.0.8 is MORE than one line! | ||||||
| 
 | 
 | ||||||
| o Version 1.0.24 (2018.??.??) | o v3.2 (2018.??.??) | ||||||
|   - *NEW*      MSG_087 |   - *NEW*      MSG_087 | ||||||
|   - *NEW*      MSG_172 |   - *NEW*      MSG_172 | ||||||
|   - *NEW*      MSG_199 |   - *NEW*      MSG_199 | ||||||
|   - *NEW*      MSG_306 |   - *NEW*      MSG_306 | ||||||
| 
 | 
 | ||||||
| o Version 1.0.23 (2018.03.27) | o v3.0 (2018.03.27) | ||||||
|   - All positioning ('m', 's') has now been removed as well as some controls, for the 3.0 UI redesign |   - All positioning ('m', 's') has now been removed as well as some controls, for the 3.0 UI redesign | ||||||
|   - *NEW*      IDS_DRIVE_PROPERTIES_TXT "Drive Properties" |   - *NEW*      IDS_DRIVE_PROPERTIES_TXT "Drive Properties" | ||||||
|   - *NEW*      IDS_BOOT_SELECTION_TXT "Boot selection" |   - *NEW*      IDS_BOOT_SELECTION_TXT "Boot selection" | ||||||
|  | @ -73,7 +73,7 @@ o Version 1.0.23 (2018.03.27) | ||||||
|                for the languages who did that. This means that "Save Log", "Clear Log" "Close Log" have become "Save", "Clear", "Close". |                for the languages who did that. This means that "Save Log", "Clear Log" "Close Log" have become "Save", "Clear", "Close". | ||||||
|                *PLEASE* verify that the modification looks correct in your language. |                *PLEASE* verify that the modification looks correct in your language. | ||||||
| 
 | 
 | ||||||
| o Version 1.0.22 (2017.07.17) | o v2.16 (2017.07.17) | ||||||
|   - *NEW* MSG_295 "Warning: Unofficial version" |   - *NEW* MSG_295 "Warning: Unofficial version" | ||||||
|   - *NEW* MSG_296 "This version of Rufus was NOT produced by its official developer(s).\n\nAre you sure you want to run it?" |   - *NEW* MSG_296 "This version of Rufus was NOT produced by its official developer(s).\n\nAre you sure you want to run it?" | ||||||
|   - *NEW* MSG_297 "Truncated ISO detected" |   - *NEW* MSG_297 "Truncated ISO detected" | ||||||
|  | @ -82,7 +82,7 @@ o Version 1.0.22 (2017.07.17) | ||||||
|     "official ones.\n\nNote that you can compute the MD5 or SHA in Rufus by clicking the '#' button." |     "official ones.\n\nNote that you can compute the MD5 or SHA in Rufus by clicking the '#' button." | ||||||
|   Note: You can test MSG_297/MSG_298 using https://rufus.akeo.ie/testing/arch_trunc.iso (A truncated version of archlinux-2017.07.01-x86_64.iso) |   Note: You can test MSG_297/MSG_298 using https://rufus.akeo.ie/testing/arch_trunc.iso (A truncated version of archlinux-2017.07.01-x86_64.iso) | ||||||
| 
 | 
 | ||||||
| o Version 1.0.21 (2017.01.16) | o v2.12 (2017.01.16) | ||||||
|   - *NEW* MSG_288 "Missing elevated privileges" |   - *NEW* MSG_288 "Missing elevated privileges" | ||||||
|   - *NEW* MSG_289 "This application can only run with elevated privileges" |   - *NEW* MSG_289 "This application can only run with elevated privileges" | ||||||
|     This message, along with the previous, is just to notify the user when they have |     This message, along with the previous, is just to notify the user when they have | ||||||
|  | @ -104,7 +104,7 @@ o Version 1.0.21 (2017.01.16) | ||||||
|   - *NEW* MSG_294 "This version of Windows is no longer supported by Rufus." |   - *NEW* MSG_294 "This version of Windows is no longer supported by Rufus." | ||||||
|     These two messages are not used anywhere yet, but may be needed in a future prompt. |     These two messages are not used anywhere yet, but may be needed in a future prompt. | ||||||
| 
 | 
 | ||||||
| o Version 1.0.20 (2016.05.09) | o v2.9 (2016.05.09) | ||||||
|   - *NEW* MSG_286 "Zeroing drive: %0.1f%% completed" |   - *NEW* MSG_286 "Zeroing drive: %0.1f%% completed" | ||||||
|     Used when filling a whole drive with zero bytes, to display progress in percent (e.g. "Zeroing drive: 12.3% completed") |     Used when filling a whole drive with zero bytes, to display progress in percent (e.g. "Zeroing drive: 12.3% completed") | ||||||
|     Can be tested with Alt-Z (CAUTION: THIS WILL COMPLETELY ERASE THE SELECTED DRIVE!!) |     Can be tested with Alt-Z (CAUTION: THIS WILL COMPLETELY ERASE THE SELECTED DRIVE!!) | ||||||
|  | @ -112,7 +112,7 @@ o Version 1.0.20 (2016.05.09) | ||||||
|     Note, this message is followed by either "enabled"/"disabled" (see MSG_250/251) and is similar to MSG_253 |     Note, this message is followed by either "enabled"/"disabled" (see MSG_250/251) and is similar to MSG_253 | ||||||
|     The message appears on the status bar and can be tested with Ctrl-Alt-F. |     The message appears on the status bar and can be tested with Ctrl-Alt-F. | ||||||
| 
 | 
 | ||||||
| o Version 1.0.19 (2015.10.15) | o v2.5 (2015.10.15) | ||||||
|     Note: The following message can be tested by pressing Alt-, (That's the 'Alt' and 'comma' keys on your keyboard) |     Note: The following message can be tested by pressing Alt-, (That's the 'Alt' and 'comma' keys on your keyboard) | ||||||
|           In case the message below is not clear, you can consider that it says "Exclusive locking of the USB drive" |           In case the message below is not clear, you can consider that it says "Exclusive locking of the USB drive" | ||||||
|   - *NEW* MSG_282 "Exclusive USB drive locking" |   - *NEW* MSG_282 "Exclusive USB drive locking" | ||||||
|  | @ -123,7 +123,7 @@ o Version 1.0.19 (2015.10.15) | ||||||
|   - *NEW* MSG_285 "The downloaded executable is signed by '%s'.\nThis is not a signature we recognize and could " |   - *NEW* MSG_285 "The downloaded executable is signed by '%s'.\nThis is not a signature we recognize and could " | ||||||
|                   "indicate some form of malicious activity...\nAre you sure you want to run this file?" |                   "indicate some form of malicious activity...\nAre you sure you want to run this file?" | ||||||
| 
 | 
 | ||||||
| o Version 1.0.18 (2015.09.03) | o v2.4 (2015.09.03) | ||||||
|   - Changed MSG_081 "Unsupported ISO" -> "Unsupported image" |   - Changed MSG_081 "Unsupported ISO" -> "Unsupported image" | ||||||
|   - Changed MSG_082 -> "This image is either non-bootable, or it uses a boot or compression method that is not supported by Rufus..." |   - Changed MSG_082 -> "This image is either non-bootable, or it uses a boot or compression method that is not supported by Rufus..." | ||||||
|   - *NEW* MSG_269 "Preserve timestamps" |   - *NEW* MSG_269 "Preserve timestamps" | ||||||
|  | @ -148,7 +148,7 @@ o Version 1.0.18 (2015.09.03) | ||||||
|   - *NEW* MSG_280 "Image selection" |   - *NEW* MSG_280 "Image selection" | ||||||
|   - *NEW* MSG_281 "(Please select an image)" |   - *NEW* MSG_281 "(Please select an image)" | ||||||
| 
 | 
 | ||||||
| o Version 1.0.17 (2015.02.04) | o v2.0 (2015.02.04) | ||||||
|   - *NEW CONTROL* IDC_WINDOWS_INSTALL "Standard Windows installation" (Main dialog) |   - *NEW CONTROL* IDC_WINDOWS_INSTALL "Standard Windows installation" (Main dialog) | ||||||
|   - *NEW CONTROL* IDC_WINDOWS_TO_GO "Windows To Go" (Main dialog) |   - *NEW CONTROL* IDC_WINDOWS_TO_GO "Windows To Go" (Main dialog) | ||||||
|   Note: to see the 2 controls above displayed, you will need to load the "Windows To Go.iso" image from |   Note: to see the 2 controls above displayed, you will need to load the "Windows To Go.iso" image from | ||||||
|  |  | ||||||
|  | @ -20,9 +20,12 @@ | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.ComponentModel; | using System.ComponentModel; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Globalization; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Net; | using System.Net; | ||||||
|  | using System.Net.Cache; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  | @ -58,6 +61,25 @@ namespace pollock | ||||||
|             this.group = group; |             this.group = group; | ||||||
|             this.id = id; |             this.id = id; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         public override bool Equals(object obj) | ||||||
|  |         { | ||||||
|  |             Id o = obj as Id; | ||||||
|  | 
 | ||||||
|  |             return (o.group == this.group) && (o.id == this.id); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public override int GetHashCode() | ||||||
|  |         { | ||||||
|  |             return (this.group + ":" + this.id).GetHashCode(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public override string ToString() | ||||||
|  |         { | ||||||
|  |             if (this.group == "MSG") | ||||||
|  |                 return this.id; | ||||||
|  |             return this.group + " → " + this.id; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public sealed class Language |     public sealed class Language | ||||||
|  | @ -67,20 +89,23 @@ namespace pollock | ||||||
|         public string version; |         public string version; | ||||||
|         public string lcid; |         public string lcid; | ||||||
|         public SortedDictionary<string, List<Message>> sections; |         public SortedDictionary<string, List<Message>> sections; | ||||||
|         public Dictionary<string, string> comments; |         public Dictionary<Id, string> comments; | ||||||
|  |         public Dictionary<Id, string> id_to_str; | ||||||
|         public Language() |         public Language() | ||||||
|         { |         { | ||||||
|             sections = new SortedDictionary<string, List<Message>>(); |             sections = new SortedDictionary<string, List<Message>>(); | ||||||
|             comments = new Dictionary<string, string>(); |             comments = new Dictionary<Id, string>(); | ||||||
|  |             id_to_str = new Dictionary<Id, string>(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     class Pollock |     class Pollock | ||||||
|     { |     { | ||||||
|         private static string app_name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; |         private static string app_name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Assembly.GetExecutingAssembly().GetName().Name); | ||||||
|         private static string app_version = "v" |         private static int[] version = new int[2] | ||||||
|             + Assembly.GetEntryAssembly().GetName().Version.Major.ToString() + "." |             { Assembly.GetEntryAssembly().GetName().Version.Major, Assembly.GetEntryAssembly().GetName().Version.Minor }; | ||||||
|             + Assembly.GetEntryAssembly().GetName().Version.Minor.ToString(); |         private static string version_str = "v" + version[0].ToString() + "." + version[1].ToString(); | ||||||
|  |         private static string app_path = AppDomain.CurrentDomain.BaseDirectory; | ||||||
|         private static bool cancel_requested = false; |         private static bool cancel_requested = false; | ||||||
|         private const string LANG_ID = "Language"; |         private const string LANG_ID = "Language"; | ||||||
|         private const string LANG_NAME = "X-Rufus-LanguageName"; |         private const string LANG_NAME = "X-Rufus-LanguageName"; | ||||||
|  | @ -88,35 +113,41 @@ namespace pollock | ||||||
|         private const string LANG_LCID = "X-Rufus-LCID"; |         private const string LANG_LCID = "X-Rufus-LCID"; | ||||||
|         private static Encoding encoding = new UTF8Encoding(false); |         private static Encoding encoding = new UTF8Encoding(false); | ||||||
|         private static List<string> rtl_languages = new List<string> { "ar-SA", "he-IL", "fa-IR" }; |         private static List<string> rtl_languages = new List<string> { "ar-SA", "he-IL", "fa-IR" }; | ||||||
|         private static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); |         private static Stopwatch sw = new System.Diagnostics.Stopwatch(); | ||||||
|         private static WebClient wc = new WebClient(); |         private static WebClient wc = new WebClient(); | ||||||
|  |         private static DateTime last_changed = DateTime.MinValue; | ||||||
|         private static int download_status; |         private static int download_status; | ||||||
|  |         private static int console_x_pos; | ||||||
|         private static bool in_progress = false; |         private static bool in_progress = false; | ||||||
|  |         private static bool in_on_change = false; | ||||||
|         private static double speed = 0.0f; |         private static double speed = 0.0f; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Wait for a key to be pressed. |         /// Wait for a key to be pressed. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         static void WaitForKey() |         static void WaitForKey(string msg = null) | ||||||
|         { |         { | ||||||
|  |             if (msg == null) | ||||||
|  |                 msg = "Press any key to continue..."; | ||||||
|             // Flush the input buffer |             // Flush the input buffer | ||||||
|             while (Console.KeyAvailable) |             while (Console.KeyAvailable) | ||||||
|                 Console.ReadKey(true); |                 Console.ReadKey(true); | ||||||
|             Console.WriteLine(""); |             Console.WriteLine(""); | ||||||
|             Console.WriteLine("Press any key to exit..."); |             Console.WriteLine(msg); | ||||||
|             Console.ReadKey(true); |             Console.ReadKey(true); | ||||||
|  |             while (Console.KeyAvailable) | ||||||
|  |                 Console.ReadKey(true); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Import languages from an existing rufus.loc |         /// Import languages from an existing Rufus loc file | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="path">The directy where the loc file is located.</param> |         /// <param name="file">The name of the loc file.</param> | ||||||
|  |         /// <param name="select_id">(Optional) If specified, only the language with this id, along with en-US will be returned.</param> | ||||||
|         /// <returns>A list of Language elements.</returns> |         /// <returns>A list of Language elements.</returns> | ||||||
|         static List<Language> ParseLocFile(string path, string id = null) |         static List<Language> ParseLocFile(string file, string select_id = null) | ||||||
|         { |         { | ||||||
|             var rufus_loc = path + @"\rufus.loc"; |             var lines = File.ReadAllLines(file); | ||||||
|             var rufus_pot = path + @"\rufus.pot"; |  | ||||||
|             var lines = File.ReadAllLines(rufus_loc); |  | ||||||
|             int line_nr = 0; |             int line_nr = 0; | ||||||
|             string format = "D" + (int)(Math.Log10((double)lines.Count()) + 0.99999); |             string format = "D" + (int)(Math.Log10((double)lines.Count()) + 0.99999); | ||||||
|             string last_key = null; |             string last_key = null; | ||||||
|  | @ -126,24 +157,24 @@ namespace pollock | ||||||
|             List<Language> langs = new List<Language>(); |             List<Language> langs = new List<Language>(); | ||||||
|             Language lang = null; |             Language lang = null; | ||||||
|             bool skip_line = false; |             bool skip_line = false; | ||||||
|  |             bool found_my_id = false; | ||||||
|  |             Id id; | ||||||
| 
 | 
 | ||||||
|             sw.Start(); |             if (!File.Exists(file)) | ||||||
| 
 |  | ||||||
|             if (!File.Exists(rufus_loc)) |  | ||||||
|             { |             { | ||||||
|                 Console.Error.WriteLine($"Could not open {rufus_loc}"); |                 Console.Error.WriteLine($"Could not open {file}"); | ||||||
|                 return null; |                 return null; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             Console.WriteLine($"Importing data from '{rufus_loc}':"); |             Console.Write($"Importing data from '{file}'... "); | ||||||
| 
 | 
 | ||||||
|             foreach (var line in lines) |             foreach (var line in lines) | ||||||
|             { |             { | ||||||
|                 if (cancel_requested) |                 if ((cancel_requested) || (found_my_id && skip_line)) | ||||||
|                     break; |                     break; | ||||||
|                 ++line_nr; |                 ++line_nr; | ||||||
|                 Console.SetCursorPosition(0, Console.CursorTop); |                 //Console.SetCursorPosition(0, Console.CursorTop); | ||||||
|                 Console.Write($"[{line_nr.ToString(format)}/{lines.Count()}] "); |                 //Console.Write($"[{line_nr.ToString(format)}/{lines.Count()}] "); | ||||||
|                 var data = line.Trim(); |                 var data = line.Trim(); | ||||||
|                 int i = data.IndexOf("#"); |                 int i = data.IndexOf("#"); | ||||||
|                 if (i > 0) |                 if (i > 0) | ||||||
|  | @ -171,13 +202,17 @@ namespace pollock | ||||||
|                             Console.WriteLine("Error: Invalid 'l' command"); |                             Console.WriteLine("Error: Invalid 'l' command"); | ||||||
|                             return null; |                             return null; | ||||||
|                         } |                         } | ||||||
|                         string lid = parts[1].Replace("\"", ""); |                         string cur_id = parts[1].Replace("\"", ""); | ||||||
|                         if (id != null) |                         if (select_id != null) | ||||||
|                         { |                         { | ||||||
|                             if ((!skip_line) && (id != lid) && (lid != "en-US")) |                             if ((select_id == "en-US") && (cur_id != "en-US")) | ||||||
|                                 skip_line = true; |                                 skip_line = true; | ||||||
|                             else if (skip_line && (id == lid)) |                             else if ((!skip_line) && (select_id != cur_id) && (cur_id != "en-US")) | ||||||
|  |                                 skip_line = true; | ||||||
|  |                             else if (skip_line && (select_id == cur_id)) | ||||||
|                                 skip_line = false; |                                 skip_line = false; | ||||||
|  |                             if (select_id == cur_id) | ||||||
|  |                                 found_my_id = true; | ||||||
|                             if (skip_line) |                             if (skip_line) | ||||||
|                                 break; |                                 break; | ||||||
|                         } |                         } | ||||||
|  | @ -186,7 +221,7 @@ namespace pollock | ||||||
|                         lang = new Language(); |                         lang = new Language(); | ||||||
|                         lang.id = parts[1].Replace("\"", ""); |                         lang.id = parts[1].Replace("\"", ""); | ||||||
|                         lang.name = parts[2].Replace("\"", ""); |                         lang.name = parts[2].Replace("\"", ""); | ||||||
|                         Console.WriteLine($"Found language {lang.id} '{lang.name}'"); |                         //Console.WriteLine($"Found language {lang.id} '{lang.name}'"); | ||||||
|                         lang.lcid = parts[3]; |                         lang.lcid = parts[3]; | ||||||
|                         for (i = 4; i < parts.Count; i++) |                         for (i = 4; i < parts.Count; i++) | ||||||
|                             lang.lcid += " " + parts[i]; |                             lang.lcid += " " + parts[i]; | ||||||
|  | @ -223,10 +258,14 @@ namespace pollock | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|                         lang.sections[section_name].Add(new Message(parts[1], parts[2])); |                         lang.sections[section_name].Add(new Message(parts[1], parts[2])); | ||||||
|  |                         // We also maintain global list of Id -> str for convenience | ||||||
|  |                         // TODO: This lookup BREAKS on multiline!! | ||||||
|  |                         lang.id_to_str.Add(new Id(section_name, (parts[1])), parts[2]); | ||||||
|                         last_key = parts[1]; |                         last_key = parts[1]; | ||||||
|                         if (comment != null) |                         if (comment != null) | ||||||
|                         { |                         { | ||||||
|                             lang.comments[last_key] = comment.Trim(); |                             id = new Id(section_name, last_key); | ||||||
|  |                             lang.comments[id] = comment.Trim(); | ||||||
|                             comment = null; |                             comment = null; | ||||||
|                         } |                         } | ||||||
|                         break; |                         break; | ||||||
|  | @ -238,16 +277,16 @@ namespace pollock | ||||||
|                         } |                         } | ||||||
|                         lang.sections[section_name].Last().str += data; |                         lang.sections[section_name].Last().str += data; | ||||||
|                         lang.sections[section_name].Last().str = lang.sections[section_name].Last().str.Replace("\"\"", ""); |                         lang.sections[section_name].Last().str = lang.sections[section_name].Last().str.Replace("\"\"", ""); | ||||||
|  |                         id = new Id(section_name, last_key); | ||||||
|  |                         lang.id_to_str[id] += data; | ||||||
|  |                         lang.id_to_str[id] = lang.id_to_str[id].Replace("\"\"", ""); | ||||||
|                         break; |                         break; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (lang != null) |             if (lang != null) | ||||||
|                 langs.Add(lang); |                 langs.Add(lang); | ||||||
| 
 | 
 | ||||||
|             sw.Stop(); |             Console.WriteLine(cancel_requested ? "CANCELLED" : "DONE"); | ||||||
|             Console.WriteLine($"{(cancel_requested ? "CANCELLED after" : "DONE in")}" + |  | ||||||
|                 $" {sw.ElapsedMilliseconds / 1000.0}s."); |  | ||||||
|             sw.Reset(); |  | ||||||
| 
 | 
 | ||||||
|             return langs; |             return langs; | ||||||
|         } |         } | ||||||
|  | @ -255,37 +294,67 @@ namespace pollock | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Create .po/.pot files from a list of Language elements. |         /// Create .po/.pot files from a list of Language elements. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="path">The path where the .po/.pot files should be created.</param> |         /// <param name="langs">A lits of Language objects to process.</param> | ||||||
|         /// <param name="langs">A lits of Languages elements</param> |         /// <param name="old_en_US">(Optional) A previous version of en-US to use for comparison.</param> | ||||||
|         /// <returns>true on success, false on error.</returns> |         /// <param name="path">(Optional) The path where the .po/.pot files should be created.</param> | ||||||
|         static bool CreatePoFiles(string path, List<Language> langs, bool merge_pot = false) |         /// <returns>The number of PO files created.</returns> | ||||||
|  |         static int CreatePoFiles(List<Language> langs, Language old_en_US = null, string path = null) | ||||||
|         { |         { | ||||||
|             if (langs == null) |             if (langs == null) | ||||||
|                 return false; |                 return 0; | ||||||
| 
 | 
 | ||||||
|             var en_US = langs.Find(x => x.id == "en-US"); |             var cur_en_US = langs.Find(x => x.id == "en-US"); | ||||||
|             if (en_US == null) |             if (cur_en_US == null) | ||||||
|                 return false; |                 return 0; | ||||||
| 
 | 
 | ||||||
|             var msg_to_ids = new Dictionary<string, List<Id>>(); |             if (path == null) | ||||||
|  |                 path = app_path; | ||||||
|  |             if (!path.EndsWith("\\")) | ||||||
|  |                 path += '\\'; | ||||||
| 
 | 
 | ||||||
|             // Build a dictionary of message string to List<Id> so that we can identify duplicates and remove them |             // Build the list of all the current IDs we need to process | ||||||
|             foreach (var section in en_US.sections) |             var en_ids = new List<Id>(); | ||||||
|  |             foreach (var kvp in cur_en_US.id_to_str) | ||||||
|  |                 en_ids.Add(new Id(kvp.Key.group, kvp.Key.id)); | ||||||
|  | 
 | ||||||
|  |             var added_ids = new List<Id>(); | ||||||
|  |             var modified_ids = new List<Id>(); | ||||||
|  | 
 | ||||||
|  |             if (old_en_US != null) | ||||||
|             { |             { | ||||||
|                 foreach (var msg in section.Value) |                 foreach (var id in cur_en_US.id_to_str.Keys) | ||||||
|                 { |                 { | ||||||
|                     if (msg_to_ids.ContainsKey(msg.str)) |                     if (!old_en_US.id_to_str.ContainsKey(id)) | ||||||
|                         msg_to_ids[msg.str].Add(new Id(section.Key, msg.id)); |                     { | ||||||
|                     else |                         // ID is not present in old -> added | ||||||
|                         msg_to_ids.Add(msg.str, new List<Id>() { new Id(section.Key, msg.id) }); |                         //Console.WriteLine($"ADDED: {id} = {cur_en_US.id_to_str[id]}"); | ||||||
|  |                         added_ids.Add(id); | ||||||
|  |                     } | ||||||
|  |                     else if (old_en_US.id_to_str[id] != cur_en_US.id_to_str[id]) | ||||||
|  |                     { | ||||||
|  |                         // Ignore messages where we just removed the trailing \n | ||||||
|  |                         if (!old_en_US.id_to_str[id].EndsWith("\\n\"")) | ||||||
|  |                         { | ||||||
|  |                             // ID exists in both but str has changed -> modified | ||||||
|  |                             //Console.WriteLine($"MODIFIED: {id} = {old_en_US.id_to_str[id]} → {cur_en_US.id_to_str[id]}"); | ||||||
|  |                             modified_ids.Add(id); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             int nb_po_saved = 0; | ||||||
|             foreach (var lang in langs) |             foreach (var lang in langs) | ||||||
|             { |             { | ||||||
|                 bool is_pot = (lang.id == "en-US"); |                 bool is_pot = (lang.id == "en-US"); | ||||||
|                 var target = path + @"\" + (is_pot ? "rufus.pot" : lang.id + ".po"); |                 // Don't create the .pot if we are producing a merge | ||||||
|                 Console.WriteLine($"Creating '{target}'"); |                 if (is_pot && old_en_US != null) | ||||||
|  |                     continue; | ||||||
|  |                 var target = path + (is_pot ? "rufus.pot" : lang.id + ".po"); | ||||||
|  |                 if (old_en_US != null) | ||||||
|  |                     Console.Write($"Computing differences and creating '{target}'... "); | ||||||
|  |                 else | ||||||
|  |                     Console.Write($"Creating '{target}'... "); | ||||||
| 
 | 
 | ||||||
|                 using (var writer = new StreamWriter(target, false, encoding)) |                 using (var writer = new StreamWriter(target, false, encoding)) | ||||||
|                 { |                 { | ||||||
|  | @ -311,50 +380,59 @@ namespace pollock | ||||||
| 
 | 
 | ||||||
|                     var dupes = new List<string>(); |                     var dupes = new List<string>(); | ||||||
| 
 | 
 | ||||||
|                     foreach (var section in lang.sections) |                     foreach(var id in en_ids) | ||||||
|                     { |                     { | ||||||
|                         foreach (var msg in section.Value) |                         var en_str = cur_en_US.sections[id.group].Find(x => x.id == id.id).str; | ||||||
|  |                         // Handle duplicate IDs | ||||||
|  |                         if (dupes.Contains(en_str)) | ||||||
|  |                             continue; | ||||||
|  | 
 | ||||||
|  |                         writer.WriteLine(); | ||||||
|  | 
 | ||||||
|  |                         var cid_list = cur_en_US.id_to_str.Where(x => x.Value == en_str).Select(x => x.Key); | ||||||
|  |                         foreach (var cid in cid_list) | ||||||
|  |                             writer.WriteLine($"#. • {cid}"); | ||||||
|  |                         if (cid_list.Count() > 1) | ||||||
|  |                             dupes.Add(en_str); | ||||||
|  | 
 | ||||||
|  |                         if (cur_en_US.comments.ContainsKey(id)) | ||||||
|                         { |                         { | ||||||
|                             var en_str = en_US.sections[section.Key].Find(x => x.id == msg.id).str; |                             writer.WriteLine("#."); | ||||||
| 
 |                             foreach (var comment in cur_en_US.comments[id].Split('\n')) | ||||||
|                             // Handle duplicates |                                 if (comment.Trim() != "") | ||||||
|                             if (dupes.Contains(en_str)) |                                     writer.WriteLine("#. " + comment); | ||||||
|                                 continue; |                         } | ||||||
|                             writer.WriteLine(); |                         if (!is_pot && lang.comments.ContainsKey(id)) | ||||||
|                             foreach (var id in msg_to_ids[en_str]) |                         { | ||||||
|                             { |                             foreach (var comment in lang.comments[id].Split('\n')) | ||||||
|                                 if (id.group == "MSG") |                                 if (comment.Trim() != "") | ||||||
|                                     writer.WriteLine($"#. • {id.id}"); |                                     writer.WriteLine("# " + comment); | ||||||
|                                 else |                         } | ||||||
|                                     writer.WriteLine($"#. • {id.group} → {id.id}"); |                         // Flag the new/modified messages as requiring work | ||||||
|                             } |                         if ((old_en_US != null) && (added_ids.Contains(id) || modified_ids.Contains(id))) | ||||||
|                             if (msg_to_ids[en_str].Count > 1) |                             writer.WriteLine("#, fuzzy"); | ||||||
|                                 dupes.Add(en_str); |                         string msg_str = lang.sections[id.group].Where(x => x.id == id.id).Select(x => x.str).FirstOrDefault(); | ||||||
| 
 |                         // Special case for MSG_240, which we missed in the last round | ||||||
|                             if (lang.comments.ContainsKey(msg.id)) |                         if (id.group == "MSG" && id.id == "MSG_240" && msg_str == null) | ||||||
|                             { |                             writer.WriteLine("#, fuzzy"); | ||||||
|                                 if (is_pot) |                         if (msg_str == null) | ||||||
|                                     writer.WriteLine("#."); |                             msg_str = "\"\""; | ||||||
|                                 foreach (var comment in lang.comments[msg.id].Split('\n')) |                         if (is_pot) | ||||||
|                                     if (comment.Trim() != "") |                         { | ||||||
|                                         writer.WriteLine((is_pot ? "#. " : "# ") + comment); |                             writer.WriteLine($"msgid {msg_str}"); | ||||||
|                             } |                             writer.WriteLine("msgstr \"\""); | ||||||
|                             if (is_pot) |                         } | ||||||
|                             { |                         else | ||||||
|                                 writer.WriteLine($"msgid {msg.str}"); |                         { | ||||||
|                                 writer.WriteLine("msgstr \"\""); |                             writer.WriteLine($"msgid {en_str}"); | ||||||
|                             } |                             writer.WriteLine($"msgstr {msg_str}"); | ||||||
|                             else |  | ||||||
|                             { |  | ||||||
|                                 writer.WriteLine($"msgid {en_str}"); |  | ||||||
|                                 writer.WriteLine($"msgstr {msg.str}"); |  | ||||||
|                             } |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |                 nb_po_saved++; | ||||||
|             } |             } | ||||||
|             Console.WriteLine("DONE."); |             Console.WriteLine("DONE"); | ||||||
|             return true; |             return nb_po_saved; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|  | @ -476,9 +554,9 @@ namespace pollock | ||||||
|                         { |                         { | ||||||
|                             if (comments != null) |                             if (comments != null) | ||||||
|                             { |                             { | ||||||
|                                 lang.comments.Add(id.id, ""); |                                 lang.comments.Add(id, ""); | ||||||
|                                 foreach (var comment in comments) |                                 foreach (var comment in comments) | ||||||
|                                     lang.comments[id.id] += comment + "\n"; |                                     lang.comments[id] += comment + "\n"; | ||||||
|                             } |                             } | ||||||
|                             // Ignore messages that have the same translation as en-US |                             // Ignore messages that have the same translation as en-US | ||||||
|                             if (msg_data[0] == msg_data[1]) |                             if (msg_data[0] == msg_data[1]) | ||||||
|  | @ -528,9 +606,10 @@ namespace pollock | ||||||
|                     writer.WriteLine($"g {section}"); |                     writer.WriteLine($"g {section}"); | ||||||
|                 foreach (var msg in lang.sections[section]) |                 foreach (var msg in lang.sections[section]) | ||||||
|                 { |                 { | ||||||
|                     if (lang.comments.ContainsKey(msg.id)) |                     var id = new Id(section, msg.id); | ||||||
|  |                     if (lang.comments.ContainsKey(id)) | ||||||
|                     { |                     { | ||||||
|                         foreach (var l in lang.comments[msg.id].Split('\n')) |                         foreach (var l in lang.comments[id].Split('\n')) | ||||||
|                             if (l.Trim() != "") |                             if (l.Trim() != "") | ||||||
|                                 writer.WriteLine($"# {l}"); |                                 writer.WriteLine($"# {l}"); | ||||||
|                     } |                     } | ||||||
|  | @ -540,16 +619,21 @@ namespace pollock | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Create a new rufus.loc from a list of Language elements. |         /// Update a rufus.loc section from a language element. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="path">The path where the new 'rufus.loc' should be created.</param> |         /// <param name="lang">The Language elements to update.</param> | ||||||
|         /// <param name="list">The list of Language elements.</param> |         /// <param name="path">(Optional) The path where 'rufus.loc' is located.</param> | ||||||
|         /// <returns>true on success, false on error.</returns> |         /// <returns>true on success, false on error.</returns> | ||||||
|         static bool UpdateLocFile(string path, Language lang) |         static bool UpdateLocFile(Language lang, string path = null) | ||||||
|         { |         { | ||||||
|             if (lang == null) |             if (lang == null) | ||||||
|                 return false; |                 return false; | ||||||
|             var target = path + @"\rufus.loc"; |             if (path == null) | ||||||
|  |                 path = app_path; | ||||||
|  |             if (!path.EndsWith("\\")) | ||||||
|  |                 path += '\\'; | ||||||
|  | 
 | ||||||
|  |             var target = path + "rufus.loc"; | ||||||
|             var lines = File.ReadAllLines(target); |             var lines = File.ReadAllLines(target); | ||||||
|             using (var writer = new StreamWriter(target, false, encoding)) |             using (var writer = new StreamWriter(target, false, encoding)) | ||||||
|             { |             { | ||||||
|  | @ -576,21 +660,25 @@ namespace pollock | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Create a new rufus.loc from a list of Language elements. |         /// Create a new rufus.loc from a list of Language elements. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="path">The path where the new 'rufus.loc' should be created.</param> |  | ||||||
|         /// <param name="list">The list of Language elements.</param> |         /// <param name="list">The list of Language elements.</param> | ||||||
|  |         /// <param name="path">(Optional) The path where the new 'rufus.loc' should be created.</param> | ||||||
|         /// <returns>true on success, false on error.</returns> |         /// <returns>true on success, false on error.</returns> | ||||||
|         static bool SaveLocFile(string path, List<Language> list) |         static bool SaveLocFile(List<Language> list, string path = null) | ||||||
|         { |         { | ||||||
|             if ((list == null) || (list.Count == 0)) |             if ((list == null) || (list.Count == 0)) | ||||||
|                 return false; |                 return false; | ||||||
|             var target = path + @"\rufus.loc"; |             if (path == null) | ||||||
|  |                 path = app_path; | ||||||
|  |             if (!path.EndsWith("\\")) | ||||||
|  |                 path += '\\'; | ||||||
|  |             var target = path + "rufus.loc"; | ||||||
| 
 | 
 | ||||||
|             sw.Start(); |             sw.Start(); | ||||||
| 
 | 
 | ||||||
|             Console.WriteLine($"Creating '{target}':"); |             Console.WriteLine($"Creating '{target}':"); | ||||||
|             using (var writer = new StreamWriter(target, false, encoding)) |             using (var writer = new StreamWriter(target, false, encoding)) | ||||||
|             { |             { | ||||||
|                 var notice = $"### Autogenerated by {app_name} {app_version} for use with Rufus - DO NOT EDIT!!! ###"; |                 var notice = $"### Autogenerated by {app_name} {version_str} for use with Rufus - DO NOT EDIT!!! ###"; | ||||||
|                 var sep = new String('#', notice.Length); |                 var sep = new String('#', notice.Length); | ||||||
|                 writer.WriteLine(sep); |                 writer.WriteLine(sep); | ||||||
|                 writer.WriteLine(notice); |                 writer.WriteLine(notice); | ||||||
|  | @ -620,25 +708,102 @@ namespace pollock | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         static bool DownloadFile(string url, string dest) |         /// <summary> | ||||||
|  |         /// Validate a download URL by checking its HTTP status code. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="url">The URL to validate.</param> | ||||||
|  |         /// <returns>true if URL is acessible, false on error.</returns> | ||||||
|  |         static bool ValidateDownload(string url) | ||||||
|         { |         { | ||||||
|             download_status = 0; |             HttpStatusCode status = HttpStatusCode.NotFound; | ||||||
|             in_progress = false; |             var uri = new Uri(url); | ||||||
|  |             WebRequest request = WebRequest.Create(uri); | ||||||
|  |             request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); | ||||||
|  |             request.Method = "HEAD"; | ||||||
|  | 
 | ||||||
|  |             // This is soooooooo retarded. Trying to simply read a 404 response throws a 404 *exception*?!? | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | ||||||
|  |                 status = response.StatusCode; | ||||||
|  |             } | ||||||
|  |             catch (WebException we) | ||||||
|  |             { | ||||||
|  |                 HttpWebResponse response = we.Response as HttpWebResponse; | ||||||
|  |                 status = response.StatusCode; | ||||||
|  |             } | ||||||
|  |             switch (status) | ||||||
|  |             { | ||||||
|  |                 case HttpStatusCode.OK: | ||||||
|  |                     return true; | ||||||
|  |                 default: | ||||||
|  |                     Console.WriteLine($"Error downloading {url}: {(int)status} - {status}"); | ||||||
|  |                     return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Download a file as a string. Codepage is assumed to be UTF-8. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="url">The URL to download from.</param> | ||||||
|  |         /// <returns>The downloaded string or null on error.</returns> | ||||||
|  |         static string DownloadString(string url) | ||||||
|  |         { | ||||||
|  |             string str = null; | ||||||
|  | 
 | ||||||
|  |             if (!ValidateDownload(url)) | ||||||
|  |                 return null; | ||||||
|  | 
 | ||||||
|             using (wc) |             using (wc) | ||||||
|             { |             { | ||||||
|                 wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted); |  | ||||||
|                 wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress); |  | ||||||
| 
 |  | ||||||
|                 Console.WriteLine($"Downloading {url}:"); |  | ||||||
|                 sw.Start(); |  | ||||||
| 
 |  | ||||||
|                 try |                 try | ||||||
|                 { |                 { | ||||||
|                     wc.DownloadFileAsync(new Uri(url), dest); |                     str = System.Text.Encoding.UTF8.GetString(wc.DownloadData(new Uri(url))); | ||||||
|                 } |                 } | ||||||
|                 catch (Exception e) |                 catch (Exception e) | ||||||
|                 { |                 { | ||||||
|                     Console.WriteLine("ERROR: " + e.Message); |                     Console.WriteLine("ERROR: " + e.Message); | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return str; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Download a file. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="url">The URL to download from.</param> | ||||||
|  |         /// <param name="dest">(Optional) The destination file. | ||||||
|  |         /// If not provided the file is saved in the current directory, using the last part of the URL as its name.</param> | ||||||
|  |         /// <returns>true if the download was complete, false otherwise.</returns> | ||||||
|  |         static bool DownloadFile(string url, string dest = null) | ||||||
|  |         { | ||||||
|  |             download_status = 0; | ||||||
|  |             in_progress = false; | ||||||
|  |             var uri = new Uri(url); | ||||||
|  | 
 | ||||||
|  |             if (dest == null) | ||||||
|  |                 dest = url.Split('/').Last(); | ||||||
|  | 
 | ||||||
|  |             if (!ValidateDownload(url)) | ||||||
|  |                 return false; | ||||||
|  | 
 | ||||||
|  |             console_x_pos = Console.CursorLeft; | ||||||
|  |             using (wc) | ||||||
|  |             { | ||||||
|  |                 wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); | ||||||
|  |                 wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted); | ||||||
|  |                 wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress); | ||||||
|  | 
 | ||||||
|  |                 sw.Start(); | ||||||
|  | 
 | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     wc.DownloadFileAsync(uri, dest); | ||||||
|  |                 } | ||||||
|  |                 catch (Exception e) | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine(" Error: " + e.Message); | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -647,16 +812,13 @@ namespace pollock | ||||||
| 
 | 
 | ||||||
|             Console.WriteLine(); |             Console.WriteLine(); | ||||||
|             if (download_status == 1) |             if (download_status == 1) | ||||||
|             { |  | ||||||
|                 Console.WriteLine("Download complete"); |  | ||||||
|                 return true; |                 return true; | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             Console.WriteLine("Download has been canceled."); |             Console.WriteLine($"Download has {((download_status == 2) ? "been cancelled" : "failed")}."); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // The event that will fire whenever the progress of the WebClient is changed |         // Progress event used by DownloadFile() | ||||||
|         static void DownloadProgress(object sender, DownloadProgressChangedEventArgs e) |         static void DownloadProgress(object sender, DownloadProgressChangedEventArgs e) | ||||||
|         { |         { | ||||||
|             if (cancel_requested) |             if (cancel_requested) | ||||||
|  | @ -671,23 +833,70 @@ namespace pollock | ||||||
|             in_progress = true; |             in_progress = true; | ||||||
| 
 | 
 | ||||||
|             speed = (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds); |             speed = (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds); | ||||||
|             Console.SetCursorPosition(0, Console.CursorTop); |             Console.SetCursorPosition(console_x_pos, Console.CursorTop); | ||||||
|             Console.Write($" {e.ProgressPercentage.ToString("000.0")} % ({speed.ToString("0.00")} KB/s)"); |             Console.Write($"{e.ProgressPercentage.ToString("0.0"), 5}% ({speed.ToString("0.00")} KB/s)"); | ||||||
|             in_progress = false; |             in_progress = false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // The event that will trigger when the WebClient is completed |         // Completed event used by DownloadFile() | ||||||
|         static void DownloadCompleted(object sender, AsyncCompletedEventArgs e) |         static void DownloadCompleted(object sender, AsyncCompletedEventArgs e) | ||||||
|         { |         { | ||||||
|             if (!e.Cancelled) |             Console.SetCursorPosition(console_x_pos, Console.CursorTop); | ||||||
|             { |  | ||||||
|                 Console.SetCursorPosition(0, Console.CursorTop); |  | ||||||
|                 Console.Write($" 100.0 % ({speed.ToString("0.00")} KB/s)"); |  | ||||||
|             } |  | ||||||
|             sw.Reset(); |             sw.Reset(); | ||||||
|             download_status = (e.Cancelled) ? 2 : 1; |             if (e.Error != null) | ||||||
|  |             { | ||||||
|  |                 Console.Write("Error: " + e.Error.Message); | ||||||
|  |                 download_status = 3; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.Write($"{100.0d.ToString("0.0"),5}% ({speed.ToString("0.00")} KB/s) {(e.Cancelled ? "CANCELLED" : "DONE")}"); | ||||||
|  |                 download_status = (e.Cancelled) ? 2 : 1; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Prompt a user for a Y/N question. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="question">The question string.</param> | ||||||
|  |         /// <returns>true if the user answered 'Y'.</returns> | ||||||
|  |         static bool PromptForQuestion(string question) | ||||||
|  |         { | ||||||
|  |             ConsoleKey response; | ||||||
|  |             do | ||||||
|  |             { | ||||||
|  |                 Console.Write(question + " [y/n] "); | ||||||
|  |                 console_x_pos = Console.CursorLeft - 6; | ||||||
|  |                 response = Console.ReadKey(false).Key; | ||||||
|  |                 if (response != ConsoleKey.Enter) | ||||||
|  |                     Console.WriteLine(); | ||||||
|  |             } while (response != ConsoleKey.Y && response != ConsoleKey.N); | ||||||
|  |             // Flush | ||||||
|  |             while (Console.KeyAvailable) | ||||||
|  |                 Console.ReadKey(true); | ||||||
|  |             return (response == ConsoleKey.Y); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Event handler for FileSystemWatcher. As usual, this is a completely BACKWARDS | ||||||
|  |         // implementation by Microsoft that has to be worked areoun with timers and stuff... | ||||||
|  |         private static void OnChanged(object source, FileSystemEventArgs e) | ||||||
|  |         { | ||||||
|  |             if (in_on_change) | ||||||
|  |                 return; | ||||||
|  |             in_on_change = true; | ||||||
|  |             DateTime file_changed_time = File.GetLastWriteTime(e.FullPath); | ||||||
|  |             if (file_changed_time >= last_changed.AddMilliseconds(250)) | ||||||
|  |             { | ||||||
|  |                 last_changed = file_changed_time; | ||||||
|  |                 Console.WriteLine("File " + e.FullPath + " was edited at " + file_changed_time.ToLongTimeString()); | ||||||
|  |                 UpdateLocFile(ParsePoFile(e.FullPath)); | ||||||
|  |             } | ||||||
|  |             in_on_change = false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // | ||||||
|  |         // Main entrypoint. | ||||||
|  |         // | ||||||
|         static void Main(string[] args) |         static void Main(string[] args) | ||||||
|         { |         { | ||||||
|             Console.OutputEncoding = System.Text.Encoding.UTF8; |             Console.OutputEncoding = System.Text.Encoding.UTF8; | ||||||
|  | @ -696,21 +905,92 @@ namespace pollock | ||||||
|                 cancel_requested = true; |                 cancel_requested = true; | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             Console.WriteLine($"{app_name} {app_version} - Poedit to rufus.loc conversion utility"); |             Console.WriteLine($"{app_name} {version_str} - Poedit to rufus.loc conversion utility"); | ||||||
|  |             Console.WriteLine(); | ||||||
| 
 | 
 | ||||||
|             var path = @"C:\pollock"; |             string loc_url = "https://github.com/pbatard/rufus/raw/master/res/localization/rufus.loc"; | ||||||
|             var loc = path + @"\download.loc"; |             string ver_url = "https://rufus.ie/Loc.ver"; | ||||||
|  |             string rufus_url = null; | ||||||
|  |             string rufus_file = null; | ||||||
|  |             string download_url = null; | ||||||
|  |             string po_file = null; | ||||||
|  |             int[] update_version = new int[2]; | ||||||
| 
 | 
 | ||||||
|             // Download the loc file |             // Check for updates of this application | ||||||
|             //var url = "https://github.com/pbatard/rufus/raw/master/res/localization/rufus.loc"; |             var ver = DownloadString(ver_url); | ||||||
|             //if (!DownloadFile(url, loc)) |             if (ver == null) | ||||||
|             //    goto Exit; |             { | ||||||
|  |                 Console.WriteLine("ERROR: Could not access latest application data."); | ||||||
|  |                 goto Exit; | ||||||
|  |             } | ||||||
|  |             foreach (var line in ver.Split('\n')) | ||||||
|  |             { | ||||||
|  |                 var parts = line.Split('='); | ||||||
|  |                 if (parts.Count() < 2) | ||||||
|  |                     continue; | ||||||
|  |                 switch(parts[0].Trim()) | ||||||
|  |                 { | ||||||
|  |                     case "version": | ||||||
|  |                         Int32.TryParse(parts[1].Split('.')[0], out update_version[0]); | ||||||
|  |                         Int32.TryParse(parts[1].Split('.')[1], out update_version[1]); | ||||||
|  |                         break; | ||||||
|  |                     case "download_url": | ||||||
|  |                         download_url = parts[1].Trim(); | ||||||
|  |                         break; | ||||||
|  |                     case "rufus_url": | ||||||
|  |                         rufus_url = parts[1].Trim(); | ||||||
|  |                         break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|  |             // Download new version | ||||||
|  |             if ((update_version[0] > version[0]) || ((update_version[0] == version[0]) && (update_version[1] > version[1]))) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(); | ||||||
|  |                 if (PromptForQuestion("A new version of this application is available! Do you want to download it?")) | ||||||
|  |                 { | ||||||
|  |                     if (DownloadFile(download_url)) | ||||||
|  |                     { | ||||||
|  |                         Console.WriteLine("Now re-launch this program using the latest version."); | ||||||
|  |                         goto Exit; | ||||||
|  |                     } | ||||||
|  |                     Console.WriteLine("Download failed."); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (rufus_url != null) | ||||||
|  |             { | ||||||
|  |                 // Download the latest version of Rufus to use for translations | ||||||
|  |                 rufus_file = rufus_url.Split('/').Last(); | ||||||
|  |                 Console.Write($"Checking for the presence of '{rufus_file}'... "); | ||||||
|  |                 if (File.Exists(rufus_file)) | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine("FOUND"); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     var rufus_name = rufus_url.Split('/').Last(); | ||||||
|  |                     Console.WriteLine("MISSING"); | ||||||
|  |                     Console.WriteLine($"{rufus_name} doesn't exist in your translation directory."); | ||||||
|  |                     Console.WriteLine("This is the required version to validate your changes."); | ||||||
|  |                     if (PromptForQuestion($"Do you want to download {rufus_name}?")) { | ||||||
|  |                         Console.SetCursorPosition(console_x_pos, Console.CursorTop - 1); | ||||||
|  |                         DownloadFile(rufus_url); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Download the latest loc file | ||||||
|  |             Console.Write("Downloading the latest loc file... "); | ||||||
|  |             if (!DownloadFile(loc_url)) | ||||||
|  |                 goto Exit; | ||||||
|  | 
 | ||||||
|  |             var loc_file = loc_url.Split('/').Last(); | ||||||
|             // Convert to CRLF and get all the language ids |             // Convert to CRLF and get all the language ids | ||||||
|             var lines = File.ReadAllLines(loc); |             var lines = File.ReadAllLines(loc_file); | ||||||
|             string id = "", name = ""; |             string id = "", name = ""; | ||||||
|             var list = new List<string[]>(); |             var list = new List<string[]>(); | ||||||
|             using (var writer = new StreamWriter(loc, false, encoding)) |             using (var writer = new StreamWriter(loc_file, false, encoding)) | ||||||
|             { |             { | ||||||
|                 foreach (var line in lines) |                 foreach (var line in lines) | ||||||
|                 { |                 { | ||||||
|  | @ -722,8 +1002,7 @@ namespace pollock | ||||||
|                     } |                     } | ||||||
|                     else if (line.StartsWith("v ")) |                     else if (line.StartsWith("v ")) | ||||||
|                     { |                     { | ||||||
|                         if (id != "en-US") |                         list.Add(new string[] { name, id, line.Substring(2) }); | ||||||
|                             list.Add(new string[] { name, id, line.Substring(2) }); |  | ||||||
|                     } |                     } | ||||||
|                     writer.WriteLine(line); |                     writer.WriteLine(line); | ||||||
|                 } |                 } | ||||||
|  | @ -733,21 +1012,21 @@ Menu: | ||||||
|             Console.WriteLine(); |             Console.WriteLine(); | ||||||
|             Console.WriteLine("Please enter the number of the language you want to edit or 'q' to quit:"); |             Console.WriteLine("Please enter the number of the language you want to edit or 'q' to quit:"); | ||||||
|             Console.WriteLine(); |             Console.WriteLine(); | ||||||
|             int split = (list.Count + 1) / 2; |             int split = list.Count / 2; | ||||||
|             for (int i = 0; i < split; i++) |             for (int i = 1; i < split + 1; i++) | ||||||
|             { |             { | ||||||
|                 name = $"{list[i][0]} ({list[i][1]})"; |                 name = $"{list[i][0]} ({list[i][1]})"; | ||||||
|                 Console.Write($"[{(i+1).ToString("00")}] {name,-29} (v{list[i][2]})"); |                 Console.Write($"[{i.ToString("00")}] {name,-29} {$"(v{list[i][2]})",-7}"); | ||||||
|                 name = $"{list[i + split][0]} ({list[i + split][1]})"; |                 name = $"{list[i + split][0]} ({list[i + split][1]})"; | ||||||
|                 Console.WriteLine($"  |  [{(i + 1 + split).ToString("00")}] {name,-29} (v{list[i + split][2]})"); |                 Console.WriteLine($"  |  [{(i + split).ToString("00")}] {name,-29} {$"(v{list[i + split][2]})",-7}"); | ||||||
|             } |             } | ||||||
|             Console.WriteLine(); |             Console.WriteLine(); | ||||||
| 
 | 
 | ||||||
| Retry: | Retry: | ||||||
|             string input = Console.ReadLine(); |             string input = Console.ReadLine(); | ||||||
|             if (input.StartsWith("q")) |             if ((input == null) || (input.StartsWith("q"))) | ||||||
|                 goto Exit; |                 goto Exit; | ||||||
|             if (!Int32.TryParse(input, out int number) || (number <= 0) || (number > list.Count)) |             if (!Int32.TryParse(input, out int index) || (index <= 0) || (index > list.Count)) | ||||||
|             { |             { | ||||||
|                 if (input.StartsWith("m")) |                 if (input.StartsWith("m")) | ||||||
|                     goto Menu; |                     goto Menu; | ||||||
|  | @ -755,28 +1034,98 @@ Retry: | ||||||
|                 goto Retry; |                 goto Retry; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             number--; |             Console.SetCursorPosition(0, Console.CursorTop - 1); | ||||||
|             Console.WriteLine($"{list[number][0]} was selected"); |             Console.WriteLine($"{list[index][0]} was selected."); | ||||||
|             CreatePoFiles(path, ParseLocFile(path, list[number][1])); |             Console.WriteLine(); | ||||||
|  |             po_file = $"{list[index][1]}.po"; | ||||||
| 
 | 
 | ||||||
|             // NB: Can find PoEdit from Computer\HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache |             Language old_en_US = null; | ||||||
|  |             if (list[index][2] == list[0][2]) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Note: This language is already at the most recent version!"); | ||||||
|  |                 if (!PromptForQuestion("Do you still want to edit it?")) | ||||||
|  |                     goto Exit; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 var old_loc_file = $"rufus-{list[index][2]}.loc"; | ||||||
|  |                 Console.WriteLine($"Note: This language is at v{list[index][2]} but the English base it at v{list[0][2]}."); | ||||||
|  |                 Console.Write($"Checking for the presence of '{old_loc_file}' to compute the differences... "); | ||||||
|  |                 if (File.Exists(old_loc_file)) | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine("FOUND"); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine("MISSING"); | ||||||
|  |                     Console.Write($"Downloading '{old_loc_file}'... "); | ||||||
|  |                     var url = "https://github.com/pbatard/rufus/releases/tag/v" + list[index][2]; | ||||||
|  |                     var str = DownloadString(url); | ||||||
|  |                     if (str == null) | ||||||
|  |                         goto Exit; | ||||||
|  |                     var sha = str.Substring(str.IndexOf("/pbatard/rufus/commit/") + 22, 40); | ||||||
|  |                     url = "https://github.com/pbatard/rufus/raw/" + sha + "/res/localization/rufus.loc"; | ||||||
|  |                     if (!DownloadFile(url, old_loc_file)) | ||||||
|  |                         goto Exit; | ||||||
|  |                 } | ||||||
|  |                 var old_langs = ParseLocFile(old_loc_file, "en-US"); | ||||||
|  |                 if ((old_langs == null) || (old_langs.Count != 1)) | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine("Error: Unable to get en-US data from previous loc file."); | ||||||
|  |                     goto Exit; | ||||||
|  |                 } | ||||||
|  |                 old_en_US = old_langs[0]; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             //CreatePoFiles(path, ParseLocFile(@"C:\rufus\res\localization")); |             if (CreatePoFiles(ParseLocFile(loc_file, list[index][1]), old_en_US) != 1) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Failed to create PO file"); | ||||||
|  |                 goto Exit; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             //var en_US = ParsePoFile(path + @"\rufus.pot"); |             // Watch for file modifications | ||||||
|             //var fr_FR = ParsePoFile(path + @"\fr-FR.po"); |             FileSystemWatcher watcher = new FileSystemWatcher(); | ||||||
|             //var ar_SA = ParsePoFile(path + @"\ar-SA.po"); |             watcher.Path = app_path; | ||||||
|             //var vi_VN = ParsePoFile(path + @"\vi-VN.po"); |             watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite; | ||||||
|             //List<Language> list = new List<Language>(); |             watcher.Filter = po_file; | ||||||
|             //list.Add(en_US); |             watcher.Changed += new FileSystemEventHandler(OnChanged); | ||||||
|             //list.Add(ar_SA); |             watcher.EnableRaisingEvents = true; | ||||||
|             //list.Add(fr_FR); | 
 | ||||||
|             //list.Add(vi_VN); |             // Open the file in PoEdit if we can | ||||||
|             //SaveLocFile(path, list); |             var poedit = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + @"\Poedit\Poedit.exe"; | ||||||
|             //            UpdateLocFile(path + @"\test", fr_FR); |             if (File.Exists(poedit)) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(); | ||||||
|  |                 //                Console.WriteLine("Please press any key to launch Poedit and edit the PO file."); | ||||||
|  |                 Console.WriteLine("*************************************************************************************"); | ||||||
|  |                 Console.WriteLine($"* The {list[index][0]} translation file is now ready to be edited in Poedit."); | ||||||
|  |                 Console.WriteLine("* Please look for any entries highlited in red: They are the ones requiring an update."); | ||||||
|  |                 Console.WriteLine("*"); | ||||||
|  |                 Console.WriteLine("* Whenever you save your changes in Poedit, 'rufus.loc' will be updated for testing"); | ||||||
|  |                 Console.WriteLine($"* with '{rufus_file}'. >>>PLEASE MAKE SURE YOU DON'T CLOSE THIS PROGRAM!<<<"); | ||||||
|  |                 Console.WriteLine("* When you are done editing your translation, simply close Poedit."); | ||||||
|  |                 Console.WriteLine("*************************************************************************************"); | ||||||
|  |                 WaitForKey("Press any key to launch Poedit..."); | ||||||
|  | 
 | ||||||
|  |                 Process ExternalProcess = new Process(); | ||||||
|  |                 ExternalProcess.StartInfo.FileName = poedit; | ||||||
|  |                 ExternalProcess.StartInfo.WorkingDirectory = app_path; | ||||||
|  |                 ExternalProcess.StartInfo.Arguments = $"{list[index][1]}.po"; | ||||||
|  |                 ExternalProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized; | ||||||
|  |                 ExternalProcess.Start(); | ||||||
|  |                 Console.SetCursorPosition(0, Console.CursorTop - 1); | ||||||
|  |                 Console.WriteLine("Running Poedit...                "); | ||||||
|  |                 ExternalProcess.WaitForExit(); | ||||||
|  |                 Console.WriteLine("Poedit was closed."); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Poedit was not found. You will have to launch it and open the"); | ||||||
|  |                 Console.WriteLine($"'{app_path + list[index][1]}.po' file manually."); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
| Exit: | Exit: | ||||||
|             WaitForKey(); |             WaitForKey("Press any key to exit..."); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -91,7 +91,7 @@ | ||||||
| # http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-LCID%5D.pdf | # http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-LCID%5D.pdf | ||||||
| # for the LCID (0x####) codes you should use | # for the LCID (0x####) codes you should use | ||||||
| l "en-US" "English (English)" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809 | l "en-US" "English (English)" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809 | ||||||
| v 1.0.23 | v 3.2 | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
| t IDS_DRIVE_PROPERTIES_TXT "Drive Properties" | t IDS_DRIVE_PROPERTIES_TXT "Drive Properties" | ||||||
|  | @ -571,7 +571,7 @@ t MSG_306 "Fast-zeroing drive: %0.1f%% completed" | ||||||
| 
 | 
 | ||||||
| l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001 | l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001 | ||||||
| a "r" | a "r" | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -982,7 +982,7 @@ t MSG_305 "إستخدام هذا الخيار لبيان م إذا كنت تري | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "az-AZ" "Azerbaijani (Azərbaycanca)" 0x042c, 0x782c | l "az-AZ" "Azerbaijani (Azərbaycanca)" 0x042c, 0x782c | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -1393,7 +1393,7 @@ t MSG_305 "Windows'u başqa bir diskə yükləmək üçün bu cihazı istifadə | ||||||
| 
 | 
 | ||||||
| ###################################################################### | ###################################################################### | ||||||
| l "bg-BG" "Bulgarian (Български)" 0x0402 | l "bg-BG" "Bulgarian (Български)" 0x0402 | ||||||
| v 1.0.22 | v 2.16 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -1784,7 +1784,7 @@ t MSG_118 "Windows To Go (Windows за USB Flash устройство)" | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "zh-CN" "Chinese Simplified (简体中文)" 0x0804, 0x1004 | l "zh-CN" "Chinese Simplified (简体中文)" 0x0804, 0x1004 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -2179,7 +2179,7 @@ t MSG_305 "请选择您希望将 Windows 安装至其他驱动器,还是直接 | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "zh-TW" "Chinese Traditional (正體中文)" 0x0404, 0x0c04, 0x1404, 0x7c04 | l "zh-TW" "Chinese Traditional (正體中文)" 0x0404, 0x0c04, 0x1404, 0x7c04 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -2557,7 +2557,7 @@ t MSG_305 "是否要使用此裝置來安裝 Windows 在另一個磁碟上," | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "hr-HR" "Croatian (Hrvatski)" 0x041a, 0x081a, 0x101a | l "hr-HR" "Croatian (Hrvatski)" 0x041a, 0x081a, 0x101a | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -2965,7 +2965,7 @@ t MSG_305 "Ovom opcijom naznačite ako želite koristiti ovaj uređaj kako bi in | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "cs-CZ" "Czech (Čeština)" 0x0405 | l "cs-CZ" "Czech (Čeština)" 0x0405 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -3375,7 +3375,7 @@ t MSG_305 "Touto volbou označte, zda chcete toto zařízení používat k insta | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "da-DK" "Danish (Dansk)" 0x0406 | l "da-DK" "Danish (Dansk)" 0x0406 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -3787,7 +3787,7 @@ t MSG_305 "Brug dette alternativ for at angive om du vil bruge denne enhed til a | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "nl-NL" "Dutch (Nederlands)" 0x0413, 0x0813 | l "nl-NL" "Dutch (Nederlands)" 0x0413, 0x0813 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -4190,7 +4190,7 @@ t MSG_305 "Gebruik deze optie om aan te geven of u dit apparaat wilt gebruiken o | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "fi-FI" "Finnish (Suomi)" 0x040B | l "fi-FI" "Finnish (Suomi)" 0x040B | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -4599,7 +4599,7 @@ t MSG_305 "Käytä tätä vaihtoehtoa valitaksesi haluatko käyttää valittua l | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "fr-FR" "French (Français)" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c | l "fr-FR" "French (Français)" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -5012,7 +5012,7 @@ t MSG_305 "Utilisez cette option pour indiquer si vous voulez utiliser ce périp | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "de-DE" "German (Deutsch)" 0x0407, 0x0807, 0x0c07, 0x1007, 0x1407 | l "de-DE" "German (Deutsch)" 0x0407, 0x0807, 0x0c07, 0x1007, 0x1407 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -5407,7 +5407,7 @@ t MSG_305 "Wollen Sie Windows auf einem anderen Laufwerk installieren oder Windo | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "el-GR" "Greek (Ελληνικά)" 0x0408 | l "el-GR" "Greek (Ελληνικά)" 0x0408 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -5823,7 +5823,7 @@ t MSG_305 "Επιλέξτε αυτό αν θέλετε να χρησιμοποι | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "he-IL" "Hebrew (עברית)" 0x040d | l "he-IL" "Hebrew (עברית)" 0x040d | ||||||
| a "r" | a "r" | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -6238,7 +6238,7 @@ t MSG_305 "ניתן להשתמש באפשרות זו כדי לציין האם ב | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "hu-HU" "Hungarian (Magyar)" 0x040e | l "hu-HU" "Hungarian (Magyar)" 0x040e | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -6649,7 +6649,7 @@ t MSG_305 "Ezt a lehetőséget arra használd, hogy jelezd, ezt az eszközt szer | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "id-ID" "Indonesian (Bahasa Indonesia)" 0x0421 | l "id-ID" "Indonesian (Bahasa Indonesia)" 0x0421 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -7062,7 +7062,7 @@ t MSG_305 "Gunakan opsi ini jika Anda ingin menggunakan perangkat ini untuk meng | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "it-IT" "Italian (Italiano)" 0x0410, 0x0810 | l "it-IT" "Italian (Italiano)" 0x0410, 0x0810 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -7474,7 +7474,7 @@ t MSG_305 "Usa questa opzione per indicare se vuoi usare questa unità per insta | ||||||
| 
 | 
 | ||||||
| ###################################################################### | ###################################################################### | ||||||
| l "ja-JP" "Japanese (日本語)" 0x0411 | l "ja-JP" "Japanese (日本語)" 0x0411 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -7902,7 +7902,7 @@ t MSG_305 "このデバイスを使用して別のディスクにWindowsをイ | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "ko-KR" "Korean (한국어)" 0x0412 | l "ko-KR" "Korean (한국어)" 0x0412 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -8313,7 +8313,7 @@ t MSG_305 "이 장치를 사용하여 다른 디스크에 Windows를 설치하 | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "lv-LV" "Latvian (Latviešu)" 0x0426 | l "lv-LV" "Latvian (Latviešu)" 0x0426 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -8721,7 +8721,7 @@ t MSG_305 "Izmantojiet šo opciju, lai norādīt vai vēlaties izmantot ierīci | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "lt-LT" "Lithuanian (Lietuvių)" 0x0427 | l "lt-LT" "Lithuanian (Lietuvių)" 0x0427 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -9137,7 +9137,7 @@ t MSG_305 "Šią parinktį naudokite norėdami nurodyti ar naudosite šį įreng | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "ms-MY" "Malay (Bahasa Malaysia)" 0x043e, 0x083e | l "ms-MY" "Malay (Bahasa Malaysia)" 0x043e, 0x083e | ||||||
| v 1.0.19 | v 2.5 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -9515,7 +9515,7 @@ t MSG_286 "Mensifarkan pemacu: %0.1f%% selesai" | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "nb-NO" "Norwegian (Norsk)" 0x0414 | l "nb-NO" "Norwegian (Norsk)" 0x0414 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -9929,7 +9929,7 @@ t MSG_305 "Bruk dette alternativet for å angi om du vil bruke denne enheten til | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "fa-IR" "Persian (فارسی)" 0x0429 | l "fa-IR" "Persian (فارسی)" 0x0429 | ||||||
| a "r" | a "r" | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -10358,7 +10358,7 @@ t MSG_305 "با استفاده از این گزینه مشخص کنید که آ | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "pl-PL" "Polish (Polski)" 0x0415 | l "pl-PL" "Polish (Polski)" 0x0415 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -10772,7 +10772,7 @@ t MSG_305 "Użyj tej opcji aby wskazać, czy chcesz użyć tego dysku do instala | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "pt-BR" "Portuguese Brazilian (Português do Brasil)" 0x0416 | l "pt-BR" "Portuguese Brazilian (Português do Brasil)" 0x0416 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -11194,7 +11194,7 @@ t MSG_305 "Use esta opção caso queira instalar o Windows neste dispositivo ou | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "pt-PT" "Portuguese Standard (Português)" 0x0816 | l "pt-PT" "Portuguese Standard (Português)" 0x0816 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -11611,7 +11611,7 @@ t MSG_305 "Usar esta opção se pretende utilizar este dispositivo para instalar | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "ro-RO" "Romanian (Română)" 0x0418, 0x0818 | l "ro-RO" "Romanian (Română)" 0x0418, 0x0818 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -12021,7 +12021,7 @@ t MSG_305 "Utilizaţi această opţiune dacă doriţi să utilizaţi acest dispo | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "ru-RU" "Russian (Русский)" 0x0419, 0x0819 | l "ru-RU" "Russian (Русский)" 0x0419, 0x0819 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -12426,7 +12426,7 @@ t MSG_305 "Используйте этот параметр, чтобы указ | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "sr-SP" "Serbian (Srpski)" 0x241a, 0x081a, 0x181a, 0x2c1a, 0x701a, 0x7c1a | l "sr-SP" "Serbian (Srpski)" 0x241a, 0x081a, 0x181a, 0x2c1a, 0x701a, 0x7c1a | ||||||
| v 1.0.22 | v 2.16 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -12816,7 +12816,7 @@ t MSG_117 "Standardna instalacija Windows-a" | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "sk-SK" "Slovak (Slovensky)" 0x041B | l "sk-SK" "Slovak (Slovensky)" 0x041B | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -13229,7 +13229,7 @@ t MSG_305 "Použite túto možnosť, ak chcete použiť toto zariadenie na inšt | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "sl-SI" "Slovenian (Slovenščina)" 0x0424 | l "sl-SI" "Slovenian (Slovenščina)" 0x0424 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -13640,7 +13640,7 @@ t MSG_305 "Tu izberete, ali želite uporabiti to napravo, da bi namestili operac | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "es-ES" "Spanish (Español)" 0x040a, 0x080a, 0x0c0a, 0x100a, 0x140a, 0x180a, 0x1c0a, 0x200a, 0x240a, 0x280a, 0x2c0a, 0x300a, 0x340a, 0x380a, 0x3c0a, 0x400a, 0x440a, 0x480a, 0x4c0a, 0x500a, 0x540a, 0x580a | l "es-ES" "Spanish (Español)" 0x040a, 0x080a, 0x0c0a, 0x100a, 0x140a, 0x180a, 0x1c0a, 0x200a, 0x240a, 0x280a, 0x2c0a, 0x300a, 0x340a, 0x380a, 0x3c0a, 0x400a, 0x440a, 0x480a, 0x4c0a, 0x500a, 0x540a, 0x580a | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -14056,7 +14056,7 @@ t MSG_305 "Use esta opción para indicar si desea usar este dispositivo para ins | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "sv-SE" "Swedish (Svenska)" 0x041d, 0x081d | l "sv-SE" "Swedish (Svenska)" 0x041d, 0x081d | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -14465,7 +14465,7 @@ t MSG_305 "Använd det här alternativet om du vill använda den här enheten f | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "th-TH" "Thai (ไทย)" 0x041e | l "th-TH" "Thai (ไทย)" 0x041e | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -14876,7 +14876,7 @@ t MSG_305 "เลือกตัวเลือกนี้หากต้อง | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "tr-TR" "Turkish (Türkçe)" 0x041F | l "tr-TR" "Turkish (Türkçe)" 0x041F | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -15292,7 +15292,7 @@ t MSG_305 "Windows'u başka bir diske yüklemek için bu cihazı kullanmak istey | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "uk-UA" "Ukrainian (Українська)" 0x0422 | l "uk-UA" "Ukrainian (Українська)" 0x0422 | ||||||
| v 1.0.23 | v 3.0 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  | @ -15702,7 +15702,7 @@ t MSG_305 "Використовуйте цей параметр, щоб вказ | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| l "vi-VN" "Vietnamese (Tiếng Việt)" 0x042A | l "vi-VN" "Vietnamese (Tiếng Việt)" 0x042A | ||||||
| v 1.0.22 | v 2.16 | ||||||
| b "en-US" | b "en-US" | ||||||
| 
 | 
 | ||||||
| g IDD_DIALOG | g IDD_DIALOG | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_ACCEPTFILES | EXSTYLE WS_EX_ACCEPTFILES | ||||||
| CAPTION "Rufus 3.2.1335" | CAPTION "Rufus 3.2.1336" | ||||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP |     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||||
|  | @ -392,8 +392,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,2,1335,0 |  FILEVERSION 3,2,1336,0 | ||||||
|  PRODUCTVERSION 3,2,1335,0 |  PRODUCTVERSION 3,2,1336,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -411,13 +411,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://akeo.ie" |             VALUE "Comments", "https://akeo.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.2.1335" |             VALUE "FileVersion", "3.2.1336" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.2.exe" |             VALUE "OriginalFilename", "rufus-3.2.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.2.1335" |             VALUE "ProductVersion", "3.2.1336" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue