| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Diagnostics;
 
- using System.IO;
 
- using System.Linq;
 
- using System.Threading.Tasks;
 
- using System.Windows;
 
- using System.Windows.Controls;
 
- using System.Windows.Data;
 
- using System.Windows.Media;
 
- using System.Windows.Media.Imaging;
 
- using InABox.Core;
 
- using InABox.WPF;
 
- using Microsoft.Win32;
 
- using Microsoft.Xaml.Behaviors.Core;
 
- using Image = System.Windows.Controls.Image;
 
- using InABox.Wpf;
 
- using System.Threading;
 
- namespace InABox.DynamicGrid;
 
- public class DocumentConverter : AbstractConverter<object, object>
 
- {
 
-     public override object Convert(object value)
 
-     {
 
-         return value;
 
-     }
 
- }
 
- public class TimeStampToBrushConverter : AbstractConverter<DateTime, System.Windows.Media.Brush?>
 
- {
 
-     public System.Windows.Media.Brush? Empty { get; init; }
 
-     public System.Windows.Media.Brush? Set { get; init; }
 
-     
 
-     public override System.Windows.Media.Brush? Convert(DateTime value)
 
-     {
 
-         return value.IsEmpty()
 
-             ? Empty
 
-             : Set;
 
-     }
 
- }
 
- public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyToManyGrid<TDocument, TEntity>
 
-     where TEntity : Entity, IPersistent, IRemotable, new()
 
-     where TDocument : Entity, IEntityDocument<TEntityLink>, IPersistent, IRemotable, new() // Entity, IPersistent, IRemotable, IManyToMany<TEntity, Document>, new()
 
-     where TEntityLink : EntityLink<TEntity>, new()
 
- {
 
-     
 
-     public bool ShowSupercededColumn { get; set; }
 
-     private bool _simpleTemplate;
 
-     public bool SimpleTemplate
 
-     {
 
-         get => _simpleTemplate;
 
-         set
 
-         {
 
-             _simpleTemplate = value;
 
-             RowHeight = value
 
-                 ? 150
 
-                 : 100;
 
-         } 
 
-     }
 
-     private DynamicTemplateColumn _template;
 
-     
 
-     public DynamicDocumentGrid()
 
-     {
 
-         MultiSelect = false;
 
-         HiddenColumns.Add(x => x.DocumentLink.ID);
 
-         HiddenColumns.Add(x => x.Superceded);
 
-         HiddenColumns.Add(x => x.DocumentLink.FileName);
 
-         HiddenColumns.Add(x => x.Thumbnail);
 
-         HiddenColumns.Add(x => x.Notes);
 
-         //ActionColumns.Add(new DynamicImageColumn(DocumentImage, ViewDocument) { Position = DynamicActionColumnPosition.Start });
 
-         //ActionColumns.Add(new DynamicImageColumn(DiskImage, SaveDocument) { Position = DynamicActionColumnPosition.Start });
 
-         _template = new DynamicTemplateColumn(DocumentTemplate)
 
-         {
 
-             Position = DynamicActionColumnPosition.Start,
 
-             Width = 0,
 
-             HeaderText = "Attached Documents"
 
-         };
 
-         ActionColumns.Add(_template);
 
-         //supercedecolumn = new DynamicImageColumn(SupercededImage, SupercedeDocument);
 
-         //ActionColumns.Add(supercedecolumn);
 
-         RowHeight = 100;
 
-     }
 
-     protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
 
-     {
 
-         var doc = SelectedRows.FirstOrDefault()?.ToObject<TDocument>();
 
-         if (doc != null)
 
-         {
 
-             var editor = new DocumentEditor(new IEntityDocument[] { doc });
 
-             //editor.PrintAllowed = Security.IsAllowed<CanPrintFactoryFloorDrawings>();
 
-             editor.SaveAllowed = false;
 
-             editor.ShowDialog();
 
-         }
 
-     }
 
-     private FrameworkElement DocumentTemplate(CoreRow row)
 
-     {
 
-         return SimpleTemplate
 
-             ? CreateSimpleTemplate()
 
-             : CreateDetailedTemplate();
 
-     }
 
-     private FrameworkElement CreateDetailedTemplate()
 
-     {
 
-         
 
-         Grid grid = new Grid()
 
-         {
 
-             Height = 100,
 
-             ContextMenu = CreateContextMenu(),
 
-             RowDefinitions = 
 
-             {
 
-                 new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
 
-                 new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) },
 
-             },
 
-             ColumnDefinitions = 
 
-             {
 
-                 new ColumnDefinition() { Width = new GridLength(100) },
 
-                 new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
 
-                 new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) },
 
