DataEntryPanel.xaml.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using InABox.DynamicGrid;
  5. using InABox.WPF;
  6. using Syncfusion.Data.Extensions;
  7. using Syncfusion.Pdf;
  8. using Syncfusion.Pdf.Graphics;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Drawing.Imaging;
  12. using System.Drawing;
  13. using System.IO;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using System.Windows;
  18. using System.Windows.Controls;
  19. using System.Windows.Data;
  20. using System.Windows.Documents;
  21. using System.Windows.Input;
  22. using System.Windows.Media;
  23. using System.Windows.Media.Imaging;
  24. using System.Windows.Navigation;
  25. using Syncfusion.Pdf.Parsing;
  26. using Encoder = System.Drawing.Imaging.Encoder;
  27. using Image = System.Windows.Controls.Image;
  28. using System.Reflection;
  29. namespace PRSDesktop
  30. {
  31. /// <summary>
  32. /// Interaction logic for DataEntryPanel.xaml
  33. /// </summary>
  34. /// <remarks>
  35. /// This is a host because it has a singular code popup editor
  36. /// </remarks>
  37. public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHost
  38. {
  39. IPopupEditorControl? Popup;
  40. public DataEntryPanel()
  41. {
  42. InitializeComponent();
  43. }
  44. public void Setup()
  45. {
  46. var types = CoreUtils.Entities
  47. .Where(x => x.IsAssignableTo(typeof(Entity))
  48. && x.HasInterface(typeof(IRemotable))
  49. && x.HasInterface(typeof(IPersistent))
  50. && x.GetCustomAttribute<AutoEntity>() is null
  51. && Security.CanEdit(x)
  52. && x.HasInterface<IScannable>())
  53. .Select(x => new Tuple<string, Type?>(x.Name, x)).OrderBy(x => x.Item1).ToList();
  54. types.Insert(0, new("", null));
  55. TypeBox.ItemsSource = types;
  56. TypeBox.DisplayMemberPath = "Item1";
  57. TypeBox.SelectedValuePath = "Item2";
  58. ScanPanel.Setup();
  59. }
  60. public void Refresh()
  61. {
  62. ScanPanel.Refresh();
  63. }
  64. public bool IsReady { get; set; }
  65. public string SectionName => "Data Entry";
  66. public DataModel DataModel(Selection selection)
  67. {
  68. return new EmptyDataModel();
  69. }
  70. public event DataModelUpdateEvent? OnUpdateDataModel;
  71. public void CreateToolbarButtons(IPanelHost host)
  72. {
  73. if (Security.IsAllowed<CanSetupScanTags>())
  74. {
  75. host.CreateSetupAction(new PanelAction
  76. {
  77. Caption = "Scan Tags",
  78. OnExecute = (action) =>
  79. {
  80. var list = new MasterList(typeof(ScanTag));
  81. list.ShowDialog();
  82. }
  83. });
  84. }
  85. }
  86. public void Heartbeat(TimeSpan time)
  87. {
  88. }
  89. public Dictionary<string, object[]> Selected()
  90. {
  91. return new Dictionary<string, object[]>();
  92. }
  93. public void Shutdown()
  94. {
  95. ScanPanel.Shutdown();
  96. }
  97. #region Host
  98. private HashSet<Type> _loadedTypes = new();
  99. public DynamicGridColumns Columns { get; set; } = new();
  100. IEnumerable<DynamicGridColumn> IDynamicEditorHost.Columns => Columns;
  101. public void LoadColumns(string column, Dictionary<string, string> columns)
  102. {
  103. var selectedType = TypeBox.SelectedValue as Type;
  104. if (selectedType is null) return;
  105. columns.Clear();
  106. foreach (var c in LookupFactory.DefineColumns(selectedType).ColumnNames().Where(x => x != "ID"))
  107. {
  108. columns.Add(c, c);
  109. }
  110. if (Popup?.EditorDefinition is CodePopupEditorControl codePopup && !columns.ContainsKey(codePopup.CodeColumn))
  111. {
  112. columns.Add(codePopup.CodeColumn, codePopup.CodeColumn);
  113. }
  114. }
  115. public IFilter? DefineFilter(Type type) => LookupFactory.DefineFilter(type);
  116. public void LoadLookups(ILookupEditorControl sender)
  117. {
  118. var editor = sender.EditorDefinition as ILookupEditor;
  119. var colname = sender.ColumnName;
  120. var values = editor.Values(colname, Editor.Items);
  121. sender.LoadLookups(values);
  122. }
  123. public Document? FindDocument(string filename) => null;
  124. public Document? GetDocument(Guid id) => null;
  125. public void SaveDocument(Document document) { }
  126. object?[] IDynamicEditorHost.GetItems() => Editor.Items;
  127. public BaseEditor? GetEditor(DynamicGridColumn column) => column.Editor.CloneEditor();
  128. #endregion
  129. private void ClearEditor(Type TEntity)
  130. {
  131. UpdateEditor(TEntity, null);
  132. if(Popup is not null)
  133. {
  134. Popup.Value = Guid.Empty;
  135. }
  136. }
  137. private bool EditorChanged = false;
  138. private IDynamicDataGrid UpdateEditor(Type TEntity, BaseObject[]? items)
  139. {
  140. DetailGrid.Children.Remove(Editor);
  141. Editor = new EmbeddedDynamicEditorForm();
  142. Editor.SetLayoutType<VerticalDynamicEditorGridLayout>();
  143. Editor.SetValue(Grid.RowProperty, 1);
  144. Editor.SetValue(Grid.ColumnProperty, 0);
  145. Editor.SetValue(Grid.ColumnSpanProperty, 4);
  146. EditorChanged = false;
  147. Editor.OnAfterEditorValueChanged += (sender, column) =>
  148. {
  149. EditorChanged = true;
  150. return null;
  151. };
  152. Editor.OnOK += () =>
  153. {
  154. var cancel = new System.ComponentModel.CancelEventArgs();
  155. Editor.SaveItem(cancel);
  156. if(!cancel.Cancel)
  157. ClearEditor(TEntity);
  158. };
  159. Editor.OnCancel += () =>
  160. {
  161. ClearEditor(TEntity);
  162. };
  163. DetailGrid.Children.Add(Editor);
  164. var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), TEntity);
  165. grid.InitialiseEditorForm(Editor, items ?? new object[] { Activator.CreateInstance(TEntity)! });
  166. return (grid as IDynamicDataGrid)!;
  167. }
  168. private void TypeBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  169. {
  170. var selectedType = TypeBox.SelectedValue as Type;
  171. if (selectedType is not null)
  172. {
  173. var dataGrid = UpdateEditor(selectedType, null);
  174. var editorColumns = dataGrid.LoadEditorColumns();
  175. if (Popup is UIElement element)
  176. DetailGrid.Children.Remove(element);
  177. var code = DatabaseSchema.Properties(selectedType)
  178. .Where(x => x.Parent is null && (x.Editor is CodeEditor || x.Editor is UniqueCodeEditor)
  179. && x.Editor.Editable != Editable.Hidden)
  180. .FirstOrDefault();
  181. BaseEditor editor;
  182. if (code is not null)
  183. {
  184. editor = new CodePopupEditor(selectedType) { CodeColumn = code.Name };
  185. Popup = new CodePopupEditorControl { Margin = new Thickness(5), CodeColumn = code.Name };
  186. }
  187. else
  188. {
  189. editor = new PopupEditor(selectedType);
  190. Popup = new PopupEditorControl { Margin = new Thickness(5) };
  191. }
  192. if (Popup is IPopupEditorControl popupEditor)
  193. {
  194. Popup.ColumnName = "ID";
  195. popupEditor.Host = this;
  196. Columns = new DynamicGridColumns();
  197. Columns.ExtractColumns(selectedType);
  198. }
  199. var el = (Popup as UIElement)!;
  200. el.SetValue(Grid.RowProperty, 0);
  201. el.SetValue(Grid.ColumnProperty, 3);
  202. Popup.EditorDefinition = editor;
  203. Popup.OnEditorValueChanged += (s, v) =>
  204. {
  205. var entityID = (Guid)v["ID"];
  206. BaseObject[]? objs = null;
  207. if (entityID != Guid.Empty)
  208. {
  209. var obj = Client.Create(selectedType)
  210. .Query(
  211. Filter.Create<Entity>(selectedType, x => x.ID).IsEqualTo(entityID),
  212. editorColumns)
  213. .ToObjects(selectedType)
  214. .FirstOrDefault();
  215. if (obj is not null)
  216. {
  217. objs = new BaseObject[] { obj };
  218. }
  219. }
  220. UpdateEditor(selectedType, objs);
  221. };
  222. Popup.Configure();
  223. Popup.Loaded = true;
  224. DetailGrid.Children.Add(el);
  225. }
  226. else
  227. {
  228. DetailGrid.Children.Remove(Editor);
  229. if (Popup is UIElement el)
  230. DetailGrid.Children.Remove(el);
  231. }
  232. }
  233. private void ScanPanel_OnSelectAppliesTo(string appliesTo)
  234. {
  235. if(CoreUtils.TryGetEntity(appliesTo, out var entity))
  236. {
  237. TypeBox.SelectedValue = entity;
  238. }
  239. }
  240. }
  241. }