SpreadsheetGrid.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. protected override void Init()
  144. {
  145. base.Init();
  146. ActionColumns.Add(new DynamicImageColumn(EditImage, EditSpreadsheet) { Position = DynamicActionColumnPosition.Start });
  147. HiddenColumns.Add(x => x.Superceded);
  148. ActionColumns.Add(new DynamicImageColumn(SupercededImage, SupercedeDocument));
  149. }
  150. protected override void DoReconfigure(FluentList<DynamicGridOption> options)
  151. {
  152. base.DoReconfigure(options);
  153. options.BeginUpdate().Clear().Add(DynamicGridOption.AddRows)
  154. .Add(DynamicGridOption.EditRows)
  155. .Add(DynamicGridOption.DeleteRows)
  156. .Add(DynamicGridOption.RecordCount)
  157. .EndUpdate();
  158. }
  159. protected override void Reload(Filters<TSpreadsheet> criteria, Columns<TSpreadsheet> columns, ref SortOrder<TSpreadsheet>? sort,
  160. Action<CoreTable?, Exception?> action)
  161. {
  162. if ((ParentID == Guid.Empty) || (ParentID == CoreUtils.FullGuid))
  163. criteria.Add(new Filter<TSpreadsheet>(x => x.ID).None());
  164. else
  165. criteria.Add(new Filter<TSpreadsheet>(x => x.Parent.ID).IsEqualTo(ParentID));
  166. base.Reload(criteria, columns, ref sort, action);
  167. }
  168. private BitmapImage SupercededImage(CoreRow? row)
  169. {
  170. if (row == null)
  171. return PRSDesktop.Resources.tick.AsBitmapImage();
  172. if (row.Get<TSpreadsheet, DateTime>(x => x.Superceded) != DateTime.MinValue)
  173. return PRSDesktop.Resources.warning.AsBitmapImage();
  174. return PRSDesktop.Resources.tick.AsBitmapImage();
  175. }
  176. private bool SupercedeDocument(CoreRow? row)
  177. {
  178. var id = row.Get<TSpreadsheet, Guid>(x => x.ID);
  179. var superceded = row.Get<TSpreadsheet, DateTime>(x => x.Superceded);
  180. var spreadsheet = new TSpreadsheet()
  181. {
  182. ID = id,
  183. Superceded = superceded.IsEmpty() ? DateTime.Now : DateTime.MinValue
  184. };
  185. new Client<TSpreadsheet>().Save(spreadsheet, "");
  186. return true;
  187. }
  188. private BitmapImage EditImage(CoreRow? arg)
  189. {
  190. return PRSDesktop.Resources.pencil.AsBitmapImage();
  191. }
  192. private bool EditSpreadsheet(CoreRow? row)
  193. {
  194. var spreadsheet = LoadItem(row);
  195. var window = new SpreadsheetWindow(spreadsheet);
  196. window.OnSave += SaveSpreadsheet;
  197. window.ShowDialog();
  198. Refresh(false, true);
  199. return false;
  200. }
  201. protected override void DoDoubleClick(object sender)
  202. {
  203. if (SelectedRows.Any())
  204. EditSpreadsheet(SelectedRows.First());
  205. else
  206. base.DoDoubleClick(sender);
  207. }
  208. protected override TSpreadsheet CreateItem()
  209. {
  210. var result = base.CreateItem();
  211. result.Parent.ID = ParentID;
  212. return result;
  213. }
  214. private void CreateMenu(ContextMenu parent, string header, Guid id)
  215. {
  216. var menu = new MenuItem();
  217. menu.Header = header;
  218. menu.Tag = id;
  219. menu.IsCheckable = false;
  220. menu.Click += (o, e) => { LoadSpreadsheet(id); };
  221. parent.Items.Add(menu);
  222. }
  223. private void LoadSpreadsheet(Guid id)
  224. {
  225. TSpreadsheet spreadsheet = CreateItem();
  226. if (id != Guid.Empty)
  227. {
  228. var template = new Client<SpreadsheetTemplate>().Query(new Filter<SpreadsheetTemplate>(x => x.ID).IsEqualTo(id)).Rows
  229. .FirstOrDefault()
  230. ?.ToObject<SpreadsheetTemplate>();
  231. spreadsheet.Code = template.Code;
  232. spreadsheet.Description = template.Description;
  233. spreadsheet.Data = template.Data;
  234. }
  235. var window = new SpreadsheetWindow(spreadsheet);
  236. window.OnSave += SaveSpreadsheet;
  237. window.ShowDialog();
  238. Refresh(false, true);
  239. }
  240. private void SaveSpreadsheet(object sender, SpreadsheetSaveArgs args)
  241. {
  242. TSpreadsheet? sheet = args.Spreadsheet as TSpreadsheet;
  243. if (sheet == null)
  244. return;
  245. if (args.SaveAs || Guid.Equals(sheet.ID,Guid.Empty))
  246. {
  247. sheet.ID = Guid.Empty;
  248. sheet.CommitChanges();
  249. sheet.Data = args.Data;
  250. EditItems(new TSpreadsheet[] { sheet });
  251. }
  252. else
  253. {
  254. sheet.Data = args.Data;
  255. new Client<TSpreadsheet>().Save(args.Spreadsheet as TSpreadsheet, "Saved by PRS Spreadsheet");
  256. }
  257. }
  258. private Dictionary<Guid, String> templates = null;
  259. protected override void DoAdd(bool OpenEditorOnDirectEdit = false)
  260. {
  261. if ((ParentID == Guid.Empty) || (ParentID == CoreUtils.FullGuid))
  262. {
  263. MessageBox.Show($"No {typeof(TEntity).EntityName().Split(".").Last()} selected!");
  264. return;
  265. }
  266. var menu = new ContextMenu();
  267. if (templates == null)
  268. {
  269. templates = new Client<SpreadsheetTemplate>().Query(
  270. new Filter<SpreadsheetTemplate>(x => x.AppliesTo).IsEqualTo(typeof(TEntity).EntityName().Split(".").Last())
  271. .And(x=>x.Active).IsEqualTo(true)
  272. ).ToDictionary<SpreadsheetTemplate, Guid, String>(
  273. x => x.ID,
  274. (r) => String.Format("{0}: {1}", r.Get<SpreadsheetTemplate, String>(c => c.Code),
  275. r.Get<SpreadsheetTemplate, String>(c => c.Description))
  276. );
  277. }
  278. if (templates.Keys.Any())
  279. {
  280. CreateMenu(menu, "Blank Spreadsheet", Guid.Empty);
  281. menu.Items.Add(new Separator());
  282. foreach (var key in templates.Keys)
  283. CreateMenu(menu, templates[key], key);
  284. menu.IsOpen = true;
  285. }
  286. else
  287. LoadSpreadsheet(Guid.Empty);
  288. }
  289. }
  290. }