Преглед изворни кода

Obsoleted DFBooleanField (still possible to view, but not add to a form); added digital form variables to spreadsheet import;
Fix to expression editor labels not displaying correctly;
moved dynamicitemslistgrid to InABox.DYnamicGrid

Kenric Nugteren пре 2 година
родитељ
комит
de5ad916db

+ 3 - 3
InABox.Core/DigitalForms/DFUtils.cs

@@ -64,7 +64,7 @@ namespace InABox.Core
 
         private static List<Type>? _fieldTypes;
 
-        public static List<Type> GetFieldTypes()
+        public static List<Type> GetFieldTypes(bool includeObsolete = false)
         {
             _fieldTypes ??= CoreUtils.TypeList(
                 AppDomain.CurrentDomain.GetAssemblies(),
@@ -72,12 +72,12 @@ namespace InABox.Core
                 && !x.IsAbstract
                 && !x.IsGenericType
                 && x.GetInterfaces().Any(x => x == typeof(IDFLayoutFormField))).ToList();
-            return _fieldTypes;
+            return includeObsolete ? _fieldTypes : _fieldTypes.Where(x => !x.HasInterface<IDFLayoutObsoleteField>()).ToList();
         }
 
         public static Type? GetFieldType(string typeName)
         {
-            var type = GetFieldTypes().Where(x => x.FullName == typeName).FirstOrDefault();
+            var type = GetFieldTypes(true).Where(x => x.FullName == typeName).FirstOrDefault();
             if(type != null) return type;
 
             if(Enum.TryParse(typeName, out DigitalFormVariableType variableType))

+ 6 - 2
InABox.Core/DigitalForms/Forms/DigitalFormVariable.cs

@@ -10,7 +10,7 @@ namespace InABox.Core
     {
         public VariableTypeLookupGenerator(DigitalFormVariable[] items) : base(items)
         {
-            foreach (var fieldType in DFUtils.GetFieldTypes())
+            foreach (var fieldType in DFUtils.GetFieldTypes(true))
             {
                 var caption = fieldType.GetCaption();
                 if (string.IsNullOrWhiteSpace(caption))
@@ -52,7 +52,7 @@ namespace InABox.Core
         public string Type { get; set; }
 
         [EditorSequence(3)]
-        [ComboLookupEditor(typeof(VariableTypeLookupGenerator), Visible = Visible.Default)]
+        [ComboLookupEditor(typeof(VariableTypeLookupGenerator), Visible = Visible.Default, Editable = Editable.Disabled)]
         public string VariableType
         {
             get => _variableType.FullName;
@@ -147,6 +147,10 @@ namespace InABox.Core
         {
             return _variableType;
         }
+        public void SetFieldType(Type type)
+        {
+            _variableType = type.HasInterface<IDFLayoutFormField>() ? type : typeof(DFLayoutStringField);
+        }
 
         protected override void Init()
         {

+ 1 - 1
InABox.Core/DigitalForms/Layouts/Fields/DFLayoutBooleanField/DFLayoutBooleanField.cs

@@ -1,7 +1,7 @@
 namespace InABox.Core
 {
     [Caption("Boolean")]
-    public class DFLayoutBooleanField : DFLayoutField<DFLayoutBooleanFieldProperties>, IDFLayoutFormField
+    public class DFLayoutBooleanField : DFLayoutField<DFLayoutBooleanFieldProperties>, IDFLayoutFormField, IDFLayoutObsoleteField
     {
     }
 }

+ 7 - 0
InABox.Core/DigitalForms/Layouts/Fields/IDFLayoutFormField.cs

@@ -11,6 +11,13 @@ namespace InABox.Core
     {
     }
 
+    /// <summary>
+    /// Used to prevent a field being able to be added to a form.
+    /// </summary>
+    public interface IDFLayoutObsoleteField
+    {
+    }
+
     /// <summary>
     /// Used to specify that the data for this field should be stored in <see cref="IBaseDigitalFormInstance.BlobData"/>.
     /// </summary>

+ 52 - 0
InABox.DynamicGrid/DynamicItemsListGrid.cs

@@ -0,0 +1,52 @@
+using InABox.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace InABox.DynamicGrid
+{
+    public class DynamicItemsListGrid<T> : DynamicGrid<T>
+        where T : BaseObject, new()
+    {
+        public List<T> Items { get; set; }
+
+        public DynamicItemsListGrid() : this(new()) { }
+
+        public DynamicItemsListGrid(List<T> items) : base()
+        {
+            Items = items;
+        }
+
+        protected override void DeleteItems(params CoreRow[] rows)
+        {
+            foreach (var row in rows.OrderByDescending(x => x.Index))
+            {
+                Items.RemoveAt(_recordmap[row].Index);
+            }
+        }
+
+        protected override T LoadItem(CoreRow row)
+        {
+            return Items[_recordmap[row].Index];
+        }
+
+        protected override void Reload(Filters<T> criteria, Columns<T> columns, ref SortOrder<T>? sort, Action<CoreTable?, Exception?> action)
+        {
+            var result = new CoreTable();
+            result.LoadColumns(typeof(T));
+            result.LoadRows(Items);
+            action.Invoke(result, null);
+        }
+
+        public override void SaveItem(T item)
+        {
+            if (!Items.Contains(item))
+            {
+                Items.Add(item);
+            }
+        }
+    }
+
+}

+ 23 - 20
InABox.DynamicGrid/Editors/ExpressionEditor/ExpressionEditorWindow.xaml

@@ -59,22 +59,23 @@
                                                     </ListBox.Template>
                                                     <ListBox.ItemTemplate>
                                                         <DataTemplate DataType="local:FunctionTemplate">
-                                                            <Label Content="{Binding Template}"
-                                                                   FontFamily="Consolas" FontSize="12"
-                                                                   Padding="5"
-                                                                   Tag="{Binding}"
-                                                                   MouseDoubleClick="FunctionTemplate_Click">
-                                                                <Label.ToolTip>
-                                                                    <ToolTip Background="LightGray">
-                                                                        <StackPanel>
-                                                                            <TextBlock Text="{Binding Tooltip}"
-                                                                                    FontFamily="Consolas" FontSize="12"/>
-                                                                            <TextBlock Text="{Binding Description}" FontSize="12"
-                                                                                    Style="{StaticResource tooltipDescriptionStyle}"/>
-                                                                        </StackPanel>
-                                                                    </ToolTip>
-                                                                </Label.ToolTip>
-                                                            </Label>
+                                                            <ContentControl MouseDoubleClick="FunctionTemplate_Click"
+                                                                            Tag="{Binding}">
+                                                                <TextBlock Text="{Binding Template}"
+                                                                           FontFamily="Consolas" FontSize="12"
+                                                                           Padding="5">
+                                                                    <TextBlock.ToolTip>
+                                                                        <ToolTip Background="LightGray">
+                                                                            <StackPanel>
+                                                                                <TextBlock Text="{Binding Tooltip}"
+                                                                                           FontFamily="Consolas" FontSize="12"/>
+                                                                                <TextBlock Text="{Binding Description}" FontSize="12"
+                                                                                           Style="{StaticResource tooltipDescriptionStyle}"/>
+                                                                            </StackPanel>
+                                                                        </ToolTip>
+                                                                    </TextBlock.ToolTip>
+                                                                </TextBlock>
+                                                            </ContentControl>
                                                         </DataTemplate>
                                                     </ListBox.ItemTemplate>
                                                 </ListBox>
@@ -99,10 +100,12 @@
                                 </ListBox.Template>
                                 <ListBox.ItemTemplate>
                                     <DataTemplate DataType="local:string">
-                                        <Label Content="{Binding}"
-                                               FontFamily="Consolas" FontSize="12"
-                                               Tag="{Binding}"
-                                               MouseDoubleClick="Variable_Click"/>
+                                        <ContentControl MouseDoubleClick="Variable_Click"
+                                                        Tag="{Binding}">
+                                            <TextBlock Text="{Binding}"
+                                                       FontFamily="Consolas" FontSize="12"
+                                                       Padding="5"/>
+                                        </ContentControl>
                                     </DataTemplate>
                                 </ListBox.ItemTemplate>
                             </ListBox>

+ 94 - 24
InABox.DynamicGrid/FormDesigner/DynamicFormLayoutGrid.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Drawing;
 using System.IO;
 using System.Linq;
+using System.Text.RegularExpressions;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media.Imaging;
@@ -119,6 +120,8 @@ namespace InABox.DynamicGrid
             return cells;
         }
 
+        private static Regex VariableRegex = new("^\\s*\\[(?<VAR>[^:\\]]+)(?::(?<TYPE>[^\\]]+))?\\]$");
+
         public static DFLayout LoadLayout(ISpreadsheet spreadsheet)
         {
             var sheet = spreadsheet.GetSheet(0);
@@ -178,33 +181,59 @@ namespace InABox.DynamicGrid
 
                 if (string.IsNullOrWhiteSpace(cell.Content) && style.Foreground == Color.Empty) continue;
 
-                var font = style.Font;
+                DFLayoutControl? control;
 
-                layout.Elements.Add(new DFLayoutLabel
+                var match = VariableRegex.Match(cell.Content);
+                if (match.Success)
                 {
-                    Caption = cell.Content,
-                    Row = cell.Row - firstRow + 1,
-                    Column = cell.Column - firstCol + 1 - colOffset,
-                    RowSpan = cell.RowSpan,
-                    ColumnSpan = cell.ColumnSpan,
+                    var variableName = match.Groups["VAR"];
+                    var variableType = match.Groups["TYPE"];
 
-                    Style = new DFLayoutTextStyle
+                    Type? fieldType = null;
+                    if (variableType.Success)
                     {
-                        FontSize = font.FontSize,
+                        fieldType = DFUtils.GetFieldType(variableType.Value);
+                    }
+                    fieldType ??= typeof(DFLayoutStringField);
 
-                        IsItalic = font.Italic,
-                        IsBold = font.Bold,
-                        Underline = font.Underline switch
+                    var field = (Activator.CreateInstance(fieldType) as DFLayoutField)!;
+                    field.Name = variableName.Value;
+                    control = field;
+                }
+                else
+                {
+                    var font = style.Font;
+
+                    control = new DFLayoutLabel
+                    {
+                        Caption = cell.Content,
+
+                        Style = new DFLayoutTextStyle
                         {
-                            Scripting.UnderlineType.None => UnderlineType.None,
-                            Scripting.UnderlineType.Single or Scripting.UnderlineType.SingleAccounting => UnderlineType.Single,
-                            Scripting.UnderlineType.Double or Scripting.UnderlineType.DoubleAccounting => UnderlineType.Double,
-                            _ => UnderlineType.None
-                        },
-                        BackgroundColour = style.Foreground,
-                        ForegroundColour = font.Colour
-                    }
-                });
+                            FontSize = font.FontSize,
+
+                            IsItalic = font.Italic,
+                            IsBold = font.Bold,
+                            Underline = font.Underline switch
+                            {
+                                Scripting.UnderlineType.None => UnderlineType.None,
+                                Scripting.UnderlineType.Single or Scripting.UnderlineType.SingleAccounting => UnderlineType.Single,
+                                Scripting.UnderlineType.Double or Scripting.UnderlineType.DoubleAccounting => UnderlineType.Double,
+                                _ => UnderlineType.None
+                            },
+                            BackgroundColour = style.Foreground,
+                            ForegroundColour = font.Colour
+                        }
+                    };
+                }
+                if(control is not null)
+                {
+                    control.Row = cell.Row - firstRow + 1;
+                    control.Column = cell.Column - firstCol + 1 - colOffset;
+                    control.RowSpan = cell.RowSpan;
+                    control.ColumnSpan = cell.ColumnSpan;
+                    layout.Elements.Add(control);
+                }
             }
 
             return layout;
@@ -249,6 +278,47 @@ namespace InABox.DynamicGrid
                     dfLayout.Layout = layout.SaveLayout();
                     if(EditItems(new DigitalFormLayout[] { dfLayout }))
                     {
+                        var newVariables = new List<DigitalFormVariable>();
+                        foreach (var element in layout.Elements)
+                        {
+                            if(element is DFLayoutField field)
+                            {
+                                var variable = new DigitalFormVariable
+                                {
+                                    Code = field.Name,
+                                    Description = field.Name
+                                };
+                                variable.SetFieldType(field.GetType());
+                                newVariables.Add(variable);
+                            }
+                        }
+                        if(newVariables.Count > 0)
+                        {
+                            var variables = GetVariableGrid();
+                            if (variables is not null)
+                            {
+                                var save = new List<DigitalFormVariable>();
+                                foreach(var newVariable in newVariables)
+                                {
+                                    var variable = variables.GetVariable(newVariable.Code);
+                                    if(variable is not null)
+                                    {
+                                        if(variable.FieldType() != newVariable.FieldType())
+                                        {
+                                            MessageBox.Show($"Variable [{newVariable.Code}] already exists with a different type!");
+                                        }
+                                    }
+                                    else
+                                    {
+                                        save.Add(newVariable);
+                                    }
+                                }
+
+                                variables.SaveItems(save.ToArray());
+                                variables.Refresh(false, true);
+                            }
+                        }
+
                         Refresh(false, true);
                     }
                 }
@@ -320,9 +390,9 @@ namespace InABox.DynamicGrid
             }
         }
 
-        private DynamicOneToManyGrid<DigitalForm, DigitalFormVariable>? GetVariableGrid()
-            => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicOneToManyGrid<DigitalForm, DigitalFormVariable>)
-                as DynamicOneToManyGrid<DigitalForm, DigitalFormVariable>;
+        private DynamicVariableGrid? GetVariableGrid()
+            => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicVariableGrid)
+                as DynamicVariableGrid;
 
         private List<DigitalFormVariable> GetVariables()
             => GetVariableGrid()?.Items.ToList() ?? new List<DigitalFormVariable>();

+ 5 - 0
InABox.DynamicGrid/FormDesigner/DynamicVariableGrid.cs

@@ -27,6 +27,11 @@ namespace InABox.DynamicGrid
             HiddenColumns.Add(x => x.Hidden);
         }
 
+        public DigitalFormVariable? GetVariable(string code)
+        {
+            return Items.Where(x => x.Code == code).FirstOrDefault();
+        }
+
         private bool ShouldHide(CoreRow[] rows)
         {
             return rows.Any(x => !x.Get<DigitalFormVariable, bool>(x => x.Hidden));