diff --git a/Ink Canvas/Helpers/SettingsService.cs b/Ink Canvas/Helpers/SettingsService.cs deleted file mode 100644 index 53e04b1f..00000000 --- a/Ink Canvas/Helpers/SettingsService.cs +++ /dev/null @@ -1,802 +0,0 @@ -using Ink_Canvas; -using Ink_Canvas.Helpers; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq.Expressions; -using System.Reflection; -using System.Windows; -using UpdateChannel = Ink_Canvas.UpdateChannel; -using UpdatePackageArchitecture = Ink_Canvas.UpdatePackageArchitecture; -using TelemetryUploadLevel = Ink_Canvas.TelemetryUploadLevel; - -namespace Ink_Canvas.Services -{ - public class SettingsService - { - private static SettingsService _instance; - private static readonly object _lock = new object(); - - private Settings _settings; - private MainWindow _mainWindow; - private bool _isChangingUpdateChannelInternally = false; - private bool _isChangingUpdatePackageArchInternally = false; - - public static readonly string settingsFileName = Path.Combine("Configs", "Settings.json"); - - public event Action SettingChanged; - - public static SettingsService Instance - { - get - { - if (_instance == null) - { - lock (_lock) - { - if (_instance == null) - { - _instance = new SettingsService(); - } - } - } - return _instance; - } - } - - private SettingsService() { } - - public void Initialize(Settings settings, MainWindow mainWindow = null) - { - _settings = settings; - _mainWindow = mainWindow; - } - - public Settings Settings => _settings; - - #region Core Settings Management - - public Settings LoadSettings(bool isStartup = false, bool skipAutoUpdateCheck = false) - { - Settings loadedSettings = null; - - try - { - if (File.Exists(App.RootPath + settingsFileName)) - { - try - { - string text = File.ReadAllText(App.RootPath + settingsFileName); - loadedSettings = JsonConvert.DeserializeObject(text); - - if (loadedSettings != null) - { - CleanupObsoleteSettings(text, ref loadedSettings); - } - - if (loadedSettings == null) - { - LogHelper.WriteLogToFile("配置文件解析失败,尝试从备份恢复", LogHelper.LogType.Warning); - if (AutoBackupManager.TryRestoreFromBackup()) - { - text = File.ReadAllText(App.RootPath + settingsFileName); - loadedSettings = JsonConvert.DeserializeObject(text); - if (loadedSettings != null) - { - CleanupObsoleteSettings(text, ref loadedSettings); - } - } - - if (loadedSettings == null) - { - LogHelper.WriteLogToFile("从备份恢复失败,使用默认设置", LogHelper.LogType.Warning); - loadedSettings = new Settings(); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"配置文件加载失败: {ex.Message}", LogHelper.LogType.Error); - - LogHelper.WriteLogToFile("尝试从备份恢复配置文件", LogHelper.LogType.Warning); - if (AutoBackupManager.TryRestoreFromBackup()) - { - try - { - string text = File.ReadAllText(App.RootPath + settingsFileName); - loadedSettings = JsonConvert.DeserializeObject(text); - if (loadedSettings != null) - { - CleanupObsoleteSettings(text, ref loadedSettings); - } - } - catch (Exception restoreEx) - { - LogHelper.WriteLogToFile($"从备份恢复后重新加载失败: {restoreEx.Message}", LogHelper.LogType.Error); - loadedSettings = new Settings(); - } - } - - if (loadedSettings == null) - { - LogHelper.WriteLogToFile("从备份恢复失败,使用默认设置", LogHelper.LogType.Warning); - loadedSettings = new Settings(); - } - } - } - else - { - LogHelper.WriteLogToFile("配置文件不存在,尝试从备份恢复", LogHelper.LogType.Warning); - if (AutoBackupManager.TryRestoreFromBackup()) - { - try - { - string text = File.ReadAllText(App.RootPath + settingsFileName); - loadedSettings = JsonConvert.DeserializeObject(text); - if (loadedSettings != null) - { - CleanupObsoleteSettings(text, ref loadedSettings); - } - } - catch (Exception restoreEx) - { - LogHelper.WriteLogToFile($"从备份恢复后加载失败: {restoreEx.Message}", LogHelper.LogType.Error); - loadedSettings = new Settings(); - } - } - else - { - LogHelper.WriteLogToFile("备份恢复失败,使用默认设置", LogHelper.LogType.Warning); - loadedSettings = new Settings(); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); - loadedSettings = new Settings(); - } - - try - { - if (loadedSettings?.Appearance != null) - { - var preferredLanguage = loadedSettings.Appearance.Language ?? string.Empty; - if (!string.IsNullOrWhiteSpace(preferredLanguage)) - { - LocalizationHelper.TrySetCulture(preferredLanguage); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"从配置应用界面语言失败: {ex.Message}", LogHelper.LogType.Error); - } - - try - { - ProcessProtectionManager.ApplyFromSettings(); - } - catch - { - } - - _settings = loadedSettings; - return loadedSettings; - } - - public void SaveSettingsToFile() - { - if (_settings == null) return; - - var text = JsonConvert.SerializeObject(_settings, Formatting.Indented); - try - { - string configsDir = Path.Combine(App.RootPath, "Configs"); - if (!Directory.Exists(configsDir)) - { - ProcessProtectionManager.WithWriteAccess(configsDir, () => Directory.CreateDirectory(configsDir)); - } - - var path = App.RootPath + settingsFileName; - ProcessProtectionManager.WithWriteAccess(path, () => File.WriteAllText(path, text)); - } - catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } - } - - private void CleanupObsoleteSettings(string userConfigJson, ref Settings settings) - { - try - { - Settings defaultSettings = new Settings(); - - JObject defaultConfigObj = JObject.FromObject(defaultSettings); - EnsureDefaultConfigSchemaIncludesIgnoredNullKeys(defaultConfigObj); - JObject userConfigObj = JObject.Parse(userConfigJson); - - bool hasChanges = false; - - RemoveObsoleteProperties(userConfigObj, defaultConfigObj, ref hasChanges); - - if (hasChanges) - { - string cleanedJson = userConfigObj.ToString(Formatting.Indented); - settings = JsonConvert.DeserializeObject(cleanedJson); - SaveSettingsToFile(); - LogHelper.WriteLogToFile("已清理过期配置项", LogHelper.LogType.Event); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"清理过期配置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - private static void EnsureDefaultConfigSchemaIncludesIgnoredNullKeys(JObject defaultConfigObj) - { - if (defaultConfigObj == null) return; - if (defaultConfigObj["appearance"] is JObject appearance && !appearance.ContainsKey("hitokotoCategories")) - appearance["hitokotoCategories"] = JValue.CreateNull(); - } - - private void RemoveObsoleteProperties(JObject userObj, JObject defaultObj, ref bool hasChanges) - { - if (userObj == null || defaultObj == null) - return; - - List keysToRemove = new List(); - - foreach (var property in userObj.Properties()) - { - string propertyName = property.Name; - - if (!defaultObj.ContainsKey(propertyName)) - { - keysToRemove.Add(propertyName); - continue; - } - - JToken userValue = property.Value; - JToken defaultValue = defaultObj[propertyName]; - - if (userValue != null && defaultValue != null) - { - if (userValue.Type == JTokenType.Object && defaultValue.Type == JTokenType.Object) - { - RemoveObsoleteProperties(userValue as JObject, defaultValue as JObject, ref hasChanges); - } - else if (userValue.Type == JTokenType.Array && defaultValue.Type == JTokenType.Array) - { - JArray userArray = userValue as JArray; - JArray defaultArray = defaultValue as JArray; - - if (userArray != null && defaultArray != null && userArray.Count > 0 && defaultArray.Count > 0) - { - if (userArray[0].Type == JTokenType.Object && defaultArray[0].Type == JTokenType.Object) - { - for (int i = 0; i < userArray.Count; i++) - { - if (userArray[i] is JObject userItemObj && defaultArray[0] is JObject defaultItemObj) - { - RemoveObsoleteProperties(userItemObj, defaultItemObj, ref hasChanges); - } - } - } - } - } - } - } - - foreach (var key in keysToRemove) - { - userObj.Remove(key); - hasChanges = true; - LogHelper.WriteLogToFile($"已删除过期配置项: {key}", LogHelper.LogType.Event); - } - } - - #endregion - - #region Generic Setting Methods - - public void Set(Expression> propertyExpression, T value, bool saveToFile = true) - { - if (_settings == null) return; - - var propertyName = GetPropertyName(propertyExpression); - var property = typeof(Settings).GetProperty(propertyName); - - if (property != null) - { - property.SetValue(_settings, value); - if (saveToFile) SaveSettingsToFile(); - SettingChanged?.Invoke(propertyName, value); - } - } - - public void Set(Expression> categoryExpression, Expression> propertyExpression, TProperty value, bool saveToFile = true) - { - if (_settings == null) return; - - var categoryPropertyName = GetPropertyName(categoryExpression); - var categoryProperty = typeof(Settings).GetProperty(categoryPropertyName); - - if (categoryProperty != null) - { - var categoryInstance = categoryProperty.GetValue(_settings); - if (categoryInstance != null) - { - var propertyName = GetPropertyName(propertyExpression); - var property = typeof(TCategory).GetProperty(propertyName); - - if (property != null) - { - property.SetValue(categoryInstance, value); - if (saveToFile) SaveSettingsToFile(); - SettingChanged?.Invoke($"{categoryPropertyName}.{propertyName}", value); - } - } - } - } - - public T Get(Expression> propertyExpression) - { - if (_settings == null) return default; - - var propertyName = GetPropertyName(propertyExpression); - var property = typeof(Settings).GetProperty(propertyName); - - if (property != null) - { - return (T)property.GetValue(_settings); - } - return default; - } - - public TProperty Get(Expression> categoryExpression, Expression> propertyExpression) - { - if (_settings == null) return default; - - var categoryPropertyName = GetPropertyName(categoryExpression); - var categoryProperty = typeof(Settings).GetProperty(categoryPropertyName); - - if (categoryProperty != null) - { - var categoryInstance = categoryProperty.GetValue(_settings); - if (categoryInstance != null) - { - var propertyName = GetPropertyName(propertyExpression); - var property = typeof(TCategory).GetProperty(propertyName); - - if (property != null) - { - return (TProperty)property.GetValue(categoryInstance); - } - } - } - return default; - } - - private string GetPropertyName(Expression> expression) - { - if (expression.Body is MemberExpression memberExpression) - { - return memberExpression.Member.Name; - } - throw new ArgumentException("Expression is not a property access", nameof(expression)); - } - - #endregion - - #region Convenience Methods for Common Settings - - #region Advanced Settings - - public void SetNoFocusMode(bool enabled, bool saveToFile = true) - { - Set(s => s.Advanced, a => a.IsNoFocusMode, enabled, saveToFile); - if (_mainWindow != null) - { - _mainWindow.Dispatcher.BeginInvoke(new Action(() => - { - _mainWindow.ApplyNoFocusMode(); - if (_settings.Advanced.IsAlwaysOnTop) - { - _mainWindow.ApplyAlwaysOnTop(); - } - })); - } - } - - public void SetAlwaysOnTop(bool enabled, bool saveToFile = true) - { - Set(s => s.Advanced, a => a.IsAlwaysOnTop, enabled, saveToFile); - if (_mainWindow != null) - { - _mainWindow.Dispatcher.BeginInvoke(new Action(() => - { - _mainWindow.ApplyAlwaysOnTop(); - _mainWindow.UpdateUIAccessTopMostVisibility(); - })); - } - } - - public void SetUIAccessTopMost(bool enabled, bool saveToFile = true) - { - Set(s => s.Advanced, a => a.EnableUIAccessTopMost, enabled, saveToFile); - if (_mainWindow != null) - { - _mainWindow.Dispatcher.BeginInvoke(new Action(() => - { - _mainWindow.ApplyUIAccessTopMost(); - })); - } - App.IsUIAccessTopMostEnabled = enabled; - } - - #endregion - - #region Canvas Settings - - public void SetInkFadeEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EnableInkFade, enabled, saveToFile); - } - - public void SetInkFadeTime(int timeMs, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.InkFadeTime, timeMs, saveToFile); - } - - public void SetHideInkFadeControlInPenMenu(bool enabled, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.HideInkFadeControlInPenMenu, enabled, saveToFile); - } - - public void SetEraserAutoSwitchBack(bool enabled, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EnableEraserAutoSwitchBack, enabled, saveToFile); - } - - public void SetEraserAutoSwitchBackDelay(int seconds, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EraserAutoSwitchBackDelaySeconds, seconds, saveToFile); - } - - public void SetBrushAutoRestore(bool enabled, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EnableBrushAutoRestore, enabled, saveToFile); - } - - public void SetBrushAutoRestoreTimes(string times, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.BrushAutoRestoreTimes, times, saveToFile); - } - - public void SetBrushAutoRestoreColor(string color, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.BrushAutoRestoreColor, color, saveToFile); - } - - public void SetBrushAutoRestoreWidth(double width, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.BrushAutoRestoreWidth, width, saveToFile); - } - - public void SetBrushAutoRestoreAlpha(int alpha, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.BrushAutoRestoreAlpha, alpha, saveToFile); - } - - public void SetInkWidth(double width, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.InkWidth, width, saveToFile); - } - - public void SetHighlighterWidth(double width, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.HighlighterWidth, width, saveToFile); - } - - public void SetInkAlpha(double alpha, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.InkAlpha, alpha, saveToFile); - } - - public void SetEraserSize(int size, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EraserSize, size, saveToFile); - } - - public void SetEraserType(int type, bool saveToFile = true) - { - Set(s => s.Canvas, c => c.EraserType, type, saveToFile); - } - - #endregion - - #region Appearance Settings - - public void SetTheme(int themeIndex, bool saveToFile = true) - { - Set(s => s.Appearance, a => a.Theme, themeIndex, saveToFile); - } - - public void SetLanguage(string languageCode, bool saveToFile = true) - { - Set(s => s.Appearance, a => a.Language, languageCode ?? string.Empty, saveToFile); - LocalizationHelper.TrySetCulture(languageCode); - } - - public void SetFloatingBarOpacity(double opacity, bool saveToFile = true) - { - Set(s => s.Appearance, a => a.ViewboxFloatingBarOpacityValue, opacity, saveToFile); - } - - public void SetFloatingBarScale(double scale, bool saveToFile = true) - { - Set(s => s.Appearance, a => a.ViewboxFloatingBarScaleTransformValue, scale, saveToFile); - } - - #endregion - - #region PowerPoint Settings - - public void SetPPTOnlyMode(bool enabled, bool saveToFile = true) - { - Set(s => s.ModeSettings, m => m.IsPPTOnlyMode, enabled, saveToFile); - } - - public void SetPowerPointSupport(bool enabled, bool saveToFile = true) - { - Set(s => s.PowerPointSettings, p => p.PowerPointSupport, enabled, saveToFile); - } - - public void SetShowGestureButtonInSlideShow(bool enabled, bool saveToFile = true) - { - Set(s => s.PowerPointSettings, p => p.ShowGestureButtonInSlideShow, enabled, saveToFile); - } - - public void SetPPTTimeCapsuleEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.PowerPointSettings, p => p.EnablePPTTimeCapsule, enabled, saveToFile); - } - - public void SetPPTTimeCapsulePosition(int position, bool saveToFile = true) - { - Set(s => s.PowerPointSettings, p => p.PPTTimeCapsulePosition, position, saveToFile); - } - - #endregion - - #region Gesture Settings - - public void SetTwoFingerZoomEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Gesture, g => g.IsEnableTwoFingerZoom, enabled, saveToFile); - } - - public void SetTwoFingerTranslateEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Gesture, g => g.IsEnableTwoFingerTranslate, enabled, saveToFile); - } - - public void SetTwoFingerRotationEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Gesture, g => g.IsEnableTwoFingerRotation, enabled, saveToFile); - } - - public void SetMultiTouchModeEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Gesture, g => g.IsEnableMultiTouchMode, enabled, saveToFile); - } - - #endregion - - #region Startup Settings - - public void SetAutoUpdate(bool enabled, bool saveToFile = true) - { - Set(s => s.Startup, s => s.IsAutoUpdate, enabled, saveToFile); - } - - public void SetUpdateChannel(UpdateChannel channel, bool saveToFile = true) - { - Set(s => s.Startup, s => s.UpdateChannel, channel, saveToFile); - } - - public void SetTelemetryUploadLevel(TelemetryUploadLevel level, bool saveToFile = true) - { - Set(s => s.Startup, s => s.TelemetryUploadLevel, level, saveToFile); - } - - #endregion - - #region Automation Settings - - public void SetAutoSaveStrokesEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Automation, a => a.IsEnableAutoSaveStrokes, enabled, saveToFile); - } - - public void SetAutoSaveStrokesInterval(int minutes, bool saveToFile = true) - { - Set(s => s.Automation, a => a.AutoSaveStrokesIntervalMinutes, minutes, saveToFile); - } - - public void SetAutoSavedStrokesLocation(string path, bool saveToFile = true) - { - Set(s => s.Automation, a => a.AutoSavedStrokesLocation, path, saveToFile); - } - - #endregion - - #region InkToShape Settings - - public void SetInkToShapeEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.InkToShape, i => i.IsInkToShapeEnabled, enabled, saveToFile); - } - - public void SetShapeRecognitionEngine(int engine, bool saveToFile = true) - { - Set(s => s.InkToShape, i => i.ShapeRecognitionEngine, engine, saveToFile); - } - - #endregion - - #region Security Settings - - public void SetPasswordEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Security, s => s.PasswordEnabled, enabled, saveToFile); - } - - public void SetProcessProtectionEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Security, s => s.EnableProcessProtection, enabled, saveToFile); - } - - #endregion - - #region Camera Settings - - public void SetCameraRotationAngle(int angle, bool saveToFile = true) - { - Set(s => s.Camera, c => c.RotationAngle, angle, saveToFile); - } - - public void SetCameraResolution(int width, int height, bool saveToFile = true) - { - Set(s => s.Camera, c => c.ResolutionWidth, width, saveToFile); - Set(s => s.Camera, c => c.ResolutionHeight, height, saveToFile); - } - - #endregion - - #endregion - - #region Startup Settings - Complete Functionality - - public bool CheckRunAtStartup() - { - try - { - return File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\Ink Canvas Annotation.lnk"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); - return false; - } - } - - // Settings 中没有 IsRunAtStartup 属性,所以这个方法被注释掉了 - // public void SetRunAtStartup(bool enabled, bool saveToFile = true) - // { - // Set(s => s.Startup, s => s.IsRunAtStartup, enabled, saveToFile); - // } - - public void SetFoldAtStartup(bool enabled, bool saveToFile = true) - { - Set(s => s.Startup, s => s.IsFoldAtStartup, enabled, saveToFile); - } - - public void SetUpdatePackageArchitecture(UpdatePackageArchitecture arch, bool saveToFile = true) - { - Set(s => s.Startup, s => s.UpdatePackageArchitecture, arch, saveToFile); - } - - public void SetAutoUpdateWithSilence(bool enabled, bool saveToFile = true) - { - Set(s => s.Startup, s => s.IsAutoUpdateWithSilence, enabled, saveToFile); - } - - public void SetAutoUpdateWithSilenceStartTime(string time, bool saveToFile = true) - { - Set(s => s.Startup, s => s.AutoUpdateWithSilenceStartTime, time, saveToFile); - } - - public void SetAutoUpdateWithSilenceEndTime(string time, bool saveToFile = true) - { - Set(s => s.Startup, s => s.AutoUpdateWithSilenceEndTime, time, saveToFile); - } - - public void SetNibModeEnabled(bool enabled, bool saveToFile = true) - { - Set(s => s.Startup, s => s.IsEnableNibMode, enabled, saveToFile); - } - - public void CheckUpdateChannelAndTelemetryConsistency(bool isLoaded) - { - if (_settings == null) return; - - var currentChannel = _settings.Startup.UpdateChannel; - if (currentChannel == UpdateChannel.Release) return; - - if (!_settings.Startup.HasAcceptedTelemetryPrivacy) - { - _settings.Startup.UpdateChannel = UpdateChannel.Release; - DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release); - SaveSettingsToFile(); - LogHelper.WriteLogToFile($"启动检测 | 用户未同意隐私协议,已切换回 Release 通道"); - return; - } - - if (_settings.Startup.TelemetryUploadLevel == TelemetryUploadLevel.None) - { - _isChangingUpdateChannelInternally = true; - try - { - _settings.Startup.UpdateChannel = UpdateChannel.Release; - DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release); - SaveSettingsToFile(); - } - finally - { - _isChangingUpdateChannelInternally = false; - } - LogHelper.WriteLogToFile($"启动检测 | 用户未启用遥测,已切换回 Release 通道"); - } - } - - #endregion - - #region Helper Methods - - public static string GetThemeName(int themeIndex) - { - return themeIndex switch - { - 0 => "浅色主题", - 1 => "深色主题", - 2 => "跟随系统", - _ => "未知主题" - }; - } - - public static string GetLanguageCode(int languageIndex) - { - return languageIndex switch - { - 1 => "zh-CN", - 2 => "en-US", - _ => string.Empty - }; - } - - public static int GetLanguageIndex(string languageCode) - { - return languageCode switch - { - "zh-CN" => 1, - "en-US" => 2, - _ => 0 - }; - } - - #endregion - } -} diff --git a/Ink Canvas/Helpers/SettingsServiceDemo.cs b/Ink Canvas/Helpers/SettingsServiceDemo.cs deleted file mode 100644 index dc12ae13..00000000 --- a/Ink Canvas/Helpers/SettingsServiceDemo.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Ink_Canvas; -using Ink_Canvas.Services; - -namespace Ink_Canvas -{ - public static class SettingsServiceDemo - { - public static void ListAllSettings() - { - var settingsType = typeof(Settings); - var allProperties = new List(); - - Console.WriteLine("=== Settings 所有属性列表 ===\n"); - - foreach (var categoryProp in settingsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if (categoryProp.PropertyType.IsClass && categoryProp.PropertyType != typeof(string) && categoryProp.PropertyType != typeof(List) && categoryProp.PropertyType != typeof(List) && categoryProp.PropertyType != typeof(List) && categoryProp.PropertyType != typeof(Dictionary) && categoryProp.PropertyType != typeof(List) && categoryProp.PropertyType != typeof(DateTime)) - { - Console.WriteLine($"\n--- 分类: {categoryProp.Name} ---\n"); - - foreach (var settingProp in categoryProp.PropertyType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - var propName = $"{categoryProp.Name}.{settingProp.Name}"; - allProperties.Add(propName); - Console.WriteLine($" {settingProp.Name,-60} ({settingProp.PropertyType.Name})"); - } - } - else - { - Console.WriteLine($"{categoryProp.Name,-60} ({categoryProp.PropertyType.Name})"); - allProperties.Add(categoryProp.Name); - } - } - - Console.WriteLine($"\n\n总计: {allProperties.Count} 个设置项\n"); - - Console.WriteLine("=== SettingsService 访问示例 ===\n"); - - Console.WriteLine("// 方式1: 泛型 Set/Get"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Canvas, c => c.InkWidth, 3.5);"); - Console.WriteLine("double inkWidth = SettingsService.Instance.Get(s => s.Canvas, c => c.InkWidth);"); - Console.WriteLine(); - - Console.WriteLine("// 方式2: 便捷方法"); - Console.WriteLine("SettingsService.Instance.SetTheme(1);"); - Console.WriteLine("SettingsService.Instance.SetNoFocusMode(true);"); - Console.WriteLine(); - - Console.WriteLine("// 方式3: 直接访问 Settings 对象"); - Console.WriteLine("var settings = SettingsService.Instance.Settings;"); - Console.WriteLine("if (settings != null) {"); - Console.WriteLine(" settings.Canvas.InkWidth = 3.5;"); - Console.WriteLine(" settings.Appearance.Theme = 1;"); - Console.WriteLine(" SettingsService.Instance.Save();"); - Console.WriteLine("}"); - Console.WriteLine(); - - Console.WriteLine("// 任意设置项示例:"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Automation, a => a.IsAutoFoldInEasiNote, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.PowerPointSettings, p => p.PowerPointSupport, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Gesture, g => g.IsEnableTwoFingerZoom, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Advanced, a => a.IsAlwaysOnTop, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Startup, s => s.IsAutoUpdate, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Security, s => s.PasswordEnabled, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Camera, c => c.RotationAngle, 90);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.InkToShape, i => i.IsInkToShapeEnabled, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.RandSettings, r => r.EnableQuickDraw, true);"); - Console.WriteLine("SettingsService.Instance.Set(s => s.Appearance, a => a.ViewboxFloatingBarOpacityValue, 0.8);"); - } - } -} diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 79fca2ae..b9434bac 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -655,6 +655,148 @@ Padding="15,5" Margin="0,10,0,0"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +