Files

225 lines
8.5 KiB
C#
Raw Permalink Normal View History

2025-09-16 16:06:41 +08:00

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);
}
}
}