181 lines
6.1 KiB
C#
181 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Windows.Forms;
|
|
|
|
namespace Inspectron.Settings.Windows.Configuration;
|
|
|
|
public partial class OptionsWindow : Form
|
|
{
|
|
private Dictionary<string, List<OptionSetting>> settingsByCategory;
|
|
private IControlFactory controlFactory;
|
|
|
|
public OptionsWindow(IControlFactory controlFactory)
|
|
{
|
|
this.controlFactory = controlFactory;
|
|
settingsByCategory = new Dictionary<string, List<OptionSetting>>();
|
|
|
|
InitializeComponent();
|
|
this.treeViewCategories.AfterSelect += new TreeViewEventHandler(this.treeViewCategories_AfterSelect);
|
|
this.buttonOK.Click += new EventHandler(this.buttonOK_Click);
|
|
this.buttonCancel.Click += new EventHandler(this.buttonCancel_Click);
|
|
}
|
|
|
|
public void LoadFromSettings(InspectronSettings inspectronSettings)
|
|
{
|
|
// UserSettings is a Tree<object> with folders (string) and UserSettingsInfo nodes.
|
|
// Traverse the tree to find all UserSettingsInfo nodes and their PropertyDescriptors.
|
|
|
|
void Traverse(object nodeObj, string path)
|
|
{
|
|
var node = nodeObj as dynamic; // Tree<object>
|
|
object value = node.Value;
|
|
|
|
if (value is string folderName)
|
|
{
|
|
// Folder node, append to path and traverse children
|
|
string newPath = string.IsNullOrEmpty(path) ? folderName : $"{path}/{folderName}";
|
|
foreach (var child in node.Children)
|
|
Traverse(child, newPath);
|
|
}
|
|
else if (value is Inspectron.Settings.InspectronSettings.UserSettingsInfo info)
|
|
{
|
|
// Leaf node: user settings group
|
|
string groupName = info.Name;
|
|
string groupPath = string.IsNullOrEmpty(path) ? groupName : $"{path}/{groupName}";
|
|
foreach (var pd in info.Settings)
|
|
{
|
|
// Try to get owner from BoundPropertyDescriptor, else skip
|
|
object owner = null;
|
|
string description = pd.Description;
|
|
if (pd is Inspectron.Settings.BoundPropertyDescriptor bpd)
|
|
{
|
|
owner = bpd.Owner;
|
|
if (string.IsNullOrEmpty(description))
|
|
description = bpd.DisplayName;
|
|
}
|
|
else
|
|
{
|
|
// If not a BoundPropertyDescriptor, cannot get owner, skip
|
|
continue;
|
|
}
|
|
RegisterUserSetting(owner, bpd.PropertyInfo.Name, groupPath, description);
|
|
}
|
|
}
|
|
}
|
|
|
|
Traverse(inspectronSettings.UserSettings.Root, "");
|
|
}
|
|
|
|
public void RegisterUserSetting(object owner, string propertyName, string treePath, string description = null)
|
|
{
|
|
// Get the PropertyInfo from owner and propertyName
|
|
var property = owner.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
|
|
if (property == null)
|
|
throw new ArgumentException($"Property '{propertyName}' not found on owner type.");
|
|
|
|
if (string.IsNullOrEmpty(description))
|
|
description = propertyName;
|
|
|
|
// Create an OptionSetting instance
|
|
var setting = new OptionSetting
|
|
{
|
|
Owner = owner,
|
|
Property = property,
|
|
Description = description,
|
|
TreePath = treePath,
|
|
Value = property.GetValue(owner)
|
|
};
|
|
|
|
// Add to settingsByCategory
|
|
if (!settingsByCategory.TryGetValue(treePath, out var settingsList))
|
|
{
|
|
settingsList = new List<OptionSetting>();
|
|
settingsByCategory[treePath] = settingsList;
|
|
}
|
|
settingsList.Add(setting);
|
|
|
|
// Add nodes to treeViewCategories
|
|
AddTreeNodes(treeViewCategories, treePath);
|
|
}
|
|
|
|
private void AddTreeNodes(TreeView treeView, string treePath)
|
|
{
|
|
var parts = treePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
TreeNodeCollection nodes = treeView.Nodes;
|
|
foreach (var part in parts)
|
|
{
|
|
var node = Enumerable.Cast<TreeNode>(nodes).FirstOrDefault(n => n.Text == part);
|
|
if (node == null)
|
|
{
|
|
node = new TreeNode(part);
|
|
nodes.Add(node);
|
|
}
|
|
nodes = node.Nodes;
|
|
}
|
|
}
|
|
|
|
private void treeViewCategories_AfterSelect(object sender, TreeViewEventArgs e)
|
|
{
|
|
// Display the settings for the selected category
|
|
string selectedPath = GetFullPath(e.Node);
|
|
DisplaySettings(selectedPath);
|
|
}
|
|
|
|
private string GetFullPath(TreeNode node)
|
|
{
|
|
if (node.Parent == null)
|
|
return node.Text;
|
|
else
|
|
return GetFullPath(node.Parent) + "/" + node.Text;
|
|
}
|
|
|
|
private void DisplaySettings(string treePath)
|
|
{
|
|
flowLayoutPanelSettings.Controls.Clear();
|
|
|
|
if (settingsByCategory.TryGetValue(treePath, out var settingsList))
|
|
{
|
|
foreach (var setting in settingsList)
|
|
{
|
|
var control = controlFactory.CreateControl(
|
|
setting.Property.Name,
|
|
setting.Description,
|
|
setting.Property,
|
|
setting.Value,
|
|
(newValue) =>
|
|
{
|
|
setting.Value = newValue;
|
|
},
|
|
this);
|
|
|
|
flowLayoutPanelSettings.Controls.Add(control);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void buttonOK_Click(object sender, EventArgs e)
|
|
{
|
|
// Update the owner properties with the values
|
|
foreach (var settingsList in settingsByCategory.Values)
|
|
{
|
|
foreach (var setting in settingsList)
|
|
{
|
|
setting.Property.SetValue(setting.Owner, setting.Value);
|
|
}
|
|
}
|
|
|
|
this.DialogResult = DialogResult.OK;
|
|
this.Close();
|
|
}
|
|
|
|
private void buttonCancel_Click(object sender, EventArgs e)
|
|
{
|
|
this.DialogResult = DialogResult.Cancel;
|
|
this.Close();
|
|
}
|
|
}
|
|
|