2020-04-09 04:53:09 +08:00
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
2020-04-15 00:24:11 +08:00
2020-04-20 23:22:36 +08:00
using System ;
using System.IO ;
using System.Threading ;
2020-04-15 00:24:11 +08:00
using System.Threading.Tasks ;
using System.Windows.Input ;
using Microsoft.PowerToys.Settings.UI.Helpers ;
2020-04-20 23:22:36 +08:00
using Microsoft.PowerToys.Settings.UI.Lib ;
2020-04-15 00:24:11 +08:00
using Microsoft.PowerToys.Settings.UI.Lib.Utilities ;
using Microsoft.PowerToys.Settings.UI.Views ;
namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
public class KeyboardManagerViewModel : Observable
{
2020-04-20 23:22:36 +08:00
private const string PowerToyName = "Keyboard Manager" ;
private const string RemapKeyboardActionName = "RemapKeyboard" ;
private const string RemapKeyboardActionValue = "Open Remap Keyboard Window" ;
private const string EditShortcutActionName = "EditShortcut" ;
private const string EditShortcutActionValue = "Open Edit Shortcut Window" ;
private const string JsonFileType = ".json" ;
private const string ConfigFileMutexName = "PowerToys.KeyboardManager.ConfigMutex" ;
private const int ConfigFileMutexWaitTimeoutMiliSeconds = 1000 ;
2020-04-15 00:24:11 +08:00
private ICommand remapKeyboardCommand ;
private ICommand editShortcutCommand ;
2020-04-20 23:22:36 +08:00
private FileSystemWatcher watcher ;
private KeyboardManagerSettings settings ;
2020-04-15 00:24:11 +08:00
public ICommand RemapKeyboardCommand = > remapKeyboardCommand ? ? ( remapKeyboardCommand = new RelayCommand ( OnRemapKeyboard ) ) ;
public ICommand EditShortcutCommand = > editShortcutCommand ? ? ( editShortcutCommand = new RelayCommand ( OnEditShortcut ) ) ;
public KeyboardManagerViewModel ( )
{
2020-04-20 23:22:36 +08:00
if ( SettingsUtils . SettingsExists ( PowerToyName ) )
{
// Todo: Be more resillent while reading and saving settings.
settings = SettingsUtils . GetSettings < KeyboardManagerSettings > ( PowerToyName ) ;
}
else
{
settings = new KeyboardManagerSettings ( PowerToyName ) ;
SettingsUtils . SaveSettings ( settings . ToJsonString ( ) , PowerToyName ) ;
}
watcher = Helper . GetFileWatcher ( PowerToyName , settings . Properties . ActiveConfiguration . Value + JsonFileType , OnConfigFileUpdate ) ;
2020-04-15 00:24:11 +08:00
}
private async void OnRemapKeyboard ( )
{
await Task . Run ( ( ) = > OnRemapKeyboardBackground ( ) ) ;
}
private async void OnEditShortcut ( )
{
await Task . Run ( ( ) = > OnEditShortcutBackground ( ) ) ;
}
private async Task OnRemapKeyboardBackground ( )
{
Helper . AllowRunnerToForeground ( ) ;
2020-04-20 23:22:36 +08:00
ShellPage . DefaultSndMSGCallback ( Helper . GetSerializedCustomAction ( PowerToyName , RemapKeyboardActionName , RemapKeyboardActionValue ) ) ;
2020-04-15 00:24:11 +08:00
await Task . CompletedTask ;
}
private async Task OnEditShortcutBackground ( )
{
Helper . AllowRunnerToForeground ( ) ;
2020-04-20 23:22:36 +08:00
ShellPage . DefaultSndMSGCallback ( Helper . GetSerializedCustomAction ( PowerToyName , EditShortcutActionName , EditShortcutActionValue ) ) ;
2020-04-15 00:24:11 +08:00
await Task . CompletedTask ;
}
2020-04-20 23:22:36 +08:00
private void OnConfigFileUpdate ( )
{
// Note: FileSystemWatcher raise notification mutiple times for single update operation.
// Todo: Handle duplicate events either by somehow supress them or re-read the configuration everytime since we will be updating the UI only if something is changed.
GetKeyboardManagerConfigFile ( ) ;
}
private void GetKeyboardManagerConfigFile ( )
{
try
{
using ( var configFileMutex = Mutex . OpenExisting ( ConfigFileMutexName ) )
{
if ( configFileMutex . WaitOne ( ConfigFileMutexWaitTimeoutMiliSeconds ) )
{
// update the UI element here.
try
{
var config = SettingsUtils . GetSettings < KeyboadManagerConfigModel > ( PowerToyName , settings . Properties . ActiveConfiguration . Value + JsonFileType ) ;
}
finally
{
// Make sure to release the mutex.
configFileMutex . ReleaseMutex ( ) ;
}
}
}
}
catch ( Exception )
{
// Failed to load the configuration.
}
}
2020-04-15 00:24:11 +08:00
}
}