-             }
 
-         };
 
-         
 
-         // grid.SetBinding(
 
-         //     Grid.BackgroundProperty,
 
-         //     new Binding("Superceded")
 
-         //     {
 
-         //         Converter = new TimeStampToBrushConverter()
 
-         //         {
 
-         //             Empty = new SolidColorBrush(Colors.LightYellow),
 
-         //             Set = new SolidColorBrush(Colors.Silver)
 
-         //         }
 
-         //     }
 
-         // );
 
-         Image thumbnail = new Image()
 
-         {
 
-             Stretch = Stretch.Uniform,
 
-             Margin = new Thickness(5, 2, 5, 2),
 
-         };
 
-         var ttImage = new Image();
 
-         ttImage.SetBinding(Image.SourceProperty,
 
-             new Binding("Thumbnail") { Converter = new BytesToBitmapImageConverter() });
 
-         thumbnail.ToolTip = new ToolTip()
 
-         {
 
-             Content = ttImage
 
-         };
 
-         thumbnail.SetBinding(Image.SourceProperty,
 
-             new Binding("Thumbnail") { Converter = new BytesToBitmapImageConverter() });
 
-         thumbnail.SetValue(Grid.RowProperty, 0);
 
-         thumbnail.SetValue(Grid.RowSpanProperty, 2);
 
-         thumbnail.SetValue(Grid.ColumnProperty, 0);
 
-         grid.Children.Add(thumbnail);
 
-         var dock = new DockPanel();
 
-         dock.SetValue(Grid.RowProperty, 0);
 
-         dock.SetValue(Grid.ColumnProperty, 1);
 
-         grid.Children.Add(dock);
 
-         var superceded = new Label()
 
-         {
 
-             FontWeight = FontWeights.Bold,
 
-             Content = "*** SUPERCEDED ***",
 
-             Margin = new Thickness(0, 0, 5, 0)
 
-         };
 
-         superceded.SetBinding(Label.VisibilityProperty,
 
-             new Binding("Superceded") { Converter = new DateTimeToVisibilityConverter() });
 
-         superceded.SetValue(DockPanel.DockProperty, Dock.Left);
 
-         dock.Children.Add(superceded);
 
-         var filename = new Label()
 
-         {
 
-             FontWeight = FontWeights.Bold
 
-         };
 
-         filename.SetBinding(Label.ContentProperty, new Binding("DocumentLink_FileName"));
 
-         filename.SetValue(DockPanel.DockProperty, Dock.Left);
 
-         dock.Children.Add(filename);
 
-         var buttons = new StackPanel()
 
-         {
 
-             Orientation = Orientation.Horizontal
 
-         };
 
-         buttons.SetValue(Grid.RowProperty, 0);
 
-         buttons.SetValue(Grid.ColumnProperty, 2);
 
-         grid.Children.Add(buttons);
 
-         var view = new Button()
 
-         {
 
-             Content = new Image() { Source = Wpf.Resources.multi_image.AsBitmapImage() },
 
-             BorderBrush = new SolidColorBrush(Colors.Transparent),
 
-             Background = new SolidColorBrush(Colors.Transparent),
 
-             Height = 32,
 
-             Width = 32,
 
-             ToolTip = "View Documents",
 
-             Command = new ActionCommand(ViewDocuments)
 
-         };
 
-         buttons.Children.Add(view);
 
-         var copy = new Button()
 
-         {
 
-             Content = new Image() { Source = Wpf.Resources.copy.AsBitmapImage() },
 
-             BorderBrush = new SolidColorBrush(Colors.Transparent),
 
-             Background = new SolidColorBrush(Colors.Transparent),
 
-             Height = 32,
 
-             Width = 32,
 
-             ToolTip = "Copy to Clipboard",
 
-             Command = new ActionCommand(CopyDocuments)
 
-         };
 
-         buttons.Children.Add(copy);
 
-         var save = new Button()
 
-         {
 
-             Content = new Image() { Source = ImageUtils.SvgToBitmapImage(Wpf.Resources.download) },
 
-             BorderBrush = new SolidColorBrush(Colors.Transparent),
 
-             Background = new SolidColorBrush(Colors.Transparent),
 
-             Height = 32,
 
-             Width = 32,
 
-             ToolTip = "Save Documents",
 
-             Command = new ActionCommand(SaveDocuments)
 
-         };
 
