SpreadsheetGrid.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Controls;
  5. using System.Windows.Documents;
  6. using System.Windows.Forms;
  7. using System.Windows.Media.Imaging;
  8. using Comal.Classes;
  9. using FastReport.Dialog;
  10. using InABox.Clients;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.DynamicGrid.Spreadsheet;
  14. using InABox.WPF;
  15. using PRSServer;
  16. namespace PRSDesktop
  17. {
  18. #region Old Stuff
  19. // public class DynamicSpreadsheetColumnGrid : DynamicItemsListGrid<CoreSpreadsheetColumn>
  20. // {
  21. //
  22. // public DynamicSpreadsheetColumnGrid()
  23. // {
  24. // OnCustomiseEditor += (form, i, column, editor) =>
  25. // {
  26. // if (editor is ButtonEditor propeditor)
  27. // propeditor.OnClick += (o, e) => PropertiesClick(o, i.FirstOrDefault());
  28. // };
  29. // }
  30. //
  31. // private void PropertiesClick(object editor, CoreSpreadsheetColumn? item)
  32. // {
  33. // if (item == null)
  34. // return;
  35. // var properties = item.GetProperties();
  36. // var gridtype = typeof(DynamicItemsListGrid<>).MakeGenericType(properties.GetType());
  37. // var grid = Activator.CreateInstance(gridtype) as IDynamicItemsListGrid;
  38. //
  39. // if (grid == null)
  40. // return;
  41. //
  42. // var expeditor = grid.MasterColumns.FirstOrDefault(x => x.Editor is ExpressionEditor)?.Editor as ExpressionEditor;
  43. // if (expeditor != null)
  44. // expeditor.OnGetVariables += () => Items.Select(x => x.Code);
  45. //
  46. // grid.Items = new List<CoreSpreadsheetColumnProperties>() { properties };
  47. //
  48. // if (grid.EditItems(new[] { properties }))
  49. // item.Properties = Serialization.Serialize(properties);
  50. // }
  51. // }
  52. // public partial class DynamicSpreadsheetGrid : UserControl
  53. // {
  54. // public DynamicSpreadsheetGrid()
  55. // {
  56. // InitializeComponent();
  57. // _sheet.ActiveGrid.Model.RowsInserted += OnInsertRows;
  58. // }
  59. //
  60. // private CoreSpreadsheet _spreadsheet = null;
  61. // public CoreSpreadsheet Spreadsheet
  62. // {
  63. // get => _spreadsheet;
  64. // set
  65. // {
  66. // _spreadsheet = value;
  67. // Load();
  68. // }
  69. // }
  70. //
  71. //
  72. // private void SetHeader(CoreSpreadsheetColumn column, int col)
  73. // {
  74. // var range = _sheet.ActiveSheet.Range[1, col];
  75. // _sheet.ActiveGrid.SetCellValue(range, String.IsNullOrWhiteSpace(column.GetProperties().Header) ? column.Code : column.GetProperties().Header);
  76. //
  77. // range.CellStyle.ColorIndex = ExcelKnownColors.Light_blue;
  78. //
  79. // range.Borders.LineStyle = ExcelLineStyle.Hair;
  80. // range.Borders.Color = ExcelKnownColors.Grey_80_percent;
  81. //
  82. // range.CellStyle.Locked = true;
  83. //
  84. // _sheet.FormatOrientation(90);
  85. // _sheet.ActiveGrid.InvalidateCell(range.Row, range.Column);
  86. // }
  87. //
  88. // private void FormatRow(CoreSpreadsheetColumn column, int row, int col)
  89. // {
  90. // var range = _sheet.ActiveSheet.Range[row, col];
  91. // var properties = column.GetProperties();
  92. // if (String.IsNullOrWhiteSpace(properties.Expression))
  93. // {
  94. // range.CellStyle.ColorIndex = Syncfusion.XlsIO.ExcelKnownColors.Light_yellow;
  95. // range.CellStyle.Locked = false;
  96. // }
  97. // else
  98. // {
  99. // _sheet.ActiveGrid.SetCellValue(range, properties.Expression);
  100. // range.CellStyle.ColorIndex = Syncfusion.XlsIO.ExcelKnownColors.Grey_25_percent;
  101. // range.CellStyle.Locked = true;
  102. // }
  103. //
  104. // range.Borders.LineStyle = ExcelLineStyle.Hair;
  105. // range.Borders.Color = ExcelKnownColors.Grey_80_percent;
  106. //
  107. // _sheet.ActiveGrid.InvalidateCell(range.Row, range.Column);
  108. // }
  109. //
  110. // public void Load()
  111. // {
  112. //
  113. // var grid = _sheet.ActiveGrid;
  114. // // Set the Header Row
  115. // int iColumn = 1;
  116. // foreach (var column in _spreadsheet.GetColumns())
  117. // SetHeader(column, iColumn++);
  118. // _sheet.ActiveSheet.AutofitRow(1);
  119. // _sheet.Workbook.ActiveSheet.Range[0, 1].FreezePanes();
  120. // _sheet.ActiveGrid.FrozenRows = 1;
  121. // _sheet.ActiveGrid.FrozenColumns = 0;
  122. //
  123. // _sheet.ProtectSheet(_sheet.ActiveSheet, Guid.NewGuid().ToString(), ExcelSheetProtection.InsertingRows | ExcelSheetProtection.DeletingRows);
  124. //
  125. // }
  126. //
  127. // private void OnInsertRows(object sender, GridRangeInsertedEventArgs e)
  128. // {
  129. // foreach (var col in _spreadsheet.GetColumns())
  130. // {
  131. //
  132. // }
  133. // }
  134. //
  135. // }
  136. #endregion
  137. public abstract class SpreadsheetGrid<TSpreadsheet, TEntity, TEntityLink> : DynamicDataGrid<TSpreadsheet>
  138. where TEntity : Entity, IPersistent, IRemotable, new()
  139. where TEntityLink : EntityLink<TEntity>, new()
  140. where TSpreadsheet : EntitySpreadsheet<TEntity, TEntityLink>, new()
  141. {
  142. public Guid ParentID { get; set; }
  143. public SpreadsheetGrid()
  144. {
  145. Options.BeginUpdate().Clear().Add(DynamicGridOption.AddRows)
  146. .Add(DynamicGridOption.EditRows)
  147. .Add(DynamicGridOption.DeleteRows)
  148. .Add(DynamicGridOption.RecordCount)
  149. .EndUpdate();
  150. ActionColumns.Add(new DynamicImageColumn(EditImage, EditSpreadsheet) { Position = DynamicActionColumnPosition.Start });
  151. HiddenColumns.Add(x => x.Superceded);
  152. ActionColumns.Add(new DynamicImageColumn(SupercededImage, SupercedeDocument));
  153. }
  154. protected override void Reload(Filters<TSpreadsheet> criteria, Columns<TSpreadsheet> columns, ref SortOrder<TSpreadsheet>? sort,
  155. Action<CoreTable?, Exception?> action)
  156. {
  157. if ((ParentID == Guid.Empty) || (ParentID == CoreUtils.FullGuid))
  158. criteria.Add(new Filter<TSpreadsheet>(x => x.ID).None());
  159. else
  160. criteria.Add(new Filter<TSpreadsheet>(x => x.Parent.ID).IsEqualTo(ParentID));
  161. base.Reload(criteria, columns, ref sort, action);
  162. }
  163. private BitmapImage SupercededImage(CoreRow? row)
  164. {
  165. if (row == null)
  166. return PRSDesktop.Resources.tick.AsBitmapImage();
  167. if (row.Get<TSpreadsheet, DateTime>(x => x.Superceded) != DateTime.MinValue)
  168. return PRSDesktop.Resources.warning.AsBitmapImage();
  169. return PRSDesktop.Resources.tick.AsBitmapImage();
  170. }
  171. private bool SupercedeDocument(CoreRow? row)
  172. {
  173. var id = row.Get<TSpreadsheet, Guid>(x => x.ID);
  174. var superceded = row.Get<TSpreadsheet, DateTime>(x => x.Superceded);
  175. var spreadsheet = new TSpreadsheet()
  176. {
  177. ID = id,
  178. Superceded = superceded.IsEmpty() ? DateTime.Now : DateTime.MinValue
  179. };
  180. new Client<TSpreadsheet>().Save(spreadsheet, "");
  181. return true;
  182. }
  183. private BitmapImage EditImage(CoreRow? arg)
  184. {
  185. return PRSDesktop.Resources.pencil.AsBitmapImage();
  186. }
  187. private bool EditSpreadsheet(CoreRow? row)
  188. {
  189. var spreadsheet = LoadItem(row);
  190. var window = new SpreadsheetWindow(spreadsheet);
  191. window.OnSave += SaveSpreadsheet;
  192. window.ShowDialog();
  193. Refresh(false, true);
  194. return false;
  195. }
  196. protected override void DoDoubleClick(object sender)
  197. {
  198. if (SelectedRows.Any())
  199. EditSpreadsheet(SelectedRows.First());
  200. else
  201. base.DoDoubleClick(sender);
  202. }
  203. protected override TSpreadsheet CreateItem()
  204. {
  205. var result = base.CreateItem();
  206. result.Parent.ID = ParentID;
  207. return result;
  208. }
  209. private void CreateMenu(ContextMenu parent, string header, Guid id)
  210. {
  211. var menu = new MenuItem();
  212. menu.Header = header;
  213. menu.Tag = id;
  214. menu.IsCheckable = false;
  215. menu.Click += (o, e) => { LoadSpreadsheet(id); };
  216. parent.Items.Add(menu);
  217. }
  218. private void LoadSpreadsheet(Guid id)
  219. {
  220. TSpreadsheet spreadsheet = CreateItem();
  221. if (id != Guid.Empty)
  222. {
  223. var template = new Client<SpreadsheetTemplate>().Query(new Filter<SpreadsheetTemplate>(x => x.ID).IsEqualTo(id)).Rows
  224. .FirstOrDefault()
  225. ?.ToObject<SpreadsheetTemplate>();
  226. spreadsheet.Code = template.Code;
  227. spreadsheet.Description = template.Description;
  228. spreadsheet.Data = template.Data;
  229. }
  230. var window = new SpreadsheetWindow(spreadsheet);
  231. window.OnSave += SaveSpreadsheet;
  232. window.ShowDialog();
  233. Refresh(false, true);
  234. }
  235. private void SaveSpreadsheet(object sender, SpreadsheetSaveArgs args)
  236. {
  237. TSpreadsheet? sheet = args.Spreadsheet as TSpreadsheet;
  238. if (sheet == null)
  239. return;
  240. if (args.SaveAs || Guid.Equals(sheet.ID,Guid.Empty))
  241. {
  242. sheet.ID = Guid.Empty;
  243. sheet.CommitChanges();
  244. sheet.Data = args.Data;
  245. EditItems(new TSpreadsheet[] { sheet });
  246. }
  247. else
  248. {
  249. sheet.Data = args.Data;
  250. new Client<TSpreadsheet>().Save(args.Spreadsheet as TSpreadsheet, "Saved by PRS Spreadsheet");
  251. }
  252. }
  253. private Dictionary<Guid, String> templates = null;
  254. protected override void DoAdd(bool OpenEditorOnDirectEdit = false)
  255. {
  256. if ((ParentID == Guid.Empty) || (ParentID == CoreUtils.FullGuid))
  257. {
  258. MessageBox.Show($"No {typeof(TEntity).EntityName().Split(".").Last()} selected!");
  259. return;
  260. }
  261. var menu = new ContextMenu();
  262. if (templates == null)
  263. {
  264. templates = new Client<SpreadsheetTemplate>().Query(
  265. new Filter<SpreadsheetTemplate>(x => x.AppliesTo).IsEqualTo(typeof(TEntity).EntityName().Split(".").Last())
  266. .And(x=>x.Active).IsEqualTo(true)
  267. ).ToDictionary<SpreadsheetTemplate, Guid, String>(
  268. x => x.ID,
  269. (r) => String.Format("{0}: {1}", r.Get<SpreadsheetTemplate, String>(c => c.Code),
  270. r.Get<SpreadsheetTemplate, String>(c => c.Description))
  271. );
  272. }
  273. if (templates.Keys.Any())
  274. {
  275. CreateMenu(menu, "Blank Spreadsheet", Guid.Empty);
  276. menu.Items.Add(new Separator());
  277. foreach (var key in templates.Keys)
  278. CreateMenu(menu, templates[key], key);
  279. menu.IsOpen = true;
  280. }
  281. else
  282. LoadSpreadsheet(Guid.Empty);
  283. }
  284. }
  285. }