413 lines
14 KiB
C#
413 lines
14 KiB
C#
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
|
||
}
|
||
}
|