/// <summary> /// Подготовка к копированию. Сбор сведений. /// </summary> public void Prepare(Dispatcher DGUI, ProjectItemIn projectSettings, DirInfoModel infoModel, Status status) { DGUI.BeginInvoke(() => { status.IsError = false; status.Message = "Подготовка.."; infoModel.OnPreparing(); }, DispatcherPriority.Normal); //+ checks if (projectSettings == null) { DGUI.BeginInvoke(() => { status.IsError = true; status.Message = "Укажите проект"; infoModel.CanPrepare = true; }); return; } if (String.IsNullOrWhiteSpace(projectSettings.DirFrom)) { DGUI.BeginInvoke(() => { status.IsError = true; status.Message = "Укажите путь к источникам"; infoModel.CanPrepare = true; }); return; } if (String.IsNullOrWhiteSpace(projectSettings.DirTo)) { DGUI.BeginInvoke(() => { status.IsError = true; status.Message = "Укажите путь назначения"; infoModel.CanPrepare = true; }); return; } var dirUtils = new DirectoryUtils(); var totalFiles = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var filePrepareIndex = 0; Action <String> onCheckFn = (d) => { TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать? DGUI.BeginInvoke(() => { status.Message = String.Format("Подготовка (шаг 1).. {0} ({1:00}:{2:00}:{3:00}) -> {4}", ++filePrepareIndex, ts.Hours, ts.Minutes, ts.Seconds, d); }); }; //+ 1. ищем все папки для работы (исходящие) var dirsIgnore = dirUtils.SearchDirs(StringUtils.StringSplitNewLines(projectSettings.DirFromIgnore), null, onCheckFn); //, Conventions.DirSeparatorStr); var dirs = dirUtils.SearchDirs(StringUtils.StringSplitNewLines(projectSettings.DirFrom), dirsIgnore, onCheckFn); //, Conventions.DirSeparatorStr); //+ 2. собираем все файлы (с их полными путями) для копирования var filePrepareTwoIndex = 0; Action <String> onCheckFilesFn = (f) => { TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать? DGUI.BeginInvoke(() => { status.Message = String.Format("Подготовка (шаг 2).. {0} ({1:00}:{2:00}:{3:00}) -> {4}", ++filePrepareTwoIndex, ts.Hours, ts.Minutes, ts.Seconds, f); }); }; var files = dirUtils.SearchFiles(dirs, onCheckFilesFn); totalFiles = files.Count; //+ 3. ищем среди имеющихся по назначению уже точно такие-же (если нет таких файлов или новые, то отдаем в работу) - ради чего все и затеялось var dirFromStr = projectSettings.DirFrom; if (dirFromStr.EndsWith(Conventions.DirSubdirSymbol)) { dirFromStr = dirFromStr.Remove(dirFromStr.Length - 1); } var fileIndex = 0; foreach (var file in files) { TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать? DGUI.BeginInvoke(() => { status.Message = String.Format("Подготовка (шаг 3).. {0}/{1} ({2:00}:{3:00}:{4:00})", ++fileIndex, totalFiles, ts.Hours, ts.Minutes, ts.Seconds); }); if (String.IsNullOrWhiteSpace(file)) { continue; } if (!file.StartsWith(dirFromStr)) { continue; //- странно } //- приводим к пути назначению var fileOut = String.Format("{0}\\{1}", projectSettings.DirTo, file.Remove(0, dirFromStr.Length)); fileOut = fileOut.Replace("\\\\", "\\"); //? to regexp (учесть не только двойные слэши, но и множественные?) // NOTE: метод "infoModel.AddFile()" может не лучший по оптимизации для TreeView // NOTE: возможно, для TreeView делать разовую обновку быстрее, чем на каждом файле //- если новый, то точно копируем if (!dirUtils.ExistsFile(fileOut)) { DGUI.BeginInvoke(() => { infoModel.AddFile(file, fileOut, true, DirTreeViewItemModelStatus.Normal, String.Empty); }); } //- если уже есть такой, то смотрим своим алгоритмом - вся суть приложения else { var isFileInWork = false; try { isFileInWork = IsFileForReplaceAlgo(file, fileOut, projectSettings, dirUtils); } catch (Exception ex) { // некоторая ошибка при сравнении файлов (возможно, не смогли сверить контент) DGUI.BeginInvoke(() => { infoModel.Errors.Add(ex.Message); infoModel.AddFile(file, fileOut, false, DirTreeViewItemModelStatus.Error, ex.Message); }); } if (isFileInWork) { DGUI.BeginInvoke(() => { infoModel.AddFile(file, fileOut, false, DirTreeViewItemModelStatus.Normal, String.Empty); }); } } } stopWatch.Stop(); //+ end (summary) DGUI.BeginInvoke(() => { infoModel.TotalFilesFrom = totalFiles; infoModel.CanWork = infoModel.Items.Any(); // files.Any(); // TODO: в идеале проверить не отмененные файлы и директории infoModel.CanPrepare = true; infoModel.ErrorsFilesFrom = infoModel.Errors.Count(); if (infoModel.ErrorsFilesFrom > 0) { status.IsError = true; status.Message = String.Format("Подготовка завершена с ошибками (ошибок: {0})", infoModel.ErrorsFilesFrom); } else { status.Message = "Подготовка завершена"; } }); }