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

413 lines
14 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.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;
LogManager.Debug("配置编辑器对话框已激活并前置显示");
}
catch (Exception ex)
{
LogManager.Error($"配置编辑器对话框初始化失败: {ex.Message}");
}
}
/// <summary>
/// 激活并显示已存在的窗口
/// </summary>
private void ActivateWindow()
{
try
{
// 如果窗口被最小化,则恢复
if (this.WindowState == WindowState.Minimized)
{
this.WindowState = WindowState.Normal;
}
// 激活并前置窗口(先置顶再取消置顶,避免独占焦点)
this.Activate();
this.Topmost = true;
this.Topmost = false;
LogManager.Info("配置编辑器对话框已激活并前置显示");
}
catch (Exception ex)
{
LogManager.Error($"激活配置编辑器对话框失败: {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();
// 使用 DialogHelper 安全地设置 owner
NavisworksTransport.Utils.DialogHelper.SetOwnerSafely(dialog);
// 设置为当前实例
_currentInstance = dialog;
// 使用 Show() 非模态显示,避免独占焦点
dialog.Show();
LogManager.Info("新的配置编辑器对话框已显示(非模态)");
return dialog;
}
}
catch (Exception ex)
{
LogManager.Error($"显示配置编辑器对话框失败: {ex.Message}");
MessageBox.Show($"显示配置编辑器对话框失败:\n{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
#endregion
}
}