From 77b973ef7bb34af0c46a84242b588bedde79e301 Mon Sep 17 00:00:00 2001 From: Paddy Xu Date: Fri, 14 Jul 2017 22:25:44 +0300 Subject: [PATCH] Add English and Chinese translations --- .../QuickLook.Plugin.TextViewer/Plugin.cs | 2 +- .../QuickLook.Plugin.TextViewer.csproj | 6 ++ .../TextViewerPanel.xaml | 3 +- .../TextViewerPanel.xaml.cs | 9 ++- .../Translations.lang | 13 ++++ QuickLook/App.xaml.cs | 7 +- QuickLook/Helpers/AutoStartupHelper.cs | 14 ++-- QuickLook/Helpers/TranslationHelper.cs | 67 +++++++++++++++++++ QuickLook/Helpers/Updater.cs | 6 +- QuickLook/MainWindowTransparent.xaml | 3 +- QuickLook/MainWindowTransparent.xaml.cs | 14 ++-- QuickLook/Plugin/ContextObject.cs | 9 +++ QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs | 21 ++++-- QuickLook/QuickLook.csproj | 9 +++ QuickLook/Translations.lang | 46 +++++++++++++ QuickLook/TrayIconManager.cs | 23 ++++--- 16 files changed, 215 insertions(+), 37 deletions(-) create mode 100644 QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.lang create mode 100644 QuickLook/Helpers/TranslationHelper.cs create mode 100644 QuickLook/Translations.lang diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.cs index bb99587..ab2f4f7 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.cs @@ -70,7 +70,7 @@ namespace QuickLook.Plugin.TextViewer public void View(string path, ContextObject context) { - _tvp = new TextViewerPanel(path); + _tvp = new TextViewerPanel(path, context); context.ViewerContent = _tvp; context.Title = $"{Path.GetFileName(path)}"; diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/QuickLook.Plugin.TextViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/QuickLook.Plugin.TextViewer.csproj index 19a887a..1dd3c04 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/QuickLook.Plugin.TextViewer.csproj +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/QuickLook.Plugin.TextViewer.csproj @@ -90,5 +90,11 @@ + + + Designer + PreserveNewest + + \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml index 561ae0e..b25ce2b 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml @@ -10,8 +10,7 @@ d:DesignWidth="448.79" UseLayoutRounding="True"> - \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml.cs index b2baaff..5a24b55 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.xaml.cs @@ -16,8 +16,10 @@ // along with this program. If not, see . using System.IO; +using System.Reflection; using System.Text; using System.Windows.Controls; +using System.Windows.Media; using ICSharpCode.AvalonEdit.Highlighting; using QuickLook.Plugin.TextViewer.SimpleHelpers; @@ -28,10 +30,15 @@ namespace QuickLook.Plugin.TextViewer /// public partial class TextViewerPanel : UserControl { - public TextViewerPanel(string path) + public TextViewerPanel(string path, ContextObject context) { InitializeComponent(); + viewer.FontFamily = + new FontFamily(context.GetString( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Translations.lang"), + "Editor_FontFamily", failsafe: "Consolas")); + LoadFile(path); } diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.lang b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.lang new file mode 100644 index 0000000..b3901ce --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.lang @@ -0,0 +1,13 @@ + + + + + Consolas + + + Consolas,Microsoft Yahei UI,Microsoft Yahei,SimSun + + + Consolas,Meiryo UI,MS UI Gothic,MS Gothic + + \ No newline at end of file diff --git a/QuickLook/App.xaml.cs b/QuickLook/App.xaml.cs index 967ed15..44591af 100644 --- a/QuickLook/App.xaml.cs +++ b/QuickLook/App.xaml.cs @@ -36,6 +36,8 @@ namespace QuickLook public static readonly string AppFullPath = Assembly.GetExecutingAssembly().Location; public static readonly string AppPath = Path.GetDirectoryName(AppFullPath); + internal static readonly string Translations = Path.Combine(AppPath, @"Translations.lang"); + private bool _isFirstInstance; private Mutex _isRunning; @@ -62,7 +64,7 @@ namespace QuickLook RemoteCallShowPreview(e); // second instance: duplicate else - MessageBox.Show("QuickLook is already running in the background."); + MessageBox.Show(TranslationHelper.GetString(Translations, "APP_SECOND")); Shutdown(); return; @@ -84,7 +86,8 @@ namespace QuickLook { TrayIconManager.GetInstance(); if (!e.Args.Contains("/autorun") && !IsUWP) - TrayIconManager.GetInstance().ShowNotification("", "QuickLook is running in the background."); + TrayIconManager.GetInstance() + .ShowNotification("", TranslationHelper.GetString(Translations, "APP_START")); if (e.Args.Contains("/first")) AutoStartupHelper.CreateAutorunShortcut(); diff --git a/QuickLook/Helpers/AutoStartupHelper.cs b/QuickLook/Helpers/AutoStartupHelper.cs index 6988cdd..006a41f 100644 --- a/QuickLook/Helpers/AutoStartupHelper.cs +++ b/QuickLook/Helpers/AutoStartupHelper.cs @@ -23,7 +23,7 @@ namespace QuickLook.Helpers { internal static class AutoStartupHelper { - private static readonly string _startupFullPath = Path.Combine( + private static readonly string StartupFullPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.ChangeExtension(Path.GetFileName(App.AppFullPath), ".lnk")); @@ -34,11 +34,11 @@ namespace QuickLook.Helpers try { - File.Create(_startupFullPath).Close(); + File.Create(StartupFullPath).Close(); var shl = new Shell(); - var dir = shl.NameSpace(Path.GetDirectoryName(_startupFullPath)); - var itm = dir.Items().Item(Path.GetFileName(_startupFullPath)); + var dir = shl.NameSpace(Path.GetDirectoryName(StartupFullPath)); + var itm = dir.Items().Item(Path.GetFileName(StartupFullPath)); var lnk = (ShellLinkObject) itm.GetLink; lnk.Path = App.AppFullPath; @@ -46,7 +46,7 @@ namespace QuickLook.Helpers lnk.SetIconLocation(App.AppFullPath, 0); lnk.WorkingDirectory = App.AppPath; - lnk.Save(_startupFullPath); + lnk.Save(StartupFullPath); } catch (Exception) { @@ -59,7 +59,7 @@ namespace QuickLook.Helpers if (App.IsUWP) return; - File.Delete(_startupFullPath); + File.Delete(StartupFullPath); } internal static bool IsAutorun() @@ -67,7 +67,7 @@ namespace QuickLook.Helpers if (App.IsUWP) return true; - return File.Exists(_startupFullPath); + return File.Exists(StartupFullPath); } } } \ No newline at end of file diff --git a/QuickLook/Helpers/TranslationHelper.cs b/QuickLook/Helpers/TranslationHelper.cs new file mode 100644 index 0000000..f5e97a2 --- /dev/null +++ b/QuickLook/Helpers/TranslationHelper.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Xml.XPath; + +namespace QuickLook.Helpers +{ + internal class TranslationHelper + { + private static readonly CultureInfo CurrentCultureInfo = CultureInfo.CurrentUICulture; + //private static readonly CultureInfo CurrentCultureInfo = CultureInfo.GetCultureInfo("zh-CN"); + + private static readonly Dictionary FileCache = new Dictionary(); + private static readonly Dictionary StringCache = new Dictionary(); + + public static string GetString(string file, string id, CultureInfo locale = null, string failsafe = null) + { + if (!File.Exists(file)) + return failsafe ?? id; + + if (locale == null) + locale = CurrentCultureInfo; + + var nav = GetLangFile(file); + + // try to get string + var s = GetStringFromXml(nav, id, locale); + if (s != null) + return s; + + // try again for parent language + if (locale.Parent.Name != string.Empty) + s = GetStringFromXml(nav, id, locale.Parent); + if (s != null) + return s; + + // use fallback language + s = GetStringFromXml(nav, id, CultureInfo.GetCultureInfo("en")); + if (s != null) + return s; + + return failsafe ?? id; + } + + private static string GetStringFromXml(XPathNavigator nav, string id, CultureInfo locale) + { + var cacheKey = $"{locale.Name}::{id}"; + if (StringCache.ContainsKey(cacheKey)) + return StringCache[cacheKey]; + + var result = nav.SelectSingleNode($@"/Translations/{locale.Name}/{id}"); + StringCache.Add(cacheKey, result?.Value); + + return result?.Value; + } + + private static XPathNavigator GetLangFile(string file) + { + if (FileCache.ContainsKey(file)) + return FileCache[file]; + + var res = new XPathDocument(file).CreateNavigator(); + FileCache.Add(file, res); + return res; + } + } +} \ No newline at end of file diff --git a/QuickLook/Helpers/Updater.cs b/QuickLook/Helpers/Updater.cs index 593dacc..9eeae7a 100644 --- a/QuickLook/Helpers/Updater.cs +++ b/QuickLook/Helpers/Updater.cs @@ -53,7 +53,7 @@ namespace QuickLook.Helpers if (!silent) Application.Current.Dispatcher.Invoke( () => TrayIconManager.GetInstance().ShowNotification("", - "You are now on the latest version.")); + TranslationHelper.GetString(App.Translations, "Update_NoUpdate"))); return; } @@ -67,7 +67,7 @@ namespace QuickLook.Helpers { ViewWindowManager.GetInstance().InvokeViewer(changeLogPath); TrayIconManager.GetInstance().ShowNotification("", - $"New version {nVersion} is released. Click here to open the download page.", + string.Format(TranslationHelper.GetString(App.Translations, "Update_Found"), nVersion), clickEvent: () => Process.Start( @"https://github.com/xupefei/QuickLook/releases/latest")); }); @@ -77,7 +77,7 @@ namespace QuickLook.Helpers Debug.WriteLine(e.Message); Application.Current.Dispatcher.Invoke( () => TrayIconManager.GetInstance().ShowNotification("", - $"Error occured when checking for updates: {e.Message}")); + string.Format(TranslationHelper.GetString(App.Translations, "Update_Error"), e.Message))); } }); } diff --git a/QuickLook/MainWindowTransparent.xaml b/QuickLook/MainWindowTransparent.xaml index acdcc96..6e37662 100644 --- a/QuickLook/MainWindowTransparent.xaml +++ b/QuickLook/MainWindowTransparent.xaml @@ -14,8 +14,7 @@ WindowStartupLocation="CenterScreen" Focusable="False" WindowStyle="None" Background="#E5FAFAFA" AllowsTransparency="True" - ShowActivated="False" ShowInTaskbar="False" - FontFamily="Segoe UI,Microsoft Yahei UI"> + ShowActivated="False" ShowInTaskbar="False"> diff --git a/QuickLook/MainWindowTransparent.xaml.cs b/QuickLook/MainWindowTransparent.xaml.cs index 489c019..0a25322 100644 --- a/QuickLook/MainWindowTransparent.xaml.cs +++ b/QuickLook/MainWindowTransparent.xaml.cs @@ -21,6 +21,7 @@ using System.IO; using System.Runtime.ExceptionServices; using System.Windows; using System.Windows.Input; +using System.Windows.Media; using System.Windows.Threading; using QuickLook.Helpers; using QuickLook.Helpers.BlurLibrary; @@ -40,6 +41,9 @@ namespace QuickLook InitializeComponent(); + FontFamily = + new FontFamily(TranslationHelper.GetString(App.Translations, "UI_FontFamily", failsafe: "Segoe UI")); + SourceInitialized += (sender, e) => { if (AllowsTransparency) @@ -177,11 +181,13 @@ namespace QuickLook buttonOpenWith.Content = isExe == null ? Directory.Exists(PreviewPath) - ? $"Browse “{Path.GetFileName(PreviewPath)}”" - : "Open..." + ? string.Format(TranslationHelper.GetString(App.Translations, "MW_BrowseFolder"), + Path.GetFileName(PreviewPath)) + : string.Format(TranslationHelper.GetString(App.Translations, "MW_Open"), + Path.GetFileName(PreviewPath)) : isExe == true - ? $"Run “{appFriendlyName}”" - : $"Open with “{appFriendlyName}”"; + ? string.Format(TranslationHelper.GetString(App.Translations, "MW_Run"), appFriendlyName) + : string.Format(TranslationHelper.GetString(App.Translations, "MW_OpenWith"), appFriendlyName); } internal void BeginHide() diff --git a/QuickLook/Plugin/ContextObject.cs b/QuickLook/Plugin/ContextObject.cs index 614d584..c44cbd5 100644 --- a/QuickLook/Plugin/ContextObject.cs +++ b/QuickLook/Plugin/ContextObject.cs @@ -17,6 +17,7 @@ using System; using System.ComponentModel; +using System.Globalization; using System.Runtime.CompilerServices; using System.Windows; using QuickLook.Annotations; @@ -126,6 +127,14 @@ namespace QuickLook.Plugin public event PropertyChangedEventHandler PropertyChanged; + /// + /// Get a string from translation Xml document. + /// + public string GetString(string file, string id, CultureInfo locale = null, string failsafe = null) + { + return TranslationHelper.GetString(file, id, locale, failsafe); + } + /// /// Show a notification balloon. /// diff --git a/QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs b/QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs index 3821dae..1b0c087 100644 --- a/QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs +++ b/QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs @@ -20,6 +20,7 @@ using System.Globalization; using System.IO; using System.Threading.Tasks; using System.Windows.Controls; +using QuickLook.Helpers; namespace QuickLook.Plugin.InfoPanel { @@ -61,7 +62,8 @@ namespace QuickLook.Plugin.InfoPanel filename.Text = string.IsNullOrEmpty(name) ? path : name; var last = File.GetLastWriteTime(path); - modDate.Text = $"Last modified at {last.ToString(CultureInfo.CurrentCulture)}"; + modDate.Text = string.Format(TranslationHelper.GetString(App.Translations, "InfoPanel_LastModified"), + last.ToString(CultureInfo.CurrentCulture)); Stop = false; @@ -83,7 +85,9 @@ namespace QuickLook.Plugin.InfoPanel Dispatcher.Invoke(() => { totalSize.Text = - $"Capacity {totalSpace.ToPrettySize(2)}, {totalFreeSpace.ToPrettySize(2)} available"; + string.Format(TranslationHelper.GetString(App.Translations, "InfoPanel_DriveSize"), + totalSpace.ToPrettySize(2), + totalFreeSpace.ToPrettySize(2)); }); } else if (Directory.Exists(path)) @@ -95,10 +99,17 @@ namespace QuickLook.Plugin.InfoPanel Dispatcher.Invoke(() => { string t; - var d = totalDirsL != 0 ? $"{totalDirsL} folders" : string.Empty; - var f = totalFilesL != 0 ? $"{totalFilesL} files" : string.Empty; + var d = totalDirsL != 0 + ? string.Format( + TranslationHelper.GetString(App.Translations, "InfoPanel_Folders"), totalDirsL) + : string.Empty; + var f = totalFilesL != 0 + ? string.Format( + TranslationHelper.GetString(App.Translations, "InfoPanel_Files"), totalFilesL) + : string.Empty; if (!string.IsNullOrEmpty(d) && !string.IsNullOrEmpty(f)) - t = $"({d} and {f})"; + t = string.Format( + TranslationHelper.GetString(App.Translations, "InfoPanel_FolderAndFile"), d, f); else if (string.IsNullOrEmpty(d) && string.IsNullOrEmpty(f)) t = string.Empty; else diff --git a/QuickLook/QuickLook.csproj b/QuickLook/QuickLook.csproj index 6a18d9a..e5a7682 100644 --- a/QuickLook/QuickLook.csproj +++ b/QuickLook/QuickLook.csproj @@ -92,6 +92,8 @@ 4.0 + + @@ -133,6 +135,7 @@ + @@ -253,6 +256,12 @@ True + + + PreserveNewest + Designer + + "$(SolutionDir)Scripts\update-version.cmd" "$(SolutionDir)" "$(SolutionDir)GitVersion.cs" diff --git a/QuickLook/Translations.lang b/QuickLook/Translations.lang new file mode 100644 index 0000000..f8f5dd2 --- /dev/null +++ b/QuickLook/Translations.lang @@ -0,0 +1,46 @@ + + + + + Segoe UI + QuickLook is running in the background. + QuickLook is already running in the background. + Browse “{0}” + Open “{0}” + Open with “{0}” + Run “{0}” + Run at &Startup + QuickLook v{0} + Check for &Updates... + &Quit + You are now on the latest version. + New version {0} is released. Click here to open the download page. + Error occured when checking for updates: {0} + Last modified at {0} + Capacity {0}, {1} available + {0} folders + {0} files + ({0} and {1}) + + + Segoe UI,Microsoft Yahei UI,Microsoft Yahei,SimSun + QuickLook 正在后台运行。 + 另一个 QuickLook 进程正在运行。 + 浏览 “{0}” + 打开 “{0}” + 用 “{0}” 打开 + 运行 “{0}” + 启动时自动运行 (&S) + QuickLook v{0} + 检查更新... (&U) + 退出 (&Q) + 您已使用了最新版本。 + 发现新版本 {0}。点击这里打开下载页面。 + 检查更新时发生错误:{0} + 最后修改于 {0} + 总容量 {0},可用 {1} + {0} 个目录 + {0} 个文件 + (含 {0}和 {1}) + + \ No newline at end of file diff --git a/QuickLook/TrayIconManager.cs b/QuickLook/TrayIconManager.cs index 2192233..4321b5d 100644 --- a/QuickLook/TrayIconManager.cs +++ b/QuickLook/TrayIconManager.cs @@ -29,29 +29,32 @@ namespace QuickLook private readonly NotifyIcon _icon; private readonly MenuItem _itemAutorun = - new MenuItem("Run at &Startup", (sender, e) => - { - if (AutoStartupHelper.IsAutorun()) - AutoStartupHelper.RemoveAutorunShortcut(); - else - AutoStartupHelper.CreateAutorunShortcut(); - }) {Enabled = !App.IsUWP}; + new MenuItem(TranslationHelper.GetString(App.Translations, "Icon_RunAtStartup"), + (sender, e) => + { + if (AutoStartupHelper.IsAutorun()) + AutoStartupHelper.RemoveAutorunShortcut(); + else + AutoStartupHelper.CreateAutorunShortcut(); + }) {Enabled = !App.IsUWP}; private TrayIconManager() { _icon = new NotifyIcon { - Text = $"QuickLook v{Application.ProductVersion}", + Text = string.Format(TranslationHelper.GetString(App.Translations, "Icon_ToolTip"), + Application.ProductVersion), Icon = Resources.app, Visible = true, ContextMenu = new ContextMenu(new[] { new MenuItem($"v{Application.ProductVersion}") {Enabled = false}, new MenuItem("-"), - new MenuItem("Check for &Updates...", + new MenuItem(TranslationHelper.GetString(App.Translations, "Icon_CheckUpdate"), (sender, e) => Updater.CheckForUpdates()) {Enabled = !App.IsUWP}, _itemAutorun, - new MenuItem("&Quit", (sender, e) => System.Windows.Application.Current.Shutdown()) + new MenuItem(TranslationHelper.GetString(App.Translations, "Icon_Quit"), + (sender, e) => System.Windows.Application.Current.Shutdown()) }) };