Files
SzmediTools/Szmedi.AIScriptRunner/RvScript/RoslynEditorViewModel.cs
2025-09-16 16:06:41 +08:00

225 lines
8.5 KiB
C#
Raw Permalink 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.Collections.ObjectModel;
using System.Windows;
using System.Xml;
using Autodesk.Revit.UI;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using Microsoft.Win32;
using RoslynPad.Editor;
using Szmedi.AIScriptRunner.Services;
namespace Szmedi.AIScriptRunner.RvScript
{
public partial class RoslynEditorViewModel : ObservableRecipient
{
private readonly ExternalEvent _externalEvent;
private readonly ScriptRunnerHandler _scriptRunnerHandler;
[ObservableProperty]
private string _result;
private DocumentViewModel _activeDocument;
[ObservableProperty]
private Visibility _isRunning = Visibility.Collapsed;
public RoslynCodeEditor CodeEditor { get; set; }
public RoslynEditorViewModel(RevitRoslynHost host, ExternalEvent externalEvent, ScriptRunnerHandler scriptRunnerHandler)
{
Host = host;
scriptRunnerHandler.RoslynEditorViewModel = this;
_externalEvent = externalEvent;
_scriptRunnerHandler = scriptRunnerHandler;
IsActive = true;
WeakReferenceMessenger.Default.Register<RoslynEditorViewModel, string, string>(this, "RunScript", (r, m) => Code = m);
}
public IHighlightingDefinition HighlightingDefinition
{
get
{
//var resourceName = "YourNamespace.Resources.CustomHighlighting.xshd";
//using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
using (var stream = File.OpenRead("Dark.xshd"))
{
var reader = new XmlTextReader(stream);
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
}
public RevitRoslynHost Host { get; }
ObservableCollection<DocumentViewModel> _documents = new ObservableCollection<DocumentViewModel>();
ReadOnlyObservableCollection<DocumentViewModel> _readonlydocuments = null;
public ReadOnlyObservableCollection<DocumentViewModel> Documents
{
get
{
if (_readonlydocuments == null)
_readonlydocuments = new ReadOnlyObservableCollection<DocumentViewModel>(_documents);
return _readonlydocuments;
}
}
[RelayCommand]
private void Open(object parameter)
{
var dlg = new OpenFileDialog
{
Filter = "C# 脚本文件 (*.csx)|*.csx",
RestoreDirectory = true,
InitialDirectory = Path.Combine(GlobalVariables.DirAssembly, "Samples")
};
if (dlg.ShowDialog().GetValueOrDefault())
{
var DocumentViewModel = Open(dlg.FileName);
ActiveDocument = DocumentViewModel;
}
}
public DocumentViewModel Open(string filepath)
{
var DocumentViewModel = _documents.FirstOrDefault(fm => fm.FilePath == filepath);
if (DocumentViewModel != null)
return DocumentViewModel;
DocumentViewModel = new DocumentViewModel(this, filepath);
_documents.Add(DocumentViewModel);
return DocumentViewModel;
}
[RelayCommand]
private void About()
{
TaskDialog mainDialog = new TaskDialog("关于");//对话框的名称
mainDialog.MainInstruction = "基于开源库开发的C#脚本执行工具";//对话框标题
//mainDialog.MainContent = "C#脚本参考以下两个开源库,进行调整。";//对话框的主要内容
//mainDialog.MainContent = "复制提示词提问";//对话框的主要内容
mainDialog.ExpandedContent = @"基于Autodesk Revit软件的直接执行C#脚本可用于将AI对话的代码粘贴执行";//对话框的扩展内容
var link1 = "https://github.com/sridharbaldava/Revit.ScriptCS";
var link2 = "https://github.com/kongdetuo/RevitTools";
////添加命令链接
mainDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, link1);
mainDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, link2);
mainDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink3, "复制AI提示词");
mainDialog.CommonButtons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel;
//mainDialog.VerificationText = "不再显示该信息";
//添加文字超链接
//mainDialog.FooterText = "<a href=\"https://github.com/sridharbaldava/Revit.ScriptCS\">" + "点此处了解更多信息</a>";
var result = mainDialog.Show();
if (result == TaskDialogResult.CommandLink1)
{
System.Diagnostics.Process.Start(link1);
}
if (result == TaskDialogResult.CommandLink2)
{
System.Diagnostics.Process.Start(link2);
}
if (result == TaskDialogResult.CommandLink3)
{
try
{
Clipboard.SetText($"{GlobalVariables.UIApplication.Application.VersionName}二次开发中使用已定义好的uidoc、doc两个变量构造一个正确执行的C#代码块保证RevitAPI方法签名准确添加关键的注释不需要方法签名和using命名空间但使用时需要完整的命名空间。需求是");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
[RelayCommand]
private void New()
{
// _documents.Add(new DocumentViewModel(this) { Document = new TextDocument() });
_documents.Add(new DocumentViewModel(this));
ActiveDocument = _documents.Last();
}
public DocumentViewModel ActiveDocument
{
get { return _activeDocument; }
set
{
if (_activeDocument != value)
{
_activeDocument = value;
OnPropertyChanged(nameof(ActiveDocument));
ActiveDocumentChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public event EventHandler ActiveDocumentChanged;
internal void Close(DocumentViewModel fileToClose)
{
if (fileToClose.IsDirty)
{
var res = MessageBox.Show(string.Format("保存文件修改 '{0}'?", fileToClose.FileName), "Revit C#脚本", MessageBoxButton.YesNoCancel);
if (res == MessageBoxResult.Cancel)
return;
if (res == MessageBoxResult.Yes)
{
Save(fileToClose);
}
}
_documents.Remove(fileToClose);
}
internal void Save(DocumentViewModel fileToSave, bool saveAsFlag = false)
{
if (fileToSave.FilePath == null || saveAsFlag)
{
var dlg = new SaveFileDialog();
dlg.Filter = "C# 脚本 (*.csx)|*.csx";
if (dlg.ShowDialog().GetValueOrDefault())
fileToSave.FilePath = dlg.FileName;
else
return;
}
File.WriteAllText(fileToSave.FilePath, fileToSave.Text);
ActiveDocument.IsDirty = false;
}
internal void Run(DocumentViewModel documentViewModel)
{
Result = string.Empty;
IsRunning = Visibility.Visible;
_scriptRunnerHandler.ScriptText = documentViewModel.Text;
_externalEvent.Raise();
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RunCodeCommand))]
[NotifyCanExecuteChangedFor(nameof(CopyCodeCommand))]
private string code;
public bool HasCode => !string.IsNullOrEmpty(Code);
[RelayCommand(CanExecute = nameof(HasCode))]
internal void RunCode()
{
Result = string.Empty;
IsRunning = Visibility.Visible;
_scriptRunnerHandler.ScriptText = Code;
_externalEvent.Raise();
}
[RelayCommand(CanExecute = nameof(HasCode))]
internal void CopyCode()
{
Clipboard.SetText(Code);
}
}
}