DynamicDocumentGrid.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using System.Drawing;
  6. using System.Drawing.Printing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text.RegularExpressions;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using System.Windows.Data;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. using FastReport;
  17. using InABox.Clients;
  18. using InABox.Core;
  19. using InABox.WPF;
  20. using Microsoft.Win32;
  21. using Microsoft.Xaml.Behaviors.Core;
  22. using RoslynPad.Editor;
  23. using Syncfusion.Pdf.Interactive;
  24. using Syncfusion.Pdf.Parsing;
  25. using Syncfusion.Pdf;
  26. using Syncfusion.Windows.Controls.Grid;
  27. using Syncfusion.Windows.PdfViewer;
  28. using Border = System.Windows.Controls.Border;
  29. using Color = System.Windows.Media.Color;
  30. using Image = System.Windows.Controls.Image;
  31. namespace InABox.DynamicGrid
  32. {
  33. public class DocumentConverter : UtilityConverter<object, object>
  34. {
  35. public override object Convert(object value)
  36. {
  37. return value;
  38. }
  39. }
  40. public class TimeStampToBrushConverter : UtilityConverter<DateTime, System.Windows.Media.Brush?>
  41. {
  42. public System.Windows.Media.Brush? Empty { get; init; }
  43. public System.Windows.Media.Brush? Set { get; init; }
  44. public override System.Windows.Media.Brush? Convert(DateTime value)
  45. {
  46. return value.IsEmpty()
  47. ? Empty
  48. : Set;
  49. }
  50. }
  51. public delegate String OnGetWatermark(CoreRow row);
  52. public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyToManyGrid<TDocument, TEntity>
  53. where TEntity : Entity, IPersistent, IRemotable, new()
  54. where TDocument : Entity, IEntityDocument<TEntityLink>, IPersistent, IRemotable, new() // Entity, IPersistent, IRemotable, IManyToMany<TEntity, Document>, new()
  55. where TEntityLink : EntityLink<TEntity>, new()
  56. {
  57. // private DynamicActionColumn supercedecolumn;
  58. //
  59. // public bool ShowSupercededColumn
  60. // {
  61. // get
  62. // {
  63. // return supercedecolumn.Position != DynamicActionColumnPosition.Hidden;
  64. // }
  65. // set
  66. // {
  67. // supercedecolumn.Position = value ? DynamicActionColumnPosition.End : DynamicActionColumnPosition.Hidden;
  68. // }
  69. // }
  70. public bool ShowSupercededColumn { get; set; }
  71. private DynamicTemplateColumn _template;
  72. public DynamicDocumentGrid()
  73. {
  74. MultiSelect = false;
  75. HiddenColumns.Add(x => x.DocumentLink.ID);
  76. HiddenColumns.Add(x => x.Superceded);
  77. HiddenColumns.Add(x => x.DocumentLink.FileName);
  78. HiddenColumns.Add(x => x.Thumbnail);
  79. HiddenColumns.Add(x => x.Notes);
  80. //ActionColumns.Add(new DynamicImageColumn(DocumentImage, ViewDocument) { Position = DynamicActionColumnPosition.Start });
  81. //ActionColumns.Add(new DynamicImageColumn(DiskImage, SaveDocument) { Position = DynamicActionColumnPosition.Start });
  82. _template = new DynamicTemplateColumn(DocumentTemplate)
  83. {
  84. Position = DynamicActionColumnPosition.Start,
  85. Width = 0,
  86. HeaderText = "Attached Documents"
  87. };
  88. ActionColumns.Add(_template);
  89. //supercedecolumn = new DynamicImageColumn(SupercededImage, SupercedeDocument);
  90. //ActionColumns.Add(supercedecolumn);
  91. }
  92. protected override void DoDoubleClick(object sender)
  93. {
  94. var doc = SelectedRows.FirstOrDefault()?.ToObject<TDocument>();
  95. if (doc != null)
  96. {
  97. var editor = new DocumentEditor(new IEntityDocument[] { doc });
  98. //editor.PrintAllowed = Security.IsAllowed<CanPrintFactoryFloorDrawings>();
  99. editor.SaveAllowed = false;
  100. editor.ShowDialog();
  101. }
  102. }
  103. private FrameworkElement DocumentTemplate()
  104. {
  105. Grid grid = new Grid()
  106. {
  107. Height = 100,
  108. RowDefinitions =
  109. {
  110. new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
  111. new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) },
  112. },
  113. ColumnDefinitions =
  114. {
  115. new ColumnDefinition() { Width = new GridLength(100) },
  116. new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
  117. new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) },
  118. },
  119. ContextMenu = new ContextMenu()
  120. };
  121. // grid.SetBinding(
  122. // Grid.BackgroundProperty,
  123. // new Binding("Superceded")
  124. // {
  125. // Converter = new TimeStampToBrushConverter()
  126. // {
  127. // Empty = new SolidColorBrush(Colors.LightYellow),
  128. // Set = new SolidColorBrush(Colors.Silver)
  129. // }
  130. // }
  131. // );
  132. grid.ContextMenu.Items.Add(new MenuItem()
  133. {
  134. Header = "View Documents",
  135. Command = new ActionCommand(ViewDocuments)
  136. });
  137. grid.ContextMenu.Items.Add(new MenuItem()
  138. {
  139. Header = "Copy To Clipboard",
  140. Command = new ActionCommand(CopyDocuments)
  141. });
  142. grid.ContextMenu.Items.Add(new MenuItem()
  143. {
  144. Header = "Save Documents",
  145. Command = new ActionCommand(SaveDocuments)
  146. });
  147. Image thumbnail = new Image()
  148. {
  149. Stretch = Stretch.Uniform,
  150. Margin = new Thickness(5,2,5,2),
  151. };
  152. var ttImage = new Image();
  153. ttImage.SetBinding(Image.SourceProperty,
  154. new Binding("Thumbnail") { Converter = new BytesToBitmapImageConverter() });
  155. thumbnail.ToolTip = new ToolTip()
  156. {
  157. Content = ttImage
  158. };
  159. thumbnail.SetBinding(Image.SourceProperty, new Binding("Thumbnail") { Converter = new BytesToBitmapImageConverter() });
  160. thumbnail.SetValue(Grid.RowProperty,0);
  161. thumbnail.SetValue(Grid.RowSpanProperty,2);
  162. thumbnail.SetValue(Grid.ColumnProperty,0);
  163. grid.Children.Add(thumbnail);
  164. var dock = new DockPanel();
  165. dock.SetValue(Grid.RowProperty,0);
  166. dock.SetValue(Grid.ColumnProperty,1);
  167. grid.Children.Add(dock);
  168. var superceded = new Label()
  169. {
  170. FontWeight = FontWeights.Bold,
  171. Content = "*** SUPERCEDED ***",
  172. Margin = new Thickness(0,0,5,0)
  173. };
  174. superceded.SetBinding(Label.VisibilityProperty, new Binding("Superceded") { Converter = new DateTimeToVisibilityConverter() });
  175. superceded.SetValue(DockPanel.DockProperty, Dock.Left);
  176. dock.Children.Add(superceded);
  177. var filename = new Label()
  178. {
  179. FontWeight = FontWeights.Bold
  180. };
  181. filename.SetBinding(Label.ContentProperty, new Binding("DocumentLink_FileName"));
  182. filename.SetValue(DockPanel.DockProperty, Dock.Left);
  183. dock.Children.Add(filename);
  184. var buttons = new StackPanel()
  185. {
  186. Orientation = Orientation.Horizontal
  187. };
  188. buttons.SetValue(Grid.RowProperty,0);
  189. buttons.SetValue(Grid.ColumnProperty,2);
  190. grid.Children.Add(buttons);
  191. var view = new Button()
  192. {
  193. Content = new Image() { Source = Wpf.Resources.multi_image.AsBitmapImage() },
  194. BorderBrush = new SolidColorBrush(Colors.Transparent),
  195. Background = new SolidColorBrush(Colors.Transparent),
  196. Height = 32,
  197. Width = 32,
  198. Command = new ActionCommand(ViewDocuments)
  199. };
  200. buttons.Children.Add(view);
  201. var copy = new Button()
  202. {
  203. Content = new Image() { Source = Wpf.Resources.copy.AsBitmapImage() },
  204. BorderBrush = new SolidColorBrush(Colors.Transparent),
  205. Background = new SolidColorBrush(Colors.Transparent),
  206. Height = 32,
  207. Width = 32,
  208. Command = new ActionCommand(CopyDocuments)
  209. };
  210. buttons.Children.Add(copy);
  211. var save = new Button()
  212. {
  213. Content = new Image() { Source = Wpf.Resources.download.AsBitmapImage() },
  214. BorderBrush = new SolidColorBrush(Colors.Transparent),
  215. Background = new SolidColorBrush(Colors.Transparent),
  216. Height = 32,
  217. Width = 32,
  218. Command = new ActionCommand(SaveDocuments)
  219. };
  220. buttons.Children.Add(save);
  221. var print = new Button()
  222. {
  223. Content = new Image() { Source = Wpf.Resources.print.AsBitmapImage(), Margin=new Thickness(2) },
  224. BorderBrush = new SolidColorBrush(Colors.Transparent),
  225. Background = new SolidColorBrush(Colors.Transparent),
  226. Height = 32,
  227. Width = 32,
  228. Command = new ActionCommand(PrintDocuments)
  229. };
  230. buttons.Children.Add(print);
  231. var notes = new Label()
  232. {
  233. };
  234. notes.SetBinding(Label.ContentProperty, new Binding("Notes"));
  235. notes.SetValue(Grid.RowProperty,1);
  236. notes.SetValue(Grid.ColumnProperty,1);
  237. notes.SetValue(Grid.ColumnSpanProperty,2);
  238. grid.Children.Add(notes);
  239. return grid;
  240. }
  241. private void GetDocuments(Action<Dictionary<string,byte[]>> action)
  242. {
  243. var ids = SelectedRows.Select(r => r.Get<IEntityDocument, Guid>(c => c.DocumentLink.ID)).ToArray();
  244. var files = new Client<Document>().Query(
  245. new Filter<Document>(x => x.ID).InList(ids),
  246. new Columns<Document>(x => x.FileName).Add(x => x.Data)
  247. ).ToDictionary<Document, String, byte[]>(x => x.FileName, x => x.Data);
  248. action?.Invoke(files);
  249. }
  250. private String SanitiseFileName(string filename)
  251. {
  252. var basefilename = Path.GetFileNameWithoutExtension(filename);
  253. var extension = Path.GetExtension(filename);
  254. return Path.ChangeExtension(string.Join("_", basefilename.Split(Path.GetInvalidFileNameChars())), extension);
  255. }
  256. private void ViewDocuments()
  257. {
  258. GetDocuments((files) =>
  259. {
  260. foreach (var file in files)
  261. {
  262. Task.Run(() =>
  263. {
  264. var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
  265. File.WriteAllBytes(tempfile, file.Value);
  266. var info = new System.Diagnostics.ProcessStartInfo(tempfile);
  267. info.UseShellExecute = true;
  268. info.Verb = "Open";
  269. Process.Start(info);
  270. });
  271. }
  272. });
  273. }
  274. private void CopyDocuments()
  275. {
  276. if (SelectedRows?.Any() != true)
  277. return;
  278. GetDocuments((files) =>
  279. {
  280. System.Collections.Specialized.StringCollection FileCollection = new System.Collections.Specialized.StringCollection();
  281. foreach(var file in files)
  282. {
  283. var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
  284. File.WriteAllBytes(tempfile, file.Value);
  285. FileCollection.Add(tempfile);
  286. }
  287. Clipboard.SetFileDropList(FileCollection);
  288. });
  289. }
  290. private void SaveDocuments()
  291. {
  292. if (SelectedRows?.Any() != true)
  293. return;
  294. using(var fbd = new System.Windows.Forms.FolderBrowserDialog())
  295. {
  296. var result = fbd.ShowDialog();
  297. if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
  298. {
  299. var path = fbd.SelectedPath;
  300. GetDocuments(files =>
  301. {
  302. foreach (var file in files)
  303. File.WriteAllBytes(Path.Combine(path, SanitiseFileName(file.Key)), file.Value);
  304. });
  305. }
  306. }
  307. }
  308. private void PrintDocuments()
  309. {
  310. if (SelectedRows?.Any() != true)
  311. return;
  312. GetDocuments(files =>
  313. {
  314. Task.Run(() =>
  315. {
  316. foreach (var file in files)
  317. {
  318. var tempfile = Path.Combine(System.IO.Path.GetTempPath(), SanitiseFileName(file.Key));
  319. File.WriteAllBytes(tempfile, file.Value);
  320. var info = new System.Diagnostics.ProcessStartInfo(tempfile);
  321. info.CreateNoWindow = true;
  322. info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
  323. info.UseShellExecute = true;
  324. info.Verb = "print";
  325. Process.Start(info);
  326. }
  327. });
  328. });
  329. }
  330. protected override DynamicGridColumns LoadColumns()
  331. {
  332. return new DynamicGridColumns();
  333. }
  334. protected override void DoReconfigure(FluentList<DynamicGridOption> options)
  335. {
  336. base.DoReconfigure(options);
  337. options.Remove(DynamicGridOption.SelectColumns);
  338. options.Add(DynamicGridOption.DragTarget);
  339. }
  340. // private bool SaveDocument(CoreRow? row)
  341. // {
  342. // var filename = row.Get<TDocument, string>(x => x.DocumentLink.FileName);
  343. // if (Path.GetExtension(filename).ToUpper().Equals(".PDF"))
  344. // {
  345. // var dlg = new SaveFileDialog();
  346. // dlg.Filter = "PDF Files (*.pdf)|*.pdf";
  347. // dlg.FileName = Path.ChangeExtension(filename, ".pdf");
  348. // if (dlg.ShowDialog() == true)
  349. // {
  350. // var imageid = row.Get<TDocument, Guid>(x => x.DocumentLink.ID);
  351. // var data = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(imageid)).Rows.FirstOrDefault().Get<Document, byte[]>(x => x.Data);
  352. // var name = dlg.FileName;
  353. // File.WriteAllBytes(name, data);
  354. //
  355. // var gsProcessInfo = new ProcessStartInfo();
  356. // gsProcessInfo.Verb = "open";
  357. // gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal;
  358. // gsProcessInfo.FileName = name;
  359. // gsProcessInfo.UseShellExecute = true;
  360. //
  361. // Process.Start(gsProcessInfo);
  362. // }
  363. //
  364. // }
  365. // else if (Path.GetExtension(filename).ToUpper().Equals(".PNG") || Path.GetExtension(filename).ToUpper().Equals(".JPG") || Path.GetExtension(filename).ToUpper().Equals(".GIF"))
  366. // {
  367. // var imageid = row.Get<TDocument, Guid>(x => x.DocumentLink.ID);
  368. // if (imageid == Guid.Empty)
  369. // return false;
  370. //
  371. // var dlg = new SaveFileDialog();
  372. // dlg.Filter = "Image Files (*.png)|*.png";
  373. // dlg.FileName = filename;
  374. // if (dlg.ShowDialog() == true)
  375. // {
  376. // var bmp = LoadBitmapFromDatabase(imageid);
  377. // bmp?.Save(dlg.FileName);
  378. // }
  379. // }
  380. //
  381. // return false;
  382. // }
  383. //
  384. // private Bitmap LoadBitmapFromDatabase(Guid imageid)
  385. // {
  386. // if (imageid == Guid.Empty)
  387. // return null;
  388. // Bitmap result = null;
  389. // var image = new Client<Document>().Query(
  390. // new Filter<Document>(x => x.ID).IsEqualTo(imageid),
  391. // new Columns<Document>(x => x.ID, x => x.Data)
  392. // ).Rows.FirstOrDefault();
  393. // if (image != null)
  394. // {
  395. // var ms = new MemoryStream(image.Get<Document, byte[]>(x => x.Data));
  396. // result = new Bitmap(ms);
  397. // }
  398. //
  399. // return result;
  400. // }
  401. // private BitmapImage? DiskImage(CoreRow? arg)
  402. // {
  403. // return Wpf.Resources.disk.AsBitmapImage();
  404. // }
  405. public override int Order()
  406. {
  407. return int.MaxValue;
  408. }
  409. // private BitmapImage SupercededImage(CoreRow? row)
  410. // {
  411. // if (row == null)
  412. // return Wpf.Resources.tick.AsBitmapImage();
  413. // if (row.Get<TDocument, DateTime>(x => x.Superceded) != DateTime.MinValue)
  414. // return Wpf.Resources.warning.AsBitmapImage();
  415. // return Wpf.Resources.tick.AsBitmapImage();
  416. // }
  417. //
  418. // private bool SupercedeDocument(CoreRow? row)
  419. // {
  420. // if (!ReadOnly)
  421. // {
  422. // var id = row.Get<TDocument, Guid>(x => x.ID);
  423. // var document = WorkingList.FirstOrDefault(x => x.ID.Equals(id));
  424. // if (document != null)
  425. // document.Superceded = document.Superceded == DateTime.MinValue ? DateTime.Now : DateTime.MinValue;
  426. // return true;
  427. // }
  428. // else
  429. // {
  430. // return false;
  431. // }
  432. // }
  433. //
  434. // private BitmapImage DocumentImage(CoreRow? arg)
  435. // {
  436. // return Wpf.Resources.view.AsBitmapImage();
  437. // }
  438. //
  439. // private bool ViewDocument(CoreRow? row)
  440. // {
  441. // var filename = row.Get<TDocument, string>(x => x.DocumentLink.FileName);
  442. // if (Path.GetExtension(filename).ToUpper().Equals(".PDF"))
  443. // {
  444. // var viewer = new DocumentEditor(row.ToObject<TDocument>());
  445. // viewer.Watermark = OnGetWaterMark?.Invoke(row);
  446. // //viewer.PrintAllowed = true;
  447. // viewer.SaveAllowed = true;
  448. // viewer.ShowDialog();
  449. // }
  450. // else
  451. // {
  452. // var id = row.Get<TDocument, Guid>(x => x.DocumentLink.ID);
  453. // var docrow = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(id)).Rows.FirstOrDefault();
  454. // if (docrow != null)
  455. // {
  456. // var tmpfile = Path.ChangeExtension(Path.GetTempFileName(), Path.GetExtension(filename));
  457. // File.WriteAllBytes(tmpfile, docrow.Get<Document, byte[]>(x => x.Data));
  458. // var gsProcessInfo = new ProcessStartInfo();
  459. // gsProcessInfo.Verb = "open";
  460. // gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal;
  461. // gsProcessInfo.FileName = tmpfile;
  462. // gsProcessInfo.UseShellExecute = true;
  463. //
  464. // Process.Start(gsProcessInfo);
  465. // }
  466. // else
  467. // {
  468. // MessageBox.Show(string.Format("Unable to retrieve {0}!", filename));
  469. // }
  470. // }
  471. //
  472. // //Document doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
  473. // //if (doc != null)
  474. // //{
  475. // // if (System.IO.Path.GetExtension(doc.FileName).ToUpper().Equals(".PDF"))
  476. // // {
  477. // // PDFViewer viewer = new PDFViewer(doc);
  478. // // viewer.ShowDialog();
  479. // // }
  480. // // else
  481. // // {
  482. // // String filename = System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), System.IO.Path.GetExtension(doc.FileName));
  483. // // System.IO.File.WriteAllBytes(filename, doc.Data);
  484. // // ProcessStartInfo gsProcessInfo = new ProcessStartInfo();
  485. // // gsProcessInfo.Verb = "open";
  486. // // gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal;
  487. // // gsProcessInfo.UseShellExecute = true;
  488. // // gsProcessInfo.FileName = filename;
  489. // // Process.Start(gsProcessInfo);
  490. // // }
  491. // //}
  492. // //else
  493. // // MessageBox.Show("Document does nto exist!");
  494. // return false;
  495. // }
  496. public event OnGetWatermark OnGetWaterMark;
  497. protected override void OnDragEnd(Type entity, CoreTable table, DragEventArgs e)
  498. {
  499. if (entity == typeof(Document))
  500. {
  501. var refresh = false;
  502. var docIDS = table.Rows.Select(x => x.Get<Document, Guid>(x => x.ID)).ToArray();
  503. var columns = new Columns<Document>(x => x.ID);
  504. foreach (var column in VisibleColumns)
  505. {
  506. if (column.ColumnName.StartsWith("DocumentLink."))
  507. {
  508. columns.Add(string.Join('.', column.ColumnName.Split('.').Skip(1)));
  509. }
  510. }
  511. var docs = new Client<Document>()
  512. .Query(
  513. new Filter<Document>(x => x.ID).InList(docIDS),
  514. columns);
  515. foreach (var doc in docs.ToObjects<Document>())
  516. {
  517. var entityDocument = new TDocument();
  518. entityDocument.EntityLink.ID = Item.ID;
  519. entityDocument.DocumentLink.ID = doc.ID;
  520. entityDocument.DocumentLink.Synchronise(doc);
  521. SaveItem(entityDocument);
  522. refresh = true;
  523. }
  524. if (refresh)
  525. {
  526. Refresh(false, true);
  527. }
  528. }
  529. else
  530. {
  531. base.OnDragEnd(entity, table, e);
  532. }
  533. }
  534. protected override void DoAdd(bool OpenEditorOnDirectEdit = false)
  535. {
  536. var dlg = new OpenFileDialog();
  537. dlg.Multiselect = true;
  538. if (dlg.ShowDialog() == true)
  539. {
  540. using (new WaitCursor())
  541. {
  542. var docs = new List<Document>();
  543. foreach (var filename in dlg.FileNames)
  544. {
  545. // Create a Document
  546. var doc = new Document();
  547. doc.FileName = Path.GetFileName(filename).ToLower();
  548. doc.TimeStamp = new FileInfo(dlg.FileName).LastWriteTime;
  549. doc.Data = File.ReadAllBytes(filename);
  550. doc.CRC = CoreUtils.CalculateCRC(doc.Data);
  551. docs.Add(doc);
  552. }
  553. if (docs.Any())
  554. {
  555. new Client<Document>().Save(docs, "Initial Upload");
  556. foreach (var doc in docs)
  557. {
  558. var newitem = CreateItem();
  559. var prop = (IEntityLink)otherproperty.GetValue(newitem);
  560. prop.ID = doc.ID;
  561. prop.Synchronise(doc);
  562. SaveItem(newitem);
  563. }
  564. DoChanged();
  565. }
  566. }
  567. Refresh(false, true);
  568. }
  569. }
  570. }
  571. }