/* * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Windows.Input; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.SystemComponents; using SafeExamBrowser.Contracts.UserInterface.Shell; namespace SafeExamBrowser.SystemComponents { public class KeyboardLayout : ISystemComponent { private const int TWO_SECONDS = 2000; private KeyboardLayoutDefinition currentLayout; private IList layouts; private ILogger logger; private CultureInfo originalLanguage; private IList controls; private IText text; public KeyboardLayout(ILogger logger, IText text) { this.controls = new List(); this.layouts = new List(); this.logger = logger; this.text = text; } public void Initialize() { originalLanguage = InputLanguageManager.Current.CurrentInputLanguage; logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}."); foreach (CultureInfo info in InputLanguageManager.Current.AvailableInputLanguages) { var layout = new KeyboardLayoutDefinition { CultureCode = info.ThreeLetterISOLanguageName.ToUpper(), CultureInfo = info, Name = info.NativeName }; if (originalLanguage.Equals(info)) { currentLayout = layout; } layouts.Add(layout); logger.Info($"Detected keyboard layout {ToString(info)}."); } InputLanguageManager.Current.InputLanguageChanged += Current_InputLanguageChanged; } public void Register(ISystemKeyboardLayoutControl control) { foreach (var layout in layouts) { control.Add(layout); } control.LayoutSelected += Control_LayoutSelected; control.SetCurrent(currentLayout); control.SetInformation(GetInfoTextFor(currentLayout)); controls.Add(control); } public void Terminate() { InputLanguageManager.Current.InputLanguageChanged -= Current_InputLanguageChanged; if (originalLanguage != null) { InputLanguageManager.Current.CurrentInputLanguage = originalLanguage; logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}."); } foreach (var control in controls) { control.Close(); } } private void Control_LayoutSelected(Guid id) { var layout = layouts.First(l => l.Id == id); logger.Info($"Changing keyboard layout to {ToString(layout.CultureInfo)}."); InputLanguageManager.Current.CurrentInputLanguage = layout.CultureInfo; } private void Current_InputLanguageChanged(object sender, InputLanguageEventArgs e) { var newLayout = layouts.First(l => l.CultureInfo.Equals(e.NewLanguage)); logger.Info($"Detected keyboard layout change from {ToString(e.PreviousLanguage)} to {ToString(e.NewLanguage)}."); currentLayout = newLayout; foreach (var control in controls) { control.SetCurrent(newLayout); control.SetInformation(GetInfoTextFor(newLayout)); } } private string GetInfoTextFor(KeyboardLayoutDefinition layout) { return text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureInfo.NativeName); } private string ToString(CultureInfo info) { return $"'{info.DisplayName}' ({info.ThreeLetterISOLanguageName.ToUpper()})"; } } }