From 4ef0d91510b6d0586e81f599215ad659a5830586 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 9 Jul 2022 15:06:49 +0200 Subject: [PATCH] Added the section user control --- .../Components/SectionTree.Designer.cs | 129 ++++++++++++++++ .../UI WinForms/Components/SectionTree.cs | 140 ++++++++++++++++++ .../UI WinForms/Components/SectionTree.resx | 60 ++++++++ 3 files changed, 329 insertions(+) create mode 100644 I18N Commander/UI WinForms/Components/SectionTree.Designer.cs create mode 100644 I18N Commander/UI WinForms/Components/SectionTree.cs create mode 100644 I18N Commander/UI WinForms/Components/SectionTree.resx diff --git a/I18N Commander/UI WinForms/Components/SectionTree.Designer.cs b/I18N Commander/UI WinForms/Components/SectionTree.Designer.cs new file mode 100644 index 0000000..9229662 --- /dev/null +++ b/I18N Commander/UI WinForms/Components/SectionTree.Designer.cs @@ -0,0 +1,129 @@ +namespace UI_WinForms.Components +{ + partial class SectionTree + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayout = new System.Windows.Forms.TableLayoutPanel(); + this.flowLayoutBottom = new System.Windows.Forms.FlowLayoutPanel(); + this.buttonAdd = new System.Windows.Forms.Button(); + this.buttonRemove = new System.Windows.Forms.Button(); + this.treeView = new System.Windows.Forms.TreeView(); + this.tableLayout.SuspendLayout(); + this.flowLayoutBottom.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayout + // + this.tableLayout.ColumnCount = 1; + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayout.Controls.Add(this.flowLayoutBottom, 0, 1); + this.tableLayout.Controls.Add(this.treeView, 0, 0); + this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayout.Location = new System.Drawing.Point(0, 0); + this.tableLayout.Name = "tableLayout"; + this.tableLayout.RowCount = 2; + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 66F)); + this.tableLayout.Size = new System.Drawing.Size(296, 511); + this.tableLayout.TabIndex = 0; + // + // flowLayoutBottom + // + this.flowLayoutBottom.Controls.Add(this.buttonAdd); + this.flowLayoutBottom.Controls.Add(this.buttonRemove); + this.flowLayoutBottom.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutBottom.Location = new System.Drawing.Point(0, 445); + this.flowLayoutBottom.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutBottom.Name = "flowLayoutBottom"; + this.flowLayoutBottom.Size = new System.Drawing.Size(296, 66); + this.flowLayoutBottom.TabIndex = 0; + // + // buttonAdd + // + this.buttonAdd.AutoSize = true; + this.buttonAdd.Image = global::UI_WinForms.Resources.Icons.icons8_add_folder_512; + this.buttonAdd.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.buttonAdd.Location = new System.Drawing.Point(3, 3); + this.buttonAdd.Name = "buttonAdd"; + this.buttonAdd.Size = new System.Drawing.Size(138, 60); + this.buttonAdd.TabIndex = 0; + this.buttonAdd.Text = "Add"; + this.buttonAdd.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.buttonAdd.UseVisualStyleBackColor = true; + this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click); + // + // buttonRemove + // + this.buttonRemove.AutoSize = true; + this.buttonRemove.Enabled = false; + this.buttonRemove.Image = global::UI_WinForms.Resources.Icons.icons8_delete_folder_512; + this.buttonRemove.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.buttonRemove.Location = new System.Drawing.Point(147, 3); + this.buttonRemove.Name = "buttonRemove"; + this.buttonRemove.Size = new System.Drawing.Size(138, 60); + this.buttonRemove.TabIndex = 1; + this.buttonRemove.Text = "Remove"; + this.buttonRemove.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.buttonRemove.UseVisualStyleBackColor = true; + // + // treeView + // + this.treeView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.treeView.Dock = System.Windows.Forms.DockStyle.Fill; + this.treeView.HideSelection = false; + this.treeView.ItemHeight = 50; + this.treeView.Location = new System.Drawing.Point(3, 3); + this.treeView.Name = "treeView"; + this.treeView.Size = new System.Drawing.Size(290, 439); + this.treeView.TabIndex = 1; + // + // SectionTree + // + this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.tableLayout); + this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Name = "SectionTree"; + this.Size = new System.Drawing.Size(296, 511); + this.tableLayout.ResumeLayout(false); + this.flowLayoutBottom.ResumeLayout(false); + this.flowLayoutBottom.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private TableLayoutPanel tableLayout; + private FlowLayoutPanel flowLayoutBottom; + private Button buttonAdd; + private Button buttonRemove; + private TreeView treeView; + } +} diff --git a/I18N Commander/UI WinForms/Components/SectionTree.cs b/I18N Commander/UI WinForms/Components/SectionTree.cs new file mode 100644 index 0000000..5858830 --- /dev/null +++ b/I18N Commander/UI WinForms/Components/SectionTree.cs @@ -0,0 +1,140 @@ +using DataModel.Database; +using DataModel.Database.Common; +using Microsoft.Extensions.DependencyInjection; +using Processor; +using UI_WinForms.Dialogs; +using UI_WinForms.Resources; + +namespace UI_WinForms.Components; + +public partial class SectionTree : UserControl +{ + private readonly DataContext db; + + public SectionTree() + { + this.InitializeComponent(); + + // Get the DI context from the main form: + this.db = Program.SERVICE_PROVIDER.GetService()!; + + // Dispose of the context when the control is disposed: + this.Disposed += (_, _) => this.db.Dispose(); + + // Create an image list from a resource: + var imgList = new ImageList(); + imgList.ImageSize = new Size(45, 45); + imgList.ColorDepth = ColorDepth.Depth32Bit; + imgList.Images.Add(Icons.icons8_documents_folder_512); + + // Set the image list to the tree view: + this.treeView.ImageList = imgList; + + // Subscribe to the load event: + this.Load += this.OnLoad; + } + + private async void OnLoad(object? sender, EventArgs e) + { + // A dictionary to cache all known tree nodes: + var treeNodes = new Dictionary(); + + // Get the max. depth of the tree: + var maxDepth = await SectionProcessor.GetDepth(this.db); + + // Store nodes, where we cannot find the parents: + var missingParents = new List(); + + // Populate the tree view out of the database, layer by layer: + for (var i = 0; i <= maxDepth; i++) + { + await foreach (var section in SectionProcessor.LoadLayer(this.db, i)) + { + // Create the tree node: + var node = new TreeNode + { + Name = section.DataKey, // [sic] name is the key + Text = section.Name, + StateImageIndex = 1, + }; + + // Cache the node: + treeNodes.Add(section.DataKey, node); + + // Is this a root node? + if (section.Depth is 0) + + // Set the root node: + this.treeView.Nodes.Add(node); + + // Otherwise, attach this section to its parent node: + else + { + // Get the parent from our cache within O(1): + treeNodes.TryGetValue(section.Parent?.DataKey ?? string.Empty, out var parent); + + // If the parent node is not found, skip this section: + if (parent is null) + { + missingParents.Add(node); + continue; + } + + // Add the node to the parent: + parent.Nodes.Add(node); + } + } + } + + // If we found any missing parents, show a dialog: + if (missingParents.Any()) + { + MessageBox.Show($"In {missingParents.Count} case(s) we could not found the matching parent. We added these nodes to a special root node, though.", "Parent not found", MessageBoxButtons.OK, MessageBoxIcon.Error); + + // Create a root node for all missing parents: + var rootMissedParents = new TreeNode + { + Name = "MISSING_PARENTS", + Text = "Missing Parents", + StateImageIndex = 1, + }; + + // Add the root node to the tree: + this.treeView.Nodes.Add(rootMissedParents); + + // Add all missing parents to the root node: + foreach (var node in missingParents) + rootMissedParents.Nodes.Add(node); + } + } + + private async void buttonAdd_Click(object sender, EventArgs e) + { + var result = InputDialog.Show("Please type the desired section name.", "Add a section", "My next section"); + if(result.DialogResult == DialogResult.Cancel) + return; + + // Get the currently selected section as parent: + var selectedNode = this.treeView.SelectedNode; + + // Add the new section to the database: + var addedSection = await SectionProcessor.AddSection(this.db, result.Text, result.IsRoot ? null : selectedNode?.Name); + + // Add the new section to the tree control: + var node = new TreeNode + { + Name = addedSection.DataKey, // [sic] name is the key + Text = addedSection.Name, + StateImageIndex = 1, + }; + + if(!result.IsRoot && selectedNode is not null) + selectedNode.Nodes.Add(node); + else + this.treeView.Nodes.Add(node); + + // Ensure, that the added node is visible and gets the focus: + node.EnsureVisible(); + this.treeView.SelectedNode = node; + } +} \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/SectionTree.resx b/I18N Commander/UI WinForms/Components/SectionTree.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/I18N Commander/UI WinForms/Components/SectionTree.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file