< Summary

Information
Class: SwitchBlade.Services.SettingsService
Assembly: SwitchBlade
File(s): D:\a\switchblade\switchblade\Services\SettingsService.cs
Tag: 203_23722840422
Line coverage
100%
Covered lines: 123
Uncovered lines: 0
Coverable lines: 123
Total lines: 231
Line coverage: 100%
Branch coverage
100%
Covered branches: 34
Total branches: 34
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Settings()100%11100%
.ctor(...)100%66100%
LoadSettings()100%1616100%
Load(...)100%22100%
SaveSettings()100%66100%
UpdateStartupRegistryEntry()100%44100%
IsStartupEnabled()100%11100%

File(s)

D:\a\switchblade\switchblade\Services\SettingsService.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using SwitchBlade.Contracts;
 4using SwitchBlade.Core;
 5
 6namespace SwitchBlade.Services
 7{
 8    // UserSettings and RefreshBehavior have been moved to Models/ directory
 9
 10    /// <summary>
 11    /// Manages user settings with support for pluggable storage backends.
 12    /// Uses nameof(UserSettings.PropertyName) to ensure Load/Save keys stay in sync.
 13    /// </summary>
 14    public class SettingsService : ISettingsService
 15    {
 16        private const string REGISTRY_KEY = @"Software\SwitchBlade";
 17        private readonly ISettingsStorage _storage;
 18        private readonly IWindowsStartupManager _startupManager;
 19        private readonly ILogger? _logger;
 20        private readonly IProcessFactory _processFactory;
 21
 95022        public UserSettings Settings { get; private set; }
 23        public event Action? SettingsChanged;
 24
 25        /// <summary>
 26        /// Creates a SettingsService with custom storage and startup manager.
 27        /// </summary>
 2228        public SettingsService(ISettingsStorage storage, IWindowsStartupManager startupManager, ILogger? logger = null, 
 2229        {
 2230            _storage = storage ?? throw new ArgumentNullException(nameof(storage));
 2131            _startupManager = startupManager ?? throw new ArgumentNullException(nameof(startupManager));
 2032            _logger = logger;
 2033            _processFactory = processFactory ?? new ProcessFactory(new SystemProcessProvider());
 2034            Settings = new UserSettings();
 2035            LoadSettings();
 2036        }
 37
 38        public void LoadSettings()
 2039        {
 2040            bool settingsDirty = false;
 41
 42            // String Lists
 2043            var excludedProcesses = _storage.GetStringList(nameof(Settings.ExcludedProcesses));
 2044            if (!_storage.HasKey(nameof(Settings.ExcludedProcesses)))
 245                settingsDirty = true;
 46
 2047            if (excludedProcesses.Count > 0)
 148                Settings.ExcludedProcesses = excludedProcesses;
 49
 2050            var disabledPlugins = _storage.GetStringList(nameof(Settings.DisabledPlugins));
 2051            if (!_storage.HasKey(nameof(Settings.DisabledPlugins)))
 252                settingsDirty = true;
 2053            Settings.DisabledPlugins = disabledPlugins;
 54
 55            // Theme
 2056            Settings.CurrentTheme = Load(nameof(Settings.CurrentTheme), "Super Light", ref settingsDirty);
 57
 58            // UI Options
 2059            Settings.EnablePreviews = Load(nameof(Settings.EnablePreviews), true, ref settingsDirty);
 2060            Settings.FadeDurationMs = Load(nameof(Settings.FadeDurationMs), 200, ref settingsDirty);
 2061            Settings.WindowOpacity = Load(nameof(Settings.WindowOpacity), 1.0, ref settingsDirty);
 62
 2063            Settings.ItemHeight = Load(nameof(Settings.ItemHeight), 64.0, ref settingsDirty);
 64
 2065            Settings.WindowWidth = Load(nameof(Settings.WindowWidth), 800.0, ref settingsDirty);
 2066            Settings.WindowHeight = Load(nameof(Settings.WindowHeight), 600.0, ref settingsDirty);
 67
 2068            Settings.ShowIcons = Load(nameof(Settings.ShowIcons), true, ref settingsDirty);
 2069            Settings.HideTaskbarIcon = Load(nameof(Settings.HideTaskbarIcon), true, ref settingsDirty);
 2070            Settings.LaunchOnStartup = Load(nameof(Settings.LaunchOnStartup), false, ref settingsDirty);
 2071            Settings.RunAsAdministrator = Load(nameof(Settings.RunAsAdministrator), false, ref settingsDirty);
 2072            _logger?.Log($"SettingsService: Loaded RunAsAdministrator = {Settings.RunAsAdministrator}");
 73
 74            // Hotkey
 2075            Settings.HotKeyModifiers = Load<uint>(nameof(Settings.HotKeyModifiers), 6, ref settingsDirty);
 2076            Settings.HotKeyKey = Load<uint>(nameof(Settings.HotKeyKey), 0x51, ref settingsDirty);
 2077            _logger?.Log($"SettingsService: Loaded HotKeyKey = {Settings.HotKeyKey}");
 78
 79            // Background Polling
 2080            Settings.EnableBackgroundPolling = Load(nameof(Settings.EnableBackgroundPolling), true, ref settingsDirty);
 2081            Settings.BackgroundPollingIntervalSeconds = Load(nameof(Settings.BackgroundPollingIntervalSeconds), 30, ref 
 82
 83            // Number Shortcuts
 2084            Settings.EnableNumberShortcuts = Load(nameof(Settings.EnableNumberShortcuts), true, ref settingsDirty);
 2085            Settings.NumberShortcutModifier = Load<uint>(nameof(Settings.NumberShortcutModifier), 1, ref settingsDirty);
 86
 87            // Badge Animations
 2088            Settings.EnableBadgeAnimations = Load(nameof(Settings.EnableBadgeAnimations), true, ref settingsDirty);
 89
 90            // Refresh Behavior
 2091            Settings.RefreshBehavior = Load(nameof(Settings.RefreshBehavior), RefreshBehavior.PreserveScroll, ref settin
 92
 93            // Regex Cache Size
 2094            Settings.RegexCacheSize = Load(nameof(Settings.RegexCacheSize), 50, ref settingsDirty);
 95
 96            // Fuzzy Search
 2097            Settings.EnableFuzzySearch = Load(nameof(Settings.EnableFuzzySearch), true, ref settingsDirty);
 98
 99            // Search Highlighting
 20100            Settings.EnableSearchHighlighting = Load(nameof(Settings.EnableSearchHighlighting), true, ref settingsDirty)
 20101            Settings.SearchHighlightColor = Load(nameof(Settings.SearchHighlightColor), "#FF0078D4", ref settingsDirty);
 102
 103            // UIA Worker Timeout
 20104            Settings.UiaWorkerTimeoutSeconds = Load(nameof(Settings.UiaWorkerTimeoutSeconds), 60, ref settingsDirty);
 105
 106            // Sync LaunchOnStartup with actual Windows Run registry state
 20107            bool actualStartupEnabled = _startupManager.IsStartupEnabled();
 20108            if (Settings.LaunchOnStartup != actualStartupEnabled)
 2109            {
 2110                Settings.LaunchOnStartup = actualStartupEnabled;
 2111                settingsDirty = true;
 2112            }
 113
 114            // Check for installer startup marker
 20115            if (_startupManager.CheckAndApplyStartupMarker())
 1116            {
 1117                Settings.LaunchOnStartup = true;
 1118                settingsDirty = true;
 1119            }
 120
 121            // HEAL: If we found any missing/corrupt values, save the clean state now
 20122            if (settingsDirty)
 7123            {
 7124                SaveSettings();
 7125            }
 20126        }
 127
 128        private T Load<T>(string key, T defaultValue, ref bool dirty)
 480129        {
 480130            if (!_storage.HasKey(key))
 25131            {
 25132                dirty = true;
 25133                return defaultValue;
 134            }
 455135            return _storage.GetValue(key, defaultValue);
 480136        }
 137
 138        public void SaveSettings()
 14139        {
 140            try
 14141            {
 142                // String Lists
 14143                _storage.SetStringList(nameof(Settings.ExcludedProcesses), Settings.ExcludedProcesses);
 14144                _storage.SetStringList(nameof(Settings.DisabledPlugins), Settings.DisabledPlugins);
 145
 146                // Theme
 14147                _storage.SetValue(nameof(Settings.CurrentTheme), Settings.CurrentTheme);
 148
 149                // UI Options
 14150                _storage.SetValue(nameof(Settings.EnablePreviews), Settings.EnablePreviews);
 14151                _storage.SetValue(nameof(Settings.FadeDurationMs), Settings.FadeDurationMs);
 14152                _storage.SetValue(nameof(Settings.WindowOpacity), Settings.WindowOpacity);
 14153                _storage.SetValue(nameof(Settings.ItemHeight), Settings.ItemHeight);
 14154                _storage.SetValue(nameof(Settings.WindowWidth), Settings.WindowWidth);
 14155                _storage.SetValue(nameof(Settings.WindowHeight), Settings.WindowHeight);
 156
 14157                _storage.SetValue(nameof(Settings.ShowIcons), Settings.ShowIcons);
 14158                _storage.SetValue(nameof(Settings.HideTaskbarIcon), Settings.HideTaskbarIcon);
 14159                _storage.SetValue(nameof(Settings.LaunchOnStartup), Settings.LaunchOnStartup);
 14160                _storage.SetValue(nameof(Settings.RunAsAdministrator), Settings.RunAsAdministrator);
 14161                _logger?.Log($"SettingsService: Saved RunAsAdministrator = {Settings.RunAsAdministrator}");
 162
 163                // Hotkey
 14164                _storage.SetValue(nameof(Settings.HotKeyModifiers), Settings.HotKeyModifiers);
 14165                _storage.SetValue(nameof(Settings.HotKeyKey), Settings.HotKeyKey);
 166
 167                // Background Polling
 14168                _storage.SetValue(nameof(Settings.EnableBackgroundPolling), Settings.EnableBackgroundPolling);
 14169                _storage.SetValue(nameof(Settings.BackgroundPollingIntervalSeconds), Settings.BackgroundPollingIntervalS
 170
 171                // Number Shortcuts
 14172                _storage.SetValue(nameof(Settings.EnableNumberShortcuts), Settings.EnableNumberShortcuts);
 14173                _storage.SetValue(nameof(Settings.NumberShortcutModifier), Settings.NumberShortcutModifier);
 174
 175                // Badge Animations
 14176                _storage.SetValue(nameof(Settings.EnableBadgeAnimations), Settings.EnableBadgeAnimations);
 177
 178                // Refresh Behavior
 14179                _storage.SetValue(nameof(Settings.RefreshBehavior), Settings.RefreshBehavior);
 180
 181                // Regex Cache Size
 14182                _storage.SetValue(nameof(Settings.RegexCacheSize), Settings.RegexCacheSize);
 183
 184                // Fuzzy Search
 14185                _storage.SetValue(nameof(Settings.EnableFuzzySearch), Settings.EnableFuzzySearch);
 186
 187                // Search Highlighting
 14188                _storage.SetValue(nameof(Settings.EnableSearchHighlighting), Settings.EnableSearchHighlighting);
 14189                _storage.SetValue(nameof(Settings.SearchHighlightColor), Settings.SearchHighlightColor);
 190
 191                // UIA Worker Timeout
 14192                _storage.SetValue(nameof(Settings.UiaWorkerTimeoutSeconds), Settings.UiaWorkerTimeoutSeconds);
 193
 194                // Flush to ensure all writes are committed
 14195                _storage.Flush();
 196
 12197                SettingsChanged?.Invoke();
 12198            }
 2199            catch (Exception ex)
 2200            {
 2201                _logger?.LogError("Failed to save settings", ex);
 2202            }
 203
 204            // Sync startup registry entry via startup manager
 14205            UpdateStartupRegistryEntry();
 14206        }
 207
 208        private void UpdateStartupRegistryEntry()
 14209        {
 14210            if (Settings.LaunchOnStartup)
 4211            {
 4212                using var currentProcess = _processFactory.GetCurrentProcess();
 4213                string? exePath = currentProcess.MainModuleFileName;
 4214                if (!string.IsNullOrEmpty(exePath))
 3215                {
 3216                    _startupManager.EnableStartup(exePath);
 3217                }
 4218            }
 219            else
 10220            {
 10221                _startupManager.DisableStartup();
 10222            }
 14223        }
 224
 225        /// <summary>
 226        /// Checks if the application is currently set to run at Windows startup.
 227        /// Delegates to the startup manager.
 228        /// </summary>
 1229        public bool IsStartupEnabled() => _startupManager.IsStartupEnabled();
 230    }
 231}