using System.Collections.ObjectModel; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; using Intromat.Actions.Hierarchy; using ReactiveUI; namespace Intromat.ViewModels { public class ExplorerViewModel : ReactiveObject { private ModuleViewModel? _currentModule; private ProjectViewModel? _currentProject; private FolderViewModel? _currentFolder; private FileViewModel? _currentFile; private readonly MainViewModel _mainVm; public ExplorerViewModel(MainViewModel mainVm) { _mainVm = mainVm; var isCurrentProjectSet = this.WhenAnyValue(vm => vm.CurrentProject).Select(p => p != null); var isCurrentModuleSet = this.WhenAnyValue(vm => vm.CurrentModule).Select(p => p != null); var isCurrentFolderSet = this.WhenAnyValue(vm => vm.CurrentFolder).Select(p => p != null); var isCurrentDocumentSet = this.WhenAnyValue(vm => vm.CurrentFile).Select(p => p != null); NewModule = ReactiveCommand.CreateFromTask(async () => { var moduleName = await mainVm.SelectName.Handle("Enter the new module's name:"); if (moduleName != null) { mainVm.UndoRedo.Execute(new CreateModuleAction(moduleName, CurrentProject!)); } }, isCurrentProjectSet); RenameModule = ReactiveCommand.CreateFromTask(async () => { var newName = await mainVm.SelectName.Handle("Enter the module's new name:"); if (newName != null) { var oldName = CurrentModule!.Name; mainVm.UndoRedo.Execute(new UndoItem(CurrentModule, CurrentModule, vm => vm.Name, oldName, newName)); } }, isCurrentModuleSet); DeleteModule = ReactiveCommand.CreateFromTask(() => { mainVm.UndoRedo.Execute(new DeleteModuleAction(CurrentModule!)); return Task.CompletedTask; }, isCurrentModuleSet); NewModuleFolder = ReactiveCommand.CreateFromTask(async () => { var moduleName = await mainVm.SelectName.Handle("Enter the new folder's name:"); if (moduleName != null) { mainVm.UndoRedo.Execute(new CreateFolderAction(moduleName, CurrentModule!, CurrentModule!)); } }, isCurrentModuleSet); NewSubFolder = ReactiveCommand.CreateFromTask(async () => { var moduleName = await mainVm.SelectName.Handle("Enter the new folder's name:"); if (moduleName != null) { mainVm.UndoRedo.Execute(new CreateFolderAction(moduleName, CurrentFolder!.Module, CurrentFolder)); } }, isCurrentFolderSet); RenameFolder = ReactiveCommand.CreateFromTask(async () => { var newName = await mainVm.SelectName.Handle("Enter the folder's new name:"); if (newName != null) { var oldName = CurrentFolder!.Name; mainVm.UndoRedo.Execute(new UndoItem(CurrentFolder.Module, CurrentFolder, vm => vm.Name, oldName, newName)); } }, isCurrentFolderSet); DeleteFolder = ReactiveCommand.CreateFromTask(() => { mainVm.UndoRedo.Execute(new DeleteFolderAction(CurrentFolder!)); return Task.CompletedTask; }, isCurrentFolderSet); NewFile = ReactiveCommand.CreateFromTask(async () => { var fileAction = await mainVm.SelectTypeAndFileName.Handle(Unit.Default); if (fileAction != null) { mainVm.UndoRedo.Execute(new CreateFileAction(mainVm, fileAction(), CurrentFolder!.Module, CurrentFolder)); } }, isCurrentFolderSet); RenameFile = ReactiveCommand.CreateFromTask(async () => { var newName = await mainVm.SelectName.Handle("Enter the graph's new name:"); if (newName != null) { var oldName = CurrentFile!.Name; mainVm.UndoRedo.Execute(new UndoItem(CurrentFile.Module, CurrentFile, vm => vm.Name, oldName, newName)); } }, isCurrentDocumentSet); DeleteFile = ReactiveCommand.CreateFromTask(() => { mainVm.UndoRedo.Execute(new DeleteFileAction(CurrentFile!)); return Task.CompletedTask; }, isCurrentDocumentSet); } public ReactiveCommand NewModule { get; set; } public ReactiveCommand RenameModule { get; set; } public ReactiveCommand DeleteModule { get; set; } public ReactiveCommand NewModuleFolder { get; set; } public ReactiveCommand NewSubFolder { get; set; } public ReactiveCommand RenameFolder { get; set; } public ReactiveCommand DeleteFolder { get; set; } public ReactiveCommand NewFile { get; set; } public ReactiveCommand RenameFile { get; set; } public ReactiveCommand DeleteFile { get; set; } public ObservableCollection TreeRoot { get; } = new(); public ProjectViewModel? CurrentProject { get => _currentProject; set => this.RaiseAndSetIfChanged(ref _currentProject, value); } public ModuleViewModel? CurrentModule { get => _currentModule; set { this.RaiseAndSetIfChanged(ref _currentModule, value); CurrentFolder = _currentModule; } } public FolderViewModel? CurrentFolder { get => _currentFolder; set => this.RaiseAndSetIfChanged(ref _currentFolder, value); } public FileViewModel? CurrentFile { get => _currentFile; set => this.RaiseAndSetIfChanged(ref _currentFile, value); } public MainViewModel MainViewModel => _mainVm; } }