diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index 5074460d..191079d2 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -175,6 +175,9 @@ public partial class MainWindow if (AssetsFolderName.SelectedItem is TreeItem folder) { await _threadWorkerView.Begin(cancellationToken => { _applicationView.CUE4Parse.ExportFolder(cancellationToken, folder); }); + FLogger.AppendInformation(); + FLogger.AppendText("Successfully exported ", Constants.WHITE); + FLogger.AppendLink(folder.PathAtThisPoint, UserSettings.Default.RawDataDirectory, true); } } diff --git a/FModel/ViewModels/AudioPlayerViewModel.cs b/FModel/ViewModels/AudioPlayerViewModel.cs index eab9f342..5befa872 100644 --- a/FModel/ViewModels/AudioPlayerViewModel.cs +++ b/FModel/ViewModels/AudioPlayerViewModel.cs @@ -329,7 +329,8 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable { Log.Information("{FileName} successfully saved", fileToSave.FileName); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully saved '{fileToSave.FileName}'", Constants.WHITE, true); + FLogger.AppendText("Successfully saved ", Constants.WHITE); + FLogger.AppendLink(fileToSave.FileName, path, true); } else { diff --git a/FModel/ViewModels/BackupManagerViewModel.cs b/FModel/ViewModels/BackupManagerViewModel.cs index bef4da3b..a9c5b983 100644 --- a/FModel/ViewModels/BackupManagerViewModel.cs +++ b/FModel/ViewModels/BackupManagerViewModel.cs @@ -104,7 +104,8 @@ public class BackupManagerViewModel : ViewModel { Log.Information("{FileName} successfully {Type}", fileName, type1); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully {type1} '{fileName}'", Constants.WHITE, true); + FLogger.AppendText($"Successfully {type1} ", Constants.WHITE); + FLogger.AppendLink(fileName, fullPath, true); } else { @@ -113,4 +114,4 @@ public class BackupManagerViewModel : ViewModel FLogger.AppendText($"Could not {type2} '{fileName}'", Constants.WHITE, true); } } -} \ No newline at end of file +} diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 589f10e4..8a6c1056 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -897,7 +897,8 @@ public class CUE4ParseViewModel : ViewModel { Log.Information("Successfully saved {FilePath}", savedFilePath); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully saved {label}", Constants.WHITE, true); + FLogger.AppendText("Successfully saved ", Constants.WHITE); + FLogger.AppendLink(label, savedFilePath, true); } else { @@ -912,9 +913,10 @@ public class CUE4ParseViewModel : ViewModel var fileName = fullPath.SubstringAfterLast('/'); if (Provider.TrySavePackage(fullPath, out var assets)) { + string path = UserSettings.Default.RawDataDirectory; Parallel.ForEach(assets, kvp => { - var path = Path.Combine(UserSettings.Default.RawDataDirectory, UserSettings.Default.KeepDirectoryStructure ? kvp.Key : kvp.Key.SubstringAfterLast('/')).Replace('\\', '/'); + path = Path.Combine(path, UserSettings.Default.KeepDirectoryStructure ? kvp.Key : kvp.Key.SubstringAfterLast('/')).Replace('\\', '/'); Directory.CreateDirectory(path.SubstringBeforeLast('/')); File.WriteAllBytes(path, kvp.Value); }); @@ -923,9 +925,9 @@ public class CUE4ParseViewModel : ViewModel { Log.Information("{FileName} successfully exported", fileName); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully exported '{fileName}'", Constants.WHITE, true); + FLogger.AppendText("Successfully exported ", Constants.WHITE); + FLogger.AppendLink(fileName, path, true); } - else ApplicationService.ApplicationView.Status.UpdateStatusLabel($"Raw Data for {fullPath.SubstringAfterLast('/')}"); } else if (updateUi) { diff --git a/FModel/ViewModels/TabControlViewModel.cs b/FModel/ViewModels/TabControlViewModel.cs index f768d4e1..440b42a4 100644 --- a/FModel/ViewModels/TabControlViewModel.cs +++ b/FModel/ViewModels/TabControlViewModel.cs @@ -379,7 +379,8 @@ public class TabItem : ViewModel { Log.Information("{FileName} successfully saved", fileName); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully saved '{fileName}'", Constants.WHITE, true); + FLogger.AppendText("Successfully saved ", Constants.WHITE); + FLogger.AppendLink(fileName, path, true); } else { diff --git a/FModel/Views/ImageMerger.xaml.cs b/FModel/Views/ImageMerger.xaml.cs index 7bc5def0..f6175aec 100644 --- a/FModel/Views/ImageMerger.xaml.cs +++ b/FModel/Views/ImageMerger.xaml.cs @@ -280,7 +280,8 @@ public partial class ImageMerger { Log.Information("{FileName} successfully saved", fileName); FLogger.AppendInformation(); - FLogger.AppendText($"Successfully saved '{fileName}'", Constants.WHITE, true); + FLogger.AppendText("Successfully saved ", Constants.WHITE); + FLogger.AppendLink(fileName, path, true); } else { @@ -294,4 +295,4 @@ public partial class ImageMerger { ClipboardExtensions.SetImage(_imageBuffer, FILENAME); } -} \ No newline at end of file +} diff --git a/FModel/Views/Resources/Controls/Rtb/CustomRichTextBox.cs b/FModel/Views/Resources/Controls/Rtb/CustomRichTextBox.cs index cc5faaa1..26e334bb 100644 --- a/FModel/Views/Resources/Controls/Rtb/CustomRichTextBox.cs +++ b/FModel/Views/Resources/Controls/Rtb/CustomRichTextBox.cs @@ -1,8 +1,10 @@ using System; +using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; +using System.Windows.Input; using System.Windows.Media; namespace FModel.Views.Resources.Controls; @@ -46,6 +48,33 @@ public class FLogger : ITextFormatter }); } + public static void AppendLink(string message, string url, bool newLine = false) + { + Application.Current.Dispatcher.Invoke(delegate + { + var link = new Hyperlink(new Run(newLine ? $"{message}{Environment.NewLine}" : message), Logger.Document.ContentEnd) + { + NavigateUri = new Uri(url), + OverridesDefaultStyle = true, + Style = new Style(typeof(Hyperlink)) { Setters = + { + new Setter(FrameworkContentElement.CursorProperty, Cursors.Hand), + new Setter(TextBlock.TextDecorationsProperty, TextDecorations.Underline), + new Setter(TextElement.ForegroundProperty, Brushes.Cornsilk) + }} + }; + + try + { + link.Click += (sender, _) => Process.Start("explorer.exe", $"/select, \"{((Hyperlink)sender).NavigateUri.AbsoluteUri}\""); + } + finally + { + Logger.ScrollToEnd(); + } + }); + } + public string GetText(FlowDocument document) { return new TextRange(document.ContentStart, document.ContentEnd).Text; @@ -168,4 +197,4 @@ public class CustomRichTextBox : RichTextBox UpdateTextFromDocument(); } } -} \ No newline at end of file +} diff --git a/FModel/Views/Resources/Resources.xaml b/FModel/Views/Resources/Resources.xaml index bd11345e..3d03acd8 100644 --- a/FModel/Views/Resources/Resources.xaml +++ b/FModel/Views/Resources/Resources.xaml @@ -1367,6 +1367,7 @@