Пример #1
0
 public override void UIDeleteFiles(DeleteFilesEventArgs args)
 {
     if (0 == Far.Api.Message("Delete files?", "MyPanel", MessageOptions.OkCancel))
     {
         base.UIDeleteFiles(args);
     }
 }
Пример #2
0
 public override void DeleteFiles(DeleteFilesEventArgs args)
 {
     foreach (var file in args.Files)
     {
         _files.RemoveAll((x) => x.Name == file.Name);
     }
 }
Пример #3
0
        /// <summary>
        /// Calls <see cref="FarNet.Explorer.DeleteFiles"/> and <see cref="OnThisFileChanged"/>.
        /// </summary>
        /// <param name="args">.</param>
        public virtual void UIDeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            Explorer.DeleteFiles(args);

            if (args.Result != JobResult.Ignore)
                OnThisFileChanged(args);
        }
Пример #4
0
 /// <include file='doc.xml' path='doc/ScriptFork/*'/>
 /// <param name="args">.</param>
 public sealed override void DeleteFiles(DeleteFilesEventArgs args)
 {
     if (AsDeleteFiles == null)
     {
         DoDeleteFiles(args);
     }
     else
     {
         A.InvokeScriptReturnAsIs(AsDeleteFiles, this, args);
     }
 }
Пример #5
0
        /// <inheritdoc/>
        public override void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // -Confirm -Recurse
            var confirmDelete       = 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete");
            var confirmDeleteFolder = 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "DeleteFolder");

            // call
            try
            {
                using (var ps = A.Psf.NewPowerShell())
                {
                    ps.AddCommand("Remove-Item")
                    .AddParameter(Prm.Force)
                    .AddParameter(Prm.ErrorAction, ActionPreference.Continue);

                    if (confirmDelete && confirmDeleteFolder)
                    {
                        ps.AddParameter(Prm.Confirm);
                    }
                    else if (confirmDelete)
                    {
                        ps.AddParameter(Prm.Confirm).AddParameter(Prm.Recurse);
                    }
                    else if (confirmDeleteFolder)
                    {
                        ps.AddParameter(Prm.Recurse);
                    }

                    ps.Invoke(args.FilesData);

                    if (ps.Streams.Error.Count > 0)
                    {
                        args.Result = JobResult.Incomplete;
                        if (args.UI)
                        {
                            A.ShowError(ps);
                        }
                    }
                }
            }
            catch
            {
                args.Result = JobResult.Incomplete;
                throw;
            }
        }
Пример #6
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // skip not default modes
            if (MemberMode != 0)
            {
                args.Result = JobResult.Ignore;
                return;
            }

            // ask
            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (Far.Api.Message("Delete selected members", Res.Delete, MessageOptions.None, new string[] { Res.Delete, Res.Cancel }) != 0)
                {
                    args.Result = JobResult.Ignore;
                    return;
                }
            }

            try
            {
                int count1 = Value.Properties.Count();

                foreach (FarFile file in args.Files)
                {
                    PSPropertyInfo pi = file.Data as PSPropertyInfo;
                    if (pi == null)
                    {
                        continue;
                    }

                    Value.Properties.Remove(pi.Name);
                }

                int count2 = Value.Properties.Count();
                if (count1 - args.Files.Count != count2)
                {
                    args.Result = JobResult.Incomplete;
                }
            }
            finally
            {
                // update always, some members can be deleted, don't leave them
                MemberPanel.WhenMemberChanged(Value);                 //????? will it be 2 times for THIS panel?
            }
        }
Пример #7
0
        internal void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            BuildDeleteCommand();

            var Files = Explorer.Cache;

            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (0 != Far.Api.Message("Delete selected record(s)?", Res.Delete, MessageOptions.None, new string[] { Res.Delete, Res.Cancel }))
                {
                    return;
                }
            }

            ToUpdateData = true;

            foreach (var file in args.Files)
            {
                var dr = file.Data as DataRow;
                if (dr == null)
                {
                    Files.Remove(file);
                    continue;
                }

                bool ok = true;
                try
                {
                    dr.Delete();
                    ok = SaveData();
                }
                catch
                {
                    ok = false;
                    throw;
                }
                finally
                {
                    if (!ok)
                    {
                        dr.RejectChanges();
                        PostData(dr);
                    }
                }
                if (!ok)
                {
                    break;
                }
            }
        }
Пример #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        private void _outputMusic_DeleteFiles(DeleteFilesEventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show(
                $"There are already files in the '{e.FolderName}' folder.  Do you want to delete these first?", AppGlobals.AppName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

            if (dialogResult == DialogResult.Yes)
            {
                e.Response = DeleteFilesResponse.Yes;
            }
            else if (dialogResult == DialogResult.No)
            {
                e.Response = DeleteFilesResponse.No;
            }
            else if (dialogResult == DialogResult.Cancel)
            {
                e.Response = DeleteFilesResponse.Cancel;
            }
        }
