ScanPanel.xaml.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. using javax.xml.crypto;
  32. using System.ComponentModel;
  33. namespace PRSDesktop
  34. {
  35. public static class PDFExtensions
  36. {
  37. public static IEnumerable<PdfPageBase> GetPages(this PdfDocumentBase doc)
  38. {
  39. if (doc is PdfLoadedDocument lDoc)
  40. return lDoc.Pages.Cast<PdfPageBase>();
  41. if (doc is PdfDocument pdfDoc)
  42. return pdfDoc.Pages.Cast<PdfPageBase>();
  43. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  44. }
  45. public static PdfPageBase GetPage(this PdfDocumentBase doc, int index)
  46. {
  47. if (doc is PdfLoadedDocument lDoc)
  48. return lDoc.Pages[index];
  49. if (doc is PdfDocument pdfDoc)
  50. return pdfDoc.Pages[index];
  51. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  52. }
  53. public static int PageCount(this PdfDocumentBase doc)
  54. {
  55. if (doc is PdfLoadedDocument lDoc)
  56. return lDoc.Pages.Count;
  57. if (doc is PdfDocument pdfDoc)
  58. return pdfDoc.Pages.Count;
  59. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  60. }
  61. public static PdfLoadedDocument AsLoadedDocument(this PdfDocumentBase doc)
  62. {
  63. if (doc is PdfLoadedDocument lDoc)
  64. return lDoc;
  65. if (doc is PdfDocument pdfDoc)
  66. {
  67. using var ms = new MemoryStream();
  68. pdfDoc.Save(ms);
  69. var array = ms.ToArray();
  70. return new PdfLoadedDocument(array);
  71. }
  72. throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
  73. }
  74. public static byte[] SaveToBytes(this PdfDocumentBase doc)
  75. {
  76. using var ms = new MemoryStream();
  77. doc.Save(ms);
  78. return ms.ToArray();
  79. }
  80. }
  81. /// <summary>
  82. /// Interaction logic for ScanPanel.xaml
  83. /// </summary>
  84. public partial class ScanPanel : UserControl, ICorePanel, IDockPanel
  85. {
  86. private List<Scan> SelectedScans = new();
  87. public event ScanGrid.SelectAppliesTo? OnSelectAppliesTo;
  88. public ScanPanel()
  89. {
  90. InitializeComponent();
  91. }
  92. #region Panel
  93. public void Setup()
  94. {
  95. ScanGrid.HiddenColumns.Add(x => x.Document.ID);
  96. ScanGrid.Refresh(true, false);
  97. }
  98. public void Refresh()
  99. {
  100. ScanGrid.Refresh(false, true);
  101. }
  102. public void Shutdown(CancelEventArgs? cancel)
  103. {
  104. }
  105. #endregion
  106. #region View List
  107. private static List<byte[]> RenderTextFile(string textData)
  108. {
  109. var pdfDocument = new PdfDocument();
  110. var page = pdfDocument.Pages.Add();
  111. var font = new PdfStandardFont(PdfFontFamily.Courier, 14);
  112. var textElement = new PdfTextElement(textData, font);
  113. var layoutFormat = new PdfLayoutFormat
  114. {
  115. Layout = PdfLayoutType.Paginate,
  116. Break = PdfLayoutBreakType.FitPage
  117. };
  118. textElement.Draw(page, new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height), layoutFormat);
  119. using var docStream = new MemoryStream();
  120. pdfDocument.Save(docStream);
  121. var loadeddoc = new PdfLoadedDocument(docStream.ToArray());
  122. Bitmap[] bmpImages = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1);
  123. var jpgEncoder = ImageUtils.GetEncoder(ImageFormat.Jpeg)!;
  124. var quality = Encoder.Quality;
  125. var encodeParams = new EncoderParameters(1);
  126. encodeParams.Param[0] = new EncoderParameter(quality, 100L);
  127. var images = new List<byte[]>();
  128. if (bmpImages != null)
  129. foreach (var image in bmpImages)
  130. {
  131. using var data = new MemoryStream();
  132. image.Save(data, jpgEncoder, encodeParams);
  133. images.Add(data.ToArray());
  134. }
  135. return images;
  136. }
  137. private void UpdateViewList()
  138. {
  139. var selected = ScanGrid.SelectedRows.Select(x => x.ToObject<Scan>()).ToList();
  140. if (selected.Count == SelectedScans.Count && !selected.Any(x => !SelectedScans.Any(y => x.ID == y.ID)))
  141. {
  142. return;
  143. }
  144. SelectedScans = selected;
  145. ViewListPanel.Children.Clear();
  146. var docIDs = SelectedScans.Select(x => x.Document.ID).Distinct().ToArray();
  147. var documents = new Client<Document>()
  148. .Query(
  149. new Filter<Document>(x => x.ID).InList(docIDs),
  150. new Columns<Document>(x => x.ID).Add(x => x.Data).Add(x => x.FileName))
  151. .ToObjects<Document>();
  152. var bitmaps = new Dictionary<Guid, List<BitmapImage>>();
  153. foreach (var document in documents)
  154. {
  155. List<byte[]> images;
  156. var extension = Path.GetExtension(document.FileName).ToLower();
  157. if (extension == ".pdf")
  158. {
  159. try
  160. {
  161. images = ImageUtils.RenderPDFToImages(document.Data);
  162. }
  163. catch (Exception e)
  164. {
  165. MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
  166. images = new List<byte[]>();
  167. }
  168. }
  169. else if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp")
  170. {
  171. images = new List<byte[]> { document.Data };
  172. }
  173. else
  174. {
  175. images = RenderTextFile(Encoding.UTF8.GetString(document.Data));
  176. }
  177. foreach (var imageData in images)
  178. {
  179. try
  180. {
  181. if(!bitmaps.TryGetValue(document.ID, out var list))
  182. {
  183. list = new List<BitmapImage>();
  184. bitmaps[document.ID] = list;
  185. }
  186. list.Add(ImageUtils.LoadImage(imageData));
  187. }
  188. catch (Exception e)
  189. {
  190. MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
  191. }
  192. }
  193. }
  194. foreach(var scan in selected)
  195. {
  196. if(bitmaps.TryGetValue(scan.Document.ID, out var list))
  197. {
  198. foreach(var bitmap in list)
  199. {
  200. var image = new Image
  201. {
  202. Source = bitmap,
  203. Margin = new Thickness(0, 0, 0, 20)
  204. };
  205. image.ContextMenu = ViewListPanel.ContextMenu;
  206. ViewListPanel.Children.Add(image);
  207. }
  208. }
  209. }
  210. }
  211. #endregion
  212. #region Uploading
  213. private void DynamicTabItem_Drop(object sender, DragEventArgs e)
  214. {
  215. Task.Run(() =>
  216. {
  217. var docs = DocumentManipulationWindow.HandleFileDrop(e);
  218. if (docs is not null)
  219. {
  220. foreach(var (filename, doc) in docs)
  221. {
  222. ScanGrid.UploadDocument(Path.ChangeExtension(filename, ".pdf"), doc.SaveToBytes(), Guid.Empty);
  223. }
  224. /*Dispatcher.Invoke(() =>
  225. {
  226. ScanGrid.ShowDocumentWindow(pages, filename);
  227. });*/
  228. }
  229. });
  230. }
  231. private void DynamicTabItem_DragOver(object sender, DragEventArgs e)
  232. {
  233. if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor"))
  234. {
  235. e.Effects = DragDropEffects.Copy;
  236. }
  237. else
  238. {
  239. e.Effects = DragDropEffects.None;
  240. }
  241. e.Handled = true;
  242. }
  243. #endregion
  244. private void ScanGrid_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
  245. {
  246. UpdateViewList();
  247. var appliesTo = e?.Rows?.Length == 1
  248. ? e.Rows[0].Get<Scan, string>(x => x.Tag.AppliesTo)
  249. : "";
  250. OnSelectAppliesTo?.Invoke(appliesTo);
  251. }
  252. private void ScanGrid_OnSelectAppliesTo(string appliesTo)
  253. {
  254. OnSelectAppliesTo?.Invoke(appliesTo);
  255. }
  256. private void _Explode_OnClick(object sender, RoutedEventArgs e)
  257. {
  258. this.ScanGrid.DoExplode();
  259. }
  260. }
  261. }