[TextExtractor] Extend settings with preferred language (#22901)

* [TextExtractor] Extend settings with preferred language

* TextExtractor simplifying code, adding update languages on dropdown opening

* fix typo

* TextExtractor fixing bug with order of languages
This commit is contained in:
Laszlo Nemeth 2022-12-28 19:54:59 +01:00 committed by GitHub
parent 1f4ba8f267
commit dd62dab831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 3 deletions

View File

@ -11,6 +11,7 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry;
using PowerOCR.Helpers; using PowerOCR.Helpers;
using PowerOCR.Settings;
using PowerOCR.Utilities; using PowerOCR.Utilities;
using Windows.Globalization; using Windows.Globalization;
using Windows.Media.Ocr; using Windows.Media.Ocr;
@ -55,14 +56,26 @@ public partial class OCROverlay : Window
{ {
InitializeComponent(); InitializeComponent();
var userSettings = new UserSettings(new Helpers.ThrottledActionInvoker());
string? selectedLanguageName = userSettings.PreferredLanguage.Value;
// build context menu // build context menu
selectedLanguage = ImageMethods.GetOCRLanguage(); if (string.IsNullOrEmpty(selectedLanguageName))
string? selectedLanguageName = selectedLanguage?.DisplayName; {
selectedLanguage = ImageMethods.GetOCRLanguage();
selectedLanguageName = selectedLanguage?.DisplayName;
}
List<Language> possibleOcrLanguages = OcrEngine.AvailableRecognizerLanguages.ToList(); List<Language> possibleOcrLanguages = OcrEngine.AvailableRecognizerLanguages.ToList();
foreach (Language language in possibleOcrLanguages) foreach (Language language in possibleOcrLanguages)
{ {
MenuItem menuItem = new MenuItem() { Header = language.DisplayName, Tag = language, IsCheckable = true }; MenuItem menuItem = new MenuItem() { Header = language.NativeName, Tag = language, IsCheckable = true };
menuItem.IsChecked = language.DisplayName.Equals(selectedLanguageName); menuItem.IsChecked = language.DisplayName.Equals(selectedLanguageName);
if (language.DisplayName.Equals(selectedLanguageName))
{
selectedLanguage = language;
}
menuItem.Click += LanguageMenuItem_Click; menuItem.Click += LanguageMenuItem_Click;
CanvasContextMenu.Items.Add(menuItem); CanvasContextMenu.Items.Add(menuItem);
} }

View File

@ -8,5 +8,7 @@ public interface IUserSettings
{ {
SettingItem<string> ActivationShortcut { get; } SettingItem<string> ActivationShortcut { get; }
SettingItem<string> PreferredLanguage { get; }
void SendSettingsTelemetry(); void SendSettingsTelemetry();
} }

View File

@ -29,6 +29,7 @@ namespace PowerOCR.Settings
{ {
_settingsUtils = new SettingsUtils(); _settingsUtils = new SettingsUtils();
ActivationShortcut = new SettingItem<string>(DefaultActivationShortcut); ActivationShortcut = new SettingItem<string>(DefaultActivationShortcut);
PreferredLanguage = new SettingItem<string>(string.Empty);
LoadSettingsFromJson(); LoadSettingsFromJson();
@ -38,6 +39,8 @@ namespace PowerOCR.Settings
public SettingItem<string> ActivationShortcut { get; private set; } public SettingItem<string> ActivationShortcut { get; private set; }
public SettingItem<string> PreferredLanguage { get; private set; }
private void LoadSettingsFromJson() private void LoadSettingsFromJson()
{ {
// TODO this IO call should by Async, update GetFileWatcher helper to support async // TODO this IO call should by Async, update GetFileWatcher helper to support async
@ -64,6 +67,7 @@ namespace PowerOCR.Settings
if (settings != null) if (settings != null)
{ {
ActivationShortcut.Value = settings.Properties.ActivationShortcut.ToString(); ActivationShortcut.Value = settings.Properties.ActivationShortcut.ToString();
PreferredLanguage.Value = settings.Properties.PreferredLanguage.ToString();
} }
retry = false; retry = false;

View File

@ -15,6 +15,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public HotkeySettings ActivationShortcut { get; set; } public HotkeySettings ActivationShortcut { get; set; }
public string PreferredLanguage { get; set; }
public override string ToString() public override string ToString()
=> JsonSerializer.Serialize(this); => JsonSerializer.Serialize(this);
} }

View File

@ -2855,4 +2855,7 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="Hosts_AdditionalLinesPosition.Description" xml:space="preserve"> <data name="Hosts_AdditionalLinesPosition.Description" xml:space="preserve">
<value>Additional content includes the file header and lines that can't parse</value> <value>Additional content includes the file header and lines that can't parse</value>
</data> </data>
<data name="TextExtractor_Languages.Header" xml:space="preserve">
<value>Preferred language</value>
</data>
</root> </root>

View File

@ -3,13 +3,18 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Timers; using System.Timers;
using global::PowerToys.GPOWrapper; using global::PowerToys.GPOWrapper;
using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
using Windows.Globalization;
using Windows.Media.Ocr;
namespace Microsoft.PowerToys.Settings.UI.ViewModels namespace Microsoft.PowerToys.Settings.UI.ViewModels
{ {
@ -31,6 +36,33 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private GpoRuleConfigured _enabledGpoRuleConfiguration; private GpoRuleConfigured _enabledGpoRuleConfiguration;
private bool _enabledStateIsGPOConfigured; private bool _enabledStateIsGPOConfigured;
private bool _isEnabled; private bool _isEnabled;
private int _languageIndex;
private List<Language> possibleOcrLanguages;
public ObservableCollection<string> AvailableLanguages { get; } = new ObservableCollection<string>();
public int LanguageIndex
{
get
{
return _languageIndex;
}
set
{
if (value != _languageIndex)
{
_languageIndex = value;
if (_powerOcrSettings != null && _languageIndex < possibleOcrLanguages.Count && _languageIndex >= 0)
{
_powerOcrSettings.Properties.PreferredLanguage = possibleOcrLanguages[_languageIndex].DisplayName;
NotifySettingsChanged();
}
OnPropertyChanged(nameof(LanguageIndex));
}
}
}
private Func<string, int> SendConfigMSG { get; } private Func<string, int> SendConfigMSG { get; }
@ -130,6 +162,48 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
} }
} }
internal void UpdateLanguages()
{
int preferredLanguageIndex = -1;
int systemLanguageIndex = -1;
CultureInfo systemCulture = CultureInfo.CurrentUICulture;
// get the list of all installed OCR languages. While processing them, search for the previously preferred language and also for the current ui language
possibleOcrLanguages = OcrEngine.AvailableRecognizerLanguages.OrderBy(x => x.NativeName).ToList();
AvailableLanguages.Clear();
foreach (Language language in possibleOcrLanguages)
{
if (_powerOcrSettings.Properties.PreferredLanguage?.Equals(language.DisplayName) == true)
{
preferredLanguageIndex = AvailableLanguages.Count;
}
if (systemCulture.DisplayName.Equals(language.DisplayName) || systemCulture.Parent.DisplayName.Equals(language.DisplayName))
{
systemLanguageIndex = AvailableLanguages.Count;
}
AvailableLanguages.Add(language.NativeName);
}
// if the previously stored preferred language is not available (has been deleted or this is the first run with language preference)
if (preferredLanguageIndex == -1)
{
// try to use the current ui language. If it is also not available, set the first language as preferred (to have any selected language)
if (systemLanguageIndex >= 0)
{
preferredLanguageIndex = systemLanguageIndex;
}
else
{
preferredLanguageIndex = 0;
}
}
// set the language index -> the preferred language gets selected in the combo box
LanguageIndex = preferredLanguageIndex;
}
private void ScheduleSavingOfSettings() private void ScheduleSavingOfSettings()
{ {
lock (_delayedActionLock) lock (_delayedActionLock)

View File

@ -55,6 +55,18 @@
MinWidth="{StaticResource SettingActionControlMinWidth}" MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" /> HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard> </labs:SettingsCard>
<labs:SettingsCard
x:Uid="TextExtractor_Languages">
<ComboBox
x:Name="TextExtractor_ComboBox"
MinWidth="{StaticResource SettingActionControlMinWidth}"
ItemsSource="{x:Bind Path=ViewModel.AvailableLanguages, Mode=OneWay}"
SelectedIndex="{x:Bind Path=ViewModel.LanguageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedColorRepresentationValue, Mode=TwoWay}"
Loaded="TextExtractor_ComboBox_Loaded"
DropDownOpened="TextExtractor_ComboBox_DropDownOpened">
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup> </controls:SettingsGroup>
</StackPanel> </StackPanel>
</controls:SettingsPageControl.ModuleContent> </controls:SettingsPageControl.ModuleContent>

View File

@ -23,5 +23,21 @@ namespace Microsoft.PowerToys.Settings.UI.Views
DataContext = ViewModel; DataContext = ViewModel;
InitializeComponent(); InitializeComponent();
} }
private void TextExtractor_ComboBox_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
/**
* UWP hack
* because UWP load the bound ItemSource of the ComboBox asynchronous,
* so after InitializeComponent() the ItemSource is still empty and can't automatically select a entry.
* Selection via SelectedItem and SelectedValue is still not working too
*/
ViewModel.UpdateLanguages();
}
private void TextExtractor_ComboBox_DropDownOpened(object sender, object e)
{
ViewModel.UpdateLanguages();
}
} }
} }