diff --git a/src/MayShow.Shared/Helpers/PDFFontResolver.cs b/src/MayShow.Shared/Helpers/PDFFontResolver.cs new file mode 100644 index 0000000..40cde71 --- /dev/null +++ b/src/MayShow.Shared/Helpers/PDFFontResolver.cs @@ -0,0 +1,82 @@ + +using System.IO; +using MayShow.Interfaces; +using PdfSharp.Fonts; + +namespace MayShow.Helpers; + +class PDFFontResolver : IFontResolver +{ + private string _runningProcessDirectory; + private ILogger? _logger; + + public PDFFontResolver(string runningProcessDirectory, ILogger? logger) + { + _logger = logger; + _runningProcessDirectory = runningProcessDirectory; + } + + public byte[]? GetFont(string faceName) + { + _logger?.LogInfo(string.Format("Loading font {0}", faceName)); + if (faceName == "Noto Sans") + { + var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf"); + if (!File.Exists(path)) + { + path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf"); + } + return File.ReadAllBytes(path); + } + if (faceName == "Noto Sans Bold") + { + var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf"); + if (!File.Exists(path)) + { + path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf"); + } + return File.ReadAllBytes(path); + } + if (faceName == "Noto Sans JP") + { + var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); + if (!File.Exists(path)) + { + path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); + } + return File.ReadAllBytes(path); + } + if (faceName == "Noto Sans JP Bold") + { + var path = Path.Combine(_runningProcessDirectory, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf"); + if (!File.Exists(path)) + { + path = Path.Combine(_runningProcessDirectory, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf"); + } + return File.ReadAllBytes(path); + } + return null; + } + + public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic) + { + // LogInfo(string.Format("Resolving font name {0}", familyName)); + if (familyName == "Noto Sans") + { + if (bold) + { + return new FontResolverInfo(familyName + " Bold"); + } + return new FontResolverInfo(familyName); + } + if (familyName == "Noto Sans JP") + { + if (bold) + { + return new FontResolverInfo(familyName + " Bold"); + } + return new FontResolverInfo(familyName); + } + return null; + } +} \ No newline at end of file diff --git a/src/MayShow.Shared/Interfaces/ILogger.cs b/src/MayShow.Shared/Interfaces/ILogger.cs new file mode 100644 index 0000000..595a557 --- /dev/null +++ b/src/MayShow.Shared/Interfaces/ILogger.cs @@ -0,0 +1,6 @@ +namespace MayShow.Interfaces; + +interface ILogger +{ + void LogInfo(string message, params object[]? arguments); +} \ No newline at end of file diff --git a/src/MayShow.Shared/ViewModels/CreatePDFReportViewModel.cs b/src/MayShow.Shared/ViewModels/CreatePDFReportViewModel.cs index 440dbd7..ce7e07b 100644 --- a/src/MayShow.Shared/ViewModels/CreatePDFReportViewModel.cs +++ b/src/MayShow.Shared/ViewModels/CreatePDFReportViewModel.cs @@ -32,7 +32,7 @@ using MigraDoc.DocumentObjectModel.Visitors; namespace MayShow.ViewModels; -class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown +class CreatePDFReportViewModel : BaseViewModel, ICanCheckShutdown, ILogger { private bool _isPerformingInitialLoad; private string _processDir; @@ -173,7 +173,7 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown } } - private void LogInfo(string message, params object[]? arguments) + public void LogInfo(string message, params object[]? arguments) { var timestamp = string.Format("[{0:s}]", DateTime.Now); Console.WriteLine(timestamp + " " + message, arguments); @@ -409,7 +409,11 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown public async void RemoveAllItems() { - var result = await DialogHost.Show(new ConfirmViewModel("Warning!", "Are you sure you want to remove all items from this report?", "Remove All Items", "Cancel")); + var result = await DialogHost.Show(new ConfirmViewModel("Warning!", "Are you sure you want to remove all items from this report?", "Remove All Items", "Cancel") + { + ConfirmButtonUsesDangerStyle = true, + ConfirmTitleIcon = "\uf1f8;" + }); if (result != null && (bool)result) { ReportFiles.Clear(); @@ -574,70 +578,6 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown } } - public byte[]? GetFont(string faceName) - { - LogInfo(string.Format("Loading font {0}", faceName)); - if (faceName == "Noto Sans") - { - var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf"); - if (!File.Exists(path)) - { - path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Regular.ttf"); - } - return File.ReadAllBytes(path); - } - if (faceName == "Noto Sans Bold") - { - var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf"); - if (!File.Exists(path)) - { - path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans/static/NotoSans-Bold.ttf"); - } - return File.ReadAllBytes(path); - } - if (faceName == "Noto Sans JP") - { - var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); - if (!File.Exists(path)) - { - path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); - } - return File.ReadAllBytes(path); - } - if (faceName == "Noto Sans JP Bold") - { - var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf"); - if (!File.Exists(path)) - { - path = Path.Combine(_processDir, "../Resources/Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-SemiBold.ttf"); - } - return File.ReadAllBytes(path); - } - return null; - } - - public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic) - { - // LogInfo(string.Format("Resolving font name {0}", familyName)); - if (familyName == "Noto Sans") - { - if (bold) - { - return new FontResolverInfo(familyName + " Bold"); - } - return new FontResolverInfo(familyName); - } - if (familyName == "Noto Sans JP") - { - if (bold) - { - return new FontResolverInfo(familyName + " Bold"); - } - return new FontResolverInfo(familyName); - } - return null; - } - private Paragraph GetFooterParagraph() { var footerPar = new Paragraph(); @@ -678,7 +618,6 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown // https://forum.pdfsharp.net/viewtopic.php?f=2&t=1025 private async Task CreatePDF(string folderPath) { - // TODO: calculate needed width for images based on page width and margins and all that? // safety checks var outputDir = _settings.SaveOutputPdfInWorkingDir ? folderPath : _settings.OutputPdfDir; if (!Directory.Exists(outputDir)) @@ -687,7 +626,7 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown return; } // setup globals and consts... - GlobalFontSettings.FontResolver = this; + GlobalFontSettings.FontResolver = new PDFFontResolver(_processDir, this); GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver(); const decimal pageWidth = 8.5m; const decimal pageHeight = 11.0m; diff --git a/src/MayShow.Shared/ViewModels/StartNewChooseReportViewModel.cs b/src/MayShow.Shared/ViewModels/StartNewChooseReportViewModel.cs index 3e271c4..89c0684 100644 --- a/src/MayShow.Shared/ViewModels/StartNewChooseReportViewModel.cs +++ b/src/MayShow.Shared/ViewModels/StartNewChooseReportViewModel.cs @@ -8,6 +8,7 @@ using MayShow.Interfaces; using MayShow.Models; using MayShow.Helpers; using MayShows.Helpers; +using System; namespace MayShow.ViewModels; @@ -46,9 +47,10 @@ class StartNewChooseReportViewModel : BaseViewModel var reportInfo = new PDFReportInfo() { Title = CreatingReportTitle, + LastSaved = DateTime.Now }; _settings.AllReportInfo.Add(reportInfo); - // ... this sort is slow, technically, but we're not going to have millions of items here, so... + // ... this sort and save is slow, technically, but we're not going to have millions of items here, so... SavedReports = new ObservableCollection(_settings.AllReportInfo.OrderBy(x => x.Title)); await _settings.SaveSettingsAsync(); // create folder for report data @@ -67,7 +69,6 @@ class StartNewChooseReportViewModel : BaseViewModel CreatingReportTitle = ""; // when user comes back they can start another new report } - public void LoadExistingReport(object info) => LoadExistingReportImpl((PDFReportInfo) info); public void LoadExistingReportImpl(PDFReportInfo reportInfo) {