Пример #9
0
        /// <inheritdoc/>
        public override void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (Far.Api.Message("Remove object(s)?", Res.Remove, MessageOptions.None, new string[] { Res.Remove, Res.Cancel }) != 0)
                {
                    args.Result = JobResult.Ignore;
                    return;
                }
            }

            foreach (FarFile file in args.Files)
            {
                Cache.Remove(file);
            }
        }
Пример #10
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            var dicTypeId = GroupFiles(args.Files, ExplorerFunctions.DeleteFiles);

            int nDone       = 0;
            int nIncomplete = 0;

            foreach (var xTypeId in dicTypeId)
            {
                Log.Source.TraceInformation("DeleteFiles TypeId='{0}'", xTypeId.Key);
                object codata = null;
                foreach (var kv in xTypeId.Value)
                {
                    var result = DeleteFilesOfExplorer(kv.Key, kv.Value, args.FilesToStay, args.Mode, args.Force, ref codata);
                    if (result == JobResult.Done)
                    {
                        ++nDone;
                    }
                    else if (result == JobResult.Incomplete)
                    {
                        ++nIncomplete;
                    }
                }
            }

            // my result
            if (nIncomplete > 0)
            {
                args.Result = JobResult.Incomplete;
            }
            else if (nDone == 0)
            {
                args.Result = JobResult.Ignore;
            }
        }
Пример #11
0
        public override void UIDeleteFiles(DeleteFilesEventArgs args)
        {
            if (!ensurePathExist())
            {
                return;
            }

            base.UIDeleteFiles(args);
        }
Пример #12
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            // skip not default modes
            if (MemberMode != 0)
            {
                args.Result = JobResult.Ignore;
                return;
            }

            // ask
            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (Far.Api.Message("Delete selected members", Res.Delete, MessageOptions.None, new string[] { Res.Delete, Res.Cancel }) != 0)
                {
                    args.Result = JobResult.Ignore;
                    return;
                }
            }

            try
            {
                int count1 = 0;
                foreach (var it in Value.Properties)
                    ++count1;

                foreach (FarFile file in args.Files)
                {
                    PSPropertyInfo pi = file.Data as PSPropertyInfo;
                    if (pi == null)
                        continue;

                    Value.Properties.Remove(pi.Name);
                }

                int count2 = 0;
                foreach (var it in Value.Properties)
                    ++count2;

                if (count1 - args.Files.Count != count2)
                    args.Result = JobResult.Incomplete;
            }
            finally
            {
                // update always, some members can be deleted, don't leave them
                MemberPanel.WhenMemberChanged(Value); //????? will it be 2 times for THIS panel?
            }
        }
Пример #13
0
        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);
        }
Пример #14
0
 /// <include file='doc.xml' path='doc/ScriptFork/*'/>
 /// <param name="args">.</param>
 public override sealed void DeleteFiles(DeleteFilesEventArgs args)
 {
     if (AsDeleteFiles == null)
         DoDeleteFiles(args);
     else
         A.InvokeScriptReturnAsIs(AsDeleteFiles, this, args);
 }
Пример #15
0
        /// <summary>
        /// Delete action.
        /// </summary>
        /// <param name="force">The force mode flag.</param>
        public void UIDelete(bool force)
        {
            // can?
            if (!Explorer.CanDeleteFiles)
                return;

            // args
            var args = new DeleteFilesEventArgs(ExplorerModes.None, SelectedFiles, force);
            if (args.Files.Count == 0)
                return;

            // call
            UIDeleteWithRecover(args, true);
        }
Пример #16
0
 ///
 public override void DoDeleteFiles(DeleteFilesEventArgs args)
 {
     Panel.DoDeleteFiles(args);
 }
Пример #17
0
        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);
            argsDelete.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;
        }
