private async Task NewFolder(IBuildFolderViewModel folder) { var name = await _dialogCoordinator.ShowValidatingInputDialogAsync(this, L10n.Message("New Folder"), L10n.Message("Enter the name of the new folder."), "", s => _buildValidator.ValidateNewFolderName(s, folder)); if (string.IsNullOrWhiteSpace(name)) { return; } var newFolder = new BuildFolderViewModel(new BuildFolder { Name = name }, Filter, BuildOnCollectionChanged); folder.Children.Add(newFolder); await SaveBuildToFile(newFolder); }
public BuildsControlViewModel(IExtendedDialogCoordinator dialogCoordinator, IPersistentData persistentData, ISkillTree skillTree) { _dialogCoordinator = dialogCoordinator; PersistentData = persistentData; DropHandler = new CustomDropHandler(this); _buildValidator = new BuildValidator(PersistentData.Options); BuildRoot = new BuildFolderViewModel(persistentData.RootBuild, Filter, BuildOnCollectionChanged); _fileSystemWatcher = new FileSystemWatcher { Path = PersistentData.Options.BuildsSavePath, IncludeSubdirectories = true, NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastWrite }; _fileSystemWatcher.Error += FileSystemWatcherOnError; _fileSystemWatcher.Changed += FileSystemWatcherOnChanged; _fileSystemWatcher.Created += FileSystemWatcherOnChanged; _fileSystemWatcher.Deleted += FileSystemWatcherOnChanged; _fileSystemWatcher.Renamed += FileSystemWatcherOnChanged; _fileSystemWatcher.EnableRaisingEvents = true; // The monitor alone is not enough because delays are necessary and those shouldn't block other save // operations, which would happen if delays are awaited directly in the save method. // It could be done awaited with .ConfigureAwait(false) if SimpleMonitor would be thread safe. _changingFileSystemMonitor.Entered += (sender, args) => _changingFileSystemCounter++; _changingFileSystemMonitor.Freed += async(sender, args) => { // Wait because FileSystemWatcherOnChanged calls are delayed a bit. await Task.Delay(2000); // This is a counter and not boolean because other save operations may happen while waiting on delay. _changingFileSystemCounter--; }; CurrentBuild = TreeFindBuildViewModel(PersistentData.CurrentBuild); SelectedBuild = TreeFindBuildViewModel(PersistentData.SelectedBuild); PersistentData.PropertyChanged += PersistentDataOnPropertyChanged; PersistentData.Options.PropertyChanged += OptionsOnPropertyChanged; NewFolderCommand = new AsyncRelayCommand <IBuildFolderViewModel>( NewFolder, vm => vm != null && _buildValidator.CanHaveSubfolder(vm)); NewBuildCommand = new RelayCommand <IBuildFolderViewModel>(NewBuild); DeleteCommand = new AsyncRelayCommand <IBuildViewModel>( Delete, o => o != BuildRoot); OpenBuildCommand = new AsyncRelayCommand <BuildViewModel>( OpenBuild, b => b != null && (b != CurrentBuild || b.Build.IsDirty)); SaveBuildCommand = new AsyncRelayCommand <BuildViewModel>( SaveBuild, b => b != null && b.Build.IsDirty); SaveBuildAsCommand = new AsyncRelayCommand <BuildViewModel>(SaveBuildAs); SaveAllBuildsCommand = new AsyncRelayCommand( SaveAllBuilds, () => TreeFind <BuildViewModel>(b => b.Build.IsDirty, BuildRoot) != null); RevertBuildCommand = new RelayCommand <BuildViewModel>( build => build.Build.RevertChanges(), b => b != null && b.Build.IsDirty && b.Build.CanRevert); MoveUpCommand = new RelayCommand <IBuildViewModel>( MoveUp, o => o != BuildRoot && o.Parent.Children.IndexOf(o) > 0); MoveDownCommand = new RelayCommand <IBuildViewModel>( MoveDown, o => o != BuildRoot && o.Parent.Children.IndexOf(o) < o.Parent.Children.Count - 1); EditCommand = new AsyncRelayCommand <IBuildViewModel>(Edit); CutCommand = new AsyncRelayCommand <IBuildViewModel>( Cut, b => b != BuildRoot && b != CurrentBuild); CopyCommand = new RelayCommand <IBuildViewModel <PoEBuild> >(Copy); PasteCommand = new AsyncRelayCommand <IBuildViewModel>(Paste, CanPaste); ReloadCommand = new AsyncRelayCommand(Reload); OpenBuildsSavePathCommand = new RelayCommand(() => Process.Start(PersistentData.Options.BuildsSavePath)); ExpandAllCommand = new RelayCommand(ExpandAll); CollapseAllCommand = new RelayCommand(CollapseAll); ExportCurrentToClipboardCommand = new RelayCommand(() => CopyToClipboard(CurrentBuild.Build)); ImportCurrentFromClipboardCommand = new AsyncRelayCommand(ImportCurrentFromClipboard, CanPasteFromClipboard); ExportGGGBuildFile = new RelayCommand <IBuildFolderViewModel>(ExportGGGBuild); ImportGGGBuildFile = new RelayCommand(() => ImportGGGBuild()); SkillTree = skillTree; ClassFilterItems = GenerateAscendancyClassItems(SkillTree.AscendancyClasses).ToList(); ClassFilter = NoFilterItem; }