using Comal.Classes; using InABox.Clients; using InABox.Core; using Syncfusion.Pdf.Graphics; using Syncfusion.Pdf.Parsing; using Syncfusion.Pdf; using System; using System.Collections.Generic; using System.Drawing.Imaging; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using InABox.DynamicGrid; using InABox.WPF; using Encoder = System.Drawing.Imaging.Encoder; using Path = System.IO.Path; using Image = System.Windows.Controls.Image; using com.sun.tools.doclets.@internal.toolkit.util; using Syncfusion.Windows.PdfViewer; using javax.xml.crypto; namespace PRSDesktop { public static class PDFExtensions { public static IEnumerable GetPages(this PdfDocumentBase doc) { if (doc is PdfLoadedDocument lDoc) return lDoc.Pages.Cast(); if (doc is PdfDocument pdfDoc) return pdfDoc.Pages.Cast(); throw new Exception($"Unsupported PDF Document type {doc.GetType()}"); } public static PdfPageBase GetPage(this PdfDocumentBase doc, int index) { if (doc is PdfLoadedDocument lDoc) return lDoc.Pages[index]; if (doc is PdfDocument pdfDoc) return pdfDoc.Pages[index]; throw new Exception($"Unsupported PDF Document type {doc.GetType()}"); } public static int PageCount(this PdfDocumentBase doc) { if (doc is PdfLoadedDocument lDoc) return lDoc.Pages.Count; if (doc is PdfDocument pdfDoc) return pdfDoc.Pages.Count; throw new Exception($"Unsupported PDF Document type {doc.GetType()}"); } public static PdfLoadedDocument AsLoadedDocument(this PdfDocumentBase doc) { if (doc is PdfLoadedDocument lDoc) return lDoc; if (doc is PdfDocument pdfDoc) { using var ms = new MemoryStream(); pdfDoc.Save(ms); var array = ms.ToArray(); return new PdfLoadedDocument(array); } throw new Exception($"Unsupported PDF Document type {doc.GetType()}"); } public static byte[] SaveToBytes(this PdfDocumentBase doc) { using var ms = new MemoryStream(); doc.Save(ms); return ms.ToArray(); } } /// /// Interaction logic for ScanPanel.xaml /// public partial class ScanPanel : UserControl, ICorePanel, IDockPanel { private List SelectedScans = new(); public event ScanGrid.SelectAppliesTo? OnSelectAppliesTo; public ScanPanel() { InitializeComponent(); } #region Panel public void Setup() { ScanGrid.HiddenColumns.Add(x => x.Document.ID); ScanGrid.Refresh(true, false); } public void Refresh() { ScanGrid.Refresh(false, true); } public void Shutdown() { } #endregion #region View List private static List RenderTextFile(string textData) { var pdfDocument = new PdfDocument(); var page = pdfDocument.Pages.Add(); var font = new PdfStandardFont(PdfFontFamily.Courier, 14); var textElement = new PdfTextElement(textData, font); var layoutFormat = new PdfLayoutFormat { Layout = PdfLayoutType.Paginate, Break = PdfLayoutBreakType.FitPage }; textElement.Draw(page, new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height), layoutFormat); using var docStream = new MemoryStream(); pdfDocument.Save(docStream); var loadeddoc = new PdfLoadedDocument(docStream.ToArray()); Bitmap[] bmpImages = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1); var jpgEncoder = ImageUtils.GetEncoder(ImageFormat.Jpeg)!; var quality = Encoder.Quality; var encodeParams = new EncoderParameters(1); encodeParams.Param[0] = new EncoderParameter(quality, 100L); var images = new List(); if (bmpImages != null) foreach (var image in bmpImages) { using var data = new MemoryStream(); image.Save(data, jpgEncoder, encodeParams); images.Add(data.ToArray()); } return images; } private void UpdateViewList() { var selected = ScanGrid.SelectedRows.Select(x => x.ToObject()).ToList(); if (selected.Count == SelectedScans.Count && !selected.Any(x => !SelectedScans.Any(y => x.ID == y.ID))) { return; } SelectedScans = selected; ViewListPanel.Children.Clear(); var docIDs = SelectedScans.Select(x => x.Document.ID).Distinct().ToArray(); var documents = new Client() .Query( new Filter(x => x.ID).InList(docIDs), new Columns(x => x.ID).Add(x => x.Data).Add(x => x.FileName)) .ToObjects(); var bitmaps = new Dictionary>(); foreach (var document in documents) { List images; var extension = Path.GetExtension(document.FileName).ToLower(); if (extension == ".pdf") { try { images = ImageUtils.RenderPDFToImages(document.Data); } catch (Exception e) { MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}"); images = new List(); } } else if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp") { images = new List { document.Data }; } else { images = RenderTextFile(Encoding.UTF8.GetString(document.Data)); } foreach (var imageData in images) { try { if(!bitmaps.TryGetValue(document.ID, out var list)) { list = new List(); bitmaps[document.ID] = list; } list.Add(ImageUtils.LoadImage(imageData)); } catch (Exception e) { MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}"); } } } foreach(var scan in selected) { if(bitmaps.TryGetValue(scan.Document.ID, out var list)) { foreach(var bitmap in list) { var image = new Image { Source = bitmap, Margin = new Thickness(0, 0, 0, 20) }; image.ContextMenu = ViewListPanel.ContextMenu; ViewListPanel.Children.Add(image); } } } } #endregion #region Uploading private void DynamicTabItem_Drop(object sender, DragEventArgs e) { Task.Run(() => { var docs = DocumentManipulationWindow.HandleFileDrop(e); if (docs is not null) { foreach(var (filename, doc) in docs) { ScanGrid.UploadDocument(Path.ChangeExtension(filename, ".pdf"), doc.SaveToBytes(), Guid.Empty); } /*Dispatcher.Invoke(() => { ScanGrid.ShowDocumentWindow(pages, filename); });*/ } }); } private void DynamicTabItem_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor")) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.None; } e.Handled = true; } #endregion private void ScanGrid_OnSelectItem(object sender, DynamicGridSelectionEventArgs e) { UpdateViewList(); var appliesTo = e?.Rows?.Length == 1 ? e.Rows[0].Get(x => x.Tag.AppliesTo) : ""; OnSelectAppliesTo?.Invoke(appliesTo); } private void ScanGrid_OnSelectAppliesTo(string appliesTo) { OnSelectAppliesTo?.Invoke(appliesTo); } private void _Explode_OnClick(object sender, RoutedEventArgs e) { this.ScanGrid.DoExplode(); } } }