-         buttons.Children.Add(save);
 
-         var print = new Button()
 
-         {
 
-             Content = new Image() { Source = Wpf.Resources.print.AsBitmapImage(), Margin = new Thickness(2) },
 
-             BorderBrush = new SolidColorBrush(Colors.Transparent),
 
-             Background = new SolidColorBrush(Colors.Transparent),
 
-             Height = 32,
 
-             Width = 32,
 
-             ToolTip = "Print Documents",
 
-             Command = new ActionCommand(PrintDocuments)
 
-         };
 
-         buttons.Children.Add(print);
 
-         var notes = new Label()
 
-         {
 
-         };
 
-         notes.SetBinding(Label.ContentProperty, new Binding("Notes"));
 
-         notes.SetValue(Grid.RowProperty, 1);
 
-         notes.SetValue(Grid.ColumnProperty, 1);
 
-         notes.SetValue(Grid.ColumnSpanProperty, 2);
 
-         grid.Children.Add(notes);
 
-         return grid;
 
-     }
 
-     private ContextMenu CreateContextMenu()
 
-     {
 
-         var menu = new ContextMenu();
 
-         menu.Items.Add(new MenuItem()
 
-         {
 
-             Header = "View Documents",
 
-             Command = new ActionCommand(ViewDocuments)
 
-         });
 
-         menu.Items.Add(new MenuItem()
 
-         {
 
-             Header = "Copy To Clipboard",
 
-             Command = new ActionCommand(CopyDocuments)
 
-         });
 
-         menu.Items.Add(new MenuItem()
 
-         {
 
-             Header = "Save Documents",
 
-             Command = new ActionCommand(SaveDocuments)
 
-         });
 
-         return menu;
 
-     }
 
-     private FrameworkElement CreateSimpleTemplate()
 
-     {
 
-         Grid grid = new Grid()
 
-         {
 
-             //Height = 150,
 
-             ContextMenu = CreateContextMenu(),
 
-             RowDefinitions = 
 
-             {
 
-                 new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) },
 
-                 new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
 
-             },
 
-             ColumnDefinitions = 
 
-             {
 
-                 new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
 
-             }
 
-         };
 
-         Image thumbnail = new Image()
 
-         {
 
-             Stretch = Stretch.Uniform,
 
-             Margin = new Thickness(5),
 
-             //HorizontalAlignment = HorizontalAlignment.Stretch,
 
-             //VerticalAlignment = VerticalAlignment.Stretch
 
-         };
 
-             
 
-         thumbnail.SetBinding(Image.SourceProperty, new Binding("Thumbnail") { Converter = new BytesToBitmapImageConverter() });
 
-         thumbnail.SetValue(Grid.RowProperty,0);
 
-         grid.Children.Add(thumbnail);
 
-         
 
-         var filename = new Label()
 
-         {
 
-             HorizontalContentAlignment = HorizontalAlignment.Center,
 
-             FontSize = 10
 
-         };
 
-         filename.SetBinding(Label.ContentProperty, new Binding("DocumentLink_FileName"));
 
-         filename.SetValue(Grid.RowProperty,1);
 
-         grid.Children.Add(filename);
 
-         
 
-         return grid;
 
-     }
 
-     private void GetDocuments(Action<Dictionary<string,byte[]>> action)
 
-     {
 
-         var ids = SelectedRows.Select(r => r.Get<IEntityDocument, Guid>(c => c.DocumentLink.ID)).ToArray();
 
-         var files = Client.Query(
 
-             new Filter<Document>(x => x.ID).InList(ids),
 
-             Columns.None<Document>().Add(x => x.FileName).Add(x => x.Data)
 
-         ).ToDictionary<Document, String, byte[]>(x => x.FileName, x => x.Data);
 
-         action?.Invoke(files);
 
-     }
 
-     private static string SanitiseFileName(string filename)
 
-     {
 
-         var basefilename = Path.GetFileNameWithoutExtension(filename);
 
-         var extension = Path.GetExtension(filename);
 
-         return Path.ChangeExtension(string.Join("_", basefilename.Split(Path.GetInvalidFileNameChars())), extension);
 
-     }
 
-     private void ViewDocuments()
 
