You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
461 lines
16 KiB
C#
461 lines
16 KiB
C#
|
1 month ago
|
using AI.AgentIntegration;
|
||
|
|
using DevExpress.XtraBars.Docking2010.Views.Tabbed;
|
||
|
|
using GeoSigma.UCDraw.Service;
|
||
|
|
using GeoSigma.UCDraw.UC;
|
||
|
|
using GeoSigmaDrawLib;
|
||
|
|
using Newtonsoft.Json;
|
||
|
|
using Newtonsoft.Json.Linq;
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Text;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
|
||
|
|
using PcgDrawR.Services;
|
||
|
|
using Document = DevExpress.XtraBars.Docking2010.Views.Tabbed.Document;
|
||
|
|
|
||
|
|
namespace PcgDrawR
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 应用程序控制器的实现类,用于管理应用程序的状态和操作
|
||
|
|
/// </summary>
|
||
|
|
public class AppController : IAppController, IAppEnvironment
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 当应用程序状态发生变化时触发的事件
|
||
|
|
/// </summary>
|
||
|
|
public event EventHandler<AppState> StateChanged;
|
||
|
|
|
||
|
|
private static readonly Lazy<AppController> lazy = new Lazy<AppController>(() =>
|
||
|
|
new AppController());
|
||
|
|
|
||
|
|
private readonly AppState state = new AppState();
|
||
|
|
|
||
|
|
private readonly NavigationService navigationService;
|
||
|
|
|
||
|
|
private readonly FileTabService fileTabService;
|
||
|
|
|
||
|
|
private readonly GriddingModuleService griddingModuleService;
|
||
|
|
|
||
|
|
private readonly ImportService importService;
|
||
|
|
|
||
|
|
private UCDrawEdit? ActiveUCDrawEdit => MainForm?.TabbedView1?.ActiveDocument?.Control as UCDrawEdit;
|
||
|
|
|
||
|
|
private GeoSigmaXY? ActivateUCDrawEditGeo => ActiveUCDrawEdit?.DrawerView?.ViewControl?.Geo;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 获取全局唯一的 AppController 实例
|
||
|
|
/// </summary>
|
||
|
|
public static AppController Instance => lazy.Value;
|
||
|
|
|
||
|
|
private AppController()
|
||
|
|
{
|
||
|
|
navigationService = new NavigationService(this);
|
||
|
|
fileTabService = new FileTabService(this);
|
||
|
|
griddingModuleService = new GriddingModuleService(this);
|
||
|
|
importService = new ImportService(this);
|
||
|
|
|
||
|
|
RegisterHandlers();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 获取或设置主窗口引用
|
||
|
|
/// </summary>
|
||
|
|
public FormMain MainForm { get; set; }
|
||
|
|
|
||
|
|
private readonly Dictionary<AppActionType, Func<AppAction, Task<AppActionResult>>> actionMap =
|
||
|
|
new Dictionary<AppActionType, Func<AppAction, Task<AppActionResult>>>();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 获取应用程序的当前状态
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>当前应用程序状态</returns>
|
||
|
|
public AppState GetCurrentState()
|
||
|
|
{
|
||
|
|
RefreshUIState();
|
||
|
|
return state;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RegisterHandlers()
|
||
|
|
{
|
||
|
|
// 扫描当前类所有的方法
|
||
|
|
var methods = this.GetType().GetMethods(
|
||
|
|
System.Reflection.BindingFlags.Instance |
|
||
|
|
System.Reflection.BindingFlags.NonPublic |
|
||
|
|
System.Reflection.BindingFlags.Public);
|
||
|
|
|
||
|
|
foreach (var method in methods)
|
||
|
|
{
|
||
|
|
// 获取方法上的 ActionHandler 特性
|
||
|
|
var attr = method.GetCustomAttributes(typeof(ActionHandlerAttribute), false)
|
||
|
|
.FirstOrDefault() as ActionHandlerAttribute;
|
||
|
|
|
||
|
|
if (attr != null)
|
||
|
|
{
|
||
|
|
// 创建强类型委托 (要求方法签名必须匹配)
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var handler = (Func<AppAction, Task<AppActionResult>>)
|
||
|
|
Delegate.CreateDelegate(typeof(Func<AppAction, Task<AppActionResult>>), this, method);
|
||
|
|
|
||
|
|
// 注册到字典
|
||
|
|
actionMap[attr.ActionType] = handler;
|
||
|
|
}
|
||
|
|
catch (ArgumentException)
|
||
|
|
{
|
||
|
|
// 这里可以加日志,提示方法签名不对 (必须是 Task<AppActionResult> Func(AppAction a))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 执行指定的应用程序操作
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="action">要执行的操作</param>
|
||
|
|
/// <returns>操作执行结果</returns>
|
||
|
|
public async Task<AppActionResult> ExecuteAsync(AppAction action)
|
||
|
|
{
|
||
|
|
if (actionMap.TryGetValue(action.Action, out var handler))
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var result = await handler(action);
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
return AppActionResult.Fail($"执行异常: {ex.Message}");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return AppActionResult.Fail($"未支持的操作类型: {action.Action}");
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.SaveFile)]
|
||
|
|
protected async Task<AppActionResult> SaveFileAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await fileTabService.SaveFileAsync(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("SaveFile");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.DescribeState)]
|
||
|
|
protected Task<AppActionResult> DescribeStateAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return navigationService.DescribeStateAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.SetBusy)]
|
||
|
|
protected async Task<AppActionResult> SetBusyAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await navigationService.SetBusyAsync(action);
|
||
|
|
UpdateState("SetBusy");
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.Navigate)]
|
||
|
|
protected async Task<AppActionResult> NavigateAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await navigationService.NavigateAsync(action);
|
||
|
|
UpdateState("Navigate");
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.NavigateBack)]
|
||
|
|
protected async Task<AppActionResult> NavigateBackAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await navigationService.NavigateBackAsync(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("NavigateBack");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.NavigateForward)]
|
||
|
|
protected async Task<AppActionResult> NavigateForwardAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await navigationService.NavigateForwardAsync(action);
|
||
|
|
UpdateState("NavigateForward");
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.SwitchTab)]
|
||
|
|
protected Task<AppActionResult> SwitchTabAsync(AppAction action)
|
||
|
|
{
|
||
|
|
SwitchTabTo(action);
|
||
|
|
UpdateState("SwitchTab");
|
||
|
|
return Task.FromResult(Success());
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.CloseAllFiles)]
|
||
|
|
protected async Task<AppActionResult> CloseAllFilesAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await fileTabService.CloseAllFilesAsync(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("CloseAllFiles");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GetOpenTabs)]
|
||
|
|
protected Task<AppActionResult> GetOpenTabsAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return navigationService.GetOpenTabsAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.CloseFile)]
|
||
|
|
protected async Task<AppActionResult> CloseFileAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await fileTabService.CloseFileAsync(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("CloseFile");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.Undo)]
|
||
|
|
protected Task<AppActionResult> UndoAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var edit = ActiveUCDrawEdit;
|
||
|
|
if (edit == null)
|
||
|
|
return Task.FromResult(Fail("当前没有打开任何图件"));
|
||
|
|
MainForm.Invoke(() => edit.DrawerView?.ToolUndo());
|
||
|
|
UpdateState("Undo");
|
||
|
|
return Task.FromResult(Success());
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.Redo)]
|
||
|
|
protected Task<AppActionResult> RedoAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var edit = ActiveUCDrawEdit;
|
||
|
|
if (edit == null)
|
||
|
|
return Task.FromResult(Fail("当前没有打开任何图件"));
|
||
|
|
MainForm.Invoke(() => edit.DrawerView?.ToolRedo());
|
||
|
|
UpdateState("Redo");
|
||
|
|
return Task.FromResult(Success());
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.Refresh)]
|
||
|
|
protected async Task<AppActionResult> RefreshAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await navigationService.RefreshAsync(action);
|
||
|
|
UpdateState("Refresh");
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.Exit)]
|
||
|
|
protected Task<AppActionResult> ExitAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return navigationService.ExitAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.RenameFile)]
|
||
|
|
protected async Task<AppActionResult> RenameFileAsync(AppAction action)
|
||
|
|
{
|
||
|
|
var result = await fileTabService.RenameFileAsync(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("RenameFile");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.SaveAll)]
|
||
|
|
protected Task<AppActionResult> SaveAllAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return fileTabService.SaveAllAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleGetParameters)]
|
||
|
|
protected Task<AppActionResult> GriddingModuleGetParametersAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.GetParametersAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleSetParameters)]
|
||
|
|
protected Task<AppActionResult> GriddingModuleSetParametersAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.SetParametersAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleGetColumns)]
|
||
|
|
protected Task<AppActionResult> GrddingModuleGetColumns(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.GetColumnsAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 打开指定路径的文件
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="action">包含文件路径参数的操作</param>
|
||
|
|
/// <returns>操作执行结果</returns>
|
||
|
|
[ActionHandler(AppActionType.OpenFile)]
|
||
|
|
protected AppActionResult OpenFile(AppAction action)
|
||
|
|
{
|
||
|
|
var result = fileTabService.OpenFile(action);
|
||
|
|
if (result.Success)
|
||
|
|
{
|
||
|
|
UpdateState("OpenFile");
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.ReloadFile)]
|
||
|
|
protected AppActionResult ReloadFile()
|
||
|
|
{
|
||
|
|
return fileTabService.ReloadFile(new AppAction { Action = AppActionType.ReloadFile });
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 切换到指定标签页
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="action">包含标签页标识符参数的操作</param>
|
||
|
|
/// <returns>操作执行结果</returns>
|
||
|
|
protected AppActionResult SwitchTabTo(AppAction action)
|
||
|
|
{
|
||
|
|
if (!action.Parameters.TryGetValue("tab", out var tabObj))
|
||
|
|
{
|
||
|
|
return Fail("缺少 'tab' 参数");
|
||
|
|
}
|
||
|
|
|
||
|
|
var tab = tabObj.ToString();
|
||
|
|
|
||
|
|
MainForm.Invoke(() => MainForm.ActivateTab = tab);
|
||
|
|
UpdateState("OpenFile");
|
||
|
|
return Success();
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.AddScaleBar)]
|
||
|
|
protected Task<AppActionResult> AddScaleBar(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.AddScaleBarAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.AddBorder)]
|
||
|
|
protected Task<AppActionResult> AddBorder(AppAction action)
|
||
|
|
{
|
||
|
|
return Task.FromResult(Fail("添加失败: 当前没有打开任何图件"));
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.AddLegend)]
|
||
|
|
protected Task<AppActionResult> AddLegend(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.AddLegendAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 更新应用程序状态
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="lastCommand">最后执行的命令名称</param>
|
||
|
|
private void UpdateState(string lastCommand)
|
||
|
|
{
|
||
|
|
state.Agent.LastCommand = lastCommand;
|
||
|
|
state.Agent.LastResult = "success";
|
||
|
|
state.System.LastActionTimeUtc = DateTime.UtcNow;
|
||
|
|
StateChanged?.Invoke(this, state);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 刷新用户界面状态
|
||
|
|
/// </summary>
|
||
|
|
private void RefreshUIState()
|
||
|
|
{
|
||
|
|
state.UI.OpenTabs = MainForm.OpenTabs;
|
||
|
|
state.UI.ActiveTab = MainForm.ActivateTab;
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleLoadXyz)]
|
||
|
|
protected async Task<AppActionResult> GriddingModuleLoadXyzAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return await griddingModuleService.LoadXyzAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleMatchColumns)]
|
||
|
|
protected Task<AppActionResult> GriddingModuleMatchColumnsAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.MatchColumnsAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleImport)]
|
||
|
|
protected async Task<AppActionResult> GriddingModuleImportAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return await griddingModuleService.ImportAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModuleRun)]
|
||
|
|
protected async Task<AppActionResult> GriddingModuleRunAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return await griddingModuleService.RunAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.GriddingModulePreviewData)]
|
||
|
|
protected Task<AppActionResult> GriddingPreviewData(AppAction action)
|
||
|
|
{
|
||
|
|
return griddingModuleService.PreviewDataAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.WellModuleImportWellPoints)]
|
||
|
|
protected Task<AppActionResult> WellModuleImportWellPointsAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return importService.ImportWellPointsAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
[ActionHandler(AppActionType.WellModuleImportCurves)]
|
||
|
|
protected Task<AppActionResult> WellModuleImportCurvesAsync(AppAction action)
|
||
|
|
{
|
||
|
|
return importService.ImportWellCurvesAsync(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 创建一个表示成功操作结果的对象
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="data">操作返回的数据</param>
|
||
|
|
/// <returns>表示成功操作结果的对象</returns>
|
||
|
|
private AppActionResult Success(object data = null)
|
||
|
|
{
|
||
|
|
return new AppActionResult { Success = true, Data = data };
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 创建一个表示失败操作结果的对象
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="message">失败消息</param>
|
||
|
|
/// <returns>表示失败操作结果的对象</returns>
|
||
|
|
private AppActionResult Fail(string message)
|
||
|
|
{
|
||
|
|
return new AppActionResult { Success = false, Message = message };
|
||
|
|
}
|
||
|
|
|
||
|
|
private PanelGraph GetActivePanelGraph()
|
||
|
|
{
|
||
|
|
if (ActiveUCDrawEdit == null)
|
||
|
|
{
|
||
|
|
throw new InvalidOperationException("当前界面不存在或不是平面图,无法获取成图面板,请新建图件或者打开");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ActiveUCDrawEdit.GraphControl == null)
|
||
|
|
{
|
||
|
|
throw new InvalidOperationException("成图面板不存在,无法成图");
|
||
|
|
}
|
||
|
|
|
||
|
|
return ActiveUCDrawEdit.GraphControl;
|
||
|
|
}
|
||
|
|
|
||
|
|
FormMain IAppEnvironment.MainForm => MainForm;
|
||
|
|
|
||
|
|
AppState IAppEnvironment.State => state;
|
||
|
|
|
||
|
|
UCDrawEdit? IAppEnvironment.ActiveUCDrawEdit => ActiveUCDrawEdit;
|
||
|
|
|
||
|
|
GeoSigmaXY? IAppEnvironment.ActiveGeo => ActivateUCDrawEditGeo;
|
||
|
|
}
|
||
|
|
}
|