seb-win-refactoring/SafeExamBrowser.SystemComponents/KeyboardLayout.cs

128 lines
3.6 KiB
C#

/*
* 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<ISystemKeyboardLayoutControl>
{
private const int TWO_SECONDS = 2000;
private KeyboardLayoutDefinition currentLayout;
private IList<KeyboardLayoutDefinition> layouts;
private ILogger logger;
private CultureInfo originalLanguage;
private IList<ISystemKeyboardLayoutControl> controls;
private IText text;
public KeyboardLayout(ILogger logger, IText text)
{
this.controls = new List<ISystemKeyboardLayoutControl>();
this.layouts = new List<KeyboardLayoutDefinition>();
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()})";
}
}
}