-     {
 
-         GetDocuments((files) =>
 
-         {
 
-             
 
-             foreach (var file in files)
 
-             {
 
-                 Task.Run(() =>
 
-                 {
 
-                     var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
 
-                     try
 
-                     {
 
-                         File.WriteAllBytes(tempfile, file.Value);
 
-                     }
 
-                     catch
 
-                     {
 
-                         // Outlook likes to keep files open apparently, which breaks this code.
 
-                     }
 
-                     var info = new System.Diagnostics.ProcessStartInfo(tempfile);
 
-                     info.UseShellExecute = true;
 
-                     info.Verb = "Open";
 
-                     Process.Start(info);
 
-                 });
 
-             }
 
-         });
 
-     }
 
-     private void CopyDocuments()
 
-     {
 
-         if (SelectedRows?.Any() != true)
 
-             return;
 
-         GetDocuments((files) =>
 
-         {
 
-             System.Collections.Specialized.StringCollection FileCollection = new System.Collections.Specialized.StringCollection();
 
-             foreach(var file in files)
 
-             {
 
-                 var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
 
-                 File.WriteAllBytes(tempfile, file.Value);
 
-                 FileCollection.Add(tempfile);
 
-             }
 
-             Clipboard.SetFileDropList(FileCollection);
 
-         });
 
-     }
 
-     private void SaveDocuments()
 
-     {
 
-         if (SelectedRows?.Any() != true)
 
-             return;
 
-         
 
-         using(var fbd = new System.Windows.Forms.FolderBrowserDialog())
 
-         {
 
-             var result = fbd.ShowDialog();
 
-             if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
 
-             {
 
-                 var path = fbd.SelectedPath;
 
-                 GetDocuments(files =>
 
-                 {
 
-                     foreach (var file in files)
 
-                         File.WriteAllBytes(Path.Combine(path, SanitiseFileName(file.Key)), file.Value);
 
-                 });
 
-             }
 
-         }
 
-     }
 
-     private void PrintDocuments()
 
-     {
 
-         if (SelectedRows?.Any() != true)
 
-             return;
 
-         GetDocuments(files =>
 
-         {
 
-             Task.Run(() =>
 
-             {
 
-                 foreach (var file in files)
 
-                 {
 
-                     var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
 
-                     File.WriteAllBytes(tempfile, file.Value);
 
-                     var info = new System.Diagnostics.ProcessStartInfo(tempfile);
 
-                     info.CreateNoWindow = true;
 
-                     info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
 
-                     info.UseShellExecute = true;
 
-                     info.Verb = "print";
 
-                     Process.Start(info);
 
-                 }
 
-             });
 
-         });
 
-     }
 
-     protected override DynamicGridColumns LoadColumns()
 
-     {
 
-         return new DynamicGridColumns();
 
-     }
 
-     
 
-     protected override void DoReconfigure(DynamicGridOptions options)
 
-     {
 
-         base.DoReconfigure(options);
 
-         options.SelectColumns = false;
 
-         options.DragTarget = true;
 
-     }
 
-     public override int Order { get; set; } = int.MaxValue;
 
-     protected override void HandleDragOver(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;
 
-     }
 
-     protected override void HandleDragDrop(object sender, DragEventArgs e)
 
-     {
 
-         var result = DocumentUtils.HandleFileDrop(e);
 
-         if(result is not null)
 
-         {
 
-             var docs = new List<Document>();
 
-             foreach (var (filename, stream) in result)
 
-             {
 
-                 var doc = new Document();
 
-                 doc.FileName = Path.GetFileName(filename).ToLower();
 
-                 if (stream is null)
 
-                 {
 
-                     doc.Data = File.ReadAllBytes(filename);
 
-                     doc.TimeStamp = new FileInfo(filename).LastWriteTime;
 
-                 }
 
-                 else
 
-                 {
 
-                     using var memoryStream = new MemoryStream();
 
-                     stream.CopyTo(memoryStream);
 
-                     doc.Data = memoryStream.ToArray();
 
-                     doc.TimeStamp = DateTime.Now;
 
-                 }
 
-                 doc.CRC = CoreUtils.CalculateCRC(doc.Data);
 
-                 docs.Add(doc);
 
-             }
 
-             AddDocuments(docs);
 
-         }
 
-     }
 
-     protected override void OnDragEnd(Type entity, CoreTable table, DragEventArgs e)
 
