IEnumerable <FarFile> DoInvokeXPath(ProgressBox progress) { // object context var objectContext = new XPathObjectContext() { Filter = this.Filter, IncrementDirectoryCount = delegate(int count) { ProcessedDirectoryCount += count; if (progress == null) { return; } var directoryPerSecond = ProcessedDirectoryCount / progress.ElapsedFromStart.TotalSeconds; progress.Activity = string.Format(null, Res.SearchActivityDeep, FoundFileCount, ProcessedDirectoryCount, directoryPerSecond); progress.ShowProgress(); }, Stopping = delegate { return(Stopping || progress != null && UIUserStop()); } }; var xsltContext = new XPathXsltContext(objectContext.NameTable); if (_XVariables != null) { foreach (var kv in _XVariables) { xsltContext.AddVariable(kv.Key, kv.Value); } } // XPath text string xpath; if (string.IsNullOrEmpty(XFile)) { xpath = XPath; } else { var input = XPathInput.ParseFile(XFile); xpath = input.Expression; foreach (var kv in input.Variables) { xsltContext.AddVariable(kv.Key, kv.Value); } } var expression = XPathExpression.Compile(xpath); if (expression.ReturnType != XPathResultType.NodeSet) { throw new InvalidOperationException("Invalid expression return type."); } expression.SetContext(xsltContext); ++ProcessedDirectoryCount; var args = new GetFilesEventArgs(ExplorerModes.Find); foreach (var file in _RootExplorer.GetFiles(args)) { // stop? if (Stopping || progress != null && UIUserStop()) //???? progress to navigator { break; } // filter out a leaf if (Filter != null && !file.IsDirectory && !Filter(_RootExplorer, file)) { continue; } var xfile = new SuperFile(_RootExplorer, file); var navigator = new XPathObjectNavigator(xfile, objectContext); var iterator = navigator.Select(expression); while (iterator.MoveNext()) { // stop? if (Stopping || progress != null && UIUserStop()) //???? progress to navigator { break; } // found file or directory, ignore anything else if (!(iterator.Current.UnderlyingObject is SuperFile currentFile)) { continue; } // filter out directory, it is already done for files if (Filter != null && currentFile.IsDirectory && (!Directory || !Filter(currentFile.Explorer, currentFile.File))) { continue; } // add yield return(currentFile); ++FoundFileCount; } } }
IEnumerable<FarFile> DoInvokeXPath(ProgressBox progress) { // object context var objectContext = new XPathObjectContext() { Filter = this.Filter, IncrementDirectoryCount = delegate(int count) { ProcessedDirectoryCount += count; if (progress == null) return; var directoryPerSecond = ProcessedDirectoryCount / progress.ElapsedFromStart.TotalSeconds; progress.Activity = string.Format(null, Res.SearchActivityDeep, FoundFileCount, ProcessedDirectoryCount, directoryPerSecond); progress.ShowProgress(); }, Stopping = delegate { return Stopping || progress != null && UIUserStop(); } }; var xsltContext = new XPathXsltContext(objectContext.NameTable); if (_XVariables != null) { foreach (var kv in _XVariables) xsltContext.AddVariable(kv.Key, kv.Value); } // XPath text string xpath; if (string.IsNullOrEmpty(XFile)) { xpath = XPath; } else { var input = XPathInput.ParseFile(XFile); xpath = input.Expression; foreach (var kv in input.Variables) xsltContext.AddVariable(kv.Key, kv.Value); } var expression = XPathExpression.Compile(xpath); if (expression.ReturnType != XPathResultType.NodeSet) throw new InvalidOperationException("Invalid expression return type."); expression.SetContext(xsltContext); ++ProcessedDirectoryCount; var args = new GetFilesEventArgs(ExplorerModes.Find); foreach (var file in _RootExplorer.GetFiles(args)) { // stop? if (Stopping || progress != null && UIUserStop()) //???? progress to navigator break; // filter out a leaf if (Filter != null && !file.IsDirectory && !Filter(_RootExplorer, file)) continue; var xfile = new SuperFile(_RootExplorer, file); var navigator = new XPathObjectNavigator(xfile, objectContext); var iterator = navigator.Select(expression); while (iterator.MoveNext()) { // stop? if (Stopping || progress != null && UIUserStop()) //???? progress to navigator break; // found file or directory, ignore anything else var currentFile = iterator.Current.UnderlyingObject as SuperFile; if (currentFile == null) continue; // filter out directory, it is already done for files if (Filter != null && currentFile.IsDirectory && (!Directory || !Filter(currentFile.Explorer, currentFile.File))) continue; // add yield return currentFile; ++FoundFileCount; } } }
JobResult DeleteFilesOfExplorer(Explorer explorer, List <SuperFile> xfilesToDelete, IList <FarFile> xfilesToStay, ExplorerModes mode, bool force, ref object codata) { // explorer files var efilesToDelete = new List <FarFile>(xfilesToDelete.Count); foreach (var file in xfilesToDelete) { efilesToDelete.Add(file.File); } // delete, mind co-data Log.Source.TraceInformation("DeleteFiles Count='{0}' Location='{1}'", efilesToDelete.Count, explorer.Location); var argsDelete = new DeleteFilesEventArgs(mode, efilesToDelete, force) { Data = codata }; explorer.DeleteFiles(argsDelete); codata = argsDelete.Data; // result: break to delete switch (argsDelete.Result) { default: return(JobResult.Ignore); case JobResult.Done: break; case JobResult.Incomplete: // recover that files to stay if (argsDelete.FilesToStay.Count == 0) { var filesAfterDelete = explorer.GetFiles(new GetFilesEventArgs(ExplorerModes.Silent)); var hashAfterDelete = Works.Kit.HashFiles(filesAfterDelete, explorer.FileComparer); foreach (var file in efilesToDelete) { if (hashAfterDelete.ContainsKey(file)) { argsDelete.FilesToStay.Add(file); } } } // convert that files to this files to stay foreach (SuperFile xfile in SuperFile.SuperFilesOfExplorerFiles(xfilesToDelete, argsDelete.FilesToStay, explorer.FileComparer)) { xfilesToDelete.Remove(xfile); xfilesToStay.Add(xfile); } break; } // remove remaining super files foreach (var file in xfilesToDelete) { _Cache.Remove(file); } return(argsDelete.Result); }
/// <inheritdoc/> public override void ExportFiles(ExportFilesEventArgs args) { if (args == null) { return; } var dicTypeId = GroupFiles(args.Files, ExplorerFunctions.ExportFiles); foreach (var xTypeId in dicTypeId) { Log.Source.TraceInformation("ExportFiles TypeId='{0}'", xTypeId.Key); object codata = null; foreach (var kv in xTypeId.Value) { // explorer and its files var explorer = kv.Key; var xfiles = kv.Value; var filesToExport = new List <FarFile>(xfiles.Count); foreach (var file in xfiles) { filesToExport.Add(file.File); } // export, mind co-data Log.Source.TraceInformation("ExportFiles Count='{0}' Location='{1}' DirectoryName='{2}'", filesToExport.Count, explorer.Location, args.DirectoryName); var argsExport = new ExportFilesEventArgs(ExplorerModes.None, filesToExport, args.Move, args.DirectoryName) { Data = codata }; explorer.ExportFiles(argsExport); codata = argsExport.Data; // info bool isIncomplete = argsExport.Result == JobResult.Incomplete; bool isAllToStay = isIncomplete && argsExport.FilesToStay.Count == 0; if (isIncomplete) { args.Result = JobResult.Incomplete; } // Copy: do not update the source, files are the same if (!args.Move) { // keep it as it is if (isAllToStay) { foreach (var file in xfiles) { args.FilesToStay.Add(file); } continue; } // recover if (isIncomplete) { foreach (var file in SuperFile.SuperFilesOfExplorerFiles(xfiles, argsExport.FilesToStay, explorer.FileComparer)) { args.FilesToStay.Add(file); } } continue; } // Move: no need to delete or all to stay or cannot delete if (!argsExport.ToDeleteFiles || isAllToStay || !explorer.CanDeleteFiles) { // recover selection if (isIncomplete) { var filesToStay = isAllToStay ? argsExport.Files : argsExport.FilesToStay; foreach (var file in SuperFile.SuperFilesOfExplorerFiles(xfiles, filesToStay, explorer.FileComparer)) { args.FilesToStay.Add(file); } } continue; } // Move: delete is requested, delete the source files // exclude this files to stay from to be deleted if (isIncomplete) { foreach (SuperFile xfile in SuperFile.SuperFilesOfExplorerFiles(xfiles, argsExport.FilesToStay, explorer.FileComparer)) { xfiles.Remove(xfile); args.FilesToStay.Add(xfile); } } // call delete on remaining files object codata2 = null; var result = DeleteFilesOfExplorer(explorer, xfiles, args.FilesToStay, ExplorerModes.Silent, false, ref codata2); if (result == JobResult.Incomplete) { args.Result = JobResult.Incomplete; } } } }
/// internal void CommitFiles(SuperPanel source, Panel target, IList <FarFile> files, bool move) { var dicTypeId = GroupFiles(files, ExplorerFunctions.None); bool SelectionExists = source.SelectionExists; var xfilesToStay = new List <FarFile>(); bool toUnselect = false; bool toUpdate = false; foreach (var xTypeId in dicTypeId) { Log.Source.TraceInformation("AcceptFiles TypeId='{0}'", xTypeId.Key); object codata = null; foreach (var kv in xTypeId.Value) { // explorer and its files var explorer = kv.Key; var xfiles = kv.Value; var filesToAccept = new List <FarFile>(xfiles.Count); foreach (var file in xfiles) { filesToAccept.Add(file.File); } // accept, mind co-data Log.Source.TraceInformation("AcceptFiles Count='{0}' Location='{1}'", filesToAccept.Count, explorer.Location); var argsAccept = new AcceptFilesEventArgs(ExplorerModes.None, filesToAccept, move, explorer) { Data = codata }; target.UIAcceptFiles(argsAccept); codata = argsAccept.Data; // info bool isIncomplete = argsAccept.Result == JobResult.Incomplete; bool isAllToStay = isIncomplete && argsAccept.FilesToStay.Count == 0; // Copy: do not update the source, files are the same if (!move) { // keep it as it is if (isAllToStay || !SelectionExists) { if (isAllToStay && SelectionExists) { foreach (var file in xfiles) { xfilesToStay.Add(file); } } continue; } // drop selection toUnselect = true; // recover if (isIncomplete) { xfilesToStay.AddRange(SuperFile.SuperFilesOfExplorerFiles(xfiles, argsAccept.FilesToStay, explorer.FileComparer)); } continue; } // Move: no need to delete or all to stay or cannot delete if (!argsAccept.ToDeleteFiles || isAllToStay || !explorer.CanDeleteFiles) { // the source may have some files deleted, update toUpdate = true; // recover selection if (isIncomplete) { xfilesToStay.AddRange(SuperFile.SuperFilesOfExplorerFiles( xfiles, isAllToStay ? argsAccept.Files : argsAccept.FilesToStay, explorer.FileComparer)); } continue; } // Move: delete is requested, delete the source files // exclude this files to stay from to be deleted if (isIncomplete) { foreach (SuperFile xfile in SuperFile.SuperFilesOfExplorerFiles(xfiles, argsAccept.FilesToStay, explorer.FileComparer)) { xfiles.Remove(xfile); xfilesToStay.Add(xfile); } } // call delete on remaining files object codata2 = null; var result = DeleteFilesOfExplorer(explorer, xfiles, xfilesToStay, ExplorerModes.Silent, false, ref codata2); if (result == JobResult.Done || result == JobResult.Incomplete) { toUpdate = true; } } } // update the target panel target.Update(true); target.Redraw(); // update/recover the source if (toUpdate) { source.Update(false); } else if (toUnselect) { source.UnselectAll(); } if (xfilesToStay.Count > 0) { source.SelectFiles(xfilesToStay, null); } source.Redraw(); }