using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using InABox.Core; using InABox.DynamicGrid; using InABox.Scripting; using InABox.WPF; using Microsoft.Win32; using Org.BouncyCastle.Asn1.Mozilla; using Syncfusion.UI.Xaml.Spreadsheet; using Syncfusion.Windows.Shared; using UnderlineType = InABox.Core.UnderlineType; namespace InABox.DynamicGrid { public static class FormLayoutImporter { private class Cell { public string Content { get; set; } public int Row { get; set; } public int Column { get; set; } public int RowSpan { get; set; } = 1; public int ColumnSpan { get; set; } = 1; public ICell InnerCell { get; set; } public Cell(int row, int column, string content, ICell cell) { Row = row; Column = column; Content = content; InnerCell = cell; } } private static void DeleteColumn(List cells, int column) { foreach(var cell in cells) { if(cell.Column <= column && cell.Column + cell.ColumnSpan - 1 >= column) { --cell.ColumnSpan; } else if(cell.Column > column) { --cell.Column; } } cells.RemoveAll(x => x.ColumnSpan < 0); } private static List GetCells(ISheet sheet) { var grid = new Dictionary>(); for (int rowIdx = sheet.FirstRow; rowIdx <= sheet.LastRow; ++rowIdx) { var row = sheet.GetRow(rowIdx); if (row is not null && row.FirstColumn >= 0) { var rowCells = new Dictionary(); for (int colIdx = row.FirstColumn; colIdx <= row.LastColumn; ++colIdx) { var cell = row.GetCell(colIdx); if (cell is not null) { rowCells.Add(colIdx, new Cell(rowIdx, colIdx, cell.GetValue(), cell)); } } grid.Add(rowIdx, rowCells); } } foreach (var region in sheet.GetMergedCells()) { for (int r = region.FirstRow; r <= region.LastRow; ++r) { if (!grid.TryGetValue(r, out var row)) continue; for (int c = region.FirstColumn; c <= region.LastColumn; ++c) { if ((r - region.FirstRow) + (c - region.FirstColumn) != 0) { row.Remove(c); } } if (row.Count == 0) { grid.Remove(r); } } if (grid.TryGetValue(region.FirstRow, out var cRow) && cRow.TryGetValue(region.FirstColumn, out var cCell)) { cCell.RowSpan = region.LastRow - region.FirstRow + 1; cCell.ColumnSpan = region.LastColumn - region.FirstColumn + 1; } } var cells = new List(); foreach (var row in grid.Values) { foreach (var cell in row.Values) { cells.Add(cell); } } return cells; } public static DFLayout LoadLayout(ISpreadsheet spreadsheet) { var sheet = spreadsheet.GetSheet(0); var cells = GetCells(sheet); int firstRow = int.MaxValue; int lastRow = 0; int firstCol = int.MaxValue; int lastCol = 0; foreach (var cell in cells) { firstCol = Math.Min(cell.Column, firstCol); lastCol = Math.Max(cell.Column + cell.ColumnSpan - 1, lastCol); firstRow = Math.Min(cell.Row, firstRow); lastRow = Math.Max(cell.Row + cell.RowSpan - 1, lastRow); } var layout = new DFLayout(); var columnWidths = new Dictionary(); var colOffset = 0; for (int col = firstCol; col <= lastCol; ++col) { var width = sheet.GetColumnWidth(col); if(width == float.MinValue) { layout.ColumnWidths.Add("10*"); } else if(width <= 0f) { DeleteColumn(cells, col); } else { layout.ColumnWidths.Add($"{width}*"); } } /*var rowHeights = new Dictionary(); for (int row = firstRow; row <= lastRow; ++row) { rowHeights[row] = sheet.GetRowHeight(row); } var totalHeight = rowHeights.Values.Sum();*/ for(int row = firstRow; row <= lastRow; ++row) { layout.RowHeights.Add("Auto"); } foreach(var cell in cells) { var style = cell.InnerCell.GetStyle(); if (string.IsNullOrWhiteSpace(cell.Content) && style.Foreground == Color.Empty) continue; var font = style.Font; layout.Elements.Add(new DFLayoutLabel { Caption = cell.Content, Row = cell.Row - firstRow + 1, Column = cell.Column - firstCol + 1 - colOffset, RowSpan = cell.RowSpan, ColumnSpan = cell.ColumnSpan, Style = new DFLayoutTextStyle { 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 } }); } return layout; } } public abstract class DynamicFormLayoutGrid : DynamicOneToManyGrid where T : Entity, IRemotable, IPersistent, new() { private readonly BitmapImage design = Properties.Resources.design.AsBitmapImage(); public DynamicFormLayoutGrid() { Options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.ImportData); ActionColumns.Add(new DynamicImageColumn(DesignImage, DesignClick)); //AddButton("Design", PRSDesktop.Resources.design.AsBitmapImage(), DesignClick); HiddenColumns.Add(x => x.Layout); AddButton("Auto Generate", null, AutoGenerate_Click); AddButton("Duplicate", null, Duplicate_Click); } private DFLayout LoadLayoutFromSpreadsheet(ISpreadsheet spreadsheet) { return FormLayoutImporter.LoadLayout(spreadsheet); } protected override void DoImport() { var dialog = new OpenFileDialog(); dialog.Filter = "Excel Spreadsheet (.xlsx)|*.xlsx"; if (dialog.ShowDialog() == true) { try { DFLayout layout; using (var fs = new FileStream(dialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { layout = LoadLayoutFromSpreadsheet(new Spreadsheet(fs)); } var dfLayout = CreateItem(); dfLayout.Layout = layout.SaveLayout(); if(EditItems(new DigitalFormLayout[] { dfLayout })) { Refresh(false, true); } } catch(Exception e) { Logger.Send(LogType.Error, "", CoreUtils.FormatException(e)); MessageBox.Show($"Error: {e.Message}"); } } } private bool Duplicate_Click(Button btn, CoreRow[] rows) { if (!rows.Any()) return false; SaveItems(rows.Select(x => { var layout = x.ToObject(); layout.ID = Guid.Empty; return layout; }).ToArray()); return true; } private bool AutoGenerate_Click(Button btn, CoreRow[] rows) { var menu = new ContextMenu(); menu.AddItem("Desktop Layout", null, AddDesktop_Click); menu.AddItem("Mobile Layout", null, AddMobile_Click); menu.IsOpen = true; return false; } private BitmapImage? DesignImage(CoreRow? row) { return row != null ? design : null; } private void AddMobile_Click() { var item = CreateItem(); item.Layout = DFLayout.GenerateAutoMobileLayout(GetVariables()).SaveLayout(); item.Type = DFLayoutType.Mobile; if (EditItems(new[] { item })) { SaveItem(item); Refresh(false, true); OnChanged?.Invoke(this); } } private void AddDesktop_Click() { var item = CreateItem(); item.Layout = DFLayout.GenerateAutoDesktopLayout(GetVariables()).SaveLayout(); item.Type = DFLayoutType.Desktop; if (EditItems(new[] { item })) { SaveItem(item); Refresh(false, true); OnChanged?.Invoke(this); } } private DynamicOneToManyGrid? GetVariableGrid() => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicOneToManyGrid) as DynamicOneToManyGrid; private List GetVariables() => GetVariableGrid()?.Items.ToList() ?? new List(); private void Design(DigitalFormLayout layout) { var variables = GetVariables(); var newVariables = new List(); var form = new DynamicFormDesignWindow { Type = layout.Type }; form.OnCreateVariable += (fieldType) => { if (DynamicVariableUtils.CreateAndEdit(Item, GetVariables(), fieldType, out var variable)) { newVariables.Add(variable); return variable; } return null; }; /*form.OnEditVariable += (variable) => { var properties = variable.CreateProperties(); if (DynamicVariableUtils.EditProperties(Item, GetVariables(), properties.GetType(), properties)) { variable.SaveProperties(properties); return true; } return false; };*/ form.LoadLayout(layout, variables); form.Initialize(); if (form.ShowDialog() == true) { layout.Layout = form.SaveLayout(); SaveItem(layout); var grid = GetVariableGrid(); if (grid is not null) { grid.SaveItems(newVariables.ToArray()); grid.Refresh(false, true); } } } private bool DesignClick(CoreRow? row) { if (row == null) return false; Design(LoadItem(row)); return false; } //public override void SaveItem(DigitalFormLayout item) //{ // bool bActive = item.Active; // foreach (var other in Items.Where(x=>(x != item) && (x.Type == item.Type))) // { // if (item.Active) // { // if (other.Active) // other.Active = false; // } // else // bActive = bActive || other.Active; // } // if (!bActive) // item.Active = true; // base.SaveItem(item); //} protected override void DoDoubleClick(object sender) { DesignClick(SelectedRows.FirstOrDefault()); } } }