NavisworksTransport/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs

445 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using System.Diagnostics;
using NavisworksTransport.Core.Config;
namespace NavisworksTransport.UI.WPF.Views
{
/// <summary>
/// 配置编辑器对话框
/// </summary>
public partial class ConfigEditorDialog : Window
{
private string _originalContent;
private bool _isModified;
/// <summary>
/// 当前显示的编辑器实例(单例模式)
/// </summary>
private static ConfigEditorDialog _currentInstance = null;
/// <summary>
/// 用于线程同步的锁对象
/// </summary>
private static readonly object _lock = new object();
/// <summary>
/// 私有构造函数,防止外部直接创建
/// </summary>
private ConfigEditorDialog()
{
InitializeComponent();
LoadConfigContent();
UpdateStatus();
}
/// <summary>
/// 加载配置文件内容
/// </summary>
private void LoadConfigContent()
{
try
{
string configPath = ConfigManager.ConfigFilePath;
// 如果配置文件不存在,创建默认配置
if (!File.Exists(configPath))
{
ConfigManager.Instance.Current.GetType(); // 触发单例初始化
}
// 读取配置文件
if (File.Exists(configPath))
{
_originalContent = File.ReadAllText(configPath, System.Text.Encoding.UTF8);
ConfigContentTextBox.Text = _originalContent;
ConfigFilePathLabel.Content = Path.GetFileName(configPath);
StatusLabel.Content = "配置已加载";
StatusLabel.Foreground = System.Windows.Media.Brushes.Green;
}
else
{
StatusLabel.Content = "配置文件不存在";
StatusLabel.Foreground = System.Windows.Media.Brushes.Red;
}
_isModified = false;
ModifiedLabel.Content = "";
}
catch (Exception ex)
{
LogManager.Error($"加载配置文件失败: {ex.Message}");
MessageBox.Show($"加载配置文件失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 更新状态信息
/// </summary>
private void UpdateStatus()
{
try
{
string configPath = ConfigManager.ConfigFilePath;
if (File.Exists(configPath))
{
var fileInfo = new FileInfo(configPath);
FileSizeLabel.Content = $"大小: {fileInfo.Length / 1024.0:F2} KB";
}
int lineCount = ConfigContentTextBox.LineCount;
LineCountLabel.Content = $"行数: {lineCount}";
}
catch (Exception ex)
{
LogManager.Error($"更新状态信息失败: {ex.Message}");
}
}
/// <summary>
/// 保存配置
/// </summary>
private bool SaveConfig()
{
try
{
string content = ConfigContentTextBox.Text;
// 验证 TOML 格式
try
{
Tomlyn.Toml.ToModel(content);
}
catch (Exception tomlEx)
{
MessageBox.Show($"TOML 格式错误:\n{tomlEx.Message}\n\n请检查配置文件语法。",
"格式错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return false;
}
// 使用 ConfigManager 的 ReloadFromContent 方法保存并加载
// 这个方法会临时禁用 FileSystemWatcher避免重复触发
ConfigManager.Instance.ReloadFromContent(content);
_originalContent = content;
_isModified = false;
ModifiedLabel.Content = "";
StatusLabel.Content = "配置已应用";
StatusLabel.Foreground = System.Windows.Media.Brushes.Green;
UpdateStatus();
LogManager.Info("配置已应用");
return true;
}
catch (Exception ex)
{
LogManager.Error($"应用配置失败: {ex.Message}");
MessageBox.Show($"应用配置失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
// 事件处理器
private void ReloadButton_Click(object sender, RoutedEventArgs e)
{
if (_isModified)
{
var result = MessageBox.Show(
"当前有未保存的修改,重新加载将丢失这些修改。\n\n确定要继续吗",
"确认", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result != MessageBoxResult.Yes)
return;
}
LoadConfigContent();
StatusLabel.Content = "配置已重新加载";
StatusLabel.Foreground = System.Windows.Media.Brushes.Green;
}
private void ResetToDefaultButton_Click(object sender, RoutedEventArgs e)
{
var result = MessageBox.Show(
"确定要恢复为默认配置吗?\n\n当前配置将被覆盖此操作无法撤销。",
"确认", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
try
{
ConfigManager.Instance.RestoreToDefaults();
LoadConfigContent();
StatusLabel.Content = "已恢复默认配置";
StatusLabel.Foreground = System.Windows.Media.Brushes.Green;
LogManager.Info("配置已恢复为默认值");
}
catch (Exception ex)
{
LogManager.Error($"恢复默认配置失败: {ex.Message}");
MessageBox.Show($"恢复默认配置失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
private void OpenConfigFolderButton_Click(object sender, RoutedEventArgs e)
{
try
{
string configDir = ConfigManager.ConfigDirectory;
if (!Directory.Exists(configDir))
{
Directory.CreateDirectory(configDir);
}
Process.Start("explorer.exe", configDir);
LogManager.Info($"打开配置文件夹: {configDir}");
}
catch (Exception ex)
{
LogManager.Error($"打开配置文件夹失败: {ex.Message}");
MessageBox.Show($"打开配置文件夹失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 应用配置(保存但不关闭窗口)
/// </summary>
private void ApplyButton_Click(object sender, RoutedEventArgs e)
{
SaveConfig();
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
if (_isModified)
{
if (SaveConfig())
{
Close();
}
}
else
{
Close();
}
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
if (_isModified)
{
var result = MessageBox.Show(
"有未保存的修改,确定要关闭吗?",
"确认", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result != MessageBoxResult.Yes)
return;
}
Close();
}
private void ConfigContentTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_originalContent != null)
{
_isModified = ConfigContentTextBox.Text != _originalContent;
if (_isModified)
{
ModifiedLabel.Content = "● 已修改";
}
else
{
ModifiedLabel.Content = "";
}
UpdateStatus();
}
}
/// <summary>
/// 窗口关闭事件
/// </summary>
protected override void OnClosed(EventArgs e)
{
try
{
// 清除静态实例引用
lock (_lock)
{
if (_currentInstance == this)
{
_currentInstance = null;
LogManager.Info("配置编辑器对话框实例已从单例缓存中移除");
}
}
}
catch (Exception ex)
{
LogManager.Error($"清理配置编辑器对话框资源失败: {ex.Message}");
}
finally
{
base.OnClosed(e);
}
}
/// <summary>
/// 窗口初始化后,确保获得稳定的键盘焦点
/// </summary>
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
try
{
this.Activate();
this.Topmost = true;
this.Topmost = false;
Dispatcher.BeginInvoke(new Action(FocusEditorTextBox), DispatcherPriority.Input);
LogManager.Debug("配置编辑器对话框已激活并前置显示");
}
catch (Exception ex)
{
LogManager.Error($"配置编辑器对话框初始化失败: {ex.Message}");
}
}
/// <summary>
/// 窗口内容渲染完成后再次请求焦点,避免宿主窗口抢占键盘
/// </summary>
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
Dispatcher.BeginInvoke(new Action(FocusEditorTextBox), DispatcherPriority.Input);
}
/// <summary>
/// 激活并显示已存在的窗口
/// </summary>
private void ActivateWindow()
{
try
{
// 如果窗口被最小化,则恢复
if (this.WindowState == WindowState.Minimized)
{
this.WindowState = WindowState.Normal;
}
this.Activate();
this.Topmost = true;
this.Topmost = false;
FocusEditorTextBox();
LogManager.Info("配置编辑器对话框已激活并前置显示");
}
catch (Exception ex)
{
LogManager.Error($"激活配置编辑器对话框失败: {ex.Message}");
}
}
private void FocusEditorTextBox()
{
try
{
if (ConfigContentTextBox == null)
{
return;
}
ConfigContentTextBox.Focus();
Keyboard.Focus(ConfigContentTextBox);
ConfigContentTextBox.CaretIndex = ConfigContentTextBox.Text?.Length ?? 0;
}
catch (Exception ex)
{
LogManager.Debug($"配置编辑器焦点设置失败: {ex.Message}");
}
}
#region
/// <summary>
/// 创建并显示配置编辑器对话框(单例模式,模态)
/// </summary>
/// <returns>对话框实例</returns>
public static ConfigEditorDialog ShowEditor()
{
try
{
lock (_lock)
{
// 如果当前已有实例且仍然打开,则激活窗口
if (_currentInstance != null)
{
try
{
// 检查窗口是否仍然有效
if (_currentInstance.IsLoaded && _currentInstance.IsVisible)
{
LogManager.Info("检测到已存在的配置编辑器窗口,激活窗口");
_currentInstance.ActivateWindow();
return _currentInstance;
}
else
{
// 窗口已关闭,清除引用
_currentInstance = null;
}
}
catch (Exception ex)
{
LogManager.Warning($"检查现有窗口状态时出现异常: {ex.Message},将创建新窗口");
_currentInstance = null;
}
}
// 创建新的对话框实例
var dialog = new ConfigEditorDialog();
// 优先设置 WPF Owner失败时回退到 Navisworks 主窗口句柄
if (!NavisworksTransport.Utils.DialogHelper.SetOwnerSafely(dialog))
{
NavisworksTransport.Utils.DialogHelper.SetWin32Owner(dialog);
}
// 设置为当前实例
_currentInstance = dialog;
// 使用 ShowDialog() 确保键盘输入不会被宿主窗口吃掉
dialog.ShowDialog();
LogManager.Info("新的配置编辑器对话框已显示(模态)");
return dialog;
}
}
catch (Exception ex)
{
LogManager.Error($"显示配置编辑器对话框失败: {ex.Message}");
MessageBox.Show($"显示配置编辑器对话框失败:\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
#endregion
}
}