diff --git a/src/InvvardDev.EZLayoutDisplay.Console/KeyDefinitionProcessor.cs b/src/InvvardDev.EZLayoutDisplay.Console/KeyDefinitionProcessor.cs index 23ffae37..d6cedb62 100644 --- a/src/InvvardDev.EZLayoutDisplay.Console/KeyDefinitionProcessor.cs +++ b/src/InvvardDev.EZLayoutDisplay.Console/KeyDefinitionProcessor.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading.Tasks; using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Model.Enum; using Newtonsoft.Json; @@ -14,9 +13,7 @@ public class KeyDefinitionProcessor private const string KeyDefinitionInputFilename = "keyDefinitions.json"; private const string KeyDefinitionOutputFilename = "keyDefinitions.output.json"; - public KeyDefinitionProcessor() { } - - public async void RunProcess() + public void RunProcess() { if (!CheckKeyDefinitionJsExists()) { diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml.cs index 168f9fcb..2a152cb0 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml.cs @@ -1,4 +1,9 @@ -using GalaSoft.MvvmLight.Threading; +using System.Globalization; +using System.Windows; +using System.Windows.Threading; +using GalaSoft.MvvmLight.Threading; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop { @@ -7,9 +12,59 @@ namespace InvvardDev.EZLayoutDisplay.Desktop /// public partial class App { - static App() + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + public App() { DispatcherHelper.Initialize(); + DispatcherUnhandledException += OnDispatcherUnhandledException; + } + + protected override void OnStartup(StartupEventArgs e) + { + ProcessArgs(e.Args); + base.OnStartup(e); + } + + protected void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + Logger.Error(e.Exception, "Unhandled exception", sender); + MessageBox.Show("Something went horribly wrong...\nBut I landed on my feet like a cat !\n\nCheck logs to get more details.", + "Almost crashed...", + MessageBoxButton.OK, + MessageBoxImage.Error); + + e.Handled = true; + } + + private void ProcessArgs(string[] args) + { + foreach (var arg in args) + { + switch (arg) + { + case var val when val.StartsWith("-loglevel=", true, CultureInfo.InvariantCulture): + (string key, string value) = SplitArg(arg); + + LogLevel level = LoggerHelper.GetLogLevel(value); + LoggerHelper.AdjustLogLevel(level); + + break; + } + } + } + + private (string, string) SplitArg(string arg) + { + var (key, value) = ("", ""); + var splitted = arg.Split('='); + + if (splitted.Length <= 1) return (key, value); + + key = splitted[0]; + value = splitted[1]; + + return (key, value); } } -} +} \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/EZLayoutMaker.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/EZLayoutMaker.cs index 26bb4c7b..42f0fa9f 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/EZLayoutMaker.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/EZLayoutMaker.cs @@ -3,11 +3,14 @@ using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Model.Dictionary; using InvvardDev.EZLayoutDisplay.Desktop.Model.Enum; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.Helper { public class EZLayoutMaker { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private const string NoCommand = "KC_NO"; private const string TransparentKey = "KC_TRANSPARENT"; private const string KeyCodeOsm = "OSM"; @@ -15,11 +18,15 @@ public class EZLayoutMaker public EZLayoutMaker() { + Logger.TraceConstructor(); _keyDefinitionDictionary = new KeyDefinitionDictionary(); } public EZLayout PrepareEZLayout(ErgodoxLayout ergodoxLayout) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(ergodoxLayout), ergodoxLayout); + var ezLayout = new EZLayout { HashId = ergodoxLayout.HashId, Name = ergodoxLayout.Title @@ -31,29 +38,39 @@ public EZLayout PrepareEZLayout(ErgodoxLayout ergodoxLayout) ezLayout.EZLayers.Add(ezLayer); } + Logger.DebugOutputParam(nameof(ezLayout), ezLayout); + return ezLayout; } private EZLayer PrepareEZLayer(ErgodoxLayer ergodoxLayer) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(ergodoxLayer), ergodoxLayer); + var layer = new EZLayer { Index = ergodoxLayer.Position, Name = ergodoxLayer.Title, Color = ergodoxLayer.Color }; - for (var index = 0 ; index < ergodoxLayer.Keys.Count ; index++) + foreach (var ergodoxKey in ergodoxLayer.Keys) { - EZKey key = PrepareKeyLabels(ergodoxLayer.Keys[index], index); + EZKey key = PrepareKeyLabels(ergodoxKey); layer.EZKeys.Add(key); } + Logger.DebugOutputParam(nameof(layer), layer); + return layer; } - private EZKey PrepareKeyLabels(ErgodoxKey ergodoxKey, int keyIndex) + private EZKey PrepareKeyLabels(ErgodoxKey ergodoxKey) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(ergodoxKey), ergodoxKey); + KeyDefinition keyDefinition = GetKeyDefinition(ergodoxKey.Code); /** Every category has a label, so no need to make a special case : @@ -145,12 +162,20 @@ private EZKey PrepareKeyLabels(ErgodoxKey ergodoxKey, int keyIndex) ProcessModifiers(ergodoxKey, key); + Logger.DebugOutputParam(nameof(key), key); + return key; } private KeyDefinition GetKeyDefinition(string ergodoxKeyCode) { - var keyDefinition = _keyDefinitionDictionary.KeyDefinitions.FirstOrDefault(k => k.KeyCode == ergodoxKeyCode) ?? GetKeyDefinition(TransparentKey); + var keyDefinition = _keyDefinitionDictionary.KeyDefinitions.FirstOrDefault(k => k.KeyCode == ergodoxKeyCode); + + if (keyDefinition == null) + { + Logger.Warn("Key code '{0}' unknown", ergodoxKeyCode); + keyDefinition = GetKeyDefinition(TransparentKey); + } return keyDefinition; } @@ -234,7 +259,7 @@ private List GetModifiersApplied(ErgodoxModifiers ergodoxModifiers) private string AggregateModifierLabels(List mods) { - var subLabel = ""; + string subLabel; switch (mods.Count) { diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/LoggerHelper.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/LoggerHelper.cs new file mode 100644 index 00000000..e2ad4c90 --- /dev/null +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Helper/LoggerHelper.cs @@ -0,0 +1,95 @@ +using System.Runtime.CompilerServices; +using NLog; + +namespace InvvardDev.EZLayoutDisplay.Desktop.Helper +{ + public static class LoggerHelper + { + internal static void TraceMethod(this Logger logger, + string message = "[Method] {0} (line {1})", + [ CallerMemberName ] string memberName = "", + [ CallerFilePath ] string sourceFilePath = "", + [ CallerLineNumber ] int sourceLineNumber = 0) + { + logger.Trace(message, memberName, sourceLineNumber); + } + + internal static void TraceRelayCommand(this Logger logger, + string message = "[Relay Command] {0} (line {1})", + [ CallerMemberName ] string memberName = "", + [ CallerFilePath ] string sourceFilePath = "", + [ CallerLineNumber ] int sourceLineNumber = 0) + { + logger.Trace(message, memberName, sourceLineNumber); + } + + internal static void TraceConstructor(this Logger logger, + string message = "[Constructor] {0} (line {1})", + [ CallerMemberName ] string memberName = "", + [ CallerFilePath ] string sourceFilePath = "", + [ CallerLineNumber ] int sourceLineNumber = 0) + { + logger.Trace(message, memberName, sourceLineNumber); + } + + internal static void DebugInputParam(this Logger logger, + string parameterName, + object parameter, + string message = "[Input {method}] {parameterName} = {@parameterValue})", + [ CallerMemberName ] string memberName = "") + { + DebugParam(logger, parameterName, parameter, message, memberName); + } + + internal static void DebugOutputParam(this Logger logger, + string parameterName, + object parameter, + string message = "[Output {method}] {parameterName} = {@parameterValue})", + [ CallerMemberName ] string memberName = "") + { + DebugParam(logger, parameterName, parameter, message, memberName); + } + + private static void DebugParam(Logger logger, + string parameterName, + object parameter, + string message, + string memberName) + { + logger.Debug(message, memberName, parameterName, parameter); + } + + internal static LogLevel GetLogLevel(string value) + { + LogLevel level; + + switch (value.ToLower()) + { + case "debug": + level = LogLevel.Debug; + + break; + case "trace": + level = LogLevel.Trace; + + break; + default: + level = LogLevel.Warn; + + break; + } + + return level; + } + + internal static void AdjustLogLevel(LogLevel logLevel) + { + var target = LogManager.Configuration.FindTargetByName("logfile"); + + if (target != null) + { + LogManager.Configuration.AddRule(logLevel, LogLevel.Fatal, target); + } + } + } +} \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/InvvardDev.EZLayoutDisplay.Desktop.csproj b/src/InvvardDev.EZLayoutDisplay.Desktop/InvvardDev.EZLayoutDisplay.Desktop.csproj index f4e87b10..e97b739f 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/InvvardDev.EZLayoutDisplay.Desktop.csproj +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/InvvardDev.EZLayoutDisplay.Desktop.csproj @@ -74,12 +74,20 @@ ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\NLog.4.5.11\lib\net45\NLog.dll + - ..\packages\NonInvasiveKeyboardHookLibrary.1.3.0\lib\net452\NonInvasiveKeyboardHookLibrary.dll + ..\packages\NonInvasiveKeyboardHookLibrary.1.4.0\lib\net452\NonInvasiveKeyboardHookLibrary.dll + + + + + ..\packages\MvvmLightLibs.5.4.1.1\lib\net45\System.Windows.Interactivity.dll @@ -102,6 +110,7 @@ Designer + @@ -142,6 +151,7 @@ + @@ -206,6 +216,9 @@ + + Always + PublicSettingsSingleFileGenerator Settings.Designer.cs diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Dictionary/KeyDefinitionDictionary.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Dictionary/KeyDefinitionDictionary.cs index a51cc8d6..f2d69140 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Dictionary/KeyDefinitionDictionary.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Dictionary/KeyDefinitionDictionary.cs @@ -1,32 +1,50 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Text; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Properties; using Newtonsoft.Json; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.Model.Dictionary { public class KeyDefinitionDictionary { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + public List KeyDefinitions { get; private set; } public KeyDefinitionDictionary() { + Logger.TraceConstructor(); InitializeKeyDefinitions(); } private void InitializeKeyDefinitions() { + Logger.TraceMethod(); KeyDefinitions = new List(); if (Resources.keyDefinitions.Length <= 0) { - // TODO : add logging + Logger.Warn("KeyDefinitioins are missing from Resources"); return; } - var json = Encoding.Default.GetString(Resources.keyDefinitions); + try + { + var json = Encoding.Default.GetString(Resources.keyDefinitions); + Logger.Debug($"Resource content = {json}"); + + var keyDefinitions = JsonConvert.DeserializeObject>(json); + Logger.Debug("Key definitions {@value1}", keyDefinitions); - KeyDefinitions.AddRange(JsonConvert.DeserializeObject>(json)); + KeyDefinitions.AddRange(keyDefinitions); + } + catch (Exception ex) + { + Logger.Error(ex); + } } } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/NLog.config b/src/InvvardDev.EZLayoutDisplay.Desktop/NLog.config new file mode 100644 index 00000000..3ca14974 --- /dev/null +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/NLog.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/ApplicationService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/ApplicationService.cs index 268ab7fd..2ef96a21 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/ApplicationService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/ApplicationService.cs @@ -1,13 +1,18 @@ using System.Windows; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation { public class ApplicationService : IApplicationService { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + /// public void ShutdownApplication() - { + { + Logger.TraceMethod(); Application.Current.Shutdown(); } } diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/KeyboardHookService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/KeyboardHookService.cs index 001276a3..0b8aa1cc 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/KeyboardHookService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/KeyboardHookService.cs @@ -1,9 +1,11 @@ using System; using System.Linq; using System.Windows; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using InvvardDev.EZLayoutDisplay.Desktop.View; +using NLog; using NonInvasiveKeyboardHookLibrary; namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation @@ -14,6 +16,7 @@ public class KeyboardHookService : IKeyboardHookService private bool disposed; private static KeyboardHookManager _hook; + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly IWindowService _windowService; private readonly ISettingsService _settingsService; @@ -30,6 +33,8 @@ public class KeyboardHookService : IKeyboardHookService public KeyboardHookService(IWindowService windowService, ISettingsService settingsService) { + Logger.TraceConstructor(); + _windowService = windowService; _settingsService = settingsService; @@ -38,8 +43,12 @@ public KeyboardHookService(IWindowService windowService, ISettingsService settin private void InitKeyboardHook() { + Logger.TraceMethod(); + Hook.Start(); + Logger.Debug("Registered hotkey {@value0}", _settingsService.HotkeyShowLayout); + var hotkeyShowLayout = _settingsService.HotkeyShowLayout; switch (hotkeyShowLayout.ModifierKeys.Count) @@ -63,11 +72,18 @@ private void InitKeyboardHook() public void RegisterHotkey(ModifierKeys modifiers, int keyCode) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(modifiers), modifiers); + Logger.DebugInputParam(nameof(keyCode), keyCode); + Hook.RegisterHotkey(modifiers, keyCode, DisplayLayout); } public void RegisterHotkey(int keyCode) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(keyCode), keyCode); + Hook.RegisterHotkey(keyCode, DisplayLayout); } @@ -77,6 +93,9 @@ public void RegisterHotkey(int keyCode) private static ModifierKeys SumModifiers(Hotkey hotkeyShowLayout) { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(hotkeyShowLayout), hotkeyShowLayout); + var sumModifierKeys = hotkeyShowLayout.ModifierKeys[0]; for (int i = 1; i < hotkeyShowLayout.ModifierKeys.Count; i++) @@ -84,11 +103,15 @@ private static ModifierKeys SumModifiers(Hotkey hotkeyShowLayout) sumModifierKeys = sumModifierKeys | hotkeyShowLayout.ModifierKeys[i]; } + Logger.DebugOutputParam(nameof(sumModifierKeys), sumModifierKeys); + return sumModifierKeys; } private void DisplayLayout() { + Logger.TraceMethod(); + Application.Current.Dispatcher.Invoke(delegate { _windowService.ShowWindow(); diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs index 97246378..f0c2ea4b 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs @@ -8,11 +8,13 @@ using InvvardDev.EZLayoutDisplay.Desktop.Properties; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using Newtonsoft.Json; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation { public class LayoutService : ILayoutService { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly string GetLayoutBody = "{{\"operationName\":\"getLayout\",\"variables\":{{\"hashId\":\"{0}\"}},\"query\":\"query getLayout($hashId: String!) {{\\n Layout(hashId: $hashId) {{\\n ...LayoutData\\n }}\\n}}\\n\\nfragment LayoutData on Layout {{\\n hashId\\n title\\n revisions {{\\n hashId\\n model\\n layers {{\\n hashId\\n keys\\n position\\n title\\n color\\n }}\\n}}\\n}}\\n\"}}"; @@ -23,19 +25,36 @@ public class LayoutService : ILayoutService /// public async Task GetErgodoxLayout(string layoutHashId) { - if (string.IsNullOrWhiteSpace(layoutHashId)) { throw new ArgumentNullException(nameof(layoutHashId), "Layout hash ID was not found."); } + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(layoutHashId), layoutHashId); + + if (string.IsNullOrWhiteSpace(layoutHashId)) + { + Logger.Error("Layout {0} was not found", layoutHashId); + throw new ArgumentNullException(nameof(layoutHashId), $"Layout hash ID \"{layoutHashId}\" was not found."); + } DataRoot layout; using (HttpClient client = new HttpClient()) { var body = string.Format(GetLayoutBody, layoutHashId); + Logger.Debug("Request body : {@body}", body); + var response = await client.PostAsync(GetLayoutRequestUri, new StringContent(body, Encoding.UTF8, "application/json")); + Logger.Debug("Response : {@response}", response); + var result = await response.Content.ReadAsStringAsync(); + Logger.Debug("Content result : {@result}", result); layout = JsonConvert.DeserializeObject(result); + Logger.Debug("Deserialized layout : {@layout}", layout); - if (layout?.LayoutRoot?.Layout == null) { throw new ArgumentException(layoutHashId, $"Hash ID \"{layoutHashId}\" does not exist"); } + if (layout?.LayoutRoot?.Layout == null) + { + Logger.Error("Layout {0} does not exist", layoutHashId); + throw new ArgumentException(layoutHashId, $"Hash ID \"{layoutHashId}\" does not exist"); + } } return layout.LayoutRoot.Layout; @@ -44,6 +63,8 @@ public async Task GetErgodoxLayout(string layoutHashId) /// public EZLayout PrepareEZLayout(ErgodoxLayout ergodoxLayout) { + Logger.TraceMethod(); + var ezLayoutMaker = new EZLayoutMaker(); EZLayout ezLayout = ezLayoutMaker.PrepareEZLayout(ergodoxLayout); @@ -53,6 +74,8 @@ public EZLayout PrepareEZLayout(ErgodoxLayout ergodoxLayout) /// public async Task> GetLayoutTemplate() { + Logger.TraceMethod(); + IEnumerable layoutTemplate = await ReadLayoutDefinition(); return layoutTemplate; @@ -64,9 +87,11 @@ public async Task> GetLayoutTemplate() private async Task> ReadLayoutDefinition() { + Logger.TraceMethod(); + if (Resources.layoutDefinition.Length <= 0) { - // TODO : add logging + Logger.Warn("Layout definition is empty"); return new List(); } @@ -78,6 +103,8 @@ private async Task> ReadLayoutDefinition() return layoutDefinition; }); + Logger.DebugOutputParam(nameof(layoutTemplate), layoutTemplate); + return layoutTemplate; } diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/SettingsService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/SettingsService.cs index a098518a..3bfa88bc 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/SettingsService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/SettingsService.cs @@ -1,10 +1,12 @@ using System; using System.Windows.Forms; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Model.Enum; using InvvardDev.EZLayoutDisplay.Desktop.Properties; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using Newtonsoft.Json; +using NLog; using ModifierKeys = NonInvasiveKeyboardHookLibrary.ModifierKeys; namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation @@ -19,6 +21,7 @@ public class SettingsService : ISettingsService #region Fields + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly Settings _settings; #endregion @@ -27,16 +30,14 @@ public class SettingsService : ISettingsService public SettingsService(Settings settings) { + Logger.TraceConstructor(); + _settings = settings; _defaultHotkey = new Hotkey(Keys.Space, ModifierKeys.Alt, ModifierKeys.Control, ModifierKeys.Shift, ModifierKeys.WindowsKey); } #endregion - #region Private methods - - #endregion - #region ISettingService implementation #region Properties @@ -46,22 +47,34 @@ public Hotkey HotkeyShowLayout { get { + Logger.TraceMethod(); Hotkey hotkey; try { var setting = (string) _settings[SettingsName.HotkeyShowLayout]; + Logger.Debug("SettingsName.HotkeyShowLayout value = '{setting}'", setting); hotkey = string.IsNullOrWhiteSpace(setting) ? _defaultHotkey : JsonConvert.DeserializeObject(setting); + Logger.Debug("Loaded hotkey = {@hotkey}", hotkey); + } + catch (Exception ex) + { + Logger.Error(ex, "Exception catched in '{0}' getter :\n", nameof(HotkeyShowLayout)); + hotkey = _defaultHotkey; } - catch (Exception) { hotkey = _defaultHotkey; } + + Logger.DebugOutputParam(nameof(hotkey), hotkey); return hotkey; } set { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(HotkeyShowLayout), value); + var setting = JsonConvert.SerializeObject(value); _settings[SettingsName.HotkeyShowLayout] = setting; } @@ -70,8 +83,22 @@ public Hotkey HotkeyShowLayout /// public string ErgodoxLayoutUrl { - get => (string) _settings[SettingsName.ErgodoxLayoutUrl]; - set => _settings[SettingsName.ErgodoxLayoutUrl] = value; + get + { + Logger.TraceMethod(); + + var url = (string) _settings[SettingsName.ErgodoxLayoutUrl]; + Logger.DebugOutputParam(nameof(ErgodoxLayoutUrl), url); + + return url; + } + set + { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(ErgodoxLayoutUrl), value); + + _settings[SettingsName.ErgodoxLayoutUrl] = value; + } } /// @@ -79,16 +106,35 @@ public EZLayout EZLayout { get { - var setting = (string) _settings[SettingsName.EZLayout]; - var ezLayout = string.IsNullOrWhiteSpace(setting) + Logger.TraceMethod(); + EZLayout ezLayout; + + try + { + var setting = (string) _settings[SettingsName.EZLayout]; + Logger.Debug("SettingsName.EZLayout value = '{setting}'", setting); + + ezLayout = string.IsNullOrWhiteSpace(setting) ? new EZLayout() : JsonConvert.DeserializeObject(setting); + Logger.Debug("Loaded Layout = {@ezLayout}", ezLayout); + } + catch (Exception ex) + { + Logger.Error(ex, "Exception catched in '{0}' getter :\n", nameof(EZLayout)); + ezLayout = new EZLayout(); + } + + Logger.DebugOutputParam(nameof(EZLayout), ezLayout); return ezLayout; } set { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(EZLayout), value); + var setting = JsonConvert.SerializeObject(value); _settings[SettingsName.EZLayout] = setting; } @@ -99,15 +145,21 @@ public EZLayout EZLayout /// public void Save() { + Logger.TraceMethod(); _settings.Save(); } /// public void Cancel() { + Logger.TraceMethod(); _settings.Reload(); } #endregion + + #region Private methods + + #endregion } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/WindowService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/WindowService.cs index 7a87bcee..d471ce90 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/WindowService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/WindowService.cs @@ -1,15 +1,19 @@ using System.Collections.Generic; using System.Windows; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation { - public class WindowService: IWindowService + public class WindowService : IWindowService { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly Dictionary _windows; public WindowService() { + Logger.TraceConstructor(); _windows = new Dictionary(); } @@ -18,9 +22,17 @@ public WindowService() public void ShowWindow() where T : Window, new() { + Logger.TraceMethod(); + Logger.Info("Opening {windowType} window", typeof(T)); + var windowKey = typeof(T).ToString(); + + Logger.Debug("Windows opened list : {@windows}", _windows); + if (!_windows.ContainsKey(windowKey)) { + Logger.Debug("{windowType} window added", typeof(T)); + _windows.Add(windowKey, new T()); _windows[windowKey].Closing += WindowService_Closing; } @@ -31,18 +43,26 @@ public void ShowWindow() public void CloseWindow() { + Logger.TraceMethod(); + Logger.Info("Closing {windowType} window", typeof(T)); + var windowKey = typeof(T).ToString(); if (_windows.ContainsKey(windowKey)) { + Logger.Debug("{windowType} window is going to be closed", typeof(T)); _windows[windowKey].Close(); } } public bool ShowWarning(string warningMessage) { + Logger.TraceMethod(); + var result = MessageBox.Show(warningMessage, "Warning", MessageBoxButton.OK, MessageBoxImage.Warning) == MessageBoxResult.OK; + Logger.DebugOutputParam(nameof(result), result); + return result; } @@ -50,9 +70,18 @@ public bool ShowWarning(string warningMessage) private void WindowService_Closing(object sender, System.ComponentModel.CancelEventArgs e) { + Logger.TraceMethod(); + var windowKey = sender.GetType().ToString(); + Logger.Debug("Window {window} is closing", windowKey); + + if (_windows.ContainsKey(windowKey)) + { + Logger.Debug("Finalizing {windowType} window close", windowKey); - if (_windows.ContainsKey(windowKey)) { _windows.Remove(windowKey); } + _windows[windowKey].Closing -= WindowService_Closing; + _windows.Remove(windowKey); + } } } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILoggingService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILoggingService.cs new file mode 100644 index 00000000..67fd99a8 --- /dev/null +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILoggingService.cs @@ -0,0 +1,7 @@ +namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Interface +{ + public interface ILoggingService + { + + } +} \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/AboutViewModel.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/AboutViewModel.cs index 7ba8992a..7d38636b 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/AboutViewModel.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/AboutViewModel.cs @@ -1,11 +1,14 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Windows.Input; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.CommandWpf; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using InvvardDev.EZLayoutDisplay.Desktop.View; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.ViewModel { @@ -13,7 +16,9 @@ public class AboutViewModel : ViewModelBase { #region Fields - private IWindowService _windowService; + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + private readonly IWindowService _windowService; private string _windowTitle; private string _appTitleLabel; @@ -148,17 +153,14 @@ public string CloseButtonLabel _closeAboutCommand ?? (_closeAboutCommand = new RelayCommand(CloseAboutWindow)); - private void CloseAboutWindow() - { - _windowService.CloseWindow(); - } - #endregion #region Constructor public AboutViewModel(IWindowService windowService) { + Logger.TraceConstructor(); + _windowService = windowService; _basedOnUrl = "https://configure.ergodox-ez.com/layouts/default/latest/0"; @@ -191,6 +193,8 @@ private void SetLabelUi() private static string GetAppTitle() { + Logger.TraceMethod(); + var appTitle = "EZ Layout Display"; var customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false).FirstOrDefault(); @@ -205,19 +209,28 @@ private static string GetAppTitle() private void NavigateBasedOnUrl() { + Logger.TraceRelayCommand(); Process.Start(_basedOnUrl); } private void NavigateProjectHomeUrl() { + Logger.TraceRelayCommand(); Process.Start(_projectHomeUrl); } private void NavigateContactUrl() { + Logger.TraceRelayCommand(); Process.Start(_contactUrl); } + private void CloseAboutWindow() + { + Logger.TraceRelayCommand(); + _windowService.CloseWindow(); + } + #endregion } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/DisplayLayoutViewModel.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/DisplayLayoutViewModel.cs index a59705b9..25f798ac 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/DisplayLayoutViewModel.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/DisplayLayoutViewModel.cs @@ -8,6 +8,7 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.Messaging; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Model.Enum; using InvvardDev.EZLayoutDisplay.Desktop.Model.Messenger; @@ -15,6 +16,7 @@ using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using InvvardDev.EZLayoutDisplay.Desktop.View; using Newtonsoft.Json; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.ViewModel { @@ -22,6 +24,8 @@ public class DisplayLayoutViewModel : ViewModelBase { #region Fields + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly IWindowService _windowService; private readonly ILayoutService _layoutService; private readonly ISettingsService _settingsService; @@ -99,6 +103,8 @@ public int CurrentLayerIndex public DisplayLayoutViewModel(IWindowService windowService, ILayoutService layoutService, ISettingsService settingsService) { + Logger.TraceConstructor(); + _windowService = windowService; _layoutService = layoutService; _settingsService = settingsService; @@ -120,6 +126,7 @@ private void SetLabelUi() private async void LoadCompleteLayout() { + Logger.TraceMethod(); CurrentLayerIndex = 0; if (IsInDesignModeStatic) @@ -130,6 +137,7 @@ private async void LoadCompleteLayout() } _ezLayout = _settingsService.EZLayout; + Logger.Debug("EZLayout = {@value0}", _ezLayout); _layoutTemplates = new List>(); @@ -137,7 +145,9 @@ private async void LoadCompleteLayout() || !_ezLayout.EZLayers.Any() || !_ezLayout.EZLayers.SelectMany(l => l.EZKeys).Any()) { + Logger.Info("No layout available"); NoLayoutAvailable = true; + return; } @@ -149,6 +159,8 @@ private async void LoadCompleteLayout() private void LoadDesignTimeModel() { + Logger.TraceMethod(); + NoLayoutAvailable = false; var json = Encoding.Default.GetString(Resources.layoutDefinition); @@ -176,21 +188,16 @@ private void LoadDesignTimeModel() CurrentLayoutTemplate[i].EZKey = new EZKey { Label = new KeyLabel("E"), Modifier = new KeyLabel("Left Shift"), - KeyCategory = KeyCategory.French, - InternationalHint = "fr" - }; + KeyCategory = KeyCategory.French, + InternationalHint = "fr" + }; } } - private async Task> LoadLayoutDefinition() - { - var layoutDefinition = await _layoutService.GetLayoutTemplate(); - - return layoutDefinition; - } - private async Task PopulateLayoutTemplates() { + Logger.TraceMethod(); + foreach (var t in _ezLayout.EZLayers) { if (!(await LoadLayoutDefinition() is List layoutTemplate)) break; @@ -204,36 +211,42 @@ private async Task PopulateLayoutTemplates() } } + private async Task> LoadLayoutDefinition() + { + Logger.TraceMethod(); + var layoutDefinition = await _layoutService.GetLayoutTemplate(); + + return layoutDefinition; + } + private void SwitchLayer() { + Logger.TraceMethod(); + Logger.Info("Switch to Layer {0} on {1}", CurrentLayerIndex, _layoutTemplates.Count - 1); + if (_layoutTemplates.Any()) { CurrentLayoutTemplate = new ObservableCollection(_layoutTemplates[CurrentLayerIndex]); } } - #region Delegates private void LoadCompleteLayout(UpdatedLayoutMessage obj) { + Logger.TraceMethod("Intercept {0} message"); LoadCompleteLayout(); } private void LostFocus() { + Logger.TraceRelayCommand(); _windowService.CloseWindow(); } - private bool NextLayerCanExecute() - { - var canExecute = _layoutTemplates.Any(); - - return canExecute; - } - private void NextLayer() { + Logger.TraceRelayCommand(); var maxLayerIndex = _ezLayout.EZLayers.Count - 1; switch (CurrentLayerIndex) @@ -252,6 +265,13 @@ private void NextLayer() SwitchLayer(); } + private bool NextLayerCanExecute() + { + var canExecute = _layoutTemplates.Any(); + + return canExecute; + } + #endregion #endregion diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/MainViewModel.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/MainViewModel.cs index 058ca6c0..d9d756a5 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/MainViewModel.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/MainViewModel.cs @@ -1,8 +1,10 @@ using System.Windows.Input; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.CommandWpf; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using InvvardDev.EZLayoutDisplay.Desktop.View; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.ViewModel { @@ -16,6 +18,8 @@ public class MainViewModel : ViewModelBase { #region Fields + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private ICommand _showLayoutCommand; private ICommand _showSettingsCommand; private ICommand _showAboutCommand; @@ -97,6 +101,8 @@ public string TrayMenuExitCommandLabel /// public MainViewModel(IWindowService windowService, IApplicationService applicationService) { + Logger.TraceConstructor(); + _windowService = windowService; _applicationService = applicationService; @@ -118,31 +124,28 @@ private void SetLabelUi() private void ShowLayoutWindow() { + Logger.TraceRelayCommand(); _windowService.ShowWindow(); } private void ShowSettingsWindow() { + Logger.TraceRelayCommand(); _windowService.ShowWindow(); } private void ShowAboutWindow() { + Logger.TraceRelayCommand(); _windowService.ShowWindow(); } private void ShutdownApplication() { + Logger.TraceRelayCommand(); _applicationService.ShutdownApplication(); } #endregion - - ////public override void Cleanup() - ////{ - //// // Clean up if needed - - //// base.Cleanup(); - ////} } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/SettingsViewModel.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/SettingsViewModel.cs index f9338d35..d1282c23 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/SettingsViewModel.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/SettingsViewModel.cs @@ -5,10 +5,12 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.Messaging; +using InvvardDev.EZLayoutDisplay.Desktop.Helper; using InvvardDev.EZLayoutDisplay.Desktop.Model; using InvvardDev.EZLayoutDisplay.Desktop.Model.Messenger; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; using InvvardDev.EZLayoutDisplay.Desktop.View; +using NLog; namespace InvvardDev.EZLayoutDisplay.Desktop.ViewModel { @@ -16,6 +18,8 @@ public class SettingsViewModel : ViewModelBase { #region Fields + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly ISettingsService _settingsService; private readonly IWindowService _windowService; private readonly ILayoutService _layoutService; @@ -123,28 +127,31 @@ public string LayoutUrlContent get => _layoutUrlContent; set { - if (Set(ref _layoutUrlContent, value)) { UpdateButtonCanExecute(); } + if (Set(ref _layoutUrlContent, value)) + { + UpdateButtonCanExecute(); + } } } - + public string AltModifierLabel { get => _altModifierLabel; set => Set(ref _altModifierLabel, value); } - + public string CtrlModifierLabel { get => _ctrlModifierLabel; set => Set(ref _ctrlModifierLabel, value); } - + public string ShiftModifierLabel { get => _shiftModifierLabel; set => Set(ref _shiftModifierLabel, value); } - + public string WindowsModifierLabel { get => _windowsModifierLabel; @@ -163,6 +170,8 @@ public Hotkey HotkeyShowLayout public SettingsViewModel(ISettingsService settingsService, IWindowService windowService, ILayoutService layoutService) { + Logger.TraceConstructor(); + _settingsService = settingsService; _windowService = windowService; _layoutService = layoutService; @@ -199,6 +208,8 @@ private void SetSettingControls() private async void SaveSettings() { + Logger.TraceMethod(); + await UpdateLayout(); _settingsService.ErgodoxLayoutUrl = LayoutUrlContent; @@ -213,6 +224,8 @@ private async void SaveSettings() private void CancelSettings() { + Logger.TraceRelayCommand(); + _settingsService.Cancel(); LayoutUrlContent = _settingsService.ErgodoxLayoutUrl; @@ -221,17 +234,22 @@ private void CancelSettings() private void CloseSettingsWindow() { + Logger.TraceRelayCommand(); + if (IsDirty()) { SaveSettings(); } + _windowService.CloseWindow(); } private void UpdateButtonCanExecute() { - ((RelayCommand)ApplySettingsCommand).RaiseCanExecuteChanged(); - ((RelayCommand)CancelSettingsCommand).RaiseCanExecuteChanged(); + Logger.TraceMethod(); + + ((RelayCommand) ApplySettingsCommand).RaiseCanExecuteChanged(); + ((RelayCommand) CancelSettingsCommand).RaiseCanExecuteChanged(); } private bool IsDirty() @@ -243,20 +261,39 @@ private bool IsDirty() private async Task UpdateLayout() { + Logger.TraceMethod(); + var layoutHashId = ExtractLayoutHashId(LayoutUrlContent); + Logger.Debug("Layout Hash ID = {0}", layoutHashId); + try { var ergodoxLayout = await _layoutService.GetErgodoxLayout(layoutHashId); + Logger.Debug("ergodoxLayout = {@value0}", ergodoxLayout); + var ezLayout = _layoutService.PrepareEZLayout(ergodoxLayout); + Logger.Debug("ezLayout = {@value0}", ezLayout); + _settingsService.EZLayout = ezLayout; } - catch (ArgumentNullException) { throw; } - catch (ArgumentException aex) { _windowService.ShowWarning(aex.Message); } + catch (ArgumentNullException anex) + { + Logger.Error(anex); + + throw; + } + catch (ArgumentException aex) + { + Logger.Error(aex); + _windowService.ShowWarning(aex.Message); + } } private string ExtractLayoutHashId(string layoutUrl) { + Logger.TraceMethod(); + var layoutHashIdGroupName = "layoutHashId"; var pattern = $"https://configure.ergodox-ez.com/layouts/(?<{layoutHashIdGroupName}>default|[a-zA-Z0-9]{{4}})(?:/latest/[0-9])?"; var layoutHashId = "default"; @@ -264,7 +301,13 @@ private string ExtractLayoutHashId(string layoutUrl) var regex = new Regex(pattern); var match = regex.Match(layoutUrl); - if (match.Success) { layoutHashId = match.Groups[layoutHashIdGroupName].Value; } + if (match.Success) + { + layoutHashId = match.Groups[layoutHashIdGroupName].Value; + } + + Logger.Debug("Layout URL = {0}", layoutUrl); + Logger.Debug("Layout Hash ID = {0}", layoutHashId); return layoutHashId; } diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/ViewModelLocator.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/ViewModelLocator.cs index 9989e67d..918efd8e 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/ViewModelLocator.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/ViewModel/ViewModelLocator.cs @@ -3,6 +3,7 @@ using GalaSoft.MvvmLight.Ioc; using InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation; using InvvardDev.EZLayoutDisplay.Desktop.Service.Interface; +using NLog; using ApplicationService = InvvardDev.EZLayoutDisplay.Desktop.Service.Design.ApplicationService; using KeyboardHookService = InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation.KeyboardHookService; using LayoutService = InvvardDev.EZLayoutDisplay.Desktop.Service.Design.LayoutService; @@ -68,6 +69,7 @@ static ViewModelLocator() public static void Cleanup() { SimpleIoc.Default.GetInstance()?.Dispose(); + LogManager.Shutdown(); } } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/packages.config b/src/InvvardDev.EZLayoutDisplay.Desktop/packages.config index 46d91e8b..8a5d7ae9 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/packages.config +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/packages.config @@ -4,5 +4,6 @@ - + + \ No newline at end of file