using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Syncfusion.Pdf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace PRSDesktop { public class ScanGrid : DynamicDataGrid { private List? _tags; private Button? ExplodeBtn; public delegate void SelectAppliesTo(string appliesTo); public event SelectAppliesTo? OnSelectAppliesTo; public ScanGrid() { Options.BeginUpdate() .Clear() .Add(DynamicGridOption.MultiSelect) .Add(DynamicGridOption.DragSource) .Add(DynamicGridOption.SelectColumns) .EndUpdate(); if (Security.CanEdit() || Security.IsAllowed()) { ActionColumns.Add(new DynamicMenuColumn(MenuBuild, null)); } // if (Security.CanEdit()) // { // ExplodeBtn = AddButton("Explode", null, Explode_Click); // } HiddenColumns.Add(x => x.Tag.ID); HiddenColumns.Add(x => x.Tag.AppliesTo); HiddenColumns.Add(x => x.Document.ID); } protected override void SelectItems(CoreRow[]? rows) { base.SelectItems(rows); if(ExplodeBtn is not null) { ExplodeBtn.Visibility = rows is not null && rows.Any() ? Visibility.Visible : Visibility.Collapsed; } } public void DoExplode() { if (DoExplode(SelectedRows)) Refresh(false,true); } private bool Explode_Click(Button button, CoreRow[] rows) { return DoExplode(rows); } private bool DoExplode(CoreRow[] rows) { Guid tagID = Guid.Empty; foreach (var row in rows) { var rowTag = row.Get(x => x.Tag.ID); if (tagID == Guid.Empty) { tagID = rowTag; } else if (rowTag != tagID) { tagID = Guid.Empty; break; } } var docIDs = rows.Select(x => x.Get(x => x.Document.ID)).ToArray(); var docs = new Client() .Query( new Filter(x => x.ID).InList(docIDs), new Columns(x => x.ID).Add(x => x.Data).Add(x => x.FileName)) .ToObjects().ToDictionary(x => x.ID, x => x); var pages = new List(); string filename = ""; foreach (var docID in docIDs) { if (docs.TryGetValue(docID, out var doc)) { filename = doc.FileName; var ms = new MemoryStream(doc.Data); var pdfDoc = DocumentManipulationWindow.RenderToPDF(doc.FileName, ms); foreach (var page in DocumentManipulationWindow.SplitIntoPages(doc.FileName, pdfDoc)) { pages.Add(page); } } } if (ShowDocumentWindow(pages, filename, tagID)) { // ShowDocumentWindow already saves new scans, so we just need to get rid of the old ones. DeleteItems(rows); return true; } return false; } private bool SetupTags_Click(System.Windows.Controls.Button button, CoreRow[] rows) { var list = new MasterList(typeof(ScanTag)); if (list.ShowDialog() == true) return true; return false; } public static List GetVisibleScanTagList() { var tags = new Client().Query().ToObjects().ToList(); var tagsList = new List(); foreach (var tag in tags) { var entity = CoreUtils.GetEntityOrNull(tag.AppliesTo); if (entity is null || Security.CanView(entity)) { var tagHasEmployee = new Client() .Query( new Filter(x => x.Tag.ID).IsEqualTo(tag.ID) .And(x => x.Employee.ID).IsEqualTo(App.EmployeeID), new Columns(x => x.ID)) .Rows.Any(); if (tagHasEmployee) { tagsList.Add(tag); } } } return tagsList; } private List GetVisibleTags() { _tags ??= GetVisibleScanTagList(); return _tags; } private void MenuBuild(DynamicMenuColumn column, CoreRow? row) { if (row is null) return; if (Security.CanEdit() || Security.IsAllowed()) { var changeTag = column.AddItem("Change Tag", null, null); changeTag.AddItem("(No Tag)", null, new Tuple(row, null), SetTag_Click); foreach (var tag in GetVisibleTags()) { changeTag.AddItem(tag.Name, null, new Tuple(row, tag), SetTag_Click); } } if (Security.CanEdit()) { var processed = row.Get(x => x.Processed); column.AddItem(processed ? "Mark as not processed" : "Mark as processed", null, Process_Click); } if(OnSelectAppliesTo is not null) { column.AddItem("Go to Document", null, Document_Click); } } private void Document_Click(CoreRow? row) { if (row is null) return; OnSelectAppliesTo?.Invoke(row.Get(x => x.Tag.AppliesTo)); } private void SetTag_Click(Tuple obj) { var scan = obj.Item1.ToObject(); scan.Tag.ID = obj.Item2?.ID ?? Guid.Empty; SaveItem(scan); Refresh(false, true); } private void Process_Click(CoreRow? row) { if (row is null) return; var scan = row.ToObject(); if (!scan.Processed && MessageBox.Show("Doing this will remove this scan from the list. Do you wish to continue?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes) { return; } scan.Processed = !scan.Processed; SaveItem(scan); Refresh(false, true); } protected override void OnRowsDragStart(CoreRow[] rows) { var table = new CoreTable(); table.Columns.Add(new CoreColumn { ColumnName = "ID", DataType = typeof(Guid) }); foreach(var row in rows) { var newRow = table.NewRow(); newRow.Set(x => x.ID, row.Get(x => x.Document.ID)); table.Rows.Add(newRow); } DragTable(typeof(Document), table); } public void UploadDocument(string filename, byte[] data, Guid tagID) { var document = new Document { FileName = filename, CRC = CoreUtils.CalculateCRC(data), TimeStamp = DateTime.Now, Data = data }; new Client().Save(document, ""); var scan = new Scan(); scan.Document.ID = document.ID; scan.Tag.ID = tagID; scan.Employee.ID = App.EmployeeID; scan.Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256); new Client().Save(scan, ""); Dispatcher.Invoke(() => { Refresh(false, true); }); } private static PdfDocumentBase CombinePages(IEnumerable pages) { var document = new PdfDocument(); foreach (var page in pages) { document.ImportPage(page.Pdf, page.PageIndex); } return document; } public bool ShowDocumentWindow(List pages, string filename, Guid tagID) { var window = new DocumentManipulationWindow(pages, filename, tagID); if (window.ShowDialog() == true) { Progress.ShowModal("Uploading Files", (progress) => { foreach (var group in window.Groups) { progress.Report($"Uploading '{group.FileName}'"); var doc = CombinePages(group.Pages); byte[] data; using (var ms = new MemoryStream()) { doc.Save(ms); data = ms.ToArray(); } UploadDocument(group.FileName, data, group.TagID); } }); return true; } return false; } protected override void DoAdd(bool OpenEditorOnDirectEdit = false) { ShowDocumentWindow(new(), "", Guid.Empty); } protected override void GenerateColumns(DynamicGridColumns columns) { columns.Add(x => x.Document.FileName, 0, "Filename", "", InABox.Core.Alignment.MiddleLeft); columns.Add(x => x.Tag.Name, 100, "Tag", "", InABox.Core.Alignment.MiddleLeft); } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { criteria.Add(new Filter(x => x.Processed).IsEqualTo(false)); var tagFilter = new Filter(x => x.Tag.ID).InList(GetVisibleTags().Select(x => x.ID).ToArray()); if (Security.IsAllowed()) { tagFilter.Or(x => x.Tag.ID).IsEqualTo(Guid.Empty); } criteria.Add(tagFilter); base.Reload(criteria, columns, ref sort, action); } } }