ScanPanel.xaml.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using Syncfusion.Pdf.Graphics;
  5. using Syncfusion.Pdf.Parsing;
  6. using Syncfusion.Pdf;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Drawing.Imaging;
  10. using System.Drawing;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15. using System.Windows;
  16. using System.Windows.Controls;
  17. using System.Windows.Data;
  18. using System.Windows.Documents;
  19. using System.Windows.Input;
  20. using System.Windows.Media;
  21. using System.Windows.Media.Imaging;
  22. using System.Windows.Navigation;
  23. using System.Windows.Shapes;
  24. using InABox.DynamicGrid;
  25. using InABox.WPF;
  26. using Encoder = System.Drawing.Imaging.Encoder;
  27. using Path = System.IO.Path;
  28. using Image = System.Windows.Controls.Image;
  29. using com.sun.tools.doclets.@internal.toolkit.util;
  30. using Syncfusion.Windows.PdfViewer;
  31. namespace PRSDesktop
  32. {
  33. public static class PDFExtensions
  34. {
  35. public static IEnumerable<PdfPageBase> GetPages(this PdfDocumentBase doc)
  36. {
  37. if (doc is PdfLoadedDocument lDoc)
  38. return lDoc.Pages.Cast<PdfPageBase>();
  39. if (doc is PdfDocument pdfDoc)
  40. return pdfDoc.Pages.Cast<PdfPageBase>();
  41. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  42. }
  43. public static PdfPageBase GetPage(this PdfDocumentBase doc, int index)
  44. {
  45. if (doc is PdfLoadedDocument lDoc)
  46. return lDoc.Pages[index];
  47. if (doc is PdfDocument pdfDoc)
  48. return pdfDoc.Pages[index];
  49. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  50. }
  51. public static int PageCount(this PdfDocumentBase doc)
  52. {
  53. if (doc is PdfLoadedDocument lDoc)
  54. return lDoc.Pages.Count;
  55. if (doc is PdfDocument pdfDoc)
  56. return pdfDoc.Pages.Count;
  57. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  58. }
  59. public static PdfLoadedDocument ToLoadedDocument(this PdfDocumentBase doc)
  60. {
  61. if (doc is PdfLoadedDocument lDoc)
  62. return lDoc;
  63. if (doc is PdfDocument pdfDoc)
  64. {
  65. using var ms = new MemoryStream();
  66. pdfDoc.Save(ms);
  67. var array = ms.ToArray();
  68. return new PdfLoadedDocument(array);
  69. }
  70. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  71. }
  72. }
  73. /// <summary>
  74. /// Interaction logic for ScanPanel.xaml
  75. /// </summary>
  76. public partial class ScanPanel : UserControl, ICorePanel, IDockPanel
  77. {
  78. private List<Scan> SelectedScans = new();
  79. private Type? appliesTo;
  80. public Type? AppliesTo
  81. {
  82. get => appliesTo;
  83. set
  84. {
  85. appliesTo = value;
  86. ScanGrid.AppliesTo = value?.EntityName();
  87. ScanGrid.Refresh(false, true);
  88. }
  89. }
  90. public ScanPanel()
  91. {
  92. InitializeComponent();
  93. }
  94. #region Panel
  95. public void Setup()
  96. {
  97. ScanGrid.HiddenColumns.Add(x => x.Document.ID);
  98. ScanGrid.Refresh(true, false);
  99. }
  100. public void Refresh()
  101. {
  102. ScanGrid.Refresh(false, true);
  103. }
  104. public void Shutdown()
  105. {
  106. }
  107. #endregion
  108. #region View List
  109. private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
  110. {
  111. if (sender != TabControl) return;
  112. if (TabControl.SelectedItem == ViewList)
  113. {
  114. UpdateViewList();
  115. }
  116. }
  117. private static List<byte[]> RenderTextFile(string textData)
  118. {
  119. var pdfDocument = new PdfDocument();
  120. var page = pdfDocument.Pages.Add();
  121. var font = new PdfStandardFont(PdfFontFamily.Courier, 14);
  122. var textElement = new PdfTextElement(textData, font);
  123. var layoutFormat = new PdfLayoutFormat
  124. {
  125. Layout = PdfLayoutType.Paginate,
  126. Break = PdfLayoutBreakType.FitPage
  127. };
  128. textElement.Draw(page, new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height), layoutFormat);
  129. using var docStream = new MemoryStream();
  130. pdfDocument.Save(docStream);
  131. var loadeddoc = new PdfLoadedDocument(docStream.ToArray());
  132. Bitmap[] bmpImages = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1);
  133. var jpgEncoder = ImageUtils.GetEncoder(ImageFormat.Jpeg)!;
  134. var quality = Encoder.Quality;
  135. var encodeParams = new EncoderParameters(1);
  136. encodeParams.Param[0] = new EncoderParameter(quality, 100L);
  137. var images = new List<byte[]>();
  138. if (bmpImages != null)
  139. foreach (var image in bmpImages)
  140. {
  141. using var data = new MemoryStream();
  142. image.Save(data, jpgEncoder, encodeParams);
  143. images.Add(data.ToArray());
  144. }
  145. return images;
  146. }
  147. private void UpdateViewList()
  148. {
  149. var selected = ScanGrid.SelectedRows.Select(x => x.ToObject<Scan>()).ToList();
  150. if (selected.Count == SelectedScans.Count && !selected.Any(x => !SelectedScans.Any(y => x.ID == y.ID)))
  151. {
  152. return;
  153. }
  154. SelectedScans = selected;
  155. ViewListPanel.Children.Clear();
  156. var docIDs = SelectedScans.Select(x => x.Document.ID).Distinct().ToArray();
  157. var documents = new Client<Document>()
  158. .Query(
  159. new Filter<Document>(x => x.ID).InList(docIDs),
  160. new Columns<Document>(x => x.ID).Add(x => x.Data).Add(x => x.FileName))
  161. .ToObjects<Document>();
  162. var bitmaps = new Dictionary<Guid, List<BitmapImage>>();
  163. foreach (var document in documents)
  164. {
  165. List<byte[]> images;
  166. var extension = Path.GetExtension(document.FileName).ToLower();
  167. if (extension == ".pdf")
  168. {
  169. try
  170. {
  171. images = ImageUtils.RenderPDFToImages(document.Data);
  172. }
  173. catch (Exception e)
  174. {
  175. MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
  176. images = new List<byte[]>();
  177. }
  178. }
  179. else if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp")
  180. {
  181. images = new List<byte[]> { document.Data };
  182. }
  183. else
  184. {
  185. images = RenderTextFile(Encoding.UTF8.GetString(document.Data));
  186. }
  187. foreach (var imageData in images)
  188. {
  189. try
  190. {
  191. if(!bitmaps.TryGetValue(document.ID, out var list))
  192. {
  193. list = new List<BitmapImage>();
  194. bitmaps[document.ID] = list;
  195. }
  196. list.Add(ImageUtils.LoadImage(imageData));
  197. }
  198. catch (Exception e)
  199. {
  200. MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
  201. }
  202. }
  203. }
  204. foreach(var scan in selected)
  205. {
  206. if(bitmaps.TryGetValue(scan.Document.ID, out var list))
  207. {
  208. foreach(var bitmap in list)
  209. {
  210. var image = new Image
  211. {
  212. Source = bitmap,
  213. Margin = new Thickness(0, 0, 0, 20)
  214. };
  215. ViewListPanel.Children.Add(image);
  216. }
  217. }
  218. }
  219. }
  220. #endregion
  221. #region Uploading
  222. private void DynamicTabItem_Drop(object sender, DragEventArgs e)
  223. {
  224. Task.Run(() =>
  225. {
  226. var pages = DocumentManipulationWindow.HandleFileDrop(e, out var filename);
  227. if (pages is not null)
  228. {
  229. Dispatcher.Invoke(() =>
  230. {
  231. ScanGrid.ShowDocumentWindow(pages, filename);
  232. });
  233. }
  234. });
  235. }
  236. private void DynamicTabItem_DragOver(object sender, DragEventArgs e)
  237. {
  238. if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor"))
  239. {
  240. e.Effects = DragDropEffects.Copy;
  241. }
  242. else
  243. {
  244. e.Effects = DragDropEffects.None;
  245. }
  246. e.Handled = true;
  247. }
  248. #endregion
  249. }
  250. }