mirror of
https://github.com/4sval/FModel.git
synced 2026-08-28 20:35:04 -05:00
improved CustomRichTextBox + updateUi parameter to speed up savings
This commit is contained in:
Submodule CUE4Parse updated: cfdd02fc0a...04239c2e1f
@@ -191,6 +191,9 @@ public partial class MainWindow
|
||||
if (AssetsFolderName.SelectedItem is TreeItem folder)
|
||||
{
|
||||
await _threadWorkerView.Begin(cancellationToken => { _applicationView.CUE4Parse.SaveFolder(cancellationToken, folder); });
|
||||
FLogger.AppendInformation();
|
||||
FLogger.AppendText("Successfully saved ", Constants.WHITE);
|
||||
FLogger.AppendLink(folder.PathAtThisPoint, UserSettings.Default.PropertiesDirectory, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +202,9 @@ public partial class MainWindow
|
||||
if (AssetsFolderName.SelectedItem is TreeItem folder)
|
||||
{
|
||||
await _threadWorkerView.Begin(cancellationToken => { _applicationView.CUE4Parse.TextureFolder(cancellationToken, folder); });
|
||||
FLogger.AppendInformation();
|
||||
FLogger.AppendText("Successfully saved ", Constants.WHITE);
|
||||
FLogger.AppendLink(folder.PathAtThisPoint, UserSettings.Default.TextureDirectory, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ public class FModelApiEndpoint : AbstractApiProvider
|
||||
|
||||
_applicationView.CUE4Parse.TabControl.AddTab($"Release Notes: {args.CurrentVersion}");
|
||||
_applicationView.CUE4Parse.TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("changelog");
|
||||
_applicationView.CUE4Parse.TabControl.SelectedTab.SetDocumentText(response.Content, false);
|
||||
_applicationView.CUE4Parse.TabControl.SelectedTab.SetDocumentText(response.Content, false, false);
|
||||
UserSettings.Default.ShowChangelog = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,8 +578,9 @@ public class CUE4ParseViewModel : ViewModel
|
||||
TabControl.SelectedTab.Directory = directory;
|
||||
}
|
||||
|
||||
var autoProperties = bulk == (EBulkType.Properties | EBulkType.Auto);
|
||||
var autoTextures = bulk == (EBulkType.Textures | EBulkType.Auto);
|
||||
var updateUi = !HasFlag(bulk, EBulkType.Auto);
|
||||
var saveProperties = HasFlag(bulk, EBulkType.Properties);
|
||||
var saveTextures = HasFlag(bulk, EBulkType.Textures);
|
||||
TabControl.SelectedTab.ClearImages();
|
||||
TabControl.SelectedTab.ResetDocumentText();
|
||||
TabControl.SelectedTab.ScrollTrigger = null;
|
||||
@@ -590,7 +591,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
case "umap":
|
||||
{
|
||||
var exports = Provider.LoadObjectExports(fullPath); // cancellationToken
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), saveProperties, updateUi);
|
||||
if (HasFlag(bulk, EBulkType.Properties)) break; // do not search for viewable exports if we are dealing with jsons
|
||||
|
||||
foreach (var e in exports)
|
||||
@@ -633,7 +634,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
using var stream = new MemoryStream(data) { Position = 0 };
|
||||
using var reader = new StreamReader(stream);
|
||||
|
||||
TabControl.SelectedTab.SetDocumentText(reader.ReadToEnd(), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(reader.ReadToEnd(), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -643,7 +644,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var metadata = new FTextLocalizationMetaDataResource(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(metadata, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(metadata, Formatting.Indented), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -653,7 +654,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var locres = new FTextLocalizationResource(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(locres, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(locres, Formatting.Indented), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -663,7 +664,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var registry = new FAssetRegistryState(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(registry, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(registry, Formatting.Indented), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -674,7 +675,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var wwise = new WwiseReader(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(wwise, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(wwise, Formatting.Indented), saveProperties, updateUi);
|
||||
foreach (var (name, data) in wwise.WwiseEncodedMedias)
|
||||
{
|
||||
SaveAndPlaySound(fullPath.SubstringBeforeWithLast("/") + name, "WEM", data);
|
||||
@@ -695,7 +696,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var header = new FOodleDictionaryArchive(archive).Header;
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(header, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(header, Formatting.Indented), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -707,7 +708,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TrySaveAsset(fullPath, out var data))
|
||||
{
|
||||
using var stream = new MemoryStream(data) { Position = 0 };
|
||||
TabControl.SelectedTab.AddImage(fileName.SubstringBeforeLast("."), false, SKBitmap.Decode(stream), autoTextures);
|
||||
TabControl.SelectedTab.AddImage(fileName.SubstringBeforeLast("."), false, SKBitmap.Decode(stream), saveTextures, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -727,7 +728,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
canvas.DrawPicture(svg.Picture, paint);
|
||||
}
|
||||
|
||||
TabControl.SelectedTab.AddImage(fileName.SubstringBeforeLast("."), false, bitmap, autoTextures);
|
||||
TabControl.SelectedTab.AddImage(fileName.SubstringBeforeLast("."), false, bitmap, saveTextures, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -744,7 +745,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var ar = new FShaderCodeArchive(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(ar, Formatting.Indented), autoProperties);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(ar, Formatting.Indented), saveProperties, updateUi);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -766,7 +767,7 @@ public class CUE4ParseViewModel : ViewModel
|
||||
|
||||
var exports = Provider.LoadObjectExports(fullPath); // cancellationToken
|
||||
TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector(""); // json
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), false);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), false, false);
|
||||
|
||||
foreach (var e in exports)
|
||||
{
|
||||
@@ -778,7 +779,8 @@ public class CUE4ParseViewModel : ViewModel
|
||||
private bool CheckExport(CancellationToken cancellationToken, UObject export, EBulkType bulk = EBulkType.None) // return true once you wanna stop searching for exports
|
||||
{
|
||||
var isNone = bulk == EBulkType.None;
|
||||
var loadTextures = isNone || HasFlag(bulk, EBulkType.Textures);
|
||||
var updateUi = !HasFlag(bulk, EBulkType.Auto);
|
||||
var saveTextures = HasFlag(bulk, EBulkType.Textures);
|
||||
switch (export)
|
||||
{
|
||||
case USolarisDigest solarisDigest when isNone:
|
||||
@@ -787,12 +789,12 @@ public class CUE4ParseViewModel : ViewModel
|
||||
|
||||
TabControl.AddTab($"{solarisDigest.ProjectName}.verse");
|
||||
TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("verse");
|
||||
TabControl.SelectedTab.SetDocumentText(solarisDigest.ReadableCode, false);
|
||||
TabControl.SelectedTab.SetDocumentText(solarisDigest.ReadableCode, false, false);
|
||||
return true;
|
||||
}
|
||||
case UTexture2D { IsVirtual: false } texture when loadTextures:
|
||||
case UTexture2D { IsVirtual: false } texture when isNone:
|
||||
{
|
||||
TabControl.SelectedTab.AddImage(texture, HasFlag(bulk, EBulkType.Auto));
|
||||
TabControl.SelectedTab.AddImage(texture, saveTextures, updateUi);
|
||||
return false;
|
||||
}
|
||||
case UAkMediaAssetData when isNone:
|
||||
@@ -845,16 +847,16 @@ public class CUE4ParseViewModel : ViewModel
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (!loadTextures)
|
||||
return false;
|
||||
if (!isNone && !saveTextures) return false;
|
||||
|
||||
using var package = new CreatorPackage(export, UserSettings.Default.CosmeticStyle);
|
||||
if (!package.TryConstructCreator(out var creator))
|
||||
return false;
|
||||
|
||||
creator.ParseForInfo();
|
||||
TabControl.SelectedTab.AddImage(export.Name, false, creator.Draw(), HasFlag(bulk, EBulkType.Auto));
|
||||
TabControl.SelectedTab.AddImage(export.Name, false, creator.Draw(), saveTextures, updateUi);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,19 +945,22 @@ public class CUE4ParseViewModel : ViewModel
|
||||
}
|
||||
});
|
||||
|
||||
Log.Information("{FileName} successfully exported", fileName);
|
||||
if (updateUi)
|
||||
{
|
||||
Log.Information("{FileName} successfully exported", fileName);
|
||||
FLogger.AppendInformation();
|
||||
FLogger.AppendText("Successfully exported ", Constants.WHITE);
|
||||
FLogger.AppendLink(fileName, path, true);
|
||||
}
|
||||
}
|
||||
else if (updateUi)
|
||||
else
|
||||
{
|
||||
Log.Error("{FileName} could not be exported", fileName);
|
||||
FLogger.AppendError();
|
||||
FLogger.AppendText($"Could not export '{fileName}'", Constants.WHITE, true);
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.AppendError();
|
||||
FLogger.AppendText($"Could not export '{fileName}'", Constants.WHITE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
|
||||
case "Directory_ArchivesInfo":
|
||||
contextViewModel.CUE4Parse.TabControl.AddTab("Archives Info");
|
||||
contextViewModel.CUE4Parse.TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("json");
|
||||
contextViewModel.CUE4Parse.TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(contextViewModel.CUE4Parse.GameDirectory.DirectoryFiles, Formatting.Indented), false);
|
||||
contextViewModel.CUE4Parse.TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(contextViewModel.CUE4Parse.GameDirectory.DirectoryFiles, Formatting.Indented), false, false);
|
||||
break;
|
||||
case "Views_3dViewer":
|
||||
contextViewModel.CUE4Parse.SnooperViewer.Run();
|
||||
|
||||
@@ -43,14 +43,14 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
|
||||
foreach (var asset in assetItems)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Properties | EBulkType.Auto);
|
||||
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Properties);
|
||||
}
|
||||
break;
|
||||
case "Assets_Save_Textures":
|
||||
foreach (var asset in assetItems)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Textures | EBulkType.Auto);
|
||||
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Textures);
|
||||
}
|
||||
break;
|
||||
case "Assets_Save_Models":
|
||||
|
||||
@@ -37,13 +37,13 @@ public class TabCommand : ViewModelCommand<TabItem>
|
||||
case "Asset_Save_Properties":
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.FullPath, false, EBulkType.Properties | EBulkType.Auto);
|
||||
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.FullPath, false, EBulkType.Properties);
|
||||
});
|
||||
break;
|
||||
case "Asset_Save_Textures":
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.FullPath, false, EBulkType.Textures | EBulkType.Auto);
|
||||
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.FullPath, false, EBulkType.Textures);
|
||||
});
|
||||
break;
|
||||
case "Asset_Save_Models":
|
||||
|
||||
@@ -230,21 +230,21 @@ public class TabItem : ViewModel
|
||||
});
|
||||
}
|
||||
|
||||
public void AddImage(UTexture2D texture, bool bulkTexture)
|
||||
=> AddImage(texture.Name, texture.bRenderNearestNeighbor, texture.Decode(UserSettings.Default.OverridedPlatform), bulkTexture);
|
||||
public void AddImage(UTexture2D texture, bool save, bool updateUi)
|
||||
=> AddImage(texture.Name, texture.bRenderNearestNeighbor, texture.Decode(UserSettings.Default.OverridedPlatform), save, updateUi);
|
||||
|
||||
public void AddImage(string name, bool rnn, SKBitmap[] img, bool bulkTexture)
|
||||
public void AddImage(string name, bool rnn, SKBitmap[] img, bool save, bool updateUi)
|
||||
{
|
||||
foreach (var i in img) AddImage(name, rnn, i, bulkTexture);
|
||||
foreach (var i in img) AddImage(name, rnn, i, save, updateUi);
|
||||
}
|
||||
|
||||
public void AddImage(string name, bool rnn, SKBitmap img, bool bulkTexture)
|
||||
public void AddImage(string name, bool rnn, SKBitmap img, bool save, bool updateUi)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var t = new TabImage(name, rnn, img);
|
||||
if (bulkTexture)
|
||||
SaveImage(t);
|
||||
if (save) SaveImage(t, updateUi);
|
||||
if (!updateUi) return;
|
||||
|
||||
_images.Add(t);
|
||||
SelectedImage ??= t;
|
||||
@@ -256,15 +256,14 @@ public class TabItem : ViewModel
|
||||
public void GoPreviousImage() => SelectedImage = _images.Previous(SelectedImage);
|
||||
public void GoNextImage() => SelectedImage = _images.Next(SelectedImage);
|
||||
|
||||
public void SetDocumentText(string text, bool bulkSave)
|
||||
public void SetDocumentText(string text, bool save, bool updateUi)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Document ??= new TextDocument();
|
||||
Document.Text = text;
|
||||
|
||||
if (bulkSave)
|
||||
SaveProperty();
|
||||
if (save) SaveProperty(updateUi);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -277,30 +276,8 @@ public class TabItem : ViewModel
|
||||
});
|
||||
}
|
||||
|
||||
public void SaveImages()
|
||||
{
|
||||
switch (_images.Count)
|
||||
{
|
||||
case 1:
|
||||
SaveImage();
|
||||
break;
|
||||
case > 1:
|
||||
var directory = Path.Combine(UserSettings.Default.TextureDirectory,
|
||||
UserSettings.Default.KeepDirectoryStructure ? Directory : "").Replace('\\', '/');
|
||||
System.IO.Directory.CreateDirectory(directory);
|
||||
|
||||
foreach (var image in _images)
|
||||
{
|
||||
if (image == null) return;
|
||||
var fileName = $"{image.ExportName}.png";
|
||||
SaveImage(image, Path.Combine(directory, fileName), fileName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveImage() => SaveImage(SelectedImage);
|
||||
private void SaveImage(TabImage image)
|
||||
public void SaveImage() => SaveImage(SelectedImage, true);
|
||||
private void SaveImage(TabImage image, bool updateUi)
|
||||
{
|
||||
if (image == null) return;
|
||||
var fileName = $"{image.ExportName}.png";
|
||||
@@ -309,13 +286,13 @@ public class TabItem : ViewModel
|
||||
|
||||
System.IO.Directory.CreateDirectory(path.SubstringBeforeLast('/'));
|
||||
|
||||
SaveImage(image, path, fileName);
|
||||
SaveImage(image, path, fileName, updateUi);
|
||||
}
|
||||
|
||||
private void SaveImage(TabImage image, string path, string fileName)
|
||||
private void SaveImage(TabImage image, string path, string fileName, bool updateUi)
|
||||
{
|
||||
SaveImage(image, path);
|
||||
SaveCheck(path, fileName);
|
||||
SaveCheck(path, fileName, updateUi);
|
||||
}
|
||||
|
||||
private void SaveImage(TabImage image, string path)
|
||||
@@ -324,7 +301,7 @@ public class TabItem : ViewModel
|
||||
fs.Write(image.ImageBuffer, 0, image.ImageBuffer.Length);
|
||||
}
|
||||
|
||||
public void SaveProperty()
|
||||
public void SaveProperty(bool updateUi)
|
||||
{
|
||||
var fileName = Path.ChangeExtension(Header, ".json");
|
||||
var directory = Path.Combine(UserSettings.Default.PropertiesDirectory,
|
||||
@@ -333,23 +310,29 @@ public class TabItem : ViewModel
|
||||
System.IO.Directory.CreateDirectory(directory.SubstringBeforeLast('/'));
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() => File.WriteAllText(directory, Document.Text));
|
||||
SaveCheck(directory, fileName);
|
||||
SaveCheck(directory, fileName, updateUi);
|
||||
}
|
||||
|
||||
private void SaveCheck(string path, string fileName)
|
||||
private void SaveCheck(string path, string fileName, bool updateUi)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Log.Information("{FileName} successfully saved", fileName);
|
||||
FLogger.AppendInformation();
|
||||
FLogger.AppendText("Successfully saved ", Constants.WHITE);
|
||||
FLogger.AppendLink(fileName, path, true);
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.AppendInformation();
|
||||
FLogger.AppendText("Successfully saved ", Constants.WHITE);
|
||||
FLogger.AppendLink(fileName, path, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("{FileName} could not be saved", fileName);
|
||||
FLogger.AppendError();
|
||||
FLogger.AppendText($"Could not save '{fileName}'", Constants.WHITE, true);
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.AppendError();
|
||||
FLogger.AppendText($"Could not save '{fileName}'", Constants.WHITE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public class FLogger : ITextFormatter
|
||||
{
|
||||
public static CustomRichTextBox Logger;
|
||||
private static readonly BrushConverter _brushConverter = new();
|
||||
private static int _previous;
|
||||
|
||||
public static void AppendInformation() => AppendText("[INF] ", Constants.BLUE);
|
||||
public static void AppendWarning() => AppendText("[WRN] ", Constants.YELLOW);
|
||||
@@ -32,18 +33,17 @@ public class FLogger : ITextFormatter
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
{
|
||||
var textRange = new TextRange(Logger.Document.ContentEnd, Logger.Document.ContentEnd)
|
||||
{
|
||||
Text = newLine ? $"{message}{Environment.NewLine}" : message
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, _brushConverter.ConvertFromString(color));
|
||||
Logger.Document.ContentEnd.InsertTextInRun(message);
|
||||
if (newLine) Logger.Document.ContentEnd.InsertLineBreak();
|
||||
|
||||
Logger.Selection.Select(Logger.Document.ContentStart.GetPositionAtOffset(_previous), Logger.Document.ContentEnd);
|
||||
Logger.Selection.ApplyPropertyValue(TextElement.ForegroundProperty, _brushConverter.ConvertFromString(color));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Logger.ScrollToEnd();
|
||||
Finally();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -52,29 +52,33 @@ public class FLogger : ITextFormatter
|
||||
{
|
||||
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}\"");
|
||||
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)
|
||||
}}
|
||||
}.Click += (sender, _) => Process.Start("explorer.exe", $"/select, \"{((Hyperlink)sender).NavigateUri.AbsoluteUri}\"");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Logger.ScrollToEnd();
|
||||
Finally();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void Finally()
|
||||
{
|
||||
Logger.ScrollToEnd();
|
||||
_previous = Math.Abs(Logger.Document.ContentEnd.GetOffsetToPosition(Logger.Document.ContentStart)) - 2;
|
||||
}
|
||||
|
||||
public string GetText(FlowDocument document)
|
||||
{
|
||||
return new TextRange(document.ContentStart, document.ContentEnd).Text;
|
||||
|
||||
Reference in New Issue
Block a user