diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index f2805a80..6ae66c55 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -162,6 +162,8 @@ public class CUE4ParseViewModel : ViewModel public CriWareProvider CriWareProvider => _criWareProviderLazy?.Value; public ConcurrentBag UnknownExtensions = []; + public int ExportedCount; + public CUE4ParseViewModel() { var currentDir = UserSettings.Default.CurrentDir; @@ -1426,6 +1428,7 @@ public class CUE4ParseViewModel : ViewModel if (conversionSuccess) savedAudioPath = wavFilePath; } + Interlocked.Increment(ref ExportedCount); Log.Information("Successfully saved {FilePath}", savedAudioPath); if (updateUi && conversionSuccess) { @@ -1439,6 +1442,9 @@ public class CUE4ParseViewModel : ViewModel return; } + if (!updateUi) + return; + // TODO // since we are currently in a thread, the audio player's lifetime (memory-wise) will keep the current thread up and running until fmodel itself closes // the solution would be to kill the current thread at this line and then open the audio player without "Application.Current.Dispatcher.Invoke" @@ -1456,6 +1462,7 @@ public class CUE4ParseViewModel : ViewModel var toSaveDirectory = new DirectoryInfo(UserSettings.Default.ModelDirectory); if (toSave.TryWriteToDir(toSaveDirectory, out var label, out var savedFilePath)) { + Interlocked.Increment(ref ExportedCount); Log.Information("Successfully saved {FilePath}", savedFilePath); if (updateUi) { @@ -1489,6 +1496,7 @@ public class CUE4ParseViewModel : ViewModel } }); + Interlocked.Increment(ref ExportedCount); Log.Information("{FileName} successfully exported", entry.Name); if (updateUi) { diff --git a/FModel/ViewModels/Commands/RightClickMenuCommand.cs b/FModel/ViewModels/Commands/RightClickMenuCommand.cs index 500015ed..9b88f7a8 100644 --- a/FModel/ViewModels/Commands/RightClickMenuCommand.cs +++ b/FModel/ViewModels/Commands/RightClickMenuCommand.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Data; using System.IO; using System.Linq; using System.Threading; @@ -16,9 +17,7 @@ public class RightClickMenuCommand : ViewModelCommand { private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView; - public RightClickMenuCommand(ApplicationViewModel contextViewModel) : base(contextViewModel) - { - } + public RightClickMenuCommand(ApplicationViewModel contextViewModel) : base(contextViewModel) { } private enum EAction { @@ -47,7 +46,7 @@ public class RightClickMenuCommand : ViewModelCommand var assets = param .Select(static item => item switch { - GameFile gf => gf, + GameFile gf => gf, // Search view passes GameFile directly GameFileViewModel gvm => gvm.Asset, _ => null }) @@ -74,6 +73,7 @@ public class RightClickMenuCommand : ViewModelCommand _ => throw new ArgumentOutOfRangeException("Unsupported asset action."), }; + Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0); await _threadWorkerView.Begin(cancellationToken => { if (action is EAction.Show) @@ -126,11 +126,7 @@ public class RightClickMenuCommand : ViewModelCommand folderAction(folder); var path = Path.Combine(dirType, UserSettings.Default.KeepDirectoryStructure ? folder.PathAtThisPoint : folder.PathAtThisPoint.SubstringAfterLast('/')).Replace('\\', '/'); - FLogger.Append(ELog.Information, () => - { - FLogger.Text($"Successfully exported {filetype} from ", Constants.WHITE); - FLogger.Link(folder.PathAtThisPoint, path, true); - }); + LogExport(contextViewModel, folder.PathAtThisPoint, path, dirType, filetype); } Action fileAction = bulktype switch @@ -155,13 +151,31 @@ public class RightClickMenuCommand : ViewModelCommand if (update) { var path = Path.Combine(dirType, UserSettings.Default.KeepDirectoryStructure ? directory : directory.SubstringAfterLast('/')).Replace('\\', '/'); - FLogger.Append(ELog.Information, () => - { - FLogger.Text($"Successfully exported {list.Length} {filetype} from ", Constants.WHITE); - FLogger.Link(directory, path, true); - }); + LogExport(contextViewModel, directory, path, dirType, filetype); } } }); } + + private void LogExport(ApplicationViewModel contextViewModel, string directory, string path, string basePath, string fileType) + { + if (contextViewModel.CUE4Parse.ExportedCount > 0) + { + FLogger.Append(ELog.Information, () => + { + FLogger.Text($"Successfully exported {contextViewModel.CUE4Parse.ExportedCount} {fileType} from ", Constants.WHITE); + FLogger.Link(directory, Path.Exists(path) ? path : basePath, true); + }); + } + else + { + // Not an error because folder simply might not contain type of asset user is trying to save + FLogger.Append(ELog.Warning, () => + { + FLogger.Text($"Failed to export any {fileType} from {directory}", Constants.WHITE, true); + }); + } + + Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0); + } } diff --git a/FModel/ViewModels/TabControlViewModel.cs b/FModel/ViewModels/TabControlViewModel.cs index 9131169a..f03fcae4 100644 --- a/FModel/ViewModels/TabControlViewModel.cs +++ b/FModel/ViewModels/TabControlViewModel.cs @@ -1,6 +1,17 @@ using System; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Media.Imaging; +using CUE4Parse.FileProvider.Objects; +using CUE4Parse.UE4.Assets.Exports.Texture; +using CUE4Parse.Utils; +using CUE4Parse_Conversion.Textures; using FModel.Extensions; using FModel.Framework; +using FModel.Services; using FModel.Settings; using FModel.ViewModels.Commands; using FModel.Views.Resources.Controls; @@ -8,15 +19,6 @@ using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Highlighting; using Serilog; using SkiaSharp; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Windows; -using System.Windows.Media.Imaging; -using CUE4Parse.UE4.Assets.Exports.Texture; -using CUE4Parse_Conversion.Textures; -using CUE4Parse.FileProvider.Objects; -using CUE4Parse.Utils; namespace FModel.ViewModels; @@ -412,6 +414,7 @@ public class TabItem : ViewModel { if (File.Exists(path)) { + Interlocked.Increment(ref ApplicationService.ApplicationView.CUE4Parse.ExportedCount); Log.Information("{FileName} successfully saved", fileName); if (updateUi) {