-     {
 
-         if (entity == typeof(Document))
 
-         {
 
-             var refresh = false;
 
-             var docIDS = table.Rows.Select(x => x.Get<Document, Guid>(x => x.ID)).ToArray();
 
-             var columns = Columns.None<Document>().Add(x => x.ID);
 
-             foreach (var column in VisibleColumns)
 
-             {
 
-                 if (column.ColumnName.StartsWith("DocumentLink."))
 
-                 {
 
-                     columns.Add(string.Join('.', column.ColumnName.Split('.').Skip(1)));
 
-                 }
 
-             }
 
-             var docs = Client.Query(
 
-                 new Filter<Document>(x => x.ID).InList(docIDS),
 
-                 columns);
 
-             foreach (var doc in docs.ToObjects<Document>())
 
-             {
 
-                 var entityDocument = new TDocument();
 
-                 entityDocument.EntityLink.ID = Item.ID;
 
-                 entityDocument.DocumentLink.ID = doc.ID;
 
-                 entityDocument.DocumentLink.Synchronise(doc);
 
-                 SaveItem(entityDocument);
 
-                 refresh = true;
 
-             }
 
-             if (refresh)
 
-             {
 
-                 DoChanged();
 
-                 Refresh(false, true);
 
-             }
 
-         }
 
-         else
 
-         {
 
-             base.OnDragEnd(entity, table, e);
 
-         }
 
-     }
 
-     private void AddDocuments(IList<Document> documents)
 
-     {
 
-         if (documents.Any())
 
-         {
 
-             Client.Save(documents, "Initial Upload");
 
-             foreach (var doc in documents)
 
-             {
 
-                 var newitem = CreateItem();
 
-                 var prop = GetOtherLink(newitem);
 
-                 prop.ID = doc.ID;
 
-                 prop.Synchronise(doc);
 
-                 SaveItem(newitem);
 
-             }
 
-             DoChanged();
 
-             Refresh(false, true);
 
-         }
 
-     }
 
-     protected override void DoAdd(bool openEditorOnDirectEdit = false)
 
-     {
 
-         var dlg = new OpenFileDialog();
 
-         dlg.Multiselect = true;
 
-         if (dlg.ShowDialog() == true)
 
-         {
 
-             using (new WaitCursor())
 
-             {
 
-                 var docs = new List<Document>();
 
-                 foreach (var filename in dlg.FileNames)
 
-                 {
 
-                     // Create a Document
 
-                     var doc = new Document();
 
-                     doc.FileName = Path.GetFileName(filename).ToLower();
 
-                     doc.TimeStamp = new FileInfo(dlg.FileName).LastWriteTime;
 
-                     doc.Data = File.ReadAllBytes(filename);
 
-                     doc.CRC = CoreUtils.CalculateCRC(doc.Data);
 
-                     docs.Add(doc);
 
-                 }
 
-                 AddDocuments(docs);
 
-             }
 
-         }
 
-     }
 
-     protected override void Reload(
 
-         Filters<TDocument> criteria, Columns<TDocument> columns, ref SortOrder<TDocument>? sort, 
 
-         CancellationToken token, Action<CoreTable?, Exception?> action)
 
-     {
 
-         base.Reload(criteria, columns, ref sort, token, (t,e) =>
 
-         {
 
-             if (token.IsCancellationRequested) return;
 
-             action(t,e);
 
-             
 
-             // Download Hi Res images in the background and replace them when available
 
-             if (t != null && SimpleTemplate)
 
-             {
 
-                 var ids = t.ExtractValues<TDocument, Guid>(x => x.DocumentLink.ID).Distinct().ToArray();
 
-                 Client.Query(
 
-                     new Filter<Document>(x => x.ID).InList(ids),
 
-                     Columns.None<Document>().Add(x => x.ID).Add(x => x.Data),
 
-                     null,
 
-                     null,
 
-                     (d, _) =>
 
-                     {
 
-                         if (token.IsCancellationRequested) return;
 
-                         if (d == null)
 
-                             return;
 
-                         var docs = d.ToDictionary<Document, Guid, byte[]>(x => x.ID, x => x.Data);
 
-                         foreach (var row in t.Rows)
 
-                         {
 
-                             if (docs.TryGetValue(row.Get<TDocument, Guid>(x => x.DocumentLink.ID),
 
-                                     out byte[]? data) && (data?.Any() == true))
 
-                             {
 
-                                 if (ImageUtils.IsPdf(data))
 
-                                     data = ImageUtils.PDFToBitmap(data, 0);
 
-                                 row.Set<TDocument, byte[]>(x => x.Thumbnail!, data);
 
-                             }
 
-                         }
 
-                         Dispatcher.BeginInvoke(() => base.Refresh(false,false));
 
-                     }
 
-                 );
 
-             }
 
-         });
 
-     }
 
- }
 
 
  |