Пример #18
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // to ask
            bool confirm = args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete");

            // names to be deleted
            List <string> names = A.FileNameList(args.Files);

            //! Registry: workaround: (default)
            if (Provider.ImplementingType == typeof(RegistryProvider))
            {
                for (int i = names.Count; --i >= 0;)
                {
                    if (Kit.Equals(names[i], "(default)"))
                    {
                        // remove or not
                        if (!confirm || 0 == Far.Api.Message("Delete the (default) property", Res.Delete, MessageOptions.YesNo))
                        {
                            A.Psf.Engine.InvokeProvider.Property.Remove(Kit.EscapeWildcard(ItemPath), string.Empty);
                        }

                        // remove from the list in any case
                        names.RemoveAt(i);
                        break;
                    }
                }

                // done?
                if (names.Count == 0)
                {
                    return;
                }
            }

            using (var ps = A.Psf.NewPowerShell())
            {
                ps.AddCommand("Remove-ItemProperty")
                .AddParameter("LiteralPath", ItemPath)
                .AddParameter(Word.Name, names)
                .AddParameter(Prm.Force)
                .AddParameter(Prm.ErrorAction, ActionPreference.Continue);

                if (confirm)
                {
                    ps.AddParameter(Prm.Confirm);
                }

                ps.Invoke();

                // ?? V2 CTP3 bug: Registry: Remove-ItemProperty -Confirm fails on 'No':
                // Remove-ItemProperty : Property X does not exist at path HKEY_CURRENT_USER\Y
                // There is no workaround added yet. Submitted: MS Connect #484664.
                if (ps.Streams.Error.Count > 0)
                {
                    args.Result = JobResult.Incomplete;
                    if (args.UI)
                    {
                        A.ShowError(ps);
                    }
                }
            }
        }
Пример #19
0
        /// <summary>
        /// Deletes files, heals selection.
        /// </summary>
        void UIDeleteWithRecover(DeleteFilesEventArgs args, bool redraw)
        {
            // call
            UIDeleteFiles(args);
            if (args.Result == JobResult.Ignore)
                return;

            // to recover
            bool recover = args.Result == JobResult.Incomplete && SelectionExists;

            // update, drop selection
            Update(false);

            // recover selection
            if (recover)
            {
                if (args.FilesToStay.Count > 0)
                    SelectFiles(args.FilesToStay, null);
                else
                    SelectFiles(args.Files, null);
            }

            // done
            if (redraw)
                Redraw();
        }
Пример #20
0
        /// <inheritdoc/>
        public override void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (Far.Api.Message("Remove object(s)?", Res.Remove, MessageOptions.None, new string[] { Res.Remove, Res.Cancel }) != 0)
                {
                    args.Result = JobResult.Ignore;
                    return;
                }
            }

            foreach (FarFile file in args.Files)
                Cache.Remove(file);
        }
Пример #21
0
 /// <summary>
 /// <see cref="Explorer.DeleteFiles"/> worker.
 /// </summary>
 /// <param name="args">.</param>
 public virtual void DoDeleteFiles(DeleteFilesEventArgs args)
 {
     base.DeleteFiles(args);
 }
Пример #22
0
 /// <summary>
 /// <see cref="Explorer.DeleteFiles"/> worker.
 /// </summary>
 /// <param name="args">.</param>
 public virtual void DoDeleteFiles(DeleteFilesEventArgs args)
 {
     base.DeleteFiles(args);
 }
Пример #23
0
        internal void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            BuildDeleteCommand();

            var Files = Explorer.Cache;

            if (args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete"))
            {
                if (0 != Far.Api.Message("Delete selected record(s)?", Res.Delete, MessageOptions.None, new string[] { Res.Delete, Res.Cancel }))
                    return;
            }

            ToUpdateData = true;

            foreach (var file in args.Files)
            {
                var dr = file.Data as DataRow;
                if (dr == null)
                {
                    Files.Remove(file);
                    continue;
                }

                bool ok = true;
                try
                {
                    dr.Delete();
                    ok = SaveData();
                }
                catch
                {
                    ok = false;
                    throw;
                }
                finally
                {
                    if (!ok)
                    {
                        dr.RejectChanges();
                        PostData(dr);
                    }
                }
                if (!ok)
                    break;
            }
        }
Пример #24
0
 ///
 public override void DoDeleteFiles(DeleteFilesEventArgs args)
 {
     Panel.DoDeleteFiles(args);
 }
Пример #25
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            var dicTypeId = GroupFiles(args.Files, ExplorerFunctions.DeleteFiles);

            int nDone = 0;
            int nIncomplete = 0;
            foreach (var xTypeId in dicTypeId)
            {
                Log.Source.TraceInformation("DeleteFiles TypeId='{0}'", xTypeId.Key);
                object codata = null;
                foreach (var kv in xTypeId.Value)
                {
                    var result = DeleteFilesOfExplorer(kv.Key, kv.Value, args.FilesToStay, args.Mode, args.Force, ref codata);
                    if (result == JobResult.Done)
                        ++nDone;
                    else if (result == JobResult.Incomplete)
                        ++nIncomplete;
                }
            }

            // my result
            if (nIncomplete > 0)
                args.Result = JobResult.Incomplete;
            else if (nDone == 0)
                args.Result = JobResult.Ignore;
        }
