mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #2427 from Flow-Launcher/double-pin
Double pinyin query
This commit is contained in:
commit
354e5ecf99
11 changed files with 345 additions and 187 deletions
22
Flow.Launcher.Infrastructure/IAlphabet.cs
Normal file
22
Flow.Launcher.Infrastructure/IAlphabet.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
namespace Flow.Launcher.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Translate a language to English letters using a given rule.
|
||||
/// </summary>
|
||||
public interface IAlphabet
|
||||
{
|
||||
/// <summary>
|
||||
/// Translate a string to English letters, using a given rule.
|
||||
/// </summary>
|
||||
/// <param name="stringToTranslate">String to translate.</param>
|
||||
/// <returns></returns>
|
||||
public (string translation, TranslationMapping map) Translate(string stringToTranslate);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a string should be translated to English letter with this Alphabet.
|
||||
/// </summary>
|
||||
/// <param name="stringToTranslate">String to translate.</param>
|
||||
/// <returns></returns>
|
||||
public bool ShouldTranslate(string stringToTranslate);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,209 +1,148 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using System.Text.Json;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using ToolGood.Words.Pinyin;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
|
||||
namespace Flow.Launcher.Infrastructure
|
||||
{
|
||||
public class TranslationMapping
|
||||
{
|
||||
private bool constructed;
|
||||
|
||||
private List<int> originalIndexs = new List<int>();
|
||||
private List<int> translatedIndexs = new List<int>();
|
||||
private int translatedLength = 0;
|
||||
|
||||
public string key { get; private set; }
|
||||
|
||||
public void setKey(string key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void AddNewIndex(int originalIndex, int translatedIndex, int length)
|
||||
{
|
||||
if (constructed)
|
||||
throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
|
||||
|
||||
originalIndexs.Add(originalIndex);
|
||||
translatedIndexs.Add(translatedIndex);
|
||||
translatedIndexs.Add(translatedIndex + length);
|
||||
translatedLength += length - 1;
|
||||
}
|
||||
|
||||
public int MapToOriginalIndex(int translatedIndex)
|
||||
{
|
||||
if (translatedIndex > translatedIndexs.Last())
|
||||
return translatedIndex - translatedLength - 1;
|
||||
|
||||
int lowerBound = 0;
|
||||
int upperBound = originalIndexs.Count - 1;
|
||||
|
||||
int count = 0;
|
||||
|
||||
// Corner case handle
|
||||
if (translatedIndex < translatedIndexs[0])
|
||||
return translatedIndex;
|
||||
if (translatedIndex > translatedIndexs.Last())
|
||||
{
|
||||
int indexDef = 0;
|
||||
for (int k = 0; k < originalIndexs.Count; k++)
|
||||
{
|
||||
indexDef += translatedIndexs[k * 2 + 1] - translatedIndexs[k * 2];
|
||||
}
|
||||
|
||||
return translatedIndex - indexDef - 1;
|
||||
}
|
||||
|
||||
// Binary Search with Range
|
||||
for (int i = originalIndexs.Count / 2;; count++)
|
||||
{
|
||||
if (translatedIndex < translatedIndexs[i * 2])
|
||||
{
|
||||
// move to lower middle
|
||||
upperBound = i;
|
||||
i = (i + lowerBound) / 2;
|
||||
}
|
||||
else if (translatedIndex > translatedIndexs[i * 2 + 1] - 1)
|
||||
{
|
||||
lowerBound = i;
|
||||
// move to upper middle
|
||||
// due to floor of integer division, move one up on corner case
|
||||
i = (i + upperBound + 1) / 2;
|
||||
}
|
||||
else
|
||||
return originalIndexs[i];
|
||||
|
||||
if (upperBound - lowerBound <= 1 &&
|
||||
translatedIndex > translatedIndexs[lowerBound * 2 + 1] &&
|
||||
translatedIndex < translatedIndexs[upperBound * 2])
|
||||
{
|
||||
int indexDef = 0;
|
||||
|
||||
for (int j = 0; j < upperBound; j++)
|
||||
{
|
||||
indexDef += translatedIndexs[j * 2 + 1] - translatedIndexs[j * 2];
|
||||
}
|
||||
|
||||
return translatedIndex - indexDef - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void endConstruct()
|
||||
{
|
||||
if (constructed)
|
||||
throw new InvalidOperationException("Mapping has already been constructed");
|
||||
constructed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translate a language to English letters using a given rule.
|
||||
/// </summary>
|
||||
public interface IAlphabet
|
||||
{
|
||||
/// <summary>
|
||||
/// Translate a string to English letters, using a given rule.
|
||||
/// </summary>
|
||||
/// <param name="stringToTranslate">String to translate.</param>
|
||||
/// <returns></returns>
|
||||
public (string translation, TranslationMapping map) Translate(string stringToTranslate);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a string can be translated to English letter with this Alphabet.
|
||||
/// </summary>
|
||||
/// <param name="stringToTranslate">String to translate.</param>
|
||||
/// <returns></returns>
|
||||
public bool CanBeTranslated(string stringToTranslate);
|
||||
}
|
||||
|
||||
public class PinyinAlphabet : IAlphabet
|
||||
{
|
||||
private ConcurrentDictionary<string, (string translation, TranslationMapping map)> _pinyinCache =
|
||||
new ConcurrentDictionary<string, (string translation, TranslationMapping map)>();
|
||||
new();
|
||||
|
||||
private Settings _settings;
|
||||
private readonly Settings _settings;
|
||||
|
||||
private ReadOnlyDictionary<string, string> currentDoublePinyinTable;
|
||||
|
||||
public PinyinAlphabet()
|
||||
{
|
||||
Initialize(Ioc.Default.GetRequiredService<Settings>());
|
||||
_settings = Ioc.Default.GetRequiredService<Settings>();
|
||||
LoadDoublePinyinTable();
|
||||
|
||||
_settings.PropertyChanged += (sender, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(Settings.UseDoublePinyin) ||
|
||||
e.PropertyName == nameof(Settings.DoublePinyinSchema))
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void Initialize([NotNull] Settings settings)
|
||||
public void Reload()
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
LoadDoublePinyinTable();
|
||||
_pinyinCache.Clear();
|
||||
}
|
||||
|
||||
public bool CanBeTranslated(string stringToTranslate)
|
||||
private void CreateDoublePinyinTableFromStream(Stream jsonStream)
|
||||
{
|
||||
return WordsHelper.HasChinese(stringToTranslate);
|
||||
Dictionary<string, Dictionary<string, string>> table = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(jsonStream);
|
||||
string schemaKey = _settings.DoublePinyinSchema.ToString(); // Convert enum to string
|
||||
if (!table.TryGetValue(schemaKey, out var value))
|
||||
{
|
||||
throw new ArgumentException("DoublePinyinSchema is invalid or double pinyin table is broken.");
|
||||
}
|
||||
currentDoublePinyinTable = new ReadOnlyDictionary<string, string>(value);
|
||||
}
|
||||
|
||||
private void LoadDoublePinyinTable()
|
||||
{
|
||||
if (_settings.UseDoublePinyin)
|
||||
{
|
||||
var tablePath = Path.Join(AppContext.BaseDirectory, "Resources", "double_pinyin.json");
|
||||
try
|
||||
{
|
||||
using var fs = File.OpenRead(tablePath);
|
||||
CreateDoublePinyinTableFromStream(fs);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Log.Exception(nameof(PinyinAlphabet), "Failed to load double pinyin table from file: " + tablePath, e);
|
||||
currentDoublePinyinTable = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDoublePinyinTable = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldTranslate(string stringToTranslate)
|
||||
{
|
||||
// If a string has Chinese characters, we don't need to translate it to pinyin.
|
||||
return _settings.ShouldUsePinyin && !WordsHelper.HasChinese(stringToTranslate);
|
||||
}
|
||||
|
||||
public (string translation, TranslationMapping map) Translate(string content)
|
||||
{
|
||||
if (_settings.ShouldUsePinyin)
|
||||
{
|
||||
if (!_pinyinCache.ContainsKey(content))
|
||||
{
|
||||
return BuildCacheFromContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _pinyinCache[content];
|
||||
}
|
||||
}
|
||||
return (content, null);
|
||||
if (!_settings.ShouldUsePinyin || !WordsHelper.HasChinese(content))
|
||||
return (content, null);
|
||||
|
||||
return _pinyinCache.TryGetValue(content, out var value)
|
||||
? value
|
||||
: BuildCacheFromContent(content);
|
||||
}
|
||||
|
||||
private (string translation, TranslationMapping map) BuildCacheFromContent(string content)
|
||||
{
|
||||
if (WordsHelper.HasChinese(content))
|
||||
var resultList = WordsHelper.GetPinyinList(content);
|
||||
|
||||
var resultBuilder = new StringBuilder();
|
||||
var map = new TranslationMapping();
|
||||
|
||||
var previousIsChinese = false;
|
||||
|
||||
for (var i = 0; i < resultList.Length; i++)
|
||||
{
|
||||
var resultList = WordsHelper.GetPinyinList(content);
|
||||
|
||||
StringBuilder resultBuilder = new StringBuilder();
|
||||
TranslationMapping map = new TranslationMapping();
|
||||
|
||||
bool pre = false;
|
||||
|
||||
for (int i = 0; i < resultList.Length; i++)
|
||||
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
|
||||
{
|
||||
if (content[i] >= 0x3400 && content[i] <= 0x9FD5)
|
||||
string translated = _settings.UseDoublePinyin ? ToDoublePin(resultList[i]) : resultList[i];
|
||||
if (i > 0)
|
||||
{
|
||||
map.AddNewIndex(i, resultBuilder.Length, resultList[i].Length + 1);
|
||||
resultBuilder.Append(' ');
|
||||
resultBuilder.Append(resultList[i]);
|
||||
pre = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pre)
|
||||
{
|
||||
pre = false;
|
||||
resultBuilder.Append(' ');
|
||||
}
|
||||
|
||||
resultBuilder.Append(resultList[i]);
|
||||
}
|
||||
map.AddNewIndex(resultBuilder.Length, translated.Length);
|
||||
resultBuilder.Append(translated);
|
||||
previousIsChinese = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (previousIsChinese)
|
||||
{
|
||||
previousIsChinese = false;
|
||||
resultBuilder.Append(' ');
|
||||
}
|
||||
map.AddNewIndex(resultBuilder.Length, resultList[i].Length);
|
||||
resultBuilder.Append(resultList[i]);
|
||||
}
|
||||
|
||||
map.endConstruct();
|
||||
|
||||
var key = resultBuilder.ToString();
|
||||
map.setKey(key);
|
||||
|
||||
return _pinyinCache[content] = (key, map);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (content, null);
|
||||
}
|
||||
|
||||
map.endConstruct();
|
||||
|
||||
var key = resultBuilder.ToString();
|
||||
|
||||
return _pinyinCache[content] = (key, map);
|
||||
}
|
||||
|
||||
#region Double Pinyin
|
||||
|
||||
private string ToDoublePin(string fullPinyin)
|
||||
{
|
||||
if (currentDoublePinyinTable.TryGetValue(fullPinyin, out var doublePinyinValue))
|
||||
{
|
||||
return doublePinyinValue;
|
||||
}
|
||||
return fullPinyin;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
|
||||
query = query.Trim();
|
||||
TranslationMapping translationMapping = null;
|
||||
if (_alphabet is not null && !_alphabet.CanBeTranslated(query))
|
||||
if (_alphabet is not null && _alphabet.ShouldTranslate(query))
|
||||
{
|
||||
// We assume that if a query can be translated (containing characters of a language, like Chinese)
|
||||
// it actually means user doesn't want it to be translated to English letters.
|
||||
|
|
@ -228,7 +228,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
return new MatchResult(false, UserSettingSearchPrecision);
|
||||
}
|
||||
|
||||
private bool IsAcronym(string stringToCompare, int compareStringIndex)
|
||||
private static bool IsAcronym(string stringToCompare, int compareStringIndex)
|
||||
{
|
||||
if (IsAcronymChar(stringToCompare, compareStringIndex) || IsAcronymNumber(stringToCompare, compareStringIndex))
|
||||
return true;
|
||||
|
|
@ -237,7 +237,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
}
|
||||
|
||||
// When counting acronyms, treat a set of numbers as one acronym ie. Visual 2019 as 2 acronyms instead of 5
|
||||
private bool IsAcronymCount(string stringToCompare, int compareStringIndex)
|
||||
private static bool IsAcronymCount(string stringToCompare, int compareStringIndex)
|
||||
{
|
||||
if (IsAcronymChar(stringToCompare, compareStringIndex))
|
||||
return true;
|
||||
|
|
|
|||
35
Flow.Launcher.Infrastructure/TranslationMapping.cs
Normal file
35
Flow.Launcher.Infrastructure/TranslationMapping.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Flow.Launcher.Infrastructure
|
||||
{
|
||||
public class TranslationMapping
|
||||
{
|
||||
private bool constructed;
|
||||
|
||||
// Assuming one original item maps to multi translated items
|
||||
// list[i] is the last translated index + 1 of original index i
|
||||
private readonly List<int> originalToTranslated = new();
|
||||
|
||||
public void AddNewIndex(int translatedIndex, int length)
|
||||
{
|
||||
if (constructed)
|
||||
throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
|
||||
|
||||
originalToTranslated.Add(translatedIndex + length);
|
||||
}
|
||||
|
||||
public int MapToOriginalIndex(int translatedIndex)
|
||||
{
|
||||
int loc = originalToTranslated.BinarySearch(translatedIndex);
|
||||
return loc >= 0 ? loc : ~loc;
|
||||
}
|
||||
|
||||
public void endConstruct()
|
||||
{
|
||||
if (constructed)
|
||||
throw new InvalidOperationException("Mapping has already been constructed");
|
||||
constructed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
}
|
||||
}
|
||||
public bool UseDropShadowEffect { get; set; } = true;
|
||||
public BackdropTypes BackdropType{ get; set; } = BackdropTypes.None;
|
||||
public BackdropTypes BackdropType { get; set; } = BackdropTypes.None;
|
||||
public string ReleaseNotesVersion { get; set; } = string.Empty;
|
||||
|
||||
/* Appearance Settings. It should be separated from the setting later.*/
|
||||
|
|
@ -228,7 +228,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int MaxHistoryResultsToShowForHomePage { get; set; } = 5;
|
||||
|
||||
public bool AutoRestartAfterChanging { get; set; } = false;
|
||||
|
|
@ -330,6 +330,36 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
/// </summary>
|
||||
public bool ShouldUsePinyin { get; set; } = false;
|
||||
|
||||
private bool _useDoublePinyin = false;
|
||||
public bool UseDoublePinyin
|
||||
{
|
||||
get => _useDoublePinyin;
|
||||
set
|
||||
{
|
||||
if (_useDoublePinyin != value)
|
||||
{
|
||||
_useDoublePinyin = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DoublePinyinSchemas _doublePinyinSchema = DoublePinyinSchemas.XiaoHe;
|
||||
|
||||
[JsonInclude, JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public DoublePinyinSchemas DoublePinyinSchema
|
||||
{
|
||||
get => _doublePinyinSchema;
|
||||
set
|
||||
{
|
||||
if (_doublePinyinSchema != value)
|
||||
{
|
||||
_doublePinyinSchema = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AlwaysPreview { get; set; } = false;
|
||||
|
||||
public bool AlwaysStartEn { get; set; } = false;
|
||||
|
|
@ -492,7 +522,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
if (!string.IsNullOrEmpty(SettingWindowHotkey))
|
||||
list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = ""));
|
||||
if (!string.IsNullOrEmpty(OpenHistoryHotkey))
|
||||
list.Add(new(OpenHistoryHotkey, "OpenHistoryHotkey", () => OpenHistoryHotkey = ""));
|
||||
list.Add(new(OpenHistoryHotkey, "OpenHistoryHotkey", () => OpenHistoryHotkey = ""));
|
||||
if (!string.IsNullOrEmpty(OpenContextMenuHotkey))
|
||||
list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = ""));
|
||||
if (!string.IsNullOrEmpty(SelectNextPageHotkey))
|
||||
|
|
@ -598,9 +628,22 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
|
||||
public enum BackdropTypes
|
||||
{
|
||||
None,
|
||||
None,
|
||||
Acrylic,
|
||||
Mica,
|
||||
MicaAlt
|
||||
}
|
||||
|
||||
public enum DoublePinyinSchemas
|
||||
{
|
||||
XiaoHe,
|
||||
ZiRanMa,
|
||||
WeiRuan,
|
||||
ZhiNengABC,
|
||||
ZiGuangPinYin,
|
||||
PinYinJiaJia,
|
||||
XingKongJianDao,
|
||||
DaNiu,
|
||||
XiaoLang
|
||||
}
|
||||
}
|
||||
|
|
|
|||
56
Flow.Launcher.Test/TranslationMappingTest.cs
Normal file
56
Flow.Launcher.Test/TranslationMappingTest.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Legacy;
|
||||
|
||||
namespace Flow.Launcher.Test
|
||||
{
|
||||
[TestFixture]
|
||||
public class TranslationMappingTest
|
||||
{
|
||||
[Test]
|
||||
public void AddNewIndex_ShouldAddTranslatedIndexPlusLength()
|
||||
{
|
||||
var mapping = new TranslationMapping();
|
||||
mapping.AddNewIndex(5, 3);
|
||||
mapping.AddNewIndex(8, 2);
|
||||
|
||||
// 5+3=8, 8+2=10
|
||||
ClassicAssert.AreEqual(2, GetOriginalToTranslatedCount(mapping));
|
||||
ClassicAssert.AreEqual(8, GetOriginalToTranslatedAt(mapping, 0));
|
||||
ClassicAssert.AreEqual(10, GetOriginalToTranslatedAt(mapping, 1));
|
||||
}
|
||||
|
||||
[TestCase(0, 0)]
|
||||
[TestCase(2, 1)]
|
||||
[TestCase(3, 1)]
|
||||
[TestCase(5, 2)]
|
||||
[TestCase(6, 2)]
|
||||
public void MapToOriginalIndex_ShouldReturnExpectedIndex(int translatedIndex, int expectedOriginalIndex)
|
||||
{
|
||||
var mapping = new TranslationMapping();
|
||||
// a测试
|
||||
// a Ce Shi
|
||||
mapping.AddNewIndex(0, 1);
|
||||
mapping.AddNewIndex(2, 2);
|
||||
mapping.AddNewIndex(5, 3);
|
||||
|
||||
|
||||
var result = mapping.MapToOriginalIndex(translatedIndex);
|
||||
ClassicAssert.AreEqual(expectedOriginalIndex, result);
|
||||
}
|
||||
|
||||
private int GetOriginalToTranslatedCount(TranslationMapping mapping)
|
||||
{
|
||||
var field = typeof(TranslationMapping).GetField("originalToTranslated", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var list = (System.Collections.Generic.List<int>)field.GetValue(mapping);
|
||||
return list.Count;
|
||||
}
|
||||
|
||||
private int GetOriginalToTranslatedAt(TranslationMapping mapping, int index)
|
||||
{
|
||||
var field = typeof(TranslationMapping).GetField("originalToTranslated", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var list = (System.Collections.Generic.List<int>)field.GetValue(mapping);
|
||||
return list[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +127,9 @@
|
|||
<None Update="Resources\dev.ico">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\double_pinyin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||
|
|
|
|||
|
|
@ -105,6 +105,19 @@
|
|||
<system:String x:Key="SearchPrecisionRegular">Regular</system:String>
|
||||
<system:String x:Key="ShouldUsePinyin">Search with Pinyin</system:String>
|
||||
<system:String x:Key="ShouldUsePinyinToolTip">Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.</system:String>
|
||||
<system:String x:Key="ShouldUseDoublePinyin">Use Double Pinyin</system:String>
|
||||
<system:String x:Key="ShouldUseDoublePinyinToolTip">Allows using Double Pinyin to search. Double Pinyin is a variation of Pinyin that uses two characters.</system:String>
|
||||
<system:String x:Key="DoublePinyinSchema">Double Pinyin Schema</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasXiaoHe">Xiao He</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasZiRanMa">Zi Ran Ma</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasWeiRuan">Wei Ruan</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasZhiNengABC">Zhi Neng ABC</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasZiGuangPinYin">Zi Guang Pin Yin</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasPinYinJiaJia">Pin Yin Jia Jia</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasXingKongJianDao">Xing Kong Jian Dao</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasDaNiu">Da Niu</system:String>
|
||||
<system:String x:Key="DoublePinyinSchemasXiaoLang">Xiao Lang</system:String>
|
||||
|
||||
<system:String x:Key="AlwaysPreview">Always Preview</system:String>
|
||||
<system:String x:Key="AlwaysPreviewToolTip">Always open preview panel when Flow activates. Press {0} to toggle preview.</system:String>
|
||||
<system:String x:Key="shadowEffectNotAllowed">Shadow effect is not allowed while current theme has blur effect enabled</system:String>
|
||||
|
|
|
|||
1
Flow.Launcher/Resources/double_pinyin.json
Normal file
1
Flow.Launcher/Resources/double_pinyin.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -35,6 +35,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
|||
public class SearchWindowAlignData : DropdownDataGeneric<SearchWindowAligns> { }
|
||||
public class SearchPrecisionData : DropdownDataGeneric<SearchPrecisionScore> { }
|
||||
public class LastQueryModeData : DropdownDataGeneric<LastQueryMode> { }
|
||||
public class DoublePinyinSchemaData : DropdownDataGeneric<DoublePinyinSchemas> { }
|
||||
|
||||
public bool StartFlowLauncherOnSystemStartup
|
||||
{
|
||||
|
|
@ -177,6 +178,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
|||
DropdownDataGeneric<SearchWindowAligns>.UpdateLabels(SearchWindowAligns);
|
||||
DropdownDataGeneric<SearchPrecisionScore>.UpdateLabels(SearchPrecisionScores);
|
||||
DropdownDataGeneric<LastQueryMode>.UpdateLabels(LastQueryModes);
|
||||
DropdownDataGeneric<DoublePinyinSchemas>.UpdateLabels(DoublePinyinSchemas);
|
||||
// Since we are using Binding instead of DynamicResource, we need to manually trigger the update
|
||||
OnPropertyChanged(nameof(AlwaysPreviewToolTip));
|
||||
}
|
||||
|
|
@ -262,9 +264,25 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
|||
public bool ShouldUsePinyin
|
||||
{
|
||||
get => Settings.ShouldUsePinyin;
|
||||
set => Settings.ShouldUsePinyin = value;
|
||||
set
|
||||
{
|
||||
if (value == false && UseDoublePinyin == true)
|
||||
{
|
||||
UseDoublePinyin = false;
|
||||
}
|
||||
Settings.ShouldUsePinyin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseDoublePinyin
|
||||
{
|
||||
set => Settings.UseDoublePinyin = value;
|
||||
get => Settings.UseDoublePinyin;
|
||||
}
|
||||
|
||||
public List<DoublePinyinSchemaData> DoublePinyinSchemas { get; } =
|
||||
DropdownDataGeneric<DoublePinyinSchemas>.GetValues<DoublePinyinSchemaData>("DoublePinyinSchemas");
|
||||
|
||||
public List<Language> Languages => _translater.LoadAvailableLanguages();
|
||||
|
||||
public string AlwaysPreviewToolTip => string.Format(
|
||||
|
|
|
|||
|
|
@ -371,16 +371,44 @@
|
|||
OnContent="{DynamicResource enable}" />
|
||||
</cc:Card>
|
||||
|
||||
<cc:Card
|
||||
Title="{DynamicResource ShouldUsePinyin}"
|
||||
Icon=""
|
||||
Sub="{DynamicResource ShouldUsePinyinToolTip}">
|
||||
<ui:ToggleSwitch
|
||||
IsOn="{Binding Settings.ShouldUsePinyin}"
|
||||
OffContent="{DynamicResource disable}"
|
||||
OnContent="{DynamicResource enable}"
|
||||
ToolTip="{DynamicResource ShouldUsePinyinToolTip}" />
|
||||
</cc:Card>
|
||||
<cc:CardGroup Margin="0 4 0 0">
|
||||
<cc:Card
|
||||
Title="{DynamicResource ShouldUsePinyin}"
|
||||
Icon=""
|
||||
Sub="{DynamicResource ShouldUsePinyinToolTip}"
|
||||
Type="First">
|
||||
<ui:ToggleSwitch
|
||||
IsOn="{Binding ShouldUsePinyin}"
|
||||
OffContent="{DynamicResource disable}"
|
||||
OnContent="{DynamicResource enable}"
|
||||
ToolTip="{DynamicResource ShouldUsePinyinToolTip}" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
Visibility="{ext:VisibleWhen {Binding ShouldUsePinyin},
|
||||
IsEqualToBool=True}"
|
||||
Title="{DynamicResource ShouldUseDoublePinyin}"
|
||||
Icon=""
|
||||
Sub="{DynamicResource ShouldUseDoublePinyinToolTip}"
|
||||
Type="Middle">
|
||||
<ui:ToggleSwitch
|
||||
IsOn="{Binding UseDoublePinyin}"
|
||||
OffContent="{DynamicResource disable}"
|
||||
OnContent="{DynamicResource enable}"
|
||||
ToolTip="{DynamicResource ShouldUseDoublePinyinToolTip}" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
Visibility="{ext:VisibleWhen {Binding UseDoublePinyin},
|
||||
IsEqualToBool=True}"
|
||||
Title="{DynamicResource DoublePinyinSchema}"
|
||||
Sub="{DynamicResource DoublePinyinSchemaToolTip}"
|
||||
Type="Last">
|
||||
<ComboBox
|
||||
DisplayMemberPath="Display"
|
||||
ItemsSource="{Binding DoublePinyinSchemas}"
|
||||
SelectedValue="{Binding Settings.DoublePinyinSchema}"
|
||||
SelectedValuePath="Value" />
|
||||
</cc:Card>
|
||||
</cc:CardGroup>
|
||||
|
||||
<cc:Card
|
||||
Title="{DynamicResource language}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue