From a4d1904b811f389f841d60ea227522dafa20534d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20B=C3=BCchel?= Date: Tue, 26 Apr 2022 16:45:53 +0200 Subject: [PATCH] SEBWIN-536, #349: Fixed keyboard system component to correctly display all installed keyboard layouts / input languages. --- .../Keyboard/IKeyboardLayout.cs | 7 ++- .../Keyboard/Keyboard.cs | 61 ++++++++++--------- .../Keyboard/KeyboardLayout.cs | 12 +++- .../ActionCenter/KeyboardLayoutButton.xaml | 11 +++- .../ActionCenter/KeyboardLayoutButton.xaml.cs | 5 +- .../KeyboardLayoutControl.xaml.cs | 4 +- .../Taskbar/KeyboardLayoutButton.xaml | 9 ++- .../Taskbar/KeyboardLayoutButton.xaml.cs | 5 +- .../Taskbar/KeyboardLayoutControl.xaml.cs | 4 +- .../ActionCenter/KeyboardLayoutButton.xaml | 9 ++- .../ActionCenter/KeyboardLayoutButton.xaml.cs | 5 +- .../KeyboardLayoutControl.xaml.cs | 4 +- .../Taskbar/KeyboardLayoutButton.xaml | 9 ++- .../Taskbar/KeyboardLayoutButton.xaml.cs | 5 +- .../Taskbar/KeyboardLayoutControl.xaml.cs | 4 +- 15 files changed, 101 insertions(+), 53 deletions(-) diff --git a/SafeExamBrowser.SystemComponents.Contracts/Keyboard/IKeyboardLayout.cs b/SafeExamBrowser.SystemComponents.Contracts/Keyboard/IKeyboardLayout.cs index 0b2061de..1db3c599 100644 --- a/SafeExamBrowser.SystemComponents.Contracts/Keyboard/IKeyboardLayout.cs +++ b/SafeExamBrowser.SystemComponents.Contracts/Keyboard/IKeyboardLayout.cs @@ -20,6 +20,11 @@ namespace SafeExamBrowser.SystemComponents.Contracts.Keyboard /// string CultureCode { get; } + /// + /// The culture name of this keyboard layout. + /// + string CultureName { get; } + /// /// The unique identifier of the keyboard layout. /// @@ -33,6 +38,6 @@ namespace SafeExamBrowser.SystemComponents.Contracts.Keyboard /// /// The name of this keyboard layout. /// - string Name { get; } + string LayoutName { get; } } } diff --git a/SafeExamBrowser.SystemComponents/Keyboard/Keyboard.cs b/SafeExamBrowser.SystemComponents/Keyboard/Keyboard.cs index ef0e2ded..995f8c9a 100644 --- a/SafeExamBrowser.SystemComponents/Keyboard/Keyboard.cs +++ b/SafeExamBrowser.SystemComponents/Keyboard/Keyboard.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Windows.Forms; using System.Windows.Input; using SafeExamBrowser.Logging.Contracts; using SafeExamBrowser.SystemComponents.Contracts.Keyboard; @@ -19,9 +20,10 @@ namespace SafeExamBrowser.SystemComponents.Keyboard { public class Keyboard : IKeyboard { - private IList layouts; - private ILogger logger; - private CultureInfo originalLanguage; + private readonly IList layouts; + private readonly ILogger logger; + + private InputLanguage originalLanguage; public event LayoutChangedEventHandler LayoutChanged; @@ -33,68 +35,71 @@ namespace SafeExamBrowser.SystemComponents.Keyboard public void ActivateLayout(Guid layoutId) { - var layout = layouts.FirstOrDefault(l => l.Id == layoutId); + var layout = layouts.First(l => l.Id == layoutId); - if (layout != default(KeyboardLayout)) - { - logger.Info($"Changing keyboard layout to {ToString(layout.CultureInfo)}."); - InputLanguageManager.Current.CurrentInputLanguage = layout.CultureInfo; - } - else - { - logger.Error($"Could not find keyboard layout with id '{layoutId}'!"); - } + logger.Info($"Changing keyboard layout to {layout}..."); + InputLanguage.CurrentInputLanguage = layout.InputLanguage; + + layout.IsCurrent = true; + LayoutChanged?.Invoke(layout); } public void Initialize() { - originalLanguage = InputLanguageManager.Current.CurrentInputLanguage; + originalLanguage = InputLanguage.CurrentInputLanguage; logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}."); - foreach (CultureInfo info in InputLanguageManager.Current.AvailableInputLanguages) + foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) { var layout = new KeyboardLayout { - CultureCode = info.ThreeLetterISOLanguageName.ToUpper(), - CultureInfo = info, - IsCurrent = originalLanguage.Equals(info), - Name = info.NativeName + CultureCode = language.Culture.ThreeLetterISOLanguageName.ToUpper(), + CultureName = language.Culture.NativeName, + InputLanguage = language, + IsCurrent = originalLanguage.Equals(language), + LayoutName = language.LayoutName }; layouts.Add(layout); - logger.Info($"Detected keyboard layout {ToString(info)}."); + logger.Info($"Detected keyboard layout {layout}."); } - InputLanguageManager.Current.InputLanguageChanged += Current_InputLanguageChanged; + InputLanguageManager.Current.InputLanguageChanged += InputLanguageManager_InputLanguageChanged; } public IEnumerable GetLayouts() { - return layouts; + return new List(layouts.OrderBy(l => l.CultureName)); } public void Terminate() { - InputLanguageManager.Current.InputLanguageChanged -= Current_InputLanguageChanged; + InputLanguageManager.Current.InputLanguageChanged -= InputLanguageManager_InputLanguageChanged; if (originalLanguage != null) { - InputLanguageManager.Current.CurrentInputLanguage = originalLanguage; + InputLanguage.CurrentInputLanguage = originalLanguage; logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}."); } } - private void Current_InputLanguageChanged(object sender, InputLanguageEventArgs e) + private void InputLanguageManager_InputLanguageChanged(object sender, InputLanguageEventArgs e) { - var layout = layouts.First(l => l.CultureInfo.Equals(e.NewLanguage)); + var layout = layouts.First(l => l.InputLanguage.Culture.Equals(e.NewLanguage)); logger.Info($"Detected keyboard layout change from {ToString(e.PreviousLanguage)} to {ToString(e.NewLanguage)}."); + layout.IsCurrent = true; LayoutChanged?.Invoke(layout); } - private string ToString(CultureInfo info) + private string ToString(InputLanguage language) { - return $"'{info.DisplayName}' ({info.ThreeLetterISOLanguageName.ToUpper()})"; + return $"'{language.Culture.NativeName}' [{language.Culture.ThreeLetterISOLanguageName.ToUpper()}, {language.LayoutName}]"; + } + + private string ToString(CultureInfo culture) + { + return $"'{culture.NativeName}' [{culture.ThreeLetterISOLanguageName.ToUpper()}]"; } } } diff --git a/SafeExamBrowser.SystemComponents/Keyboard/KeyboardLayout.cs b/SafeExamBrowser.SystemComponents/Keyboard/KeyboardLayout.cs index 3d70579d..fe070217 100644 --- a/SafeExamBrowser.SystemComponents/Keyboard/KeyboardLayout.cs +++ b/SafeExamBrowser.SystemComponents/Keyboard/KeyboardLayout.cs @@ -7,23 +7,29 @@ */ using System; -using System.Globalization; +using System.Windows.Forms; using SafeExamBrowser.SystemComponents.Contracts.Keyboard; namespace SafeExamBrowser.SystemComponents.Keyboard { internal class KeyboardLayout : IKeyboardLayout { - internal CultureInfo CultureInfo { get; set; } + internal InputLanguage InputLanguage { get; set; } public string CultureCode { get; set; } + public string CultureName { get; set; } public Guid Id { get; } public bool IsCurrent { get; set; } - public string Name { get; set; } + public string LayoutName { get; set; } public KeyboardLayout() { Id = Guid.NewGuid(); } + + public override string ToString() + { + return $"'{CultureName}' [{CultureCode}, {LayoutName}]"; + } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml index 85af0d8a..abdcaff9 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml @@ -1,8 +1,9 @@ - @@ -23,7 +24,13 @@ - + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs index eb3ef696..44a6f756 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter { internal partial class KeyboardLayoutButton : UserControl { - private IKeyboardLayout layout; + private readonly IKeyboardLayout layout; internal bool IsCurrent { @@ -41,7 +41,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter { Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty); CultureCodeTextBlock.Text = layout.CultureCode; - LayoutNameTextBlock.Text = layout.Name; + CultureNameTextBlock.Text = layout.CultureName; + LayoutNameTextBlock.Text = layout.LayoutName; } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs index 9935acb1..5a1a09f9 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs @@ -77,7 +77,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter private void SetCurrent(IKeyboardLayout layout) { - var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name); + var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName); foreach (var child in LayoutsStackPanel.Children) { @@ -87,7 +87,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter } } - Text.Text = layout.Name; + Text.Text = layout.CultureName; Button.ToolTip = tooltip; } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml index 8c4a4cd8..90170748 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml @@ -3,6 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls" mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250"> @@ -23,7 +24,13 @@ - + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml.cs index 4b7c1786..8dc22819 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutButton.xaml.cs @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar { internal partial class KeyboardLayoutButton : UserControl { - private IKeyboardLayout layout; + private readonly IKeyboardLayout layout; internal bool IsCurrent { @@ -41,7 +41,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar { Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty); CultureCodeTextBlock.Text = layout.CultureCode; - LayoutNameTextBlock.Text = layout.Name; + CultureNameTextBlock.Text = layout.CultureName; + LayoutNameTextBlock.Text = layout.LayoutName; } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutControl.xaml.cs index 0eafc957..a607a677 100644 --- a/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/Controls/Taskbar/KeyboardLayoutControl.xaml.cs @@ -100,8 +100,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar private void SetCurrent(IKeyboardLayout layout) { - var name = layout.Name?.Length > 3 ? String.Join(string.Empty, layout.Name.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.Name; - var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name); + var name = layout.CultureName?.Length > 3 ? String.Join(string.Empty, layout.CultureName.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.CultureName; + var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName); foreach (var child in LayoutsStackPanel.Children) { diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml index 10a91466..b48391c9 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml @@ -3,6 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls" mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250"> @@ -23,7 +24,13 @@ - + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs index 6e07728a..7813146a 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutButton.xaml.cs @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter { internal partial class KeyboardLayoutButton : UserControl { - private IKeyboardLayout layout; + private readonly IKeyboardLayout layout; internal bool IsCurrent { @@ -41,7 +41,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter { Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty); CultureCodeTextBlock.Text = layout.CultureCode; - LayoutNameTextBlock.Text = layout.Name; + CultureNameTextBlock.Text = layout.CultureName; + LayoutNameTextBlock.Text = layout.LayoutName; } } } diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs index bb74a6be..8ff5c7e1 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/ActionCenter/KeyboardLayoutControl.xaml.cs @@ -77,7 +77,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter private void SetCurrent(IKeyboardLayout layout) { - var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name); + var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName); foreach (var child in LayoutsStackPanel.Children) { @@ -87,7 +87,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter } } - Text.Text = layout.Name; + Text.Text = layout.CultureName; Button.ToolTip = tooltip; } } diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml index 4b263182..48f7ba96 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml @@ -3,6 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls" mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250"> @@ -23,7 +24,13 @@ - + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs index 21e61a56..2b0c827a 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutButton.xaml.cs @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar { internal partial class KeyboardLayoutButton : UserControl { - private IKeyboardLayout layout; + private readonly IKeyboardLayout layout; internal bool IsCurrent { @@ -41,7 +41,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar { Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty); CultureCodeTextBlock.Text = layout.CultureCode; - LayoutNameTextBlock.Text = layout.Name; + CultureNameTextBlock.Text = layout.CultureName; + LayoutNameTextBlock.Text = layout.LayoutName; } } } diff --git a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs index 78afa3d0..2c9ab85a 100644 --- a/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs +++ b/SafeExamBrowser.UserInterface.Mobile/Controls/Taskbar/KeyboardLayoutControl.xaml.cs @@ -100,8 +100,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar private void SetCurrent(IKeyboardLayout layout) { - var name = layout.Name?.Length > 3 ? String.Join(string.Empty, layout.Name.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.Name; - var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name); + var name = layout.CultureName?.Length > 3 ? String.Join(string.Empty, layout.CultureName.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.CultureName; + var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName); foreach (var child in LayoutsStackPanel.Children) {