Add English and Chinese translations

This commit is contained in:
Paddy Xu
2017-07-14 22:25:44 +03:00
parent 751bd6e28e
commit 77b973ef7b
16 changed files with 215 additions and 37 deletions

View File

@@ -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)}";

View File

@@ -90,5 +90,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="Translations.lang">
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -10,8 +10,7 @@
d:DesignWidth="448.79"
UseLayoutRounding="True">
<Grid>
<avalonEdit:TextEditor x:Name="viewer" Background="#00FFFFFF" FontFamily="Consolas" FontSize="14"
ShowLineNumbers="True"
<avalonEdit:TextEditor x:Name="viewer" Background="#00FFFFFF" FontSize="14" ShowLineNumbers="True"
WordWrap="True" IsReadOnly="True" />
</Grid>
</UserControl>

View File

@@ -16,8 +16,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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
/// </summary>
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);
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<en>
<Editor_FontFamily>Consolas</Editor_FontFamily>
</en>
<zh-CN>
<Editor_FontFamily>Consolas,Microsoft Yahei UI,Microsoft Yahei,SimSun</Editor_FontFamily>
</zh-CN>
<ja-JP>
<Editor_FontFamily>Consolas,Meiryo UI,MS UI Gothic,MS Gothic</Editor_FontFamily>
</ja-JP>
</Translations>

View File

@@ -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();

View File

@@ -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);
}
}
}

View File

@@ -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<string, XPathNavigator> FileCache = new Dictionary<string, XPathNavigator>();
private static readonly Dictionary<string, string> StringCache = new Dictionary<string, string>();
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;
}
}
}

View File

@@ -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)));
}
});
}

View File

@@ -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">
<Window.Resources>
<converters:BooleanToResizeModeConverter x:Key="BooleanToResizeModeConverter" />
<converters:BooleanToResizeBorderThicknessConverter x:Key="BooleanToResizeBorderThicknessConverter" />

View File

@@ -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()

View File

@@ -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;
/// <summary>
/// Get a string from translation Xml document.
/// </summary>
public string GetString(string file, string id, CultureInfo locale = null, string failsafe = null)
{
return TranslationHelper.GetString(file, id, locale, failsafe);
}
/// <summary>
/// Show a notification balloon.
/// </summary>

View File

@@ -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

View File

@@ -92,6 +92,8 @@
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@@ -133,6 +135,7 @@
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\WindowsVistaWindowBlurController.cs" />
<Compile Include="Helpers\FileHelper.cs" />
<Compile Include="Helpers\ProcessHelper.cs" />
<Compile Include="Helpers\TranslationHelper.cs" />
<Compile Include="MainWindowNoTransparent.cs" />
<Compile Include="PipeServerManager.cs" />
<Compile Include="PluginManager.cs" />
@@ -253,6 +256,12 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None Include="Translations.lang">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>"$(SolutionDir)Scripts\update-version.cmd" "$(SolutionDir)" "$(SolutionDir)GitVersion.cs"</PreBuildEvent>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Translations>
<en>
<UI_FontFamily>Segoe UI</UI_FontFamily>
<APP_START>QuickLook is running in the background.</APP_START>
<APP_SECOND>QuickLook is already running in the background.</APP_SECOND>
<MW_BrowseFolder>Browse “{0}”</MW_BrowseFolder>
<MW_Open>Open “{0}”</MW_Open>
<MW_OpenWith>Open with “{0}”</MW_OpenWith>
<MW_Run>Run “{0}”</MW_Run>
<Icon_RunAtStartup>Run at &amp;Startup</Icon_RunAtStartup>
<Icon_ToolTip>QuickLook v{0}</Icon_ToolTip>
<Icon_CheckUpdate>Check for &amp;Updates...</Icon_CheckUpdate>
<Icon_Quit>&amp;Quit</Icon_Quit>
<Update_NoUpdate>You are now on the latest version.</Update_NoUpdate>
<Update_Found>New version {0} is released. Click here to open the download page.</Update_Found>
<Update_Error>Error occured when checking for updates: {0}</Update_Error>
<InfoPanel_LastModified>Last modified at {0}</InfoPanel_LastModified>
<InfoPanel_DriveSize>Capacity {0}, {1} available</InfoPanel_DriveSize>
<InfoPanel_Folders>{0} folders</InfoPanel_Folders>
<InfoPanel_Files>{0} files</InfoPanel_Files>
<InfoPanel_FolderAndFile>({0} and {1})</InfoPanel_FolderAndFile>
</en>
<zh-CN>
<UI_FontFamily>Segoe UI,Microsoft Yahei UI,Microsoft Yahei,SimSun</UI_FontFamily>
<APP_START>QuickLook 正在后台运行。</APP_START>
<APP_SECOND>另一个 QuickLook 进程正在运行。</APP_SECOND>
<MW_BrowseFolder>浏览 “{0}”</MW_BrowseFolder>
<MW_Open>打开 “{0}”</MW_Open>
<MW_OpenWith>用 “{0}” 打开</MW_OpenWith>
<MW_Run>运行 “{0}”</MW_Run>
<Icon_RunAtStartup>启动时自动运行 (&amp;S)</Icon_RunAtStartup>
<Icon_ToolTip>QuickLook v{0}</Icon_ToolTip>
<Icon_CheckUpdate>检查更新... (&amp;U)</Icon_CheckUpdate>
<Icon_Quit>退出 (&amp;Q)</Icon_Quit>
<Update_NoUpdate>您已使用了最新版本。</Update_NoUpdate>
<Update_Found>发现新版本 {0}。点击这里打开下载页面。</Update_Found>
<Update_Error>检查更新时发生错误:{0}</Update_Error>
<InfoPanel_LastModified>最后修改于 {0}</InfoPanel_LastModified>
<InfoPanel_DriveSize>总容量 {0},可用 {1}</InfoPanel_DriveSize>
<InfoPanel_Folders>{0} 个目录</InfoPanel_Folders>
<InfoPanel_Files>{0} 个文件</InfoPanel_Files>
<InfoPanel_FolderAndFile>(含 {0}和 {1})</InfoPanel_FolderAndFile>
</zh-CN>
</Translations>

View File

@@ -29,7 +29,8 @@ namespace QuickLook
private readonly NotifyIcon _icon;
private readonly MenuItem _itemAutorun =
new MenuItem("Run at &Startup", (sender, e) =>
new MenuItem(TranslationHelper.GetString(App.Translations, "Icon_RunAtStartup"),
(sender, e) =>
{
if (AutoStartupHelper.IsAutorun())
AutoStartupHelper.RemoveAutorunShortcut();
@@ -41,17 +42,19 @@ namespace QuickLook
{
_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())
})
};