Пример #26
0
        void UICopyMoveComplete(CopyFilesEventArgs args)
        {
            // info
            bool isIncomplete = args.Result == JobResult.Incomplete;
            bool isAllToStay = isIncomplete && args.FilesToStay.Count == 0;

            // Copy: do not update the source, files are the same
            if (!args.Move)
            {
                // keep it as it is
                if (isAllToStay || !SelectionExists)
                    return;

                // drop selection
                this.UnselectAll();

                // recover
                if (isIncomplete)
                    SelectFiles(args.FilesToStay, null);

                // show
                this.Redraw();
                return;
            }

            // Move: no need to delete or all to stay or cannot delete
            if (!args.ToDeleteFiles || isAllToStay || !this.Explorer.CanDeleteFiles)
            {
                // the source may have some files deleted, update, drop selection
                this.Update(false);

                // recover selection
                if (isIncomplete)
                {
                    if (isAllToStay)
                        SelectFiles(args.Files, null);
                    else
                        SelectFiles(args.FilesToStay, null);
                }

                // show
                this.Redraw();
                return;
            }

            // Move: delete is requested, delete the source files

            // exclude files to stay
            var filesToDelete = args.Files;
            if (isIncomplete)
            {
                var filesToDelete2 = new List<FarFile>(filesToDelete);
                foreach (var file in args.FilesToStay)
                    filesToDelete2.Remove(file);
                filesToDelete = filesToDelete2;
            }

            // call
            var argsDelete = new DeleteFilesEventArgs(ExplorerModes.Silent, filesToDelete, false);
            this.UIDeleteWithRecover(argsDelete, false);
            if (isIncomplete)
                SelectFiles(args.FilesToStay, null);

            // show
            Redraw();
        }
Пример #27
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            // to ask
            bool confirm = args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete");

            // names to be deleted
            List<string> names = A.FileNameList(args.Files);

            //! Registry: workaround: (default)
            if (Provider.ImplementingType == typeof(RegistryProvider))
            {
                for (int i = names.Count; --i >= 0; )
                {
                    if (Kit.Equals(names[i], "(default)"))
                    {
                        // remove or not
                        if (!confirm || 0 == Far.Api.Message("Delete the (default) property", Res.Delete, MessageOptions.YesNo))
                            A.Psf.Engine.InvokeProvider.Property.Remove(Kit.EscapeWildcard(ItemPath), string.Empty);

                        // remove from the list in any case
                        names.RemoveAt(i);
                        break;
                    }
                }

                // done?
                if (names.Count == 0)
                    return;
            }

            using (var ps = A.Psf.NewPowerShell())
            {
                ps.AddCommand("Remove-ItemProperty")
                    .AddParameter("LiteralPath", ItemPath)
                    .AddParameter(Word.Name, names)
                    .AddParameter(Prm.Force)
                    .AddParameter(Prm.ErrorAction, ActionPreference.Continue);

                if (confirm)
                    ps.AddParameter(Prm.Confirm);

                ps.Invoke();

                // ?? V2 CTP3 bug: Registry: Remove-ItemProperty -Confirm fails on 'No':
                // Remove-ItemProperty : Property X does not exist at path HKEY_CURRENT_USER\Y
                // There is no workaround added yet. Submitted: MS Connect #484664.
                if (ps.Streams.Error.Count > 0)
                {
                    args.Result = JobResult.Incomplete;
                    if (args.UI)
                        A.ShowError(ps);
                }
            }
        }
Пример #28
0
 /// <summary>
 /// Deletes the files.
 /// </summary>
 /// <param name="args">.</param>
 public virtual void DeleteFiles(DeleteFilesEventArgs args)
 {
     if (args != null) args.Result = JobResult.Ignore;
 }
Пример #29
0
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            OperationResult or = get(args).DeleteContent(args.Files, args.Force);

            args.Result = processResult(or, args.Mode.HasFlag(ExplorerModes.Silent), args.FilesToStay);
        }
Пример #30
0
        /// <inheritdoc/>
        public override void DoDeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null) return;

            // -Confirm -Recurse
            var confirmDelete = 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete");
            var confirmDeleteFolder = 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "DeleteFolder");

            // call
            try
            {
                using (var ps = A.Psf.NewPowerShell())
                {
                    ps.AddCommand("Remove-Item")
                        .AddParameter(Prm.Force)
                        .AddParameter(Prm.ErrorAction, ActionPreference.Continue);

                    if (confirmDelete && confirmDeleteFolder)
                        ps.AddParameter(Prm.Confirm);
                    else if (confirmDelete)
                        ps.AddParameter(Prm.Confirm).AddParameter(Prm.Recurse);
                    else if (confirmDeleteFolder)
                        ps.AddParameter(Prm.Recurse);

                    ps.Invoke(args.FilesData);

                    if (ps.Streams.Error.Count > 0)
                    {
                        args.Result = JobResult.Incomplete;
                        if (args.UI)
                            A.ShowError(ps);
                    }
                }
            }
            catch
            {
                args.Result = JobResult.Incomplete;
                throw;
            }
        }