DynamicVariableGrid.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Controls;
  5. using InABox.Core;
  6. using NPOI.Util.Collections;
  7. namespace InABox.DynamicGrid
  8. {
  9. internal class DynamicVariableGrid : DynamicOneToManyGrid<DigitalForm, DigitalFormVariable>
  10. {
  11. public DynamicVariableGrid()
  12. {
  13. Options.Add(DynamicGridOption.MultiSelect);
  14. }
  15. public bool EditProperties(Type type, DFLayoutFieldProperties item)
  16. {
  17. var editor = new DynamicEditorForm(type);
  18. if (item is DFLayoutLookupFieldProperties)
  19. {
  20. editor.OnFormCustomiseEditor += LookupEditor_OnFormCustomiseEditor;
  21. editor.OnEditorValueChanged += (sender, name, value) =>
  22. {
  23. var result = DynamicGridUtils.UpdateEditorValue(new[] { item }, name, value);
  24. if (name == "LookupType")
  25. {
  26. var grid = (sender as DynamicEditorGrid)!;
  27. var edit = grid.FindEditor("Filter");
  28. if (edit is FilterEditorControl filter)
  29. {
  30. filter.FilterType = value is string str ?
  31. CoreUtils.GetEntityOrNull(str) :
  32. null;
  33. }
  34. var propertiesEditor = grid.FindEditor(nameof(DFLayoutLookupFieldProperties.AdditionalProperties));
  35. if(propertiesEditor is MultiLookupEditorControl multi && multi.EditorDefinition is ComboMultiLookupEditor combo)
  36. {
  37. combo.Clear();
  38. multi.Configure();
  39. }
  40. }
  41. return new();
  42. };
  43. }
  44. else
  45. {
  46. editor.OnFormCustomiseEditor += Editor_OnFormCustomiseEditor;
  47. }
  48. editor.Items = new BaseObject[] { item };
  49. editor.OnDefineLookups += o =>
  50. {
  51. var def = (o.EditorDefinition as ILookupEditor)!;
  52. var colname = o.ColumnName;
  53. // Nope, there is nothing dodgy about this at all
  54. // I am not breaking any rules by passing in the QA Form instance, rather than the Field instance
  55. // so that I can get access to the "AppliesTo" property, and thus the list of properties that can be updated
  56. // Nothing to see here, I promise!
  57. CoreTable? values;
  58. if(o.ColumnName == "Property")
  59. {
  60. values = def.Values(colname, new object[] { Item });
  61. }
  62. else
  63. {
  64. values = def.Values(colname, new object[] { item });
  65. }
  66. o.LoadLookups(values);
  67. };
  68. return editor.ShowDialog() == true;
  69. }
  70. private void Editor_OnFormCustomiseEditor(IDynamicEditorForm sender, object[] items, DynamicGridColumn column, BaseEditor editor)
  71. {
  72. if ((column.ColumnName == "Expression" || column.ColumnName == "ColourExpression") && editor is ExpressionEditor exp)
  73. {
  74. var variables = new List<string>();
  75. foreach (var variable in Items)
  76. {
  77. //variables.Add(variable.Code);
  78. foreach (var col in variable.GetVariableColumns())
  79. {
  80. variables.Add(col.ColumnName);
  81. }
  82. }
  83. variables.Sort();
  84. exp.VariableNames = variables;
  85. }
  86. }
  87. private void LookupEditor_OnFormCustomiseEditor(IDynamicEditorForm sender, object[] items, DynamicGridColumn column, BaseEditor editor)
  88. {
  89. if(column.ColumnName == "Filter" && editor is FilterEditor fe)
  90. {
  91. var properties = items[0] as DFLayoutLookupFieldProperties;
  92. var lookupType = properties.LookupType;
  93. var entityType = CoreUtils.GetEntityOrNull(lookupType);
  94. fe.Type = entityType;
  95. }
  96. Editor_OnFormCustomiseEditor(sender, items, column, editor);
  97. }
  98. private void CreateMenu(ContextMenu parent, string header, Type type)
  99. {
  100. var menu = new MenuItem();
  101. menu.Header = header;
  102. menu.Tag = type;
  103. menu.Click += (o, e) =>
  104. {
  105. var itemtype = (o as MenuItem).Tag as Type;
  106. var fieldBaseType = itemtype.GetSuperclassDefinition(typeof(DFLayoutField<>));
  107. if(fieldBaseType != null)
  108. {
  109. var propertiesType = fieldBaseType.GetGenericArguments()[0];
  110. var properties = Activator.CreateInstance(propertiesType) as DFLayoutFieldProperties;
  111. if (EditProperties(propertiesType, properties))
  112. {
  113. var variable = CreateItem();
  114. variable.SaveProperties(itemtype, properties);
  115. SaveItem(variable);
  116. Refresh(false, true);
  117. }
  118. }
  119. };
  120. parent.Items.Add(menu);
  121. }
  122. protected override void DoAdd()
  123. {
  124. var menu = new ContextMenu();
  125. foreach(var fieldType in DFUtils.GetFieldTypes())
  126. {
  127. var caption = fieldType.GetCaption();
  128. if (string.IsNullOrWhiteSpace(caption))
  129. {
  130. caption = CoreUtils.Neatify(fieldType.Name);
  131. }
  132. CreateMenu(menu, caption, fieldType);
  133. }
  134. menu.IsOpen = true;
  135. }
  136. /*protected override DigitalFormVariable LoadItem(CoreRow row)
  137. {
  138. return Items.FirstOrDefault(r => r.ID.Equals(row.Get<DigitalFormVariable, Guid>(c => c.ID)));
  139. }*/
  140. protected override void DoEdit()
  141. {
  142. if (!SelectedRows.Any())
  143. return;
  144. var variable = LoadItem(SelectedRows.First());
  145. var properties = variable.CreateProperties();
  146. if (EditProperties(properties.GetType(), properties))
  147. {
  148. variable.SaveProperties(properties);
  149. SaveItem(variable);
  150. Refresh(false, true);
  151. }
  152. }
  153. }
  154. }