From a5d6135f0c5cb55e5c8fa4d6788202b1a8789f24 Mon Sep 17 00:00:00 2001
From: PrefacedCorg <1876568293@qq.com>
Date: Sun, 19 Apr 2026 14:42:11 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=E8=BF=81=E7=A7=BB=E8=AE=BE=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Ink Canvas/MainWindow.xaml | 761 +---------
Ink Canvas/MainWindow.xaml.cs | 404 +-----
Ink Canvas/MainWindow_cs/MW_Settings.cs | 1255 +----------------
Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 202 +--
Ink Canvas/MainWindow_cs/MW_Timer.cs | 5 +
Ink Canvas/Properties/Strings.en-US.resx | 6 +
Ink Canvas/Properties/Strings.resx | 6 +
.../SettingsViews/Pages/AboutPage.xaml | 211 ++-
.../SettingsViews/Pages/AboutPage.xaml.cs | 418 +++++-
.../SettingsViews/Pages/CanvasPage.xaml | 361 +++++
.../SettingsViews/Pages/CanvasPage.xaml.cs | 403 ++++++
.../SettingsViews/Pages/StartupPage.xaml | 29 +-
.../SettingsViews/Pages/StartupPage.xaml.cs | 4 +-
.../SettingsViews/Pages/UpdatePage.xaml | 146 ++
.../SettingsViews/Pages/UpdatePage.xaml.cs | 468 ++++++
.../Windows/SettingsViews/SettingsWindow.xaml | 85 +-
.../SettingsViews/SettingsWindow.xaml.cs | 11 +-
17 files changed, 2089 insertions(+), 2686 deletions(-)
create mode 100644 Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml
create mode 100644 Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml.cs
create mode 100644 Ink Canvas/Windows/SettingsViews/Pages/UpdatePage.xaml
create mode 100644 Ink Canvas/Windows/SettingsViews/Pages/UpdatePage.xaml.cs
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 91c55768..b21a9a6c 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -656,216 +656,10 @@
FontSize="26" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -896,9 +690,9 @@
-
+
+ Visibility="{Binding ElementName=ToggleSwitchEnablePalmEraser, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
@@ -906,112 +700,11 @@
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Visibility="{Binding ElementName=ToggleSwitchEnablePalmEraser, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}" />
+
@@ -3447,446 +3140,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CJK_mkp
-
-
-
-
-
-
-
-
-
-
- Dubi906w
-
-
-
-
-
-
-
-
-
-
- ChangSakura
-
-
-
-
-
-
-
-
-
-
- WXRIW
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Raspberry Kan
-
-
-
-
-
-
-
-
-
- Kengwang
-
-
-
-
-
-
-
-
-
- Charles Jia
-
-
-
-
-
-
-
-
-
- clover_yan
-
-
-
-
-
-
-
-
-
- Netherite_Bowl
-
-
-
-
-
-
-
-
-
- Yoojun Zhou
-
-
-
-
-
-
-
-
-
- YuWenHui2020
-
-
-
-
-
-
-
-
-
- ZongziTEK
-
-
-
-
-
-
-
-
-
- Aesthed
-
-
-
-
-
-
-
-
-
- Wei
-
-
-
-
-
-
-
-
-
- Alan-CRL
-
-
-
-
-
-
-
-
-
- PrefacedCorg
-
-
-
-
-
-
-
-
-
- PANDA-JSR
-
-
-
-
-
-
-
-
-
-
diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs
index 70077a9a..12925040 100644
--- a/Ink Canvas/MainWindow.xaml.cs
+++ b/Ink Canvas/MainWindow.xaml.cs
@@ -1183,7 +1183,6 @@ namespace Ink_Canvas
LoadSettings(true);
ApplyLanguageFromSettings();
AutoBackupManager.Initialize(Settings);
- CheckUpdateChannelAndTelemetryConsistency();
// 初始化上传队列(恢复上次的上传队列)
try
@@ -1275,8 +1274,6 @@ namespace Ink_Canvas
}
// HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow();
- if (Environment.Is64BitProcess) GroupBoxInkRecognition.Visibility = Visibility.Collapsed;
-
// 根据设置应用主题
switch (Settings.Appearance.Theme)
{
@@ -1380,16 +1377,6 @@ namespace Ink_Canvas
ApplyUIAccessTopMost();
}
- // 初始化橡皮擦自动切换回批注模式开关
- if (ToggleSwitchEnableEraserAutoSwitchBack != null)
- {
- ToggleSwitchEnableEraserAutoSwitchBack.IsOn = Settings.Canvas.EnableEraserAutoSwitchBack;
- }
- if (EraserAutoSwitchBackDelaySlider != null)
- {
- EraserAutoSwitchBackDelaySlider.Value = Settings.Canvas.EraserAutoSwitchBackDelaySeconds;
- }
-
// 初始化剪贴板监控
InitializeClipboardMonitoring();
@@ -1875,7 +1862,7 @@ namespace Ink_Canvas
}
// 使用多线路组下载更新
- private async Task DownloadUpdateWithFallback(string version, AutoUpdateHelper.UpdateLineGroup primaryGroup, UpdateChannel channel)
+ internal async Task DownloadUpdateWithFallback(string version, AutoUpdateHelper.UpdateLineGroup primaryGroup, UpdateChannel channel)
{
try
{
@@ -1905,7 +1892,7 @@ namespace Ink_Canvas
}
}
- private async void AutoUpdate()
+ public async void AutoUpdate()
{
if (!string.IsNullOrEmpty(Settings.Startup.AutoUpdatePauseUntilDate))
{
@@ -2366,10 +2353,7 @@ namespace Ink_Canvas
private void NavAbout_Click(object sender, RoutedEventArgs e)
{
- // 切换到关于页面
ShowSettingsSection("about");
- // 刷新设备信息
- RefreshDeviceInfo();
}
// 个性化设置
@@ -2394,88 +2378,6 @@ namespace Ink_Canvas
BorderSettingsMask.Background = null; // 确保清除蒙层背景
}
- ///
- /// 刷新设备信息按钮点击事件
- ///
- private void RefreshDeviceInfo_Click(object sender, RoutedEventArgs e)
- {
- RefreshDeviceInfo();
- }
-
- ///
- /// 刷新设备信息显示
- ///
- private void RefreshDeviceInfo()
- {
- try
- {
- // 获取设备ID
- string deviceId = DeviceIdentifier.GetDeviceId();
- DeviceIdTextBlock.Text = deviceId;
-
- // 获取使用频率
- var usageFrequency = DeviceIdentifier.GetUsageFrequency();
- string frequencyText;
- switch (usageFrequency)
- {
- case DeviceIdentifier.UsageFrequency.High:
- frequencyText = "高频用户";
- break;
- case DeviceIdentifier.UsageFrequency.Medium:
- frequencyText = "中频用户";
- break;
- case DeviceIdentifier.UsageFrequency.Low:
- frequencyText = "低频用户";
- break;
- default:
- frequencyText = "未知";
- break;
- }
- UsageFrequencyTextBlock.Text = frequencyText;
-
- // 获取更新优先级
- var updatePriority = DeviceIdentifier.GetUpdatePriority();
- string priorityText;
- switch (updatePriority)
- {
- case DeviceIdentifier.UpdatePriority.High:
- priorityText = "高优先级(优先推送更新)";
- break;
- case DeviceIdentifier.UpdatePriority.Medium:
- priorityText = "中优先级(正常推送更新)";
- break;
- case DeviceIdentifier.UpdatePriority.Low:
- priorityText = "低优先级(延迟推送更新)";
- break;
- default:
- priorityText = "未知";
- break;
- }
- UpdatePriorityTextBlock.Text = priorityText;
-
- // 获取使用统计(秒级精度)
- var (launchCount, totalSeconds, avgSessionSeconds, _) = DeviceIdentifier.GetUsageStats();
- LaunchCountTextBlock.Text = launchCount.ToString();
-
- // 使用新的格式化方法显示秒级精度的使用时长
- string totalUsageText = DeviceIdentifier.FormatDuration(totalSeconds);
- TotalUsageTextBlock.Text = totalUsageText;
-
- LogHelper.WriteLogToFile($"MainWindow | 设备信息已刷新 - ID: {deviceId}, 频率: {frequencyText}, 优先级: {priorityText}");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"MainWindow | 刷新设备信息失败: {ex.Message}", LogHelper.LogType.Error);
-
- // 显示错误信息
- DeviceIdTextBlock.Text = "获取失败";
- UsageFrequencyTextBlock.Text = "获取失败";
- UpdatePriorityTextBlock.Text = "获取失败";
- LaunchCountTextBlock.Text = "获取失败";
- TotalUsageTextBlock.Text = "获取失败";
- }
- }
-
// 折叠侧边栏
private void CollapseNavSidebar_Click(object sender, RoutedEventArgs e)
{
@@ -2534,15 +2436,9 @@ namespace Ink_Canvas
case "startup":
targetGroupBox = GroupBoxStartup;
break;
- case "canvas":
- targetGroupBox = GroupBoxCanvas;
- break;
case "gesture":
targetGroupBox = GroupBoxGesture;
break;
- case "inkrecognition":
- targetGroupBox = GroupBoxInkRecognition;
- break;
case "crashaction":
targetGroupBox = GroupBoxCrashAction;
break;
@@ -2565,9 +2461,6 @@ namespace Ink_Canvas
// 快捷键设置部分可能尚未实现
targetGroupBox = null;
break;
- case "about":
- targetGroupBox = GroupBoxAbout;
- break;
default:
// 默认滚动到顶部
SettingsPanelScrollViewer.ScrollToTop();
@@ -3181,29 +3074,40 @@ namespace Ink_Canvas
}
#endregion
- #region 墨迹渐隐功能
- ///
- /// 墨迹渐隐开关切换事件处理
- ///
- private void ToggleSwitchEnableInkFade_Toggled(object sender, RoutedEventArgs e)
+
+ private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e)
{
try
{
- Settings.Canvas.EnableInkFade = ToggleSwitchEnableInkFade.IsOn;
- _inkFadeManager.IsEnabled = Settings.Canvas.EnableInkFade;
+ var toggle = sender as ToggleSwitch;
+ if (toggle == null) return;
+ Settings.InkToShape.IsInkToShapeEnabled = toggle.IsOn;
+ SaveSettingsToFile();
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"切换墨迹纠正功能时出错: {ex.Message}", LogHelper.LogType.Error);
+ }
+ }
- // 同步批注子面板中的开关状态
- if (ToggleSwitchInkFadeInPanel != null)
+ private void ToggleSwitchInkFadeInPanel_Toggled(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var toggle = sender as ToggleSwitch;
+ if (toggle == null) return;
+ Settings.Canvas.EnableInkFade = toggle.IsOn;
+ if (_inkFadeManager != null)
{
- ToggleSwitchInkFadeInPanel.IsOn = Settings.Canvas.EnableInkFade;
+ _inkFadeManager.IsEnabled = Settings.Canvas.EnableInkFade;
}
- // 同步普通画笔面板中的开关状态
if (ToggleSwitchInkFadeInPanel2 != null)
{
ToggleSwitchInkFadeInPanel2.IsOn = Settings.Canvas.EnableInkFade;
}
+ SaveSettingsToFile();
}
catch (Exception ex)
{
@@ -3211,259 +3115,29 @@ namespace Ink_Canvas
}
}
- ///
- /// 墨迹渐隐时间滑块值改变事件处理
- ///
- private void InkFadeTimeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- try
- {
- Settings.Canvas.InkFadeTime = (int)e.NewValue;
- if (_inkFadeManager != null)
- {
- _inkFadeManager.UpdateFadeTime(Settings.Canvas.InkFadeTime);
- }
- LogHelper.WriteLogToFile($"墨迹渐隐时间已更新为 {Settings.Canvas.InkFadeTime}ms", LogHelper.LogType.Event);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"更新墨迹渐隐时间时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
-
-
- ///
- /// 批注子面板中墨迹渐隐开关切换事件处理
- ///
- private void ToggleSwitchInkFadeInPanel_Toggled(object sender, RoutedEventArgs e)
- {
- try
- {
- Settings.Canvas.EnableInkFade = ToggleSwitchInkFadeInPanel.IsOn;
- _inkFadeManager.IsEnabled = Settings.Canvas.EnableInkFade;
-
- // 同步设置面板中的开关状态
- if (ToggleSwitchEnableInkFade != null)
- {
- ToggleSwitchEnableInkFade.IsOn = Settings.Canvas.EnableInkFade;
- }
-
- // 同步普通画笔面板中的开关状态
- if (ToggleSwitchInkFadeInPanel2 != null)
- {
- ToggleSwitchInkFadeInPanel2.IsOn = Settings.Canvas.EnableInkFade;
- }
-
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"批注子面板中切换墨迹渐隐功能时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 在笔工具菜单中隐藏墨迹渐隐控制开关切换事件处理
- ///
- /// 切换“在笔工具菜单中隐藏墨迹渐隐控制开关”设置并立即应用该更改。
- ///
- ///
- /// 当控件切换时,方法会更新 Settings.Canvas.HideInkFadeControlInPenMenu 的值、将设置写回配置文件、刷新墨迹渐隐控件的可见性,并记录事件日志或错误日志。
- ///
- private void ToggleSwitchHideInkFadeControlInPenMenu_Toggled(object sender, RoutedEventArgs e)
- {
- try
- {
- if (isLoaded)
- {
- Settings.Canvas.HideInkFadeControlInPenMenu = ToggleSwitchHideInkFadeControlInPenMenu.IsOn;
- SaveSettingsToFile();
- }
-
- // 立即更新墨迹渐隐控制开关的可见性
- UpdateInkFadeControlVisibility();
-
- LogHelper.WriteLogToFile($"在笔工具菜单中隐藏墨迹渐隐控制开关已{(Settings.Canvas.HideInkFadeControlInPenMenu ? "启用" : "禁用")}", LogHelper.LogType.Event);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"切换在笔工具菜单中隐藏墨迹渐隐控制开关时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 橡皮擦自动切换回批注模式开关切换事件处理
- ///
- private void ToggleSwitchEnableEraserAutoSwitchBack_Toggled(object sender, RoutedEventArgs e)
+ private void ComboBoxEraserSizeFloatingBar_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
if (!isLoaded) return;
- Settings.Canvas.EnableEraserAutoSwitchBack = ToggleSwitchEnableEraserAutoSwitchBack.IsOn;
+ var comboBox = sender as System.Windows.Controls.ComboBox;
+ if (comboBox == null) return;
+
+ Settings.Canvas.EraserSize = comboBox.SelectedIndex;
SaveSettingsToFile();
- // 如果禁用,停止计时器
- if (!Settings.Canvas.EnableEraserAutoSwitchBack)
+ if (comboBox.Name == "ComboBoxEraserSizeFloatingBar" && BoardComboBoxEraserSize != null)
{
- StopEraserAutoSwitchBackTimer();
+ BoardComboBoxEraserSize.SelectedIndex = comboBox.SelectedIndex;
}
-
- LogHelper.WriteLogToFile($"橡皮擦自动切换回批注模式已{(Settings.Canvas.EnableEraserAutoSwitchBack ? "启用" : "禁用")}", LogHelper.LogType.Event);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"切换橡皮擦自动切换回批注模式时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 橡皮擦自动切换延迟时间滑块值改变事件处理
- ///
- private void EraserAutoSwitchBackDelaySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- Settings.Canvas.EraserAutoSwitchBackDelaySeconds = (int)e.NewValue;
- SaveSettingsToFile();
-
- // 如果计时器正在运行,重新启动以应用新的延迟时间
- if (_eraserAutoSwitchBackTimer != null && _eraserAutoSwitchBackTimer.IsEnabled)
+ else if (comboBox.Name == "BoardComboBoxEraserSize" && ComboBoxEraserSizeFloatingBar != null)
{
- StartEraserAutoSwitchBackTimer();
- }
-
- LogHelper.WriteLogToFile($"橡皮擦自动切换延迟时间已更新为 {Settings.Canvas.EraserAutoSwitchBackDelaySeconds} 秒", LogHelper.LogType.Event);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"更新橡皮擦自动切换延迟时间时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 根据开关状态启用或禁用画笔自动恢复:更新设置并保存,启用时初始化并安排恢复定时器,禁用时停止计时器。
- ///
- private void ToggleSwitchBrushAutoRestore_Toggled(object sender, RoutedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- Settings.Canvas.EnableBrushAutoRestore = ToggleSwitchBrushAutoRestore.IsOn;
- SaveSettingsToFile();
-
- if (Settings.Canvas.EnableBrushAutoRestore)
- {
- InitBrushAutoRestoreTimer();
- ScheduleBrushAutoRestore();
- }
- else
- {
- if (_brushAutoRestoreTimer != null)
- {
- _brushAutoRestoreTimer.Stop();
- }
+ ComboBoxEraserSizeFloatingBar.SelectedIndex = comboBox.SelectedIndex;
}
}
catch (Exception ex)
{
- LogHelper.WriteLogToFile($"切换画笔自动恢复功能时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 当“画笔自动恢复次数”文本改变时更新并保存设置;若启用画笔自动恢复,则重新调度自动恢复定时器。
- ///
- ///
- /// 在窗口未完成加载或 Settings.Canvas 为 null 时不执行任何操作;方法内部会捕获并记录异常,不向调用方抛出异常。
- ///
- private void BrushAutoRestoreTimesTextBox_TextChanged(object sender, TextChangedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- if (Settings?.Canvas == null) return;
-
- Settings.Canvas.BrushAutoRestoreTimes = BrushAutoRestoreTimesTextBox.Text ?? string.Empty;
- SaveSettingsToFile();
- if (Settings.Canvas.EnableBrushAutoRestore)
- {
- ScheduleBrushAutoRestore();
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"BrushAutoRestoreTimes: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 响应画笔自动恢复颜色下拉框的选择变更并将选中项保存为设置中的目标颜色。
- ///
- ///
- /// 当窗口已加载且 Settings.Canvas 可用时,将选中 ComboBoxItem 的 Tag(十六进制颜色字符串)写入 Settings.Canvas.BrushAutoRestoreColor 并持久化到设置文件;若发生异常则记录错误日志。
- ///
- private void ComboBoxBrushAutoRestoreColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- if (Settings?.Canvas == null) return;
-
- if (ComboBoxBrushAutoRestoreColor.SelectedItem is ComboBoxItem item)
- {
- string hex = item.Tag as string ?? string.Empty;
- Settings.Canvas.BrushAutoRestoreColor = hex;
- SaveSettingsToFile();
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"更新画笔自动恢复目标颜色时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 将画笔自动恢复的目标粗细设置为滑块的新值并将更改保存到设置文件。
- ///
- /// 触发事件的滑块控件(通常为 BrushAutoRestoreWidthSlider)。
- /// 包含滑块的新值的事件参数;使用 e.NewValue 作为目标粗细。
- ///
- /// 如果窗口尚未完成加载或 Settings.Canvas 为 null,则不执行任何操作。
- ///
- private void BrushAutoRestoreWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- if (Settings?.Canvas == null) return;
-
- Settings.Canvas.BrushAutoRestoreWidth = e.NewValue;
- SaveSettingsToFile();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"更新画笔自动恢复目标粗细时出错: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
- ///
- /// 在画笔自动恢复透明度滑块的值发生变化时,将新的透明度值保存到 Settings.Canvas.BrushAutoRestoreAlpha 并持久化到设置文件。
- ///
- /// 来自滑块的事件参数;使用 e.NewValue 的整数值作为新的透明度目标。
- private void BrushAutoRestoreAlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- try
- {
- if (!isLoaded) return;
- if (Settings?.Canvas == null) return;
-
- Settings.Canvas.BrushAutoRestoreAlpha = (int)e.NewValue;
- SaveSettingsToFile();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"更新画笔自动恢复目标透明度时出错: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"切换橡皮擦大小时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
@@ -3684,8 +3358,6 @@ namespace Ink_Canvas
}
}
- #endregion
-
///
/// 初始化文件关联状态显示
@@ -3812,10 +3484,6 @@ namespace Ink_Canvas
// 获取所有滑块控件并添加触摸支持
var sliders = new List
{
- InkFadeTimeSlider,
- AutoStraightenLineThresholdSlider,
- LineStraightenSensitivitySlider,
- LineEndpointSnappingThresholdSlider,
ViewboxFloatingBarScaleTransformValueSlider,
ViewboxFloatingBarOpacityValueSlider,
ViewboxFloatingBarOpacityInPPTValueSlider,
@@ -3842,9 +3510,7 @@ namespace Ink_Canvas
InkAlphaSlider,
HighlighterWidthSlider,
MLAvoidanceHistorySlider,
- MLAvoidanceWeightSlider,
- BrushAutoRestoreWidthSlider,
- BrushAutoRestoreAlphaSlider
+ MLAvoidanceWeightSlider
};
foreach (var slider in sliders)
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index edc5d3ba..3a6bbe69 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -1,4 +1,4 @@
-using H.NotifyIcon;
+using H.NotifyIcon;
using Ink_Canvas.Helpers;
using Ink_Canvas.Windows.SettingsViews.Helpers;
using Newtonsoft.Json;
@@ -41,652 +41,7 @@ namespace Ink_Canvas
private bool _isChangingUpdateChannelInternally;
/// 内部标记:是否正在内部更改「更新包架构」(32/64 位 ZIP)
private bool _isChangingUpdatePackageArchInternally;
- ///
- /// 内部标记:是否正在内部更改遥测设置
- ///
- private bool _isChangingTelemetryInternally;
- ///
- /// 内部标记:是否正在内部更改遥测隐私设置
- ///
- private bool _isChangingTelemetryPrivacyInternally;
- ///
- /// 检查隐私文件是否存在
- ///
- /// 如果隐私文件存在则返回true,否则返回false
- ///
- /// 尝试从程序集资源中查找privacy.txt文件
- /// 如果找到则返回true,否则返回false
- ///
- private static bool PrivacyFileExists()
- {
- try
- {
- var assembly = Assembly.GetExecutingAssembly();
- var resourceName = "Ink_Canvas.privacy.txt";
- using (Stream stream = assembly.GetManifestResourceStream(resourceName))
- {
- return stream != null;
- }
- }
- catch
- {
- return false;
- }
- }
-
- ///
- /// 查找隐私文件
- ///
- /// 隐私文件路径,如果是嵌入资源则返回"embedded",如果未找到则返回null
- ///
- /// 先尝试从文件系统读取,搜索路径包括:
- /// 1. App.RootPath
- /// 2. 程序集所在目录
- /// 3. 程序集所在目录的上一级目录
- /// 如果文件系统中未找到,则回退到嵌入资源
- ///
- private static string FindPrivacyFile()
- {
- // 先尝试从文件系统读取
- string assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- string[] searchPaths = new string[]
- {
- App.RootPath,
- assemblyDir,
- Path.GetDirectoryName(assemblyDir) // One level up from assembly directory
- };
-
- string foundPath = null;
- foreach (string searchPath in searchPaths)
- {
- if (string.IsNullOrEmpty(searchPath)) continue;
-
- string testPathTxt = Path.Combine(searchPath, "privacy.txt");
- string testPathNoExt = Path.Combine(searchPath, "privacy");
-
- if (File.Exists(testPathTxt))
- {
- foundPath = testPathTxt;
- break;
- }
- else if (File.Exists(testPathNoExt))
- {
- foundPath = testPathNoExt;
- break;
- }
- }
-
- if (foundPath != null && File.Exists(foundPath))
- {
- return foundPath;
- }
-
- // 回退到嵌入资源
- try
- {
- var assembly = Assembly.GetExecutingAssembly();
- var resourceName = "Ink_Canvas.privacy.txt";
- using (Stream stream = assembly.GetManifestResourceStream(resourceName))
- {
- if (stream != null)
- {
- // 返回特殊字符串表示来自嵌入资源
- return "embedded";
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"从程序集资源查找隐私说明失败: {ex.Message}", LogHelper.LogType.Warning);
- }
-
- return null;
- }
-
- private void CheckUpdateChannelAndTelemetryConsistency()
- {
- var currentChannel = Settings.Startup.UpdateChannel;
- bool isTestChannel = currentChannel == UpdateChannel.Preview || currentChannel == UpdateChannel.Beta;
-
- if (!isTestChannel)
- {
- return;
- }
- if (!Settings.Startup.HasAcceptedTelemetryPrivacy)
- {
- var result = MessageBox.Show(
- $"检测到您当前处于 {currentChannel} 通道,但尚未同意隐私说明。\n\n" +
- "使用预览/测试通道需要同意隐私说明并启用匿名使用数据上传。\n\n" +
- "是否现在同意隐私说明并启用基础数据上传?\n" +
- "(选择“否”将自动切换回正式通道)",
- "更新通道与隐私协议不匹配",
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result == MessageBoxResult.Yes)
- {
- try
- {
- // 使用 FindPrivacyFile 方法,支持文件系统和嵌入资源
- string privacyPath = FindPrivacyFile();
-
- if (string.IsNullOrEmpty(privacyPath))
- {
- MessageBox.Show(
- "未找到隐私说明文件(privacy.txt 或 privacy)。\n\n将切换回正式通道。",
- "隐私文件缺失",
- MessageBoxButton.OK,
- MessageBoxImage.Warning);
- }
- else
- {
- var privacyWindow = new PrivacyAgreementWindow();
- privacyWindow.Owner = this;
- bool? dialogResult = privacyWindow.ShowDialog();
-
- if (dialogResult == true && privacyWindow.UserAccepted)
- {
- // 用户同意,保存设置
- Settings.Startup.HasAcceptedTelemetryPrivacy = true;
- Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.Basic;
-
- // 更新UI,即使 isLoaded 为 false(启动时)
- // 使用标志避免触发事件处理程序
- // 使用 Dispatcher 确保在 UI 线程上更新
- Dispatcher.BeginInvoke(new Action(() =>
- {
- _isChangingTelemetryPrivacyInternally = true;
- _isChangingTelemetryInternally = true;
- try
- {
- if (CheckBoxTelemetryPrivacyAccepted != null)
- {
- CheckBoxTelemetryPrivacyAccepted.IsChecked = true;
- }
- if (ComboBoxTelemetryUploadLevel != null)
- {
- ComboBoxTelemetryUploadLevel.SelectedIndex = 1;
- }
- }
- finally
- {
- _isChangingTelemetryPrivacyInternally = false;
- _isChangingTelemetryInternally = false;
- }
- }), DispatcherPriority.Normal);
-
- SaveSettingsToFile();
- DeviceIdentifier.UpdateUsageChannel(currentChannel);
- LogHelper.WriteLogToFile($"启动检测 | 用户同意隐私协议并启用基础遥测,保持 {currentChannel} 通道");
- return; // 用户同意,直接返回,不执行后面的切换通道逻辑
- }
- else
- {
- // 用户取消或关闭窗口,切换回正式通道
- LogHelper.WriteLogToFile($"启动检测 | 用户取消隐私协议,将切换回 Release 通道");
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"启动检测 | 读取隐私文件失败: {ex.Message}", LogHelper.LogType.Error);
- MessageBox.Show(
- "读取隐私说明文件时出错。\n\n将切换回正式通道。",
- "读取隐私文件失败",
- MessageBoxButton.OK,
- MessageBoxImage.Error);
- }
- }
- else
- {
- // 用户选择"否",切换回正式通道
- LogHelper.WriteLogToFile($"启动检测 | 用户选择不同意隐私协议,将切换回 Release 通道");
- }
-
- // 只有在用户不同意或取消的情况下,才切换回正式通道
- Settings.Startup.UpdateChannel = UpdateChannel.Release;
- DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
- SaveSettingsToFile();
-
- Dispatcher.BeginInvoke(new Action(() =>
- {
- _isChangingUpdateChannelInternally = true;
- try
- {
- if (isLoaded && UpdateChannelSelector != null)
- {
- foreach (var item in UpdateChannelSelector.Items)
- {
- if (item is RadioButton rb && rb.Tag != null &&
- string.Equals(rb.Tag.ToString(), "Release", StringComparison.OrdinalIgnoreCase))
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }), DispatcherPriority.Normal);
-
- LogHelper.WriteLogToFile($"启动检测 | 用户未同意隐私协议,已切换回 Release 通道");
- return;
- }
-
- if (Settings.Startup.TelemetryUploadLevel == TelemetryUploadLevel.None)
- {
- var result = MessageBox.Show(
- $"检测到您当前处于 {currentChannel} 通道,但匿名使用数据上传已关闭。\n\n" +
- "使用预览/测试通道需要启用匿名使用数据上传。\n\n" +
- "是否现在启用基础数据上传?\n" +
- "(选择“否”将自动切换回正式通道)",
- "更新通道与遥测状态不匹配",
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result == MessageBoxResult.Yes)
- {
- Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.Basic;
-
- if (isLoaded && ComboBoxTelemetryUploadLevel != null)
- {
- ComboBoxTelemetryUploadLevel.SelectedIndex = 1;
- }
-
- SaveSettingsToFile();
- DeviceIdentifier.UpdateUsageChannel(currentChannel);
- LogHelper.WriteLogToFile($"启动检测 | 用户启用基础遥测,保持 {currentChannel} 通道");
- }
- else
- {
- Settings.Startup.UpdateChannel = UpdateChannel.Release;
- DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
- SaveSettingsToFile();
-
- Dispatcher.BeginInvoke(new Action(() =>
- {
- _isChangingUpdateChannelInternally = true;
- try
- {
- if (isLoaded && UpdateChannelSelector != null)
- {
- foreach (var item in UpdateChannelSelector.Items)
- {
- if (item is RadioButton rb && rb.Tag != null &&
- string.Equals(rb.Tag.ToString(), "Release", StringComparison.OrdinalIgnoreCase))
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }), DispatcherPriority.Normal);
-
- LogHelper.WriteLogToFile($"启动检测 | 用户未启用遥测,已切换回 Release 通道");
- }
- }
- }
-
- ///
- /// 处理遥测上传级别选择更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 根据选择的遥测级别执行相应操作:
- /// 1. 如果选择关闭遥测且当前不是正式通道,提示用户并切换到正式通道
- /// 2. 如果选择开启遥测但未同意隐私说明,提示用户需要先同意隐私说明
- /// 3. 保存设置并显示通知
- ///
- private void ComboBoxTelemetryUploadLevel_SelectionChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- if (_isChangingTelemetryInternally) return;
- var oldLevel = Settings.Startup.TelemetryUploadLevel;
- var item = ComboBoxTelemetryUploadLevel?.SelectedItem as ComboBoxItem;
- if (item == null) return;
-
- var tag = item.Tag?.ToString() ?? "0";
- var newLevel = TelemetryUploadLevel.None;
- switch (tag)
- {
- case "1":
- newLevel = TelemetryUploadLevel.Basic;
- break;
- case "2":
- newLevel = TelemetryUploadLevel.Extended;
- break;
- default:
- newLevel = TelemetryUploadLevel.None;
- break;
- }
-
- if (newLevel == TelemetryUploadLevel.None &&
- oldLevel != TelemetryUploadLevel.None &&
- Settings.Startup.UpdateChannel != UpdateChannel.Release)
- {
- var result = MessageBox.Show(
- "关闭匿名使用数据上传后,将无法继续使用预览/测试通道,系统会自动切换回正式通道(Release)。\n\n是否确认关闭?",
- "确认关闭遥测",
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result != MessageBoxResult.Yes)
- {
- _isChangingTelemetryInternally = true;
- try
- {
- int idx = 0;
- switch (oldLevel)
- {
- case TelemetryUploadLevel.Basic:
- idx = 1;
- break;
- case TelemetryUploadLevel.Extended:
- idx = 2;
- break;
- default:
- idx = 0;
- break;
- }
- ComboBoxTelemetryUploadLevel.SelectedIndex = idx;
- }
- finally
- {
- _isChangingTelemetryInternally = false;
- }
- return;
- }
-
- _isChangingUpdateChannelInternally = true;
- try
- {
- Settings.Startup.UpdateChannel = UpdateChannel.Release;
- DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
-
- if (UpdateChannelSelector != null)
- {
- foreach (var u in UpdateChannelSelector.Items)
- {
- var rb = u as RadioButton;
- if (rb != null && rb.Tag != null && rb.Tag.ToString() == "Release")
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }
-
- if (newLevel != TelemetryUploadLevel.None && !Settings.Startup.HasAcceptedTelemetryPrivacy)
- {
- MessageBox.Show(
- "在开启匿名使用数据上传前,请先阅读并勾选上方的隐私说明。",
- "需要同意隐私说明",
- MessageBoxButton.OK,
- MessageBoxImage.Warning);
-
- _isChangingTelemetryInternally = true;
- try
- {
- Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.None;
- if (ComboBoxTelemetryUploadLevel != null)
- {
- ComboBoxTelemetryUploadLevel.SelectedIndex = 0;
- }
- }
- finally
- {
- _isChangingTelemetryInternally = false;
- }
-
- return;
- }
-
- Settings.Startup.TelemetryUploadLevel = newLevel;
-
- SaveSettingsToFile();
- ShowNotification("匿名使用数据上传设置已保存");
- }
-
- ///
- /// 处理遥测隐私同意复选框状态更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 当用户勾选或取消勾选隐私同意复选框时执行:
- /// 1. 勾选时:显示隐私协议窗口,用户同意后保存设置
- /// 2. 取消勾选时:提示用户会关闭遥测并切回正式通道,用户确认后执行相应操作
- ///
- private void CheckBoxTelemetryPrivacyAccepted_Checked(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- if (_isChangingTelemetryPrivacyInternally) return;
-
- bool isChecked = CheckBoxTelemetryPrivacyAccepted.IsChecked == true;
-
- if (isChecked)
- {
- if (!PrivacyFileExists())
- {
- MessageBox.Show(
- "未找到隐私说明文件(privacy / privacy.txt),暂时无法启用匿名使用数据上传。",
- "隐私说明缺失",
- MessageBoxButton.OK,
- MessageBoxImage.Warning);
-
- _isChangingTelemetryPrivacyInternally = true;
- try
- {
- CheckBoxTelemetryPrivacyAccepted.IsChecked = false;
- }
- finally
- {
- _isChangingTelemetryPrivacyInternally = false;
- }
-
- Settings.Startup.HasAcceptedTelemetryPrivacy = false;
- SaveSettingsToFile();
- return;
- }
-
- var privacyWindow = new PrivacyAgreementWindow();
- privacyWindow.Owner = this;
- bool? dialogResult = privacyWindow.ShowDialog();
-
- if (dialogResult == true && privacyWindow.UserAccepted)
- {
- Settings.Startup.HasAcceptedTelemetryPrivacy = true;
- SaveSettingsToFile();
- }
- else
- {
- _isChangingTelemetryPrivacyInternally = true;
- try
- {
- CheckBoxTelemetryPrivacyAccepted.IsChecked = false;
- }
- finally
- {
- _isChangingTelemetryPrivacyInternally = false;
- }
-
- Settings.Startup.HasAcceptedTelemetryPrivacy = false;
- SaveSettingsToFile();
- }
- }
- else
- {
- // 用户主动取消勾选,提示会关闭遥测并切回正式通道
- var result = MessageBox.Show(
- "取消同意隐私说明后,将关闭匿名使用数据上传,并切回正式通道(Release)。\n\n是否确认?",
- "确认取消隐私同意",
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result != MessageBoxResult.Yes)
- {
- // 撤销取消操作,恢复为已勾选
- _isChangingTelemetryPrivacyInternally = true;
- try
- {
- CheckBoxTelemetryPrivacyAccepted.IsChecked = true;
- }
- finally
- {
- _isChangingTelemetryPrivacyInternally = false;
- }
- return;
- }
-
- // 1. 关闭遥测等级
- _isChangingTelemetryInternally = true;
- try
- {
- Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.None;
- if (ComboBoxTelemetryUploadLevel != null)
- {
- ComboBoxTelemetryUploadLevel.SelectedIndex = 0;
- }
- }
- finally
- {
- _isChangingTelemetryInternally = false;
- }
-
- // 2. 若当前不是 Release 通道,则切回 Release
- if (Settings.Startup.UpdateChannel != UpdateChannel.Release)
- {
- _isChangingUpdateChannelInternally = true;
- try
- {
- Settings.Startup.UpdateChannel = UpdateChannel.Release;
- DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
-
- if (UpdateChannelSelector != null)
- {
- foreach (var u in UpdateChannelSelector.Items)
- {
- var rb = u as RadioButton;
- if (rb != null && rb.Tag != null && rb.Tag.ToString() == "Release")
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }
-
- // 3. 最后真正取消隐私同意并保存
- Settings.Startup.HasAcceptedTelemetryPrivacy = false;
- SaveSettingsToFile();
- }
- }
-
- ///
- /// 处理自动更新开关状态更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 当自动更新开关状态更改时:
- /// 1. 保存自动更新设置
- /// 2. 自动更新关闭时隐藏静默更新选项
- /// 3. 如果关闭了自动更新,同时也关闭静默更新
- /// 4. 根据静默更新设置显示或隐藏静默更新时间区域
- ///
- private void ToggleSwitchIsAutoUpdate_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Startup.IsAutoUpdate = ToggleSwitchIsAutoUpdate.IsOn;
-
- // 如果关闭了自动更新,同时也关闭静默更新
- if (!ToggleSwitchIsAutoUpdate.IsOn)
- {
- Settings.Startup.IsAutoUpdateWithSilence = false;
- ToggleSwitchIsAutoUpdateWithSilence.IsOn = false;
- }
-
- // 无论如何,静默更新时间区域的显示都要跟随静默更新设置
- AutoUpdateTimePeriodBlock.Visibility =
- (Settings.Startup.IsAutoUpdateWithSilence && Settings.Startup.IsAutoUpdate) ?
- Visibility.Visible : Visibility.Collapsed;
-
- SaveSettingsToFile();
- }
-
- ///
- /// 处理静默自动更新开关状态更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 当静默自动更新开关状态更改时:
- /// 1. 保存静默自动更新设置
- /// 2. 根据静默更新设置显示或隐藏静默更新时间区域
- ///
- private void ToggleSwitchIsAutoUpdateWithSilence_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Startup.IsAutoUpdateWithSilence = ToggleSwitchIsAutoUpdateWithSilence.IsOn;
-
- // 静默更新的时间设置区域只在静默更新开启时显示
- AutoUpdateTimePeriodBlock.Visibility =
- Settings.Startup.IsAutoUpdateWithSilence ? Visibility.Visible : Visibility.Collapsed;
-
- SaveSettingsToFile();
- }
-
- ///
- /// 处理静默自动更新开始时间选择更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 当选择静默自动更新开始时间时,保存设置到文件
- ///
- private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Startup.AutoUpdateWithSilenceStartTime =
- (string)AutoUpdateWithSilenceStartTimeComboBox.SelectedItem;
- SaveSettingsToFile();
- }
-
- ///
- /// 处理静默自动更新结束时间选择更改事件
- ///
- /// 事件发送者
- /// 路由事件参数
- ///
- /// 当选择静默自动更新结束时间时,保存设置到文件
- ///
- private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Startup.AutoUpdateWithSilenceEndTime = (string)AutoUpdateWithSilenceEndTimeComboBox.SelectedItem;
- SaveSettingsToFile();
- }
///
/// 处理PowerPoint支持开关状态更改事件
@@ -2619,115 +1974,15 @@ namespace Ink_Canvas
PPTBtnPreviewToolbar.Width = scaledToolbarWidth;
}
- private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.IsShowCursor = ToggleSwitchShowCursor.IsOn;
- inkCanvas_EditingModeChanged(inkCanvas, null);
- SaveSettingsToFile();
- }
- private void ToggleSwitchEnablePressureTouchMode_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.EnablePressureTouchMode = ToggleSwitchEnablePressureTouchMode.IsOn;
- // 如果启用了压感触屏模式,则自动关闭屏蔽压感
- if (Settings.Canvas.EnablePressureTouchMode && Settings.Canvas.DisablePressure)
- {
- Settings.Canvas.DisablePressure = false;
- ToggleSwitchDisablePressure.IsOn = false;
- }
- SaveSettingsToFile();
- }
- private void ToggleSwitchDisablePressure_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.DisablePressure = ToggleSwitchDisablePressure.IsOn;
- inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
- // 如果启用了屏蔽压感,则自动关闭压感触屏模式
- if (Settings.Canvas.DisablePressure && Settings.Canvas.EnablePressureTouchMode)
- {
- Settings.Canvas.EnablePressureTouchMode = false;
- ToggleSwitchEnablePressureTouchMode.IsOn = false;
- }
-
- SaveSettingsToFile();
- }
-
- private void ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth =
- ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn;
- SaveSettingsToFile();
- }
-
- private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.AutoStraightenLine = ToggleSwitchAutoStraightenLine.IsOn;
- SaveSettingsToFile();
- }
-
- private void AutoStraightenLineThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.AutoStraightenLineThreshold = (int)e.NewValue;
- SaveSettingsToFile();
- }
-
- private void ToggleSwitchLineEndpointSnapping_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.LineEndpointSnapping = ToggleSwitchLineEndpointSnapping.IsOn;
- SaveSettingsToFile();
- }
-
- private void LineEndpointSnappingThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.LineEndpointSnappingThreshold = (int)e.NewValue;
- SaveSettingsToFile();
- }
-
- private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
- {
- if (!isLoaded) return;
-
- // 记录旧值用于调试
- double oldValue = Settings.InkToShape.LineStraightenSensitivity;
-
- // 确保灵敏度值被正确保存到设置中
- Settings.InkToShape.LineStraightenSensitivity = e.NewValue;
-
- // 输出调试信息,观察值变化
- Debug.WriteLine($"LineStraightenSensitivity changed: {oldValue} -> {e.NewValue}");
-
- // 立即保存设置到文件,确保设置不会丢失
- SaveSettingsToFile();
- }
-
- private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
-
- Settings.Canvas.HighPrecisionLineStraighten = ToggleSwitchHighPrecisionLineStraighten.IsOn;
- Debug.WriteLine($"HighPrecisionLineStraighten changed: {Settings.Canvas.HighPrecisionLineStraighten}");
- SaveSettingsToFile();
- }
#endregion
@@ -2775,48 +2030,7 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
- private void ComboBoxEraserSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.EraserSize = ComboBoxEraserSize.SelectedIndex;
- // 使用新的高级橡皮擦形状应用方法
- ApplyAdvancedEraserShape();
-
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
- }
- SaveSettingsToFile();
- }
-
- private void ComboBoxEraserSizeFloatingBar_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (!isLoaded) return;
- ComboBox s = (ComboBox)sender;
- Settings.Canvas.EraserSize = s.SelectedIndex;
- if (s == ComboBoxEraserSizeFloatingBar)
- {
- BoardComboBoxEraserSize.SelectedIndex = s.SelectedIndex;
- ComboBoxEraserSize.SelectedIndex = s.SelectedIndex;
- }
- else if (s == BoardComboBoxEraserSize)
- {
- ComboBoxEraserSizeFloatingBar.SelectedIndex = s.SelectedIndex;
- ComboBoxEraserSize.SelectedIndex = s.SelectedIndex;
- }
-
- // 使用新的高级橡皮擦形状应用方法
- ApplyAdvancedEraserShape();
-
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
- }
- SaveSettingsToFile();
- }
private void SwitchToCircleEraser(object sender, MouseButtonEventArgs e)
{
@@ -2894,13 +2108,6 @@ namespace Ink_Canvas
///
/// 根据组合框的当前选择更新双曲线渐近线选项(Settings.Canvas.HyperbolaAsymptoteOption),并将更改保存到设置文件。
///
- private void ComboBoxHyperbolaAsymptoteOption_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.HyperbolaAsymptoteOption =
- (OptionalOperation)ComboBoxHyperbolaAsymptoteOption.SelectedIndex;
- SaveSettingsToFile();
- }
#endregion
@@ -3239,54 +2446,9 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
- private void ToggleSwitchHideStrokeWhenSelecting_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.HideStrokeWhenSelecting = ToggleSwitchHideStrokeWhenSelecting.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleSwitchClearCanvasAndClearTimeMachine_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.ClearCanvasAndClearTimeMachine = ToggleSwitchClearCanvasAndClearTimeMachine.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleSwitchFitToCurve_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- drawingAttributes.FitToCurve = ToggleSwitchFitToCurve.IsOn;
- Settings.Canvas.FitToCurve = ToggleSwitchFitToCurve.IsOn;
- // 启用原来的FitToCurve时自动禁用高级贝塞尔平滑
- if (ToggleSwitchFitToCurve.IsOn)
- {
- ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
- Settings.Canvas.UseAdvancedBezierSmoothing = false;
- }
-
- SaveSettingsToFile();
- }
-
- private void ToggleSwitchAdvancedBezierSmoothing_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.UseAdvancedBezierSmoothing = ToggleSwitchAdvancedBezierSmoothing.IsOn;
-
- // 启用高级贝塞尔平滑时自动禁用原来的FitToCurve
- if (ToggleSwitchAdvancedBezierSmoothing.IsOn)
- {
- ToggleSwitchFitToCurve.IsOn = false;
- Settings.Canvas.FitToCurve = false;
- drawingAttributes.FitToCurve = false;
- }
-
- // 更新墨迹平滑管理器配置
- _inkSmoothingManager?.UpdateConfig();
-
- SaveSettingsToFile();
- }
// 注释掉这些方法,因为对应的UI控件还没有在XAML中定义
/*
@@ -3905,68 +3067,13 @@ namespace Ink_Canvas
#region Ink To Shape
- private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeEnabled = ToggleSwitchEnableInkToShape.IsOn;
- SaveSettingsToFile();
- }
- private void ComboBoxShapeRecognitionEngine_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (!isLoaded || ComboBoxShapeRecognitionEngine == null) return;
- int idx = ComboBoxShapeRecognitionEngine.SelectedIndex;
- if (idx < 0) idx = 0;
- if (idx > 2) idx = 2;
- Settings.InkToShape.ShapeRecognitionEngine = idx;
- SaveSettingsToFile();
- }
- private void ToggleSwitchEnableWinRtHandwritingStrokeBeautify_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.EnableWinRtHandwritingStrokeBeautify =
- ToggleSwitchEnableWinRtHandwritingStrokeBeautify != null &&
- ToggleSwitchEnableWinRtHandwritingStrokeBeautify.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleSwitchEnableInkToShapeNoFakePressureTriangle_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeNoFakePressureTriangle =
- ToggleSwitchEnableInkToShapeNoFakePressureTriangle.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleSwitchEnableInkToShapeNoFakePressureRectangle_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeNoFakePressureRectangle =
- ToggleSwitchEnableInkToShapeNoFakePressureRectangle.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleCheckboxEnableInkToShapeTriangle_CheckedChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeTriangle = (bool)ToggleCheckboxEnableInkToShapeTriangle.IsChecked;
- SaveSettingsToFile();
- }
- private void ToggleCheckboxEnableInkToShapeRectangle_CheckedChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeRectangle = (bool)ToggleCheckboxEnableInkToShapeRectangle.IsChecked;
- SaveSettingsToFile();
- }
- private void ToggleCheckboxEnableInkToShapeRounded_CheckedChanged(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.InkToShape.IsInkToShapeRounded = (bool)ToggleCheckboxEnableInkToShapeRounded.IsChecked;
- SaveSettingsToFile();
- }
#endregion
@@ -5157,344 +4264,8 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile($"Settings | Update package architecture: {newArch}");
}
- private async void UpdateChannelSelector_Checked(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- if (_isChangingUpdateChannelInternally) return;
- var radioButton = sender as RadioButton;
- if (radioButton != null)
- {
- var oldChannel = Settings.Startup.UpdateChannel;
- string channel = radioButton.Tag.ToString();
- UpdateChannel newChannel = channel == "Beta" ? UpdateChannel.Beta
- : channel == "Preview" ? UpdateChannel.Preview
- : UpdateChannel.Release;
- // 如果通道没有变化,不需要执行更新检查
- if (Settings.Startup.UpdateChannel == newChannel)
- {
- return;
- }
- bool isTestChannel = newChannel == UpdateChannel.Preview || newChannel == UpdateChannel.Beta;
- if (isTestChannel && !Settings.Startup.HasAcceptedTelemetryPrivacy)
- {
- MessageBox.Show(
- "加入预览 / 测试通道前,请先在关于页面勾选“我已阅读并同意 privacy 中的隐私说明”。",
- "需要同意隐私说明",
- MessageBoxButton.OK,
- MessageBoxImage.Warning);
-
- Settings.Startup.UpdateChannel = oldChannel;
- Dispatcher.BeginInvoke(new Action(() =>
- {
- _isChangingUpdateChannelInternally = true;
- try
- {
- if (UpdateChannelSelector != null)
- {
- string oldChannelTag = oldChannel.ToString();
- foreach (var item in UpdateChannelSelector.Items)
- {
- if (item is RadioButton rb && rb.Tag != null &&
- string.Equals(rb.Tag.ToString(), oldChannelTag, StringComparison.OrdinalIgnoreCase))
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }), DispatcherPriority.Normal);
-
- SaveSettingsToFile();
- LogHelper.WriteLogToFile("Settings | User not accepted privacy, reverted update channel");
- return;
- }
-
- if (isTestChannel && Settings.Startup.TelemetryUploadLevel == TelemetryUploadLevel.None)
- {
- var result = MessageBox.Show(
- "加入预览 / 测试通道需要开启匿名基础数据上传。\n\n是否立即开启匿名基础数据上传?",
- "需要开启匿名使用数据上传",
- MessageBoxButton.YesNo,
- MessageBoxImage.Warning);
-
- if (result == MessageBoxResult.Yes)
- {
- Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.Basic;
- if (ComboBoxTelemetryUploadLevel != null)
- {
- ComboBoxTelemetryUploadLevel.SelectedIndex = 1;
- }
- SaveSettingsToFile();
- LogHelper.WriteLogToFile("Settings | Telemetry enabled (Basic) for preview/beta update channel");
- }
- else
- {
- Settings.Startup.UpdateChannel = oldChannel;
- Dispatcher.BeginInvoke(new Action(() =>
- {
- _isChangingUpdateChannelInternally = true;
- try
- {
- if (UpdateChannelSelector != null)
- {
- string oldChannelTag = oldChannel.ToString();
- foreach (var item in UpdateChannelSelector.Items)
- {
- if (item is RadioButton rb && rb.Tag != null &&
- string.Equals(rb.Tag.ToString(), oldChannelTag, StringComparison.OrdinalIgnoreCase))
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- }
- finally
- {
- _isChangingUpdateChannelInternally = false;
- }
- }), DispatcherPriority.Normal);
-
- SaveSettingsToFile();
- LogHelper.WriteLogToFile("Settings | User declined telemetry, reverted update channel");
- return;
- }
- }
-
- Settings.Startup.UpdateChannel = newChannel;
- DeviceIdentifier.UpdateUsageChannel(newChannel);
- LogHelper.WriteLogToFile($"Settings | Update channel changed to {Settings.Startup.UpdateChannel}");
- SaveSettingsToFile();
-
- // 如果启用了自动更新,立即执行完整的检查更新操作
- if (Settings.Startup.IsAutoUpdate)
- {
- LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, performing immediate update check");
- ResetUpdateCheckRetry();
-
- // 执行完整的更新检查
- await Task.Run(async () =>
- {
- try
- {
- // 调用主窗口的AutoUpdate方法,它会自动清除之前的更新状态并使用新通道重新检查
- Dispatcher.Invoke(() =>
- {
- AutoUpdate();
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"AutoUpdate | Error during channel switch update check: {ex.Message}", LogHelper.LogType.Error);
- }
- });
- }
- else
- {
- LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, but auto-update is disabled");
- }
- }
- }
-
- private async void ManualUpdateButton_Click(object sender, RoutedEventArgs e)
- {
- ManualUpdateButton.IsEnabled = false;
- ManualUpdateButton.Content = "正在检查更新...";
-
- try
- {
- LogHelper.WriteLogToFile("ManualUpdate | Manual update button clicked");
-
- // 使用当前选择的更新通道检查更新
- var (remoteVersion, lineGroup, apiReleaseNotes) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true, false);
-
- if (remoteVersion != null)
- {
- LogHelper.WriteLogToFile($"ManualUpdate | Found new version: {remoteVersion}");
-
- // 获取当前版本
- string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
-
- // 创建并显示更新窗口
- HasNewUpdateWindow updateWindow = new HasNewUpdateWindow(currentVersion, remoteVersion, "", apiReleaseNotes);
- updateWindow.Owner = Application.Current.MainWindow;
- bool? dialogResult = updateWindow.ShowDialog();
-
- // 如果窗口被关闭但没有点击按钮,则不执行任何操作
- if (dialogResult != true)
- {
- LogHelper.WriteLogToFile("ManualUpdate | Update dialog closed without selection");
- return;
- }
-
- // 根据用户选择处理更新
- switch (updateWindow.Result)
- {
- case HasNewUpdateWindow.UpdateResult.UpdateNow:
- // 立即更新:显示下载进度,下载完成后立即安装
- LogHelper.WriteLogToFile("ManualUpdate | User chose to update now");
-
- // 显示下载进度提示
- MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information);
-
- // 下载更新文件,使用多线路组下载功能
- bool isDownloadSuccessful = await DownloadUpdateWithFallback(remoteVersion, lineGroup, Settings.Startup.UpdateChannel);
-
- if (isDownloadSuccessful)
- {
- // 下载成功,提示用户准备安装
- MessageBoxResult result = MessageBox.Show("更新已下载完成,点击确定后将关闭软件并安装新版本!", "安装更新", MessageBoxButton.OKCancel, MessageBoxImage.Information);
-
- // 只有当用户点击确定按钮后才关闭软件
- if (result == MessageBoxResult.OK)
- {
- // 设置为用户主动退出,避免被看门狗判定为崩溃
- App.IsAppExitByUser = true;
-
- // 准备批处理脚本
- AutoUpdateHelper.InstallNewVersionApp(remoteVersion, true);
-
- // 关闭软件,让安装程序接管
- Application.Current.Shutdown();
- }
- else
- {
- LogHelper.WriteLogToFile("ManualUpdate | User cancelled update installation");
- }
- }
- else
- {
- // 下载失败
- MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
- }
- break;
-
- case HasNewUpdateWindow.UpdateResult.UpdateLater:
- // 稍后更新:静默下载,在软件关闭时自动安装
- LogHelper.WriteLogToFile("ManualUpdate | User chose to update later");
-
- // 不管设置如何,都进行下载,使用多线路组下载功能
- isDownloadSuccessful = await DownloadUpdateWithFallback(remoteVersion, lineGroup, Settings.Startup.UpdateChannel);
-
- if (isDownloadSuccessful)
- {
- LogHelper.WriteLogToFile("ManualUpdate | Update downloaded successfully, will install when application closes");
-
- // 设置标志,在应用程序关闭时安装
- Settings.Startup.IsAutoUpdate = true;
- Settings.Startup.IsAutoUpdateWithSilence = true;
-
- // 启动检查定时器
- timerCheckAutoUpdateWithSilence.Start();
-
- // 通知用户
- MessageBox.Show("更新已下载完成,将在软件关闭时自动安装。", "更新已准备就绪", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- else
- {
- LogHelper.WriteLogToFile("ManualUpdate | Update download failed", LogHelper.LogType.Error);
- MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
- }
- break;
-
- case HasNewUpdateWindow.UpdateResult.SkipVersion:
- // 跳过该版本:记录到设置中
- LogHelper.WriteLogToFile($"ManualUpdate | User chose to skip version {remoteVersion}");
-
- // 记录要跳过的版本号
- Settings.Startup.SkippedVersion = remoteVersion;
-
- // 保存设置到文件
- SaveSettingsToFile();
-
- // 通知用户
- MessageBox.Show($"已设置跳过版本 {remoteVersion},在下次发布新版本之前不会再提示更新。",
- "已跳过此版本",
- MessageBoxButton.OK,
- MessageBoxImage.Information);
- break;
- }
- }
- else
- {
- // 没有更新
- LogHelper.WriteLogToFile("ManualUpdate | No updates available");
- MessageBox.Show("当前已是最新版本!", "无可用更新", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"Error in ManualUpdateButton_Click: {ex.Message}", LogHelper.LogType.Error);
- MessageBox.Show(
- $"手动更新过程中发生错误: {ex.Message}",
- "更新错误",
- MessageBoxButton.OK,
- MessageBoxImage.Error);
- }
- finally
- {
- // 恢复按钮状态
- ManualUpdateButton.IsEnabled = true;
- ManualUpdateButton.Content = "手动更新";
- }
- }
-
- private async void FixVersionButton_Click(object sender, RoutedEventArgs e)
- {
- // 显示确认对话框
- var confirm = MessageBox.Show(
- "此操作将下载当前选择通道的最新版本并安装,软件将自动关闭并更新。\n\n确定要执行版本修复吗?",
- "版本修复确认",
- MessageBoxButton.YesNo,
- MessageBoxImage.Question);
-
- if (confirm == MessageBoxResult.Yes)
- {
- // 禁用按钮,避免重复点击
- FixVersionButton.IsEnabled = false;
- FixVersionButton.Content = "正在修复...";
-
- try
- {
- // 执行版本修复
- bool result = await AutoUpdateHelper.FixVersion(Settings.Startup.UpdateChannel);
-
- if (!result)
- {
- MessageBox.Show(
- "版本修复失败,可能是网络问题或当前已是最新版本。",
- "修复失败",
- MessageBoxButton.OK,
- MessageBoxImage.Error);
-
- // 恢复按钮状态
- FixVersionButton.IsEnabled = true;
- FixVersionButton.Content = "版本修复";
- }
- // 成功则会自动关闭应用程序并安装
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"Error in FixVersionButton_Click: {ex.Message}", LogHelper.LogType.Error);
- MessageBox.Show(
- $"版本修复过程中发生错误: {ex.Message}",
- "修复错误",
- MessageBoxButton.OK,
- MessageBoxImage.Error);
-
- // 恢复按钮状态
- FixVersionButton.IsEnabled = true;
- FixVersionButton.Content = "版本修复";
- }
- }
- }
// 自定义点名背景相关方法
public void UpdatePickNameBackgroundsInComboBox()
@@ -5563,19 +4334,7 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
- private void ToggleSwitchClearCanvasAlsoClearImages_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.ClearCanvasAlsoClearImages = ToggleSwitchClearCanvasAlsoClearImages.IsOn;
- SaveSettingsToFile();
- }
- private void ToggleSwitchCompressPicturesUploaded_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.IsCompressPicturesUploaded = ToggleSwitchCompressPicturesUploaded.IsOn;
- SaveSettingsToFile();
- }
private void ToggleSwitchAutoFoldAfterPPTSlideShow_Toggled(object sender, RoutedEventArgs e)
{
@@ -5612,13 +4371,6 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
- private void ToggleSwitchShowCircleCenter_Toggled(object sender, RoutedEventArgs e)
- {
- if (!isLoaded) return;
- Settings.Canvas.ShowCircleCenter = ToggleSwitchShowCircleCenter.IsOn;
- SaveSettingsToFile();
- }
-
#region 底部按钮水平位置控制
private void PPTButtonLBPositionValueSlider_ValueChanged(object sender, RoutedEventArgs e)
@@ -5810,4 +4562,7 @@ namespace Ink_Canvas
#endregion
}
-}
\ No newline at end of file
+}
+
+
+
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index 23fd71fc..8e8c967b 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -37,7 +37,6 @@ namespace Ink_Canvas
/// 指示是否跳过自动更新检查;为 true 时不会在加载设置后执行自动更新检测。
private void LoadSettings(bool isStartup = false, bool skipAutoUpdateCheck = false)
{
- AppVersionTextBlock.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
try
{
if (File.Exists(App.RootPath + settingsFileName))
@@ -184,32 +183,6 @@ namespace Ink_Canvas
{
if (Settings?.Startup != null)
{
- if (ComboBoxTelemetryUploadLevel != null)
- {
- int idx = 0;
- switch (Settings.Startup.TelemetryUploadLevel)
- {
- case TelemetryUploadLevel.None:
- idx = 0;
- break;
- case TelemetryUploadLevel.Basic:
- idx = 1;
- break;
- case TelemetryUploadLevel.Extended:
- idx = 2;
- break;
- default:
- idx = 0;
- break;
- }
-
- ComboBoxTelemetryUploadLevel.SelectedIndex = idx;
- }
-
- if (CheckBoxTelemetryPrivacyAccepted != null)
- {
- CheckBoxTelemetryPrivacyAccepted.IsChecked = Settings.Startup.HasAcceptedTelemetryPrivacy;
- }
}
}
catch
@@ -241,9 +214,6 @@ namespace Ink_Canvas
}
// 设置自动更新相关选项
- ToggleSwitchIsAutoUpdate.IsOn = Settings.Startup.IsAutoUpdate;
-
- // 只有在启用了自动更新功能时才检查更新
if (Settings.Startup.IsAutoUpdate && !skipAutoUpdateCheck)
{
if (isStartup)
@@ -251,63 +221,12 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check at startup");
AutoUpdate();
}
- // 当设置被修改时也检查更新(非启动时)
else
{
LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check after settings change");
AutoUpdate();
}
}
-
- if (Settings.Startup.IsAutoUpdateWithSilence)
- {
- ToggleSwitchIsAutoUpdateWithSilence.IsOn = true;
- }
-
- // 初始化更新通道选择
- foreach (var radioButton in UpdateChannelSelector.Items)
- {
- if (radioButton is RadioButton rb)
- {
- if (rb.Tag.ToString() == Settings.Startup.UpdateChannel.ToString())
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
-
- // 初始化更新包架构
- if (UpdatePackageArchitectureSelector != null)
- {
- _isChangingUpdatePackageArchInternally = true;
- try
- {
- string wantTag = Settings.Startup.UpdatePackageArchitecture == UpdatePackageArchitecture.X64 ? "X64" : "X86";
- foreach (var item in UpdatePackageArchitectureSelector.Items)
- {
- if (item is RadioButton rb && rb.Tag != null &&
- string.Equals(rb.Tag.ToString(), wantTag, StringComparison.OrdinalIgnoreCase))
- {
- rb.IsChecked = true;
- break;
- }
- }
- }
- finally
- {
- _isChangingUpdatePackageArchInternally = false;
- }
- }
-
- AutoUpdateTimePeriodBlock.Visibility = Settings.Startup.IsAutoUpdateWithSilence
- ? Visibility.Visible
- : Visibility.Collapsed;
-
- AutoUpdateWithSilenceTimeComboBox.InitializeAutoUpdateWithSilenceTimeComboBoxOptions(
- AutoUpdateWithSilenceStartTimeComboBox, AutoUpdateWithSilenceEndTimeComboBox);
- AutoUpdateWithSilenceStartTimeComboBox.SelectedItem = Settings.Startup.AutoUpdateWithSilenceStartTime;
- AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = Settings.Startup.AutoUpdateWithSilenceEndTime;
}
else
{
@@ -789,7 +708,6 @@ namespace Ink_Canvas
if (BoardInkAlphaSlider != null) BoardInkAlphaSlider.Value = alpha;
- ComboBoxHyperbolaAsymptoteOption.SelectedIndex = (int)Settings.Canvas.HyperbolaAsymptoteOption;
if (Settings.Canvas.UsingWhiteboard)
{
@@ -810,24 +728,17 @@ namespace Ink_Canvas
if (Settings.Canvas.IsShowCursor)
{
- ToggleSwitchShowCursor.IsOn = true;
inkCanvas.ForceCursor = true;
}
else
{
- ToggleSwitchShowCursor.IsOn = false;
inkCanvas.ForceCursor = false;
}
- // 初始化压感触屏模式开关状态
- ToggleSwitchEnablePressureTouchMode.IsOn = Settings.Canvas.EnablePressureTouchMode;
// 初始化屏蔽压感开关状态
- ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure;
inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
- ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn =
- Settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth;
if (Settings.Canvas.EnableVelocityBrushTip)
{
@@ -842,14 +753,9 @@ namespace Ink_Canvas
ComboBoxPenStyle.SelectedIndex = penStyleUi;
BoardComboBoxPenStyle.SelectedIndex = penStyleUi;
- ComboBoxEraserSize.SelectedIndex = Settings.Canvas.EraserSize;
ComboBoxEraserSizeFloatingBar.SelectedIndex = Settings.Canvas.EraserSize;
BoardComboBoxEraserSize.SelectedIndex = Settings.Canvas.EraserSize;
- ToggleSwitchClearCanvasAndClearTimeMachine.IsOn =
- Settings.Canvas.ClearCanvasAndClearTimeMachine;
- ToggleSwitchClearCanvasAlsoClearImages.IsOn = Settings.Canvas.ClearCanvasAlsoClearImages;
- ToggleSwitchShowCircleCenter.IsOn = Settings.Canvas.ShowCircleCenter;
switch (Settings.Canvas.EraserShapeType)
{
@@ -903,28 +809,21 @@ namespace Ink_Canvas
CheckEraserTypeTab();
- ToggleSwitchHideStrokeWhenSelecting.IsOn = Settings.Canvas.HideStrokeWhenSelecting;
// 初始化贝塞尔曲线平滑设置
if (Settings.Canvas.UseAdvancedBezierSmoothing)
{
// 如果启用高级贝塞尔平滑,则禁用原来的FitToCurve
- ToggleSwitchAdvancedBezierSmoothing.IsOn = true;
- ToggleSwitchFitToCurve.IsOn = false;
drawingAttributes.FitToCurve = false;
}
else if (Settings.Canvas.FitToCurve)
{
// 如果启用原来的FitToCurve,则禁用高级贝塞尔平滑
- ToggleSwitchFitToCurve.IsOn = true;
- ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
drawingAttributes.FitToCurve = true;
}
else
{
// 两者都禁用
- ToggleSwitchFitToCurve.IsOn = false;
- ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
drawingAttributes.FitToCurve = false;
}
@@ -946,16 +845,10 @@ namespace Ink_Canvas
*/
// 初始化直线自动拉直相关设置
- ToggleSwitchAutoStraightenLine.IsOn = Settings.Canvas.AutoStraightenLine;
- AutoStraightenLineThresholdSlider.Value = Settings.Canvas.AutoStraightenLineThreshold;
// 直线拉直灵敏度也在这里初始化,即使它存储在InkToShape中
- LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity;
// 初始化高精度直线拉直设置
- ToggleSwitchHighPrecisionLineStraighten.IsOn = Settings.Canvas.HighPrecisionLineStraighten;
// 初始化直线端点吸附相关设置
- ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
- ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded;
}
else
{
@@ -1032,30 +925,13 @@ namespace Ink_Canvas
// InkToShape
if (Settings.InkToShape != null)
{
- ToggleSwitchEnableInkToShape.IsOn = Settings.InkToShape.IsInkToShapeEnabled;
- if (ComboBoxShapeRecognitionEngine != null)
- {
- int eng = Settings.InkToShape.ShapeRecognitionEngine;
- if (eng < 0 || eng > 2) eng = 0;
- ComboBoxShapeRecognitionEngine.SelectedIndex = eng;
- }
- if (ToggleSwitchEnableWinRtHandwritingStrokeBeautify != null)
- ToggleSwitchEnableWinRtHandwritingStrokeBeautify.IsOn =
- Settings.InkToShape.EnableWinRtHandwritingStrokeBeautify;
- ToggleSwitchEnableInkToShapeNoFakePressureRectangle.IsOn =
- Settings.InkToShape.IsInkToShapeNoFakePressureRectangle;
- ToggleSwitchEnableInkToShapeNoFakePressureTriangle.IsOn =
- Settings.InkToShape.IsInkToShapeNoFakePressureTriangle;
- ToggleCheckboxEnableInkToShapeTriangle.IsChecked = Settings.InkToShape.IsInkToShapeTriangle;
- ToggleCheckboxEnableInkToShapeRectangle.IsChecked = Settings.InkToShape.IsInkToShapeRectangle;
- ToggleCheckboxEnableInkToShapeRounded.IsChecked = Settings.InkToShape.IsInkToShapeRounded;
// 直线拉直灵敏度在Canvas部分已经初始化,这里不再重复
}
@@ -1315,73 +1191,12 @@ namespace Ink_Canvas
{
try
{
- // 同步设置面板中的开关状态
- if (ToggleSwitchBrushAutoRestore != null)
- {
- ToggleSwitchBrushAutoRestore.IsOn = Settings.Canvas.EnableBrushAutoRestore;
- }
- // 同步时间点输入框
- if (BrushAutoRestoreTimesTextBox != null)
- {
- BrushAutoRestoreTimesTextBox.Text = Settings.Canvas.BrushAutoRestoreTimes ?? string.Empty;
- }
- // 同步颜色下拉框
- if (ComboBoxBrushAutoRestoreColor != null)
- {
- if (string.IsNullOrWhiteSpace(Settings.Canvas.BrushAutoRestoreColor))
- {
- Settings.Canvas.BrushAutoRestoreColor = "#FFFF0000";
- }
- bool found = false;
- foreach (ComboBoxItem item in ComboBoxBrushAutoRestoreColor.Items)
- {
- if (item.Tag != null && item.Tag.ToString() == Settings.Canvas.BrushAutoRestoreColor)
- {
- ComboBoxBrushAutoRestoreColor.SelectionChanged -= ComboBoxBrushAutoRestoreColor_SelectionChanged;
- try
- {
- ComboBoxBrushAutoRestoreColor.SelectedItem = item;
- }
- finally
- {
- ComboBoxBrushAutoRestoreColor.SelectionChanged += ComboBoxBrushAutoRestoreColor_SelectionChanged;
- }
- found = true;
- break;
- }
- }
- if (!found && ComboBoxBrushAutoRestoreColor.Items.Count > 0)
- {
- ComboBoxBrushAutoRestoreColor.SelectionChanged -= ComboBoxBrushAutoRestoreColor_SelectionChanged;
- try
- {
- ComboBoxBrushAutoRestoreColor.SelectedIndex = 0;
- Settings.Canvas.BrushAutoRestoreColor = "#FFFF0000";
- }
- finally
- {
- ComboBoxBrushAutoRestoreColor.SelectionChanged += ComboBoxBrushAutoRestoreColor_SelectionChanged;
- }
- }
- }
- // 同步粗细滑块
- if (BrushAutoRestoreWidthSlider != null)
- {
- BrushAutoRestoreWidthSlider.Value = Settings.Canvas.BrushAutoRestoreWidth > 0
- ? Settings.Canvas.BrushAutoRestoreWidth
- : 5;
- }
- // 同步透明度滑块
- if (BrushAutoRestoreAlphaSlider != null)
- {
- BrushAutoRestoreAlphaSlider.Value = Settings.Canvas.BrushAutoRestoreAlpha;
- }
// 如果功能已启用,初始化并启动定时器
if (Settings.Canvas.EnableBrushAutoRestore)
@@ -1405,11 +1220,6 @@ namespace Ink_Canvas
{
try
{
- // 同步设置面板中的开关状态
- if (ToggleSwitchEnableInkFade != null)
- {
- ToggleSwitchEnableInkFade.IsOn = Settings.Canvas.EnableInkFade;
- }
// 同步批注子面板中的开关状态
if (ToggleSwitchInkFadeInPanel != null)
@@ -1423,11 +1233,6 @@ namespace Ink_Canvas
ToggleSwitchInkFadeInPanel2.IsOn = Settings.Canvas.EnableInkFade;
}
- // 同步滑块值
- if (InkFadeTimeSlider != null)
- {
- InkFadeTimeSlider.Value = Settings.Canvas.InkFadeTime;
- }
@@ -1438,11 +1243,6 @@ namespace Ink_Canvas
_inkFadeManager.UpdateFadeTime(Settings.Canvas.InkFadeTime);
}
- // 同步在笔工具菜单中隐藏墨迹渐隐控制开关的设置
- if (ToggleSwitchHideInkFadeControlInPenMenu != null)
- {
- ToggleSwitchHideInkFadeControlInPenMenu.IsOn = Settings.Canvas.HideInkFadeControlInPenMenu;
- }
// 根据设置更新墨迹渐隐控制开关的可见性
UpdateInkFadeControlVisibility();
@@ -1584,4 +1384,4 @@ namespace Ink_Canvas
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs
index 0190d673..8ea3a7d8 100644
--- a/Ink Canvas/MainWindow_cs/MW_Timer.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs
@@ -1388,6 +1388,11 @@ namespace Ink_Canvas
}
}
+ public void StartSilentUpdateTimer()
+ {
+ timerCheckAutoUpdateWithSilence.Start();
+ }
+
///
/// 初始化橡皮擦自动切换回批注模式计时器
///
diff --git a/Ink Canvas/Properties/Strings.en-US.resx b/Ink Canvas/Properties/Strings.en-US.resx
index 2955f65e..e9b085ce 100644
--- a/Ink Canvas/Properties/Strings.en-US.resx
+++ b/Ink Canvas/Properties/Strings.en-US.resx
@@ -1722,6 +1722,12 @@
privacy statement
+
+ Privacy & Telemetry
+
+
+ I have read and agree to the privacy statement
+
Anonymous usage data upload:
diff --git a/Ink Canvas/Properties/Strings.resx b/Ink Canvas/Properties/Strings.resx
index 69d55a09..60b4234f 100644
--- a/Ink Canvas/Properties/Strings.resx
+++ b/Ink Canvas/Properties/Strings.resx
@@ -1765,6 +1765,12 @@
中的隐私说明
+
+ 隐私与遥测
+
+
+ 我已阅读并同意 privacy 中的隐私说明
+
匿名使用数据上传:
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml b/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml
index 89458f8a..8c1ca40d 100644
--- a/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml
+++ b/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml
@@ -1,17 +1,194 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml.cs b/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml.cs
index d743d4b6..3e7d2850 100644
--- a/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml.cs
+++ b/Ink Canvas/Windows/SettingsViews/Pages/AboutPage.xaml.cs
@@ -1,12 +1,424 @@
-using iNKORE.UI.WPF.Modern.Controls;
+using Ink_Canvas.Helpers;
+using Ink_Canvas.Windows.SettingsViews.Helpers;
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
namespace Ink_Canvas.Windows.SettingsViews.Pages
{
- public partial class AboutPage : Page
+ public class AvatarItem
{
+ public string AvatarPath { get; set; }
+ public string Name { get; set; }
+ public string Role { get; set; }
+ }
+
+ public partial class AboutPage : iNKORE.UI.WPF.Modern.Controls.Page
+ {
+ private bool _isLoaded = false;
+ private bool _isChangingTelemetryInternally;
+ private bool _isChangingTelemetryPrivacyInternally;
+ private DispatcherTimer _usageRefreshTimer;
+ private long _savedTotalSeconds;
+ private DateTime _sessionStartTime;
+
public AboutPage()
{
InitializeComponent();
+ Loaded += AboutPage_Loaded;
+ Unloaded += AboutPage_Unloaded;
+ InitializeAvatarData();
}
+
+ private void InitializeAvatarData()
+ {
+ var developers = new ObservableCollection
+ {
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/CJKmkp.jpg", Name = "CJK_mkp", Role = LocalizationHelper.GetString("About_Dev_ICCCE") },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/dubi906w.jpg", Name = "Dubi906w", Role = LocalizationHelper.GetString("About_Dev_ICC") },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/ChangSakura.png", Name = "ChangSakura", Role = LocalizationHelper.GetString("About_Dev_ICA") },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/WXRIW.png", Name = "WXRIW", Role = LocalizationHelper.GetString("About_Dev_InkCanvas") }
+ };
+
+ var contributors = new ObservableCollection
+ {
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/RaspberryKan.jpg", Name = "Raspberry Kan" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/kengwang.png", Name = "Kengwang" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/jiajiaxd.jpg", Name = "Charles Jia" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/clover-yan.png", Name = "clover_yan" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/NetheriteBowl.png", Name = "Netherite_Bowl" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/NotYoojun.png", Name = "Yoojun Zhou" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/yuwenhui2020.png", Name = "YuWenHui2020" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/STBBRD.png", Name = "ZongziTEK" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/aaaaaaccd.jpg", Name = "Aesthed" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/wwei.png", Name = "Wei" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/Alan-CRL.png", Name = "Alan-CRL" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/PrefacedCorg.jpg", Name = "PrefacedCorg" },
+ new AvatarItem { AvatarPath = "/Resources/DeveloperAvatars/PANDA-JSR.jpg", Name = "PANDA-JSR" }
+ };
+
+ DeveloperItemsControl.ItemsSource = developers;
+ ContributorItemsControl.ItemsSource = contributors;
+ }
+
+ private void AboutPage_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadSettings();
+ _isLoaded = true;
+
+ if (_usageRefreshTimer == null)
+ {
+ _usageRefreshTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
+ _usageRefreshTimer.Tick += UsageRefreshTimer_Tick;
+ }
+ _usageRefreshTimer.Start();
+ }
+
+ private void AboutPage_Unloaded(object sender, RoutedEventArgs e)
+ {
+ if (_usageRefreshTimer != null)
+ {
+ _usageRefreshTimer.Stop();
+ _usageRefreshTimer.Tick -= UsageRefreshTimer_Tick;
+ _usageRefreshTimer = null;
+ }
+ }
+
+ private void UsageRefreshTimer_Tick(object sender, EventArgs e)
+ {
+ try
+ {
+ long currentSessionSeconds = (long)(DateTime.Now - _sessionStartTime).TotalSeconds;
+ TotalUsageTextBlock.Text = DeviceIdentifier.FormatDuration(_savedTotalSeconds + currentSessionSeconds);
+ }
+ catch { }
+ }
+
+ private void LoadSettings()
+ {
+ _isLoaded = false;
+
+ try
+ {
+ AppVersionTextBlock.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+
+ var settings = SettingsManager.Settings;
+ if (settings?.Startup != null)
+ {
+ int idx = 0;
+ switch (settings.Startup.TelemetryUploadLevel)
+ {
+ case TelemetryUploadLevel.None:
+ idx = 0;
+ break;
+ case TelemetryUploadLevel.Basic:
+ idx = 1;
+ break;
+ case TelemetryUploadLevel.Extended:
+ idx = 2;
+ break;
+ default:
+ idx = 0;
+ break;
+ }
+ ComboBoxTelemetryUploadLevel.SelectedIndex = idx;
+ CheckBoxTelemetryPrivacyAccepted.IsChecked = settings.Startup.HasAcceptedTelemetryPrivacy;
+ }
+
+ RefreshDeviceInfo();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"加载关于页面设置时出错: {ex.Message}");
+ }
+
+ _isLoaded = true;
+ }
+
+ private void RefreshDeviceInfo_Click(object sender, RoutedEventArgs e)
+ {
+ RefreshDeviceInfo();
+ }
+
+ private void RefreshDeviceInfo()
+ {
+ try
+ {
+ string deviceId = DeviceIdentifier.GetDeviceId();
+ DeviceIdTextBlock.Text = deviceId;
+
+ var usageFrequency = DeviceIdentifier.GetUsageFrequency();
+ string frequencyText;
+ switch (usageFrequency)
+ {
+ case DeviceIdentifier.UsageFrequency.High:
+ frequencyText = "高频用户";
+ break;
+ case DeviceIdentifier.UsageFrequency.Medium:
+ frequencyText = "中频用户";
+ break;
+ case DeviceIdentifier.UsageFrequency.Low:
+ frequencyText = "低频用户";
+ break;
+ default:
+ frequencyText = "未知";
+ break;
+ }
+ UsageFrequencyTextBlock.Text = frequencyText;
+
+ var updatePriority = DeviceIdentifier.GetUpdatePriority();
+ string priorityText;
+ switch (updatePriority)
+ {
+ case DeviceIdentifier.UpdatePriority.High:
+ priorityText = "高优先级(优先推送更新)";
+ break;
+ case DeviceIdentifier.UpdatePriority.Medium:
+ priorityText = "中优先级(正常推送更新)";
+ break;
+ case DeviceIdentifier.UpdatePriority.Low:
+ priorityText = "低优先级(延迟推送更新)";
+ break;
+ default:
+ priorityText = "未知";
+ break;
+ }
+ UpdatePriorityTextBlock.Text = priorityText;
+
+ var (launchCount, totalSeconds, avgSessionSeconds, _) = DeviceIdentifier.GetUsageStats();
+ _savedTotalSeconds = totalSeconds;
+ _sessionStartTime = DateTime.Now;
+ LaunchCountTextBlock.Text = launchCount.ToString();
+ TotalUsageTextBlock.Text = DeviceIdentifier.FormatDuration(totalSeconds);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"刷新设备信息失败: {ex.Message}", LogHelper.LogType.Error);
+ DeviceIdTextBlock.Text = "获取失败";
+ UsageFrequencyTextBlock.Text = "获取失败";
+ UpdatePriorityTextBlock.Text = "获取失败";
+ LaunchCountTextBlock.Text = "获取失败";
+ TotalUsageTextBlock.Text = "获取失败";
+ }
+ }
+
+ private void ComboBoxTelemetryUploadLevel_SelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ if (_isChangingTelemetryInternally) return;
+ var oldLevel = SettingsManager.Settings.Startup.TelemetryUploadLevel;
+ var item = ComboBoxTelemetryUploadLevel?.SelectedItem as ComboBoxItem;
+ if (item == null) return;
+
+ var tag = item.Tag?.ToString() ?? "0";
+ var newLevel = TelemetryUploadLevel.None;
+ switch (tag)
+ {
+ case "1":
+ newLevel = TelemetryUploadLevel.Basic;
+ break;
+ case "2":
+ newLevel = TelemetryUploadLevel.Extended;
+ break;
+ default:
+ newLevel = TelemetryUploadLevel.None;
+ break;
+ }
+
+ if (newLevel == TelemetryUploadLevel.None &&
+ oldLevel != TelemetryUploadLevel.None &&
+ SettingsManager.Settings.Startup.UpdateChannel != UpdateChannel.Release)
+ {
+ var result = MessageBox.Show(
+ "关闭匿名使用数据上传后,将无法继续使用预览/测试通道,系统会自动切换回正式通道(Release)。\n\n是否确认关闭?",
+ "确认关闭遥测",
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Warning);
+
+ if (result != MessageBoxResult.Yes)
+ {
+ _isChangingTelemetryInternally = true;
+ try
+ {
+ int idx = 0;
+ switch (oldLevel)
+ {
+ case TelemetryUploadLevel.Basic:
+ idx = 1;
+ break;
+ case TelemetryUploadLevel.Extended:
+ idx = 2;
+ break;
+ default:
+ idx = 0;
+ break;
+ }
+ ComboBoxTelemetryUploadLevel.SelectedIndex = idx;
+ }
+ finally
+ {
+ _isChangingTelemetryInternally = false;
+ }
+ return;
+ }
+
+ SettingsManager.Settings.Startup.UpdateChannel = UpdateChannel.Release;
+ DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
+ }
+
+ if (newLevel != TelemetryUploadLevel.None && !SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy)
+ {
+ MessageBox.Show(
+ "在开启匿名使用数据上传前,请先阅读并勾选上方的隐私说明。",
+ "需要同意隐私说明",
+ MessageBoxButton.OK,
+ MessageBoxImage.Warning);
+
+ _isChangingTelemetryInternally = true;
+ try
+ {
+ SettingsManager.Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.None;
+ if (ComboBoxTelemetryUploadLevel != null)
+ {
+ ComboBoxTelemetryUploadLevel.SelectedIndex = 0;
+ }
+ }
+ finally
+ {
+ _isChangingTelemetryInternally = false;
+ }
+
+ return;
+ }
+
+ SettingsManager.Settings.Startup.TelemetryUploadLevel = newLevel;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void CheckBoxTelemetryPrivacyAccepted_Checked(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ if (_isChangingTelemetryPrivacyInternally) return;
+
+ bool isChecked = CheckBoxTelemetryPrivacyAccepted.IsChecked == true;
+
+ if (isChecked)
+ {
+ if (!PrivacyFileExists())
+ {
+ MessageBox.Show(
+ "未找到隐私说明文件(privacy / privacy.txt),暂时无法启用匿名使用数据上传。",
+ "隐私说明缺失",
+ MessageBoxButton.OK,
+ MessageBoxImage.Warning);
+
+ _isChangingTelemetryPrivacyInternally = true;
+ try
+ {
+ CheckBoxTelemetryPrivacyAccepted.IsChecked = false;
+ }
+ finally
+ {
+ _isChangingTelemetryPrivacyInternally = false;
+ }
+
+ SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy = false;
+ SettingsManager.SaveSettingsToFile();
+ return;
+ }
+
+ var privacyWindow = new PrivacyAgreementWindow();
+ bool? dialogResult = privacyWindow.ShowDialog();
+
+ if (dialogResult == true && privacyWindow.UserAccepted)
+ {
+ SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy = true;
+ SettingsManager.SaveSettingsToFile();
+ }
+ else
+ {
+ _isChangingTelemetryPrivacyInternally = true;
+ try
+ {
+ CheckBoxTelemetryPrivacyAccepted.IsChecked = false;
+ }
+ finally
+ {
+ _isChangingTelemetryPrivacyInternally = false;
+ }
+
+ SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy = false;
+ SettingsManager.SaveSettingsToFile();
+ }
+ }
+ else
+ {
+ var result = MessageBox.Show(
+ "取消同意隐私说明后,将关闭匿名使用数据上传,并切回正式通道(Release)。\n\n是否确认?",
+ "确认取消隐私同意",
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Warning);
+
+ if (result != MessageBoxResult.Yes)
+ {
+ _isChangingTelemetryPrivacyInternally = true;
+ try
+ {
+ CheckBoxTelemetryPrivacyAccepted.IsChecked = true;
+ }
+ finally
+ {
+ _isChangingTelemetryPrivacyInternally = false;
+ }
+ return;
+ }
+
+ _isChangingTelemetryInternally = true;
+ try
+ {
+ SettingsManager.Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.None;
+ if (ComboBoxTelemetryUploadLevel != null)
+ {
+ ComboBoxTelemetryUploadLevel.SelectedIndex = 0;
+ }
+ }
+ finally
+ {
+ _isChangingTelemetryInternally = false;
+ }
+
+ if (SettingsManager.Settings.Startup.UpdateChannel != UpdateChannel.Release)
+ {
+ SettingsManager.Settings.Startup.UpdateChannel = UpdateChannel.Release;
+ DeviceIdentifier.UpdateUsageChannel(UpdateChannel.Release);
+ }
+
+ SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy = false;
+ SettingsManager.SaveSettingsToFile();
+ }
+ }
+
+ private static bool PrivacyFileExists()
+ {
+ try
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+ var resourceName = "Ink_Canvas.privacy.txt";
+ using (Stream stream = assembly.GetManifestResourceStream(resourceName))
+ {
+ return stream != null;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
}
-}
\ No newline at end of file
+}
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml b/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml
new file mode 100644
index 00000000..a5360d41
--- /dev/null
+++ b/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml
@@ -0,0 +1,361 @@
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml.cs b/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml.cs
new file mode 100644
index 00000000..158cce8c
--- /dev/null
+++ b/Ink Canvas/Windows/SettingsViews/Pages/CanvasPage.xaml.cs
@@ -0,0 +1,403 @@
+using Ink_Canvas.Helpers;
+using Ink_Canvas.Windows.SettingsViews.Helpers;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Ink_Canvas.Windows.SettingsViews.Pages
+{
+ public partial class CanvasPage : iNKORE.UI.WPF.Modern.Controls.Page
+ {
+ private bool _isLoaded = false;
+
+ public CanvasPage()
+ {
+ InitializeComponent();
+ Loaded += CanvasPage_Loaded;
+ }
+
+ private void CanvasPage_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadSettings();
+ _isLoaded = true;
+ }
+
+ private void LoadSettings()
+ {
+ _isLoaded = false;
+
+ try
+ {
+ var settings = SettingsManager.Settings;
+ if (settings.Canvas != null)
+ {
+ CardShowCursor.IsOn = settings.Canvas.IsShowCursor;
+ CardEnablePressureTouchMode.IsOn = settings.Canvas.EnablePressureTouchMode;
+ CardDisablePressure.IsOn = settings.Canvas.DisablePressure;
+ ComboBoxEraserSize.SelectedIndex = settings.Canvas.EraserSize;
+ CardHideStrokeWhenSelecting.IsOn = settings.Canvas.HideStrokeWhenSelecting;
+ CardClearCanvasAndClearTimeMachine.IsOn = settings.Canvas.ClearCanvasAndClearTimeMachine;
+ CardClearCanvasAlsoClearImages.IsOn = settings.Canvas.ClearCanvasAlsoClearImages;
+ CardCompressPicturesUploaded.IsOn = settings.Canvas.IsCompressPicturesUploaded;
+ CardLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn = settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth;
+ ComboBoxHyperbolaAsymptoteOption.SelectedIndex = (int)settings.Canvas.HyperbolaAsymptoteOption;
+ CardShowCircleCenter.IsOn = settings.Canvas.ShowCircleCenter;
+ CardFitToCurve.IsOn = settings.Canvas.FitToCurve;
+ CardAdvancedBezierSmoothing.IsOn = settings.Canvas.UseAdvancedBezierSmoothing;
+ CardEnableInkFade.IsOn = settings.Canvas.EnableInkFade;
+ InkFadeTimeSlider.Value = settings.Canvas.InkFadeTime;
+ CardHideInkFadeControlInPenMenu.IsOn = settings.Canvas.HideInkFadeControlInPenMenu;
+ CardBrushAutoRestore.IsOn = settings.Canvas.EnableBrushAutoRestore;
+ BrushAutoRestoreTimesTextBox.Text = settings.Canvas.BrushAutoRestoreTimes ?? string.Empty;
+ LoadBrushAutoRestoreColor(settings.Canvas.BrushAutoRestoreColor);
+ BrushAutoRestoreWidthSlider.Value = settings.Canvas.BrushAutoRestoreWidth > 0 ? settings.Canvas.BrushAutoRestoreWidth : 5;
+ BrushAutoRestoreAlphaSlider.Value = settings.Canvas.BrushAutoRestoreAlpha;
+ CardEnableEraserAutoSwitchBack.IsOn = settings.Canvas.EnableEraserAutoSwitchBack;
+ EraserAutoSwitchBackDelaySlider.Value = settings.Canvas.EraserAutoSwitchBackDelaySeconds;
+ CardAutoStraightenLine.IsOn = settings.Canvas.AutoStraightenLine;
+ AutoStraightenLineThresholdSlider.Value = settings.Canvas.AutoStraightenLineThreshold;
+ CardHighPrecisionLineStraighten.IsOn = settings.Canvas.HighPrecisionLineStraighten;
+ CardLineEndpointSnapping.IsOn = settings.Canvas.LineEndpointSnapping;
+ }
+
+ if (settings.InkToShape != null)
+ {
+ CardEnableInkToShape.IsOn = settings.InkToShape.IsInkToShapeEnabled;
+ int eng = settings.InkToShape.ShapeRecognitionEngine;
+ if (eng < 0) eng = 0;
+ if (eng > 2) eng = 2;
+ ComboBoxShapeRecognitionEngine.SelectedIndex = eng;
+ CardEnableWinRtHandwritingStrokeBeautify.IsOn = settings.InkToShape.EnableWinRtHandwritingStrokeBeautify;
+ CardEnableInkToShapeNoFakePressureRectangle.IsOn = settings.InkToShape.IsInkToShapeNoFakePressureRectangle;
+ CardEnableInkToShapeNoFakePressureTriangle.IsOn = settings.InkToShape.IsInkToShapeNoFakePressureTriangle;
+ ToggleCheckboxEnableInkToShapeTriangle.IsChecked = settings.InkToShape.IsInkToShapeTriangle;
+ ToggleCheckboxEnableInkToShapeRectangle.IsChecked = settings.InkToShape.IsInkToShapeRectangle;
+ ToggleCheckboxEnableInkToShapeRounded.IsChecked = settings.InkToShape.IsInkToShapeRounded;
+ LineStraightenSensitivitySlider.Value = settings.InkToShape.LineStraightenSensitivity;
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"加载画板设置时出错: {ex.Message}");
+ }
+
+ _isLoaded = true;
+ }
+
+ private void LoadBrushAutoRestoreColor(string hex)
+ {
+ try
+ {
+ foreach (var item in ComboBoxBrushAutoRestoreColor.Items)
+ {
+ if (item is ComboBoxItem cbi && cbi.Tag != null &&
+ string.Equals(cbi.Tag.ToString(), hex, StringComparison.OrdinalIgnoreCase))
+ {
+ ComboBoxBrushAutoRestoreColor.SelectedItem = cbi;
+ return;
+ }
+ }
+ ComboBoxBrushAutoRestoreColor.SelectedIndex = 0;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"加载画笔恢复颜色时出错: {ex.Message}");
+ }
+ }
+
+ #region 画板设置事件处理
+
+ private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.IsShowCursor = CardShowCursor.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnablePressureTouchMode_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EnablePressureTouchMode = CardEnablePressureTouchMode.IsOn;
+ if (SettingsManager.Settings.Canvas.EnablePressureTouchMode && SettingsManager.Settings.Canvas.DisablePressure)
+ {
+ SettingsManager.Settings.Canvas.DisablePressure = false;
+ CardDisablePressure.IsOn = false;
+ }
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchDisablePressure_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.DisablePressure = CardDisablePressure.IsOn;
+ if (SettingsManager.Settings.Canvas.DisablePressure && SettingsManager.Settings.Canvas.EnablePressureTouchMode)
+ {
+ SettingsManager.Settings.Canvas.EnablePressureTouchMode = false;
+ CardEnablePressureTouchMode.IsOn = false;
+ }
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ComboBoxEraserSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EraserSize = ComboBoxEraserSize.SelectedIndex;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchHideStrokeWhenSelecting_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.HideStrokeWhenSelecting = CardHideStrokeWhenSelecting.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchClearCanvasAndClearTimeMachine_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.ClearCanvasAndClearTimeMachine = CardClearCanvasAndClearTimeMachine.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchClearCanvasAlsoClearImages_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.ClearCanvasAlsoClearImages = CardClearCanvasAlsoClearImages.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchCompressPicturesUploaded_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.IsCompressPicturesUploaded = CardCompressPicturesUploaded.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth = CardLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ComboBoxHyperbolaAsymptoteOption_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.HyperbolaAsymptoteOption = (OptionalOperation)ComboBoxHyperbolaAsymptoteOption.SelectedIndex;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchShowCircleCenter_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.ShowCircleCenter = CardShowCircleCenter.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchFitToCurve_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.FitToCurve = CardFitToCurve.IsOn;
+ if (CardFitToCurve.IsOn)
+ {
+ SettingsManager.Settings.Canvas.UseAdvancedBezierSmoothing = false;
+ CardAdvancedBezierSmoothing.IsOn = false;
+ }
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchAdvancedBezierSmoothing_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.UseAdvancedBezierSmoothing = CardAdvancedBezierSmoothing.IsOn;
+ if (CardAdvancedBezierSmoothing.IsOn)
+ {
+ SettingsManager.Settings.Canvas.FitToCurve = false;
+ CardFitToCurve.IsOn = false;
+ }
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnableInkFade_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EnableInkFade = CardEnableInkFade.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void InkFadeTimeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.InkFadeTime = (int)e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchHideInkFadeControlInPenMenu_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.HideInkFadeControlInPenMenu = CardHideInkFadeControlInPenMenu.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchBrushAutoRestore_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EnableBrushAutoRestore = CardBrushAutoRestore.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void BrushAutoRestoreTimesTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.BrushAutoRestoreTimes = BrushAutoRestoreTimesTextBox.Text ?? string.Empty;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ComboBoxBrushAutoRestoreColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ if (ComboBoxBrushAutoRestoreColor.SelectedItem is ComboBoxItem item)
+ {
+ string hex = item.Tag as string ?? string.Empty;
+ SettingsManager.Settings.Canvas.BrushAutoRestoreColor = hex;
+ SettingsManager.SaveSettingsToFile();
+ }
+ }
+
+ private void BrushAutoRestoreWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.BrushAutoRestoreWidth = e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void BrushAutoRestoreAlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.BrushAutoRestoreAlpha = (int)e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnableEraserAutoSwitchBack_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EnableEraserAutoSwitchBack = CardEnableEraserAutoSwitchBack.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void EraserAutoSwitchBackDelaySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.EraserAutoSwitchBackDelaySeconds = (int)e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ #endregion
+
+ #region 墨迹识别事件处理
+
+ private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeEnabled = CardEnableInkToShape.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ComboBoxShapeRecognitionEngine_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded || ComboBoxShapeRecognitionEngine == null) return;
+ int idx = ComboBoxShapeRecognitionEngine.SelectedIndex;
+ if (idx < 0) idx = 0;
+ if (idx > 2) idx = 2;
+ SettingsManager.Settings.InkToShape.ShapeRecognitionEngine = idx;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnableWinRtHandwritingStrokeBeautify_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.EnableWinRtHandwritingStrokeBeautify = CardEnableWinRtHandwritingStrokeBeautify.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnableInkToShapeNoFakePressureRectangle_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeNoFakePressureRectangle = CardEnableInkToShapeNoFakePressureRectangle.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchEnableInkToShapeNoFakePressureTriangle_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeNoFakePressureTriangle = CardEnableInkToShapeNoFakePressureTriangle.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleCheckboxEnableInkToShapeTriangle_CheckedChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeTriangle = (bool)ToggleCheckboxEnableInkToShapeTriangle.IsChecked;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleCheckboxEnableInkToShapeRectangle_CheckedChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeRectangle = (bool)ToggleCheckboxEnableInkToShapeRectangle.IsChecked;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleCheckboxEnableInkToShapeRounded_CheckedChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.IsInkToShapeRounded = (bool)ToggleCheckboxEnableInkToShapeRounded.IsChecked;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.AutoStraightenLine = CardAutoStraightenLine.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void AutoStraightenLineThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.AutoStraightenLineThreshold = (int)e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.InkToShape.LineStraightenSensitivity = e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.HighPrecisionLineStraighten = CardHighPrecisionLineStraighten.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void ToggleSwitchLineEndpointSnapping_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.LineEndpointSnapping = CardLineEndpointSnapping.IsOn;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ private void LineEndpointSnappingThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ SettingsManager.Settings.Canvas.LineEndpointSnappingThreshold = (int)e.NewValue;
+ SettingsManager.SaveSettingsToFile();
+ }
+
+ #endregion
+ }
+}
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/StartupPage.xaml b/Ink Canvas/Windows/SettingsViews/Pages/StartupPage.xaml
index 462f691c..666fbcdc 100644
--- a/Ink Canvas/Windows/SettingsViews/Pages/StartupPage.xaml
+++ b/Ink Canvas/Windows/SettingsViews/Pages/StartupPage.xaml
@@ -10,7 +10,8 @@
xmlns:i18n="clr-namespace:Ink_Canvas.MarkupExtensions"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:controls="clr-namespace:Ink_Canvas.Controls;assembly=InkCanvas.Controls"
- mc:Ignorable="d"
+ xmlns:c="clr-namespace:Ink_Canvas.Converter"
+ mc:Ignorable="d"
Title="启动">
@@ -18,6 +19,7 @@
4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/Pages/UpdatePage.xaml.cs b/Ink Canvas/Windows/SettingsViews/Pages/UpdatePage.xaml.cs
new file mode 100644
index 00000000..13640713
--- /dev/null
+++ b/Ink Canvas/Windows/SettingsViews/Pages/UpdatePage.xaml.cs
@@ -0,0 +1,468 @@
+using Ink_Canvas.Helpers;
+using Ink_Canvas.Windows.SettingsViews.Helpers;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
+
+namespace Ink_Canvas.Windows.SettingsViews.Pages
+{
+ public partial class UpdatePage : iNKORE.UI.WPF.Modern.Controls.Page
+ {
+ private bool _isLoaded = false;
+ private bool _isChangingUpdateChannelInternally = false;
+ private bool _isChangingUpdatePackageArchInternally = false;
+
+ public UpdatePage()
+ {
+ InitializeComponent();
+ Loaded += UpdatePage_Loaded;
+ }
+
+ private void UpdatePage_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadSettings();
+ _isLoaded = true;
+ }
+
+ private void LoadSettings()
+ {
+ _isLoaded = false;
+
+ try
+ {
+ var settings = SettingsManager.Settings;
+ if (settings.Startup != null)
+ {
+ CardAutoUpdate.IsOn = settings.Startup.IsAutoUpdate;
+ CardSilentUpdate.IsOn = settings.Startup.IsAutoUpdateWithSilence;
+
+ AutoUpdateWithSilenceTimeComboBox.InitializeAutoUpdateWithSilenceTimeComboBoxOptions(
+ AutoUpdateWithSilenceStartTimeComboBox, AutoUpdateWithSilenceEndTimeComboBox);
+ AutoUpdateWithSilenceStartTimeComboBox.SelectedItem = settings.Startup.AutoUpdateWithSilenceStartTime;
+ AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = settings.Startup.AutoUpdateWithSilenceEndTime;
+
+ foreach (var item in UpdateChannelSelector.Items)
+ {
+ if (item is ComboBoxItem cbi && cbi.Tag != null &&
+ string.Equals(cbi.Tag.ToString(), settings.Startup.UpdateChannel.ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ UpdateChannelSelector.SelectedItem = cbi;
+ break;
+ }
+ }
+
+ _isChangingUpdatePackageArchInternally = true;
+ try
+ {
+ string wantTag = settings.Startup.UpdatePackageArchitecture == UpdatePackageArchitecture.X64 ? "X64" : "X86";
+ foreach (var item in UpdatePackageArchitectureSelector.Items)
+ {
+ if (item is ComboBoxItem cbi && cbi.Tag != null &&
+ string.Equals(cbi.Tag.ToString(), wantTag, StringComparison.OrdinalIgnoreCase))
+ {
+ UpdatePackageArchitectureSelector.SelectedItem = cbi;
+ break;
+ }
+ }
+ }
+ finally
+ {
+ _isChangingUpdatePackageArchInternally = false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"加载更新设置时出错: {ex.Message}");
+ }
+
+ _isLoaded = true;
+ }
+
+ #region 自动更新事件处理
+
+ private void ToggleSwitchIsAutoUpdate_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+
+ try
+ {
+ bool newState = CardAutoUpdate.IsOn;
+ SettingsManager.Settings.Startup.IsAutoUpdate = newState;
+
+ if (!newState)
+ {
+ SettingsManager.Settings.Startup.IsAutoUpdateWithSilence = false;
+ CardSilentUpdate.IsOn = false;
+ }
+
+ SettingsManager.SaveSettingsToFile();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"设置自动更新时出错: {ex.Message}");
+ }
+ }
+
+ private void ToggleSwitchIsAutoUpdateWithSilence_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+
+ try
+ {
+ bool newState = CardSilentUpdate.IsOn;
+ SettingsManager.Settings.Startup.IsAutoUpdateWithSilence = newState;
+ SettingsManager.SaveSettingsToFile();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"设置静默更新时出错: {ex.Message}");
+ }
+ }
+
+ private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+
+ try
+ {
+ SettingsManager.Settings.Startup.AutoUpdateWithSilenceStartTime =
+ (string)AutoUpdateWithSilenceStartTimeComboBox.SelectedItem;
+ SettingsManager.SaveSettingsToFile();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"设置静默更新开始时间时出错: {ex.Message}");
+ }
+ }
+
+ private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e)
+ {
+ if (!_isLoaded) return;
+
+ try
+ {
+ SettingsManager.Settings.Startup.AutoUpdateWithSilenceEndTime =
+ (string)AutoUpdateWithSilenceEndTimeComboBox.SelectedItem;
+ SettingsManager.SaveSettingsToFile();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"设置静默更新结束时间时出错: {ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 更新通道和架构事件处理
+
+ private void UpdatePackageArchitectureSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ if (_isChangingUpdatePackageArchInternally) return;
+ if (!(UpdatePackageArchitectureSelector.SelectedItem is ComboBoxItem cbi) || cbi.Tag == null) return;
+
+ var newArch = string.Equals(cbi.Tag.ToString(), "X64", StringComparison.OrdinalIgnoreCase)
+ ? UpdatePackageArchitecture.X64
+ : UpdatePackageArchitecture.X86;
+
+ if (SettingsManager.Settings.Startup.UpdatePackageArchitecture == newArch)
+ return;
+
+ SettingsManager.Settings.Startup.UpdatePackageArchitecture = newArch;
+ SettingsManager.SaveSettingsToFile();
+ LogHelper.WriteLogToFile($"Settings | Update package architecture: {newArch}");
+ }
+
+ private async void UpdateChannelSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!_isLoaded) return;
+ if (_isChangingUpdateChannelInternally) return;
+ if (!(UpdateChannelSelector.SelectedItem is ComboBoxItem cbi) || cbi.Tag == null) return;
+
+ var oldChannel = SettingsManager.Settings.Startup.UpdateChannel;
+ string channel = cbi.Tag.ToString();
+ UpdateChannel newChannel = channel == "Beta" ? UpdateChannel.Beta
+ : channel == "Preview" ? UpdateChannel.Preview
+ : UpdateChannel.Release;
+
+ if (SettingsManager.Settings.Startup.UpdateChannel == newChannel)
+ return;
+
+ bool isTestChannel = newChannel == UpdateChannel.Preview || newChannel == UpdateChannel.Beta;
+
+ if (isTestChannel && !SettingsManager.Settings.Startup.HasAcceptedTelemetryPrivacy)
+ {
+ MessageBox.Show(
+ "加入预览 / 测试通道前,请先在关于页面勾选\u201C我已阅读并同意 privacy 中的隐私说明\u201D。",
+ "需要同意隐私说明",
+ MessageBoxButton.OK,
+ MessageBoxImage.Warning);
+
+ SettingsManager.Settings.Startup.UpdateChannel = oldChannel;
+ RevertChannelSelection(oldChannel);
+ SettingsManager.SaveSettingsToFile();
+ LogHelper.WriteLogToFile("Settings | User not accepted privacy, reverted update channel");
+ return;
+ }
+
+ if (isTestChannel && SettingsManager.Settings.Startup.TelemetryUploadLevel == TelemetryUploadLevel.None)
+ {
+ var result = MessageBox.Show(
+ "加入预览 / 测试通道需要开启匿名基础数据上传。\n\n是否立即开启匿名基础数据上传?",
+ "需要开启匿名使用数据上传",
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Warning);
+
+ if (result == MessageBoxResult.Yes)
+ {
+ SettingsManager.Settings.Startup.TelemetryUploadLevel = TelemetryUploadLevel.Basic;
+ SettingsManager.SaveSettingsToFile();
+ LogHelper.WriteLogToFile("Settings | Telemetry enabled (Basic) for preview/beta update channel");
+ }
+ else
+ {
+ SettingsManager.Settings.Startup.UpdateChannel = oldChannel;
+ RevertChannelSelection(oldChannel);
+ SettingsManager.SaveSettingsToFile();
+ LogHelper.WriteLogToFile("Settings | User declined telemetry, reverted update channel");
+ return;
+ }
+ }
+
+ SettingsManager.Settings.Startup.UpdateChannel = newChannel;
+ DeviceIdentifier.UpdateUsageChannel(newChannel);
+ LogHelper.WriteLogToFile($"Settings | Update channel changed to {SettingsManager.Settings.Startup.UpdateChannel}");
+ SettingsManager.SaveSettingsToFile();
+
+ if (SettingsManager.Settings.Startup.IsAutoUpdate)
+ {
+ LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, performing immediate update check");
+
+ var mainWindow = Application.Current.MainWindow as MainWindow;
+ if (mainWindow != null)
+ {
+ mainWindow.ResetUpdateCheckRetry();
+ await System.Threading.Tasks.Task.Run(async () =>
+ {
+ try
+ {
+ Dispatcher.Invoke(() =>
+ {
+ mainWindow.AutoUpdate();
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"AutoUpdate | Error during channel switch update check: {ex.Message}", LogHelper.LogType.Error);
+ }
+ });
+ }
+ }
+ else
+ {
+ LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, but auto-update is disabled");
+ }
+ }
+
+ private void RevertChannelSelection(UpdateChannel targetChannel)
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ _isChangingUpdateChannelInternally = true;
+ try
+ {
+ string targetTag = targetChannel.ToString();
+ foreach (var item in UpdateChannelSelector.Items)
+ {
+ if (item is ComboBoxItem cbi && cbi.Tag != null &&
+ string.Equals(cbi.Tag.ToString(), targetTag, StringComparison.OrdinalIgnoreCase))
+ {
+ UpdateChannelSelector.SelectedItem = cbi;
+ break;
+ }
+ }
+ }
+ finally
+ {
+ _isChangingUpdateChannelInternally = false;
+ }
+ }), DispatcherPriority.Normal);
+ }
+
+ #endregion
+
+ #region 手动操作事件处理
+
+ private async void ManualUpdateButton_Click(object sender, RoutedEventArgs e)
+ {
+ ManualUpdateButton.IsEnabled = false;
+ ManualUpdateButton.Content = "正在检查更新...";
+
+ try
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | Manual update button clicked");
+
+ var (remoteVersion, lineGroup, apiReleaseNotes) = await AutoUpdateHelper.CheckForUpdates(SettingsManager.Settings.Startup.UpdateChannel, true, false);
+
+ if (remoteVersion != null)
+ {
+ LogHelper.WriteLogToFile($"ManualUpdate | Found new version: {remoteVersion}");
+
+ string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+
+ HasNewUpdateWindow updateWindow = new HasNewUpdateWindow(currentVersion, remoteVersion, "", apiReleaseNotes);
+ updateWindow.Owner = Application.Current.MainWindow;
+ bool? dialogResult = updateWindow.ShowDialog();
+
+ if (dialogResult != true)
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | Update dialog closed without selection");
+ return;
+ }
+
+ var mainWindow = Application.Current.MainWindow as MainWindow;
+
+ switch (updateWindow.Result)
+ {
+ case HasNewUpdateWindow.UpdateResult.UpdateNow:
+ LogHelper.WriteLogToFile("ManualUpdate | User chose to update now");
+ MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information);
+
+ bool isDownloadSuccessful = mainWindow != null
+ && await mainWindow.DownloadUpdateWithFallback(remoteVersion, lineGroup, SettingsManager.Settings.Startup.UpdateChannel);
+
+ if (isDownloadSuccessful)
+ {
+ MessageBoxResult result = MessageBox.Show("更新已下载完成,点击确定后将关闭软件并安装新版本!", "安装更新", MessageBoxButton.OKCancel, MessageBoxImage.Information);
+
+ if (result == MessageBoxResult.OK)
+ {
+ App.IsAppExitByUser = true;
+ AutoUpdateHelper.InstallNewVersionApp(remoteVersion, true);
+ Application.Current.Shutdown();
+ }
+ else
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | User cancelled update installation");
+ }
+ }
+ else
+ {
+ MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ break;
+
+ case HasNewUpdateWindow.UpdateResult.UpdateLater:
+ LogHelper.WriteLogToFile("ManualUpdate | User chose to update later");
+
+ isDownloadSuccessful = mainWindow != null
+ && await mainWindow.DownloadUpdateWithFallback(remoteVersion, lineGroup, SettingsManager.Settings.Startup.UpdateChannel);
+
+ if (isDownloadSuccessful)
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | Update downloaded successfully, will install when application closes");
+ SettingsManager.Settings.Startup.IsAutoUpdate = true;
+ SettingsManager.Settings.Startup.IsAutoUpdateWithSilence = true;
+
+ if (mainWindow != null)
+ mainWindow.StartSilentUpdateTimer();
+
+ MessageBox.Show("更新已下载完成,将在软件关闭时自动安装。", "更新已准备就绪", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ else
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | Update download failed", LogHelper.LogType.Error);
+ MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ break;
+
+ case HasNewUpdateWindow.UpdateResult.SkipVersion:
+ LogHelper.WriteLogToFile($"ManualUpdate | User chose to skip version {remoteVersion}");
+ SettingsManager.Settings.Startup.SkippedVersion = remoteVersion;
+ SettingsManager.SaveSettingsToFile();
+ MessageBox.Show($"已设置跳过版本 {remoteVersion},在下次发布新版本之前不会再提示更新。",
+ "已跳过此版本",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ break;
+ }
+ }
+ else
+ {
+ LogHelper.WriteLogToFile("ManualUpdate | No updates available");
+ MessageBox.Show("当前已是最新版本!", "无可用更新", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"Error in ManualUpdateButton_Click: {ex.Message}", LogHelper.LogType.Error);
+ MessageBox.Show(
+ $"手动更新过程中发生错误: {ex.Message}",
+ "更新错误",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+ finally
+ {
+ ManualUpdateButton.IsEnabled = true;
+ ManualUpdateButton.Content = "手动更新";
+ }
+ }
+
+ private async void FixVersionButton_Click(object sender, RoutedEventArgs e)
+ {
+ var confirm = MessageBox.Show(
+ "此操作将下载当前选择通道的最新版本并安装,软件将自动关闭并更新。\n\n确定要执行版本修复吗?",
+ "版本修复确认",
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Question);
+
+ if (confirm == MessageBoxResult.Yes)
+ {
+ FixVersionButton.IsEnabled = false;
+ FixVersionButton.Content = "正在修复...";
+
+ try
+ {
+ bool result = await AutoUpdateHelper.FixVersion(SettingsManager.Settings.Startup.UpdateChannel);
+
+ if (!result)
+ {
+ MessageBox.Show(
+ "版本修复失败,可能是网络问题或当前已是最新版本。",
+ "修复失败",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+
+ FixVersionButton.IsEnabled = true;
+ FixVersionButton.Content = "版本修复";
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"Error in FixVersionButton_Click: {ex.Message}", LogHelper.LogType.Error);
+ MessageBox.Show(
+ $"版本修复过程中发生错误: {ex.Message}",
+ "修复错误",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+
+ FixVersionButton.IsEnabled = true;
+ FixVersionButton.Content = "版本修复";
+ }
+ }
+ }
+
+ private void HistoryRollbackButton_Click(object sender, RoutedEventArgs e)
+ {
+ var win = new HistoryRollbackWindow(SettingsManager.Settings.Startup.UpdateChannel);
+ win.Owner = Application.Current.MainWindow;
+ win.ShowDialog();
+ }
+
+ #endregion
+ }
+}
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
index 1382fd42..d154f894 100644
--- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
+++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
@@ -147,86 +147,39 @@
-
+
+ x:Name="UpdatePageItem"
+ Content="更新"
+ Tag="UpdatePage"
+ ToolTipService.ToolTip="更新设置">
-
+
-
+
+ x:Name="CanvasPageItem"
+ Content="画板"
+ Tag="CanvasPage"
+ ToolTipService.ToolTip="画板与墨迹设置">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ x:Name="DebugPageItem"
+ Content="Debug"
+ Tag="DebugPage"
+ ToolTipService.ToolTip="Debug">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+