WIP: Add iOS version #10

Draft
Deadpikle wants to merge 67 commits from feature/ios into main
10 changed files with 233 additions and 54 deletions
Showing only changes of commit e71de9016e - Show all commits
+1 -1
View File
@@ -3,7 +3,7 @@
; Non-commercial use only ; Non-commercial use only
#define MyAppName "MayShow" #define MyAppName "MayShow"
#define MyAppVersion "1.4.0" #define MyAppVersion "1.4.2"
#define MyAppPublisher "Quickity Quack Productions" #define MyAppPublisher "Quickity Quack Productions"
#define MyAppExeName "MayShow.exe" #define MyAppExeName "MayShow.exe"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION="1.4.0" VERSION="1.4.2"
SRC_DIR="src" # user ran script from main folder SRC_DIR="src" # user ran script from main folder
if [ ! -d "$SRC_DIR" ]; then if [ ! -d "$SRC_DIR" ]; then
SRC_DIR= "../src" # try SRC_DIR= "../src" # try
+1 -1
View File
@@ -3,7 +3,7 @@
<!-- This manifest is used on Windows only. <!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls. Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests --> For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.4.0.0" name="MayShow.Desktop"/> <assemblyIdentity version="1.4.2.0" name="MayShow.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application> <application>
+1 -1
View File
@@ -3,7 +3,7 @@ namespace MayShow.Helpers;
class Constants class Constants
{ {
public static string AppVersion = "1.4.0"; public static string AppVersion = "1.4.2";
public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ]; public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ];
public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ]; public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ];
+22 -9
View File
@@ -1,10 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Tmds.DBus.Protocol;
namespace MayShows.Helpers; namespace MayShows.Helpers;
@@ -23,16 +25,27 @@ class Utilities
public static DateOnly? CheckValidDateInString(string str) public static DateOnly? CheckValidDateInString(string str)
{ {
// https://stackoverflow.com/a/14918404/3938401 // https://stackoverflow.com/a/14918404/3938401
var rgx = new Regex(@"\d{4}-\d{2}-\d{2}"); // formats = regex format -> DateTime parsing format
var mat = rgx.Match(str); var formats = new Dictionary<string, string>
if (mat.Success)
{ {
var dtStr = mat.ToString(); {@"\d{4}-\d{2}-\d{2}", "yyyy-MM-dd"},
string[] formats = ["yyyy-MM-dd"]; {@"\d{4}.d{2}.d{2}", "yyyy.MM.dd"},
DateTime parsedDateTime; {@"\d{8}", "yyyyMMdd"}
var didWork = DateTime.TryParseExact(dtStr, formats, CultureInfo.InvariantCulture, };
DateTimeStyles.None, out parsedDateTime); foreach (var data in formats)
return didWork ? DateOnly.FromDateTime(parsedDateTime) : null; {
var rgx = new Regex(data.Key);
var mat = rgx.Match(str);
if (mat.Success)
{
var dtStr = mat.ToString();
var didWork = DateTime.TryParseExact(dtStr, [data.Value], CultureInfo.InvariantCulture,
DateTimeStyles.None, out var parsedDateTime);
if (didWork)
{
return DateOnly.FromDateTime(parsedDateTime);
}
}
} }
return null; return null;
} }
+1 -1
View File
@@ -60,7 +60,7 @@
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets> <PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="PDFsharp-MigraDoc" Version="6.2.4" /> <PackageReference Include="PDFsharp-MigraDoc" Version="6.2.4" />
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.10.3" /> <PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.10.4" />
<PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" /> <PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" />
<PackageReference Include="DialogHost.Avalonia" Version="0.10.4" /> <PackageReference Include="DialogHost.Avalonia" Version="0.10.4" />
<PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" /> <PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" />
@@ -28,6 +28,7 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using Docnet.Core.Readers; using Docnet.Core.Readers;
using MigraDoc.DocumentObjectModel.Visitors;
namespace MayShow.ViewModels; namespace MayShow.ViewModels;
@@ -576,6 +577,24 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public byte[]? GetFont(string faceName) public byte[]? GetFont(string faceName)
{ {
LogInfo(string.Format("Loading font {0}", 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") if (faceName == "Noto Sans JP")
{ {
var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf"); var path = Path.Combine(_processDir, "Assets/Fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf");
@@ -600,6 +619,14 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic) public FontResolverInfo? ResolveTypeface(string familyName, bool bold, bool italic)
{ {
// LogInfo(string.Format("Resolving font name {0}", familyName)); // 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 (familyName == "Noto Sans JP")
{ {
if (bold) if (bold)
@@ -611,6 +638,43 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
return null; return null;
} }
private Paragraph GetFooterParagraph()
{
var footerPar = new Paragraph();
footerPar.Format.Alignment = ParagraphAlignment.Center;
footerPar.Format.Font.Size = 10;
footerPar.AddText("--Page ");
footerPar.AddPageField();
footerPar.AddText(" of ");
footerPar.AddNumPagesField();
footerPar.AddText("--");
footerPar.AddLineBreak();
footerPar.AddText("Report generated on " + DateTime.Now.ToString("f"));
footerPar.Tag = "FooterPar";
footerPar.Format.Font.Name = "Noto Sans";
return footerPar;
}
private decimal GetExistingPageItemHeight(PdfDocumentRenderer pdfRenderer, decimal footerParagraphHeight)
{
pdfRenderer.DocumentRenderer.PrepareDocument();
var currPageCount = pdfRenderer.DocumentRenderer.FormattedDocument?.PageCount;
var heightForExistingItemsOnPage = footerParagraphHeight;
if (currPageCount.HasValue)
{
var renderInfo = pdfRenderer.DocumentRenderer.GetRenderInfoFromPage(currPageCount.Value);
if (renderInfo != null)
{
// Console.WriteLine("Got render info for page: {0}", currPageCount);
foreach (var item in renderInfo)
{
heightForExistingItemsOnPage += (decimal)item.LayoutInfo.ContentArea.Height.Inch;
}
}
}
return heightForExistingItemsOnPage;
}
// https://forum.pdfsharp.net/viewtopic.php?f=2&t=1025 // https://forum.pdfsharp.net/viewtopic.php?f=2&t=1025
private async Task CreatePDF(string folderPath) private async Task CreatePDF(string folderPath)
{ {
@@ -622,12 +686,26 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
await DialogHost.Show(new WarningViewModel("Output directory not found! Please adjust your application Settings before continuing. Output directory: " + outputDir)); await DialogHost.Show(new WarningViewModel("Output directory not found! Please adjust your application Settings before continuing. Output directory: " + outputDir));
return; return;
} }
// setup globals and consts...
GlobalFontSettings.FontResolver = this;
GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver();
const decimal pageWidth = 8.5m;
const decimal pageHeight = 11.0m;
const decimal margin = 0.5m;
const int imageResolution = 72;
const int imageInsertMarginPixels = 30; // we calculate max available; use max - this # for max image size
var maxItemPxWidth = ((pageWidth - (2 * margin)) * imageResolution) - imageInsertMarginPixels;
// start making PDF! // start making PDF!
IsCreatingPDF = true; IsCreatingPDF = true;
var pdfDoc = new Document(); var pdfDoc = new Document();
var outputFileName = ReportTitle + ".pdf"; var outputFileName = ReportTitle + ".pdf";
var folderName = new DirectoryInfo(folderPath).Name; var folderName = new DirectoryInfo(folderPath).Name;
const int imageWidth = 425; const int maxImageWidth = 425;
var imageLineFormat = new MigraDoc.DocumentObjectModel.Shapes.LineFormat()
{
Color = Colors.Black,
Width = Unit.FromPoint(2),
};;
if (folderName.Contains('-')) if (folderName.Contains('-'))
{ {
// see if year/month format // see if year/month format
@@ -642,33 +720,51 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
LogInfo("Auto-changed output file name to " + outputFileName); LogInfo("Auto-changed output file name to " + outputFileName);
} }
} }
// setup initial section (for page characteristics)
var section = pdfDoc.AddSection(); var section = pdfDoc.AddSection();
section.PageSetup.PageFormat = PageFormat.Letter; section.PageSetup.PageFormat = PageFormat.Letter;
section.PageSetup.PageWidth = "8.5in"; section.PageSetup.PageWidth = pageWidth + "in";
section.PageSetup.PageHeight = "11in"; section.PageSetup.PageHeight = pageHeight + "in";
section.PageSetup.TopMargin = "0.5in"; section.PageSetup.TopMargin = margin + "in";
section.PageSetup.RightMargin = "0.5in"; section.PageSetup.RightMargin = margin + "in";
section.PageSetup.BottomMargin = "0.5in"; section.PageSetup.BottomMargin = margin + "in";
section.PageSetup.LeftMargin = "0.5in"; section.PageSetup.LeftMargin = margin + "in";
// setup footer for page number // setup footer for page number
var footerPar = new Paragraph(); var footerPar = GetFooterParagraph();
footerPar.Format.Alignment = ParagraphAlignment.Center;
footerPar.Format.Font.Size = 10;
footerPar.AddText("--Page ");
footerPar.AddPageField();
footerPar.AddText(" of ");
footerPar.AddNumPagesField();
footerPar.AddText("--");
footerPar.AddLineBreak();
footerPar.AddText("Report generated on " + DateTime.Now.ToString("f"));
section.Footers.Primary.Add(footerPar); section.Footers.Primary.Add(footerPar);
// add report title // create a quick PDF doc renderer to measure footer paragraph height
var footerParagraphHeight = 0.4m; // estimate
var footerOnlyPdfDoc = new Document();
var sectionClone = section.Clone();
footerOnlyPdfDoc.Add(sectionClone);
sectionClone.Add(GetFooterParagraph());
var footerPdfRenderer = new PdfDocumentRenderer
{
Document = footerOnlyPdfDoc
};
footerPdfRenderer.DocumentRenderer.PrepareDocument();
var footerRenderInfo = footerPdfRenderer.DocumentRenderer.GetRenderInfoFromPage(1);
if (footerRenderInfo != null)
{
foreach (var item in footerRenderInfo)
{
if (item.DocumentObject.Tag?.ToString() == "FooterPar")
{
Console.WriteLine("Got footer paragraph height!");
footerParagraphHeight = (decimal)item.LayoutInfo.ContentArea.Height.Inch;
break;
}
}
}
// continue setting up document
// First page only: add report title
var reportTitlePar = section.AddParagraph(); var reportTitlePar = section.AddParagraph();
reportTitlePar.Format.Alignment = ParagraphAlignment.Center; reportTitlePar.Format.Alignment = ParagraphAlignment.Center;
reportTitlePar.Format.Font.Size = 16; reportTitlePar.Format.Font.Size = 16;
reportTitlePar.Format.Font.Bold = true; reportTitlePar.Format.Font.Bold = true;
reportTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too reportTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
reportTitlePar.AddText(ReportTitle); reportTitlePar.AddText(ReportTitle);
reportTitlePar.Tag = "TitlePar";
// get converted files directory path and create it if necessary // get converted files directory path and create it if necessary
var convertedDir = Path.Combine(Utilities.GetInternalDataPath(), "converted"); var convertedDir = Path.Combine(Utilities.GetInternalDataPath(), "converted");
if (!Directory.Exists(convertedDir)) if (!Directory.Exists(convertedDir))
@@ -676,8 +772,11 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
Directory.CreateDirectory(convertedDir); Directory.CreateDirectory(convertedDir);
} }
// //
GlobalFontSettings.FontResolver = this; var pdfRenderer = new PdfDocumentRenderer
GlobalFontSettings.FallbackFontResolver = new FailsafeFontResolver(); {
Document = pdfDoc,
WorkingDirectory = folderPath
};
var hasAddedData = false; var hasAddedData = false;
for (var i = 0; i < ReportFiles.Count; i++) for (var i = 0; i < ReportFiles.Count; i++)
{ {
@@ -704,12 +803,14 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
imageTitlePar.Format.Font.Bold = true; imageTitlePar.Format.Font.Bold = true;
imageTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too imageTitlePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
imageTitlePar.AddText(string.IsNullOrWhiteSpace(file.Title) ? file.FileName : file.Title); imageTitlePar.AddText(string.IsNullOrWhiteSpace(file.Title) ? file.FileName : file.Title);
imageTitlePar.Tag = "ReceiptTitlePar";
var receiptDatePar = section.AddParagraph(); var receiptDatePar = section.AddParagraph();
receiptDatePar.Format.Alignment = ParagraphAlignment.Center; receiptDatePar.Format.Alignment = ParagraphAlignment.Center;
receiptDatePar.Format.Font.Size = 12; receiptDatePar.Format.Font.Size = 12;
receiptDatePar.Format.Font.Bold = true; receiptDatePar.Format.Font.Bold = true;
receiptDatePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too receiptDatePar.Format.Font.Name = "Noto Sans JP"; // has english letters in it, too
receiptDatePar.AddText(file.ReceiptDate.ToString("yyyy-MM-dd")); receiptDatePar.AddText(file.ReceiptDate.ToString("yyyy-MM-dd"));
receiptDatePar.Tag = "ReceiptDatePar";
if (!string.IsNullOrWhiteSpace(file.Notes)) if (!string.IsNullOrWhiteSpace(file.Notes))
{ {
var imageNotesPar = section.AddParagraph(); var imageNotesPar = section.AddParagraph();
@@ -718,8 +819,10 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
imageNotesPar.Format.Font.Bold = false; imageNotesPar.Format.Font.Bold = false;
imageNotesPar.Format.Font.Name = "Noto Sans JP"; imageNotesPar.Format.Font.Name = "Noto Sans JP";
imageNotesPar.AddText(file.Notes); imageNotesPar.AddText(file.Notes);
imageNotesPar.Tag = "ReceiptNotesPar";
} }
section.AddParagraph(); // add empty line for spacing var emptyPar = section.AddParagraph(); // add empty line for spacing
emptyPar.Tag = "EmptyParagraph";
// now add the image // now add the image
var lowerName = fileName.ToLower(); var lowerName = fileName.ToLower();
var isPDF = lowerName.EndsWith(".pdf"); var isPDF = lowerName.EndsWith(".pdf");
@@ -731,6 +834,14 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
var info = new FileInfo(file.FilePath); var info = new FileInfo(file.FilePath);
uint loadedImageWidth = 0; uint loadedImageWidth = 0;
uint loadedImageHeight = 0; uint loadedImageHeight = 0;
// get max pixel height remaining for items on this page
// (For multi-page PDFs, showing page 2 and on will have more height since they have no title,
// but to keep things consistent we will use the same height for all PDF pages.)
// render up to now on this page and get height remaining in inches
var currPageCount = pdfRenderer.DocumentRenderer.FormattedDocument?.PageCount;
var heightForExistingItemsOnPage = GetExistingPageItemHeight(pdfRenderer, footerParagraphHeight);
var remainingHeightInches = pageHeight - (2 * margin) - heightForExistingItemsOnPage;
var remainingHeightPixels = (remainingHeightInches * imageResolution) - imageInsertMarginPixels;
if (!isPDF) if (!isPDF)
{ {
using var mImage = new MagickImage(info.FullName); using var mImage = new MagickImage(info.FullName);
@@ -776,17 +887,23 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
var image = paragraph.AddImage(filePath); var image = paragraph.AddImage(filePath);
image.LockAspectRatio = true; image.Resolution = imageResolution; // dots per inch
if (!isPDF && loadedImageHeight > 600) image.Tag = "ReceiptImageTag";
paragraph.Tag = "ReceiptImageParagraphTag";
image.LineFormat = imageLineFormat.Clone();
// resize down until it will fit on the page
while (loadedImageHeight > remainingHeightPixels || loadedImageWidth > maxItemPxWidth)
{ {
image.Height = 550; // make sure it will fit on one page // Console.WriteLine("Image height = {0}, width = {1}; decreasing size by 5% to h={2}, w={3}", loadedImageHeight, loadedImageWidth, (uint)Math.Floor(loadedImageHeight * 0.95), (uint)Math.Floor(loadedImageWidth * 0.95));
} // keep reducing size by 5% (little by little) until it fits on the page
else // ...might skew ever so slightly but should not be noticable...
{ loadedImageHeight = (uint)Math.Floor(loadedImageHeight * 0.95);
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins... loadedImageWidth = (uint)Math.Floor(loadedImageWidth * 0.95);
} }
image.Height = loadedImageHeight;
image.Width = loadedImageWidth;
} }
else else // isPDF
{ {
// need to render PDF to images // need to render PDF to images
if (_settings.UseDocnetPDFImageRendering) if (_settings.UseDocnetPDFImageRendering)
@@ -825,9 +942,23 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
pgCount == 1 ? "" : "s")); pgCount == 1 ? "" : "s"));
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
// get image height/width off of disk so we can resize down if needed
var image = paragraph.AddImage(convertedPdfImagePath); var image = paragraph.AddImage(convertedPdfImagePath);
image.Width = imageWidth;
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.LineFormat = imageLineFormat.Clone();
using (var firstPdfPageImage = new MagickImage(convertedPdfImagePath))
{
var pdfPageImageWidth = firstPdfPageImage.Width;
var pdfPageImageHeight = firstPdfPageImage.Height;
// resize down until it will fit on the page
while (pdfPageImageHeight > remainingHeightPixels || pdfPageImageWidth > maxItemPxWidth)
{
pdfPageImageHeight = (uint)Math.Floor(pdfPageImageHeight * 0.95);
pdfPageImageWidth = (uint)Math.Floor(pdfPageImageWidth * 0.95);
}
image.Height = pdfPageImageHeight;
image.Width = pdfPageImageWidth;
}
for (var j = 1; j < pgCount; j++) for (var j = 1; j < pgCount; j++)
{ {
section.AddPageBreak(); section.AddPageBreak();
@@ -836,18 +967,37 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
convertedPdfImagePath = RenderPdfPageToImage(docReader, j); convertedPdfImagePath = RenderPdfPageToImage(docReader, j);
image = paragraph.AddImage(convertedPdfImagePath); image = paragraph.AddImage(convertedPdfImagePath);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; image.Width = maxImageWidth;
image.LineFormat = imageLineFormat.Clone();
using (var otherPdfPageImage = new MagickImage(convertedPdfImagePath))
{
var pdfPageImageWidth = otherPdfPageImage.Width;
var pdfPageImageHeight = otherPdfPageImage.Height;
// resize down until it will fit on the page
while (pdfPageImageHeight > remainingHeightPixels || pdfPageImageWidth > maxItemPxWidth)
{
pdfPageImageHeight = (uint)Math.Floor(pdfPageImageHeight * 0.95);
pdfPageImageWidth = (uint)Math.Floor(pdfPageImageWidth * 0.95);
}
image.Height = pdfPageImageHeight;
image.Width = pdfPageImageWidth;
}
} }
} }
} }
else else
{ {
// use older, not-docnet rendering method.
// uses MigraDoc rendering. Does not work with annotations, and since Migradoc
// doesn't let us know how big the image is, we can't do the image resizing, so
// we just do our best.
// render first page (eventually need to improve code to just do everything in a loop) // render first page (eventually need to improve code to just do everything in a loop)
var paragraph = section.AddParagraph(); var paragraph = section.AddParagraph();
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
var image = paragraph.AddImage(filePath); var image = paragraph.AddImage(filePath);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins... image.Width = maxImageWidth; // can't be too wide now...not sure why...maybe due to margins...
image.LineFormat = imageLineFormat.Clone();
// render other PDF pages, if any // render other PDF pages, if any
// see: https://stackoverflow.com/a/65091204/3938401 // see: https://stackoverflow.com/a/65091204/3938401
var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import); var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import);
@@ -862,20 +1012,18 @@ class CreatePDFReportViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.Alignment = ParagraphAlignment.Center;
image = paragraph.AddImage(filePath + "#" + j); image = paragraph.AddImage(filePath + "#" + j);
image.LockAspectRatio = true; image.LockAspectRatio = true;
image.Width = imageWidth; image.Width = maxImageWidth;
image.LineFormat = imageLineFormat.Clone();
} }
} }
} }
LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath)); LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath));
hasAddedData = true; hasAddedData = true;
} }
var pdfRenderer = new PdfDocumentRenderer
{
Document = pdfDoc,
WorkingDirectory = folderPath
};
LogInfo("Rendering document to PDF file..."); LogInfo("Rendering document to PDF file...");
pdfRenderer.DocumentRenderer.PrepareDocument(); // needed if you make edits after first PrepareDocument() is called
pdfRenderer.RenderDocument(); pdfRenderer.RenderDocument();
// actually save to disk now
string outputPDFFilePath = Path.Join(outputDir, outputFileName); string outputPDFFilePath = Path.Join(outputDir, outputFileName);
LogInfo("Saving PDF document to disk..."); LogInfo("Saving PDF document to disk...");
pdfRenderer.PdfDocument.Save(outputPDFFilePath); pdfRenderer.PdfDocument.Save(outputPDFFilePath);
@@ -18,6 +18,7 @@ using PdfSharp.Snippets.Font;
using MayShow.Interfaces; using MayShow.Interfaces;
using MayShow.Models; using MayShow.Models;
using MayShow.Helpers; using MayShow.Helpers;
using MayShows.Helpers;
namespace MayShow.ViewModels; namespace MayShow.ViewModels;
@@ -126,6 +127,18 @@ class SettingsViewModel: ChangeNotifier
} }
} }
public void OpenSettingsDir()
{
var topLevel = _topLevelGrabber?.GetTopLevel();
Console.WriteLine(Utilities.GetInternalDataPath());
var dirName = Utilities.GetInternalDataPath();
if (topLevel is not null && dirName != null)
{
var launcher = topLevel.Launcher;
launcher.LaunchUriAsync(new Uri(dirName));
}
}
public void Cancel() public void Cancel()
{ {
DialogHost.Close("DialogHost", null); DialogHost.Close("DialogHost", null);
+1 -1
View File
@@ -11,7 +11,7 @@
MaxWidth="450"> MaxWidth="450">
<StackPanel Orientation="Vertical" <StackPanel Orientation="Vertical"
Spacing="4"> Spacing="4">
<TextBlock Text="MayShow 1.4.0" <TextBlock Text="MayShow 1.4.2"
HorizontalAlignment="Center" HorizontalAlignment="Center"
TextWrapping="Wrap" TextWrapping="Wrap"
FontSize="18" FontSize="18"
@@ -47,6 +47,11 @@
VerticalAlignment="Top"/> VerticalAlignment="Top"/>
</Grid> </Grid>
<CheckBox IsChecked="{Binding SaveReportJsonDataInInternalDir}">Save report data (names, notes, etc.) in MayShow settings directory (saves in working directory by default)</CheckBox> <CheckBox IsChecked="{Binding SaveReportJsonDataInInternalDir}">Save report data (names, notes, etc.) in MayShow settings directory (saves in working directory by default)</CheckBox>
<Button Command="{Binding OpenSettingsDir}">
<TextBlock>
<Run Text="&#xf07c;"
FontFamily="{StaticResource FontAwesomeSolid}" /> Open MayShow Settings Directory</TextBlock>
</Button>
<TextBlock TextWrapping="Wrap" <TextBlock TextWrapping="Wrap"
Foreground="Red" Foreground="Red"
Text="{Binding ErrorMessage}" Text="{Binding ErrorMessage}"