using System.Collections.Generic;
using System.Drawing;
using System;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using DPumpHydr.WinFrmUI.WenSkin.Json.Utilities;
using System.Linq;
using System.IO;
namespace DPumpHydr.WinFrmUI.WenSkin;
public class Ini
{
private IniGroupCollection items;
public Ini() { }
public Ini(string path) : this(path, Encoding.UTF8) { }
public Ini(string path, Encoding encoding)
{
Path = path;
Encoding = encoding;
Load(path, encoding);
}
public string? this[string name]
{
get => GetItem(name);
set
{
var item = Items.SelectMany(t => t.Items)?.ToList().Find(t => t.Name?.ToLower() == name.ToLower());
if (item == null)
{
AddItem(null, name, value);
}
else
{
item.Value = value;
}
}
}
public string? this[string key, string name]
{
get => Items[key]?.Items[name]?.Value;
set
{
//获取Group
if (Items[key] is not IniGroup group)
{
group = this.Items.Add(key);
}
if (group.Items[name] is not IniItem iniItem)
{
iniItem = group.Items.Add(name, value);
}
iniItem.Value = value;
}
}
#region 公有属性
public string FileName => System.IO.Path.GetFileName(Path);
///
/// 路径
///
public string Path { get; private set; }
///
/// 编码方式
///
public Encoding Encoding { get; private set; }
///
/// 内容
///
public string Text => string.Join("\r\n", Items.Select(g => g.Text));
#endregion
///
/// 加载(默认UTF8编码)
///
///
public void Load(string path) => Load(path, Encoding.UTF8);
///
/// 加载( 指定文件编码)
///
///
///
public void Load(string path, Encoding encoding)
{
Items.Clear();
if (!File.Exists(path))
return;
string[] texts = File.ReadAllLines(path, encoding);
IniGroup? group = null;
foreach (var text in texts)
{
//选项
string t = text.Replace(" ", "");
var idx = text.IndexOf("=");
//添加组
if (t.StartsWith("[") && t.EndsWith("]"))
{
group = Items.Add(text.Substring(text.IndexOf("[") + 1, text.IndexOf("]") - 1));
continue;
}
else if (Items.Count == 0)
{
group = Items.Add(null);
}
//添加选项
if (t.StartsWith("!") || t.StartsWith(";") || t.StartsWith("]") || t.StartsWith("//") || string.IsNullOrEmpty(t))
{
group?.Items.Add(null, text);
}
else if (idx == -1)
{
group?.Items.Add(null, text);
}
else if (idx == 0)
{
group?.Items.Add("", text);
}
else if (idx > 0)
{
group?.Items.Add(text.Substring(0, idx), text.Substring(idx + 1));
}
}
}
///
/// 添加注释
///
///
///
public void AddRemark(string groupName, string value) => AddItem(groupName, null, value);
///
/// 添加选项
///
///
///
///
public void AddItem(string? groupName, string? name, string? value)
{
var g = this.Items[groupName];
g ??= this.Items.Add(groupName);
g.Items.Add(name, value);
}
///
/// 获取选项
///
/// 组名称
/// 名称
///
public string? GetItem(string groupName, string name) => Items[groupName]?.Items[name]?.Value;
///
/// 获取选项值
///
/// 名称
///
public string? GetItem(string name) => Items.SelectMany(t => t.Items)?.ToList().Find(t => t.Name?.ToLower() == name.ToLower())?.Value;
///
/// 保存
///
public void Save()
{
SaveAs(Path);
}
///
/// 另存为
///
///
public void SaveAs(string path)
{
SaveAs(path, Encoding);
}
///
/// 另存为(指定文件编码)
///
/// 路径
/// 文件编码
public void SaveAs(string path, Encoding encoding)
{
File.WriteAllText(path, Text, encoding);
}
///
/// 选项
///
public IniGroupCollection Items => items ??= new IniGroupCollection(this);
///
/// 组
///
public class IniGroup
{
private readonly IniGroupCollection owner;
private IniItemCollection? items;
public IniGroup(IniGroupCollection owner, string? name)
{
this.owner = owner;
Name = name;
}
public Ini Ini => this.owner.Ini;
///
/// 名称
///
public string? Name { get; private set; }
///
/// 选项合集
///
public IniItemCollection Items => items ??= new IniItemCollection(this);
///
/// 内容
///
public string Text => (string.IsNullOrWhiteSpace(Name) ? "" : $"[{Name}]\r\n") + string.Join("\r\n", Items.Select(x => x.Text));
}
///
/// 组合计
///
public class IniGroupCollection : List
{
private readonly Ini owner;
public IniGroupCollection(Ini owner)
{
this.owner = owner;
}
///
/// Ini
///
public Ini Ini => this.owner;
///
/// 获取选项
///
///
///
public IniGroup? this[string? name] => Find(a => a.Name?.ToUpper() == name?.ToUpper());
///
/// 添加选项
///
///
///
public IniGroup Add(string? name)
{
var g = new IniGroup(this, name);
if (name is null)
{
this.Insert(0, g);
}
else
{
Add(g);
}
return g;
}
}
///
/// 选项
///
public class IniItem
{
private readonly IniItemCollection owner;
public IniItem(IniItemCollection owner, string? name, string? value)
{
this.owner = owner;
Name = name;
Value = value;
}
public Ini Ini => owner.Ini;
public IniItemCollection Owner => owner;
public int Index => owner.IndexOf(this);
///
/// 名称
///
public string? Name { get; set; }
///
/// 值
///
public string? Value { get; set; }
///
/// 文本
///
public string? Text => string.IsNullOrWhiteSpace(Name) ?
(string.IsNullOrWhiteSpace(Value) || Value.StartsWith('!') || Value.StartsWith(';') ? Value : (";" + Value)) :
$"{Name}={Value}";
///
/// 是否是注释行
///
public bool IsRemarkLine => string.IsNullOrWhiteSpace(this.Name);
}
///
/// 选项合集
///
public class IniItemCollection : List
{
private readonly IniGroup owner;
public IniItemCollection(IniGroup owner)
{
this.owner = owner;
}
public Ini Ini => owner.Ini;
public IniItem? this[string name] => Find(a => a.Name?.ToUpper() == name?.ToUpper());
public IniItem Add(string? name, string? value)
{
var item = new IniItem(this, name, value);
this.Add(item);
return item;
}
}
///
/// 弹出编辑窗口
///
public void Show() => IniFormShow();
///
/// 弹出编辑窗口
///
public void IniFormShow()
{
var fm = new Form()
{
Width = 925,
Height = 571,
Text = $"INI可视化编辑器 - 珠海森云科技出品 - {this.FileName} - {this.Encoding.EncodingName}",
StartPosition = FormStartPosition.CenterScreen,
};
fm.Controls.Add(new IniControl(this) { Dock = DockStyle.Fill });
fm.ShowDialog();
}
public static StringFormat StringConters { get; set; } = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap)
{
LineAlignment = StringAlignment.Center,
Trimming = StringTrimming.EllipsisCharacter
};
public class IniControl : Control
{
private Ini Ini;
public IniControl(Ini ini)
{
this.Ini = ini;
this.Size = new Size(900, 540);
this.BackColor = Color.White;
Initcom();
if (ini != null)
Load();
}
private FlowLayoutPanel Flow;
private void Initcom()
{
Button button = new Button()
{
Text = "保存 应用",
Dock = DockStyle.Bottom,
};
button.Click += (s, e) =>
{
Ini.Save();
MessageBox.Show("保存成功!");
};
Flow = new FlowLayoutPanel()
{
Dock = DockStyle.Fill,
AutoScroll = true,
FlowDirection = FlowDirection.TopDown,
WrapContents = false,
};
this.Controls.Add(Flow);
this.Controls.Add(button);
}
public IniItem Selected => SelectedControl.IniItem;
public IniItemControl SelectedControl { get; private set; }
private void Load()
{
foreach (var ini in Ini.Items)
{
var groupBox = new GroupBox()
{
Text = ini.Name ?? "Default (Is not group name)",
ForeColor = Color.DarkOrchid,
AutoSize = true,
};
var flow = new FlowLayoutPanel()
{
AutoSize = true,
FlowDirection = FlowDirection.TopDown,
Dock = DockStyle.Fill,
};
foreach (var item in ini.Items)
{
var control = new IniItemControl(this, flow, item);
control.Click += (s, e) =>
{
if (this.SelectedControl != null)
this.SelectedControl.SelectColor = Color.White;
control.SelectColor = Color.DarkGray;
this.SelectedControl = control;
};
flow.Controls.Add(control);
}
groupBox.Controls.Add(flow);
Flow.Controls.Add(groupBox);
}
}
}
public class IniItemControl : Control
{
private readonly IniControl owner;
private readonly FlowLayoutPanel flow;
private readonly IniItem iniItem;
public IniItemControl(IniControl owner, FlowLayoutPanel flow, IniItem iniItem)
{
base.SetStyle(
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.SupportsTransparentBackColor, true);
base.UpdateStyles();
this.BackColor = Color.Transparent;
this.owner = owner;
this.flow = flow;
this.iniItem = iniItem;
this.Height = 30;
this.Width = 870;
this.Margin = new Padding(1, 0, 1, 0);
this.Name = iniItem.Name;
this.Text = iniItem.Text;
menuStrip.Items.Add("注释", null, (s, e) =>
{
var item = new IniItem(IniItem.Owner, null, ";注释");
this.IniItem.Owner.Insert(this.IniItem.Index, item);
var control = new IniItemControl(owner, flow, item);
this.flow.Controls.Add(control);
this.flow.Controls.SetChildIndex(control, this.IniItem.Index - 1);
});
menuStrip.Items.Add("插入", null, (s, e) =>
{
var item = new IniItem(IniItem.Owner, "Name", "Value");
this.IniItem.Owner.Insert(this.IniItem.Index, item);
var control = new IniItemControl(owner, flow, item);
this.flow.Controls.Add(control);
this.flow.Controls.SetChildIndex(control, this.IniItem.Index - 1);
});
menuStrip.Items.Add("添加", null, (s, e) =>
{
var item = new IniItem(IniItem.Owner, "Name", "Value");
this.IniItem.Owner.Add(item);
var control = new IniItemControl(owner, flow, item);
this.flow.Controls.Add(control);
});
menuStrip.Items.Add("删除", null, (s, e) =>
{
this.IniItem.Owner.Remove(this.IniItem);
this.Dispose();
});
this.ContextMenuStrip = menuStrip;
}
private readonly ContextMenuStrip menuStrip = new ContextMenuStrip();
private Color selectColor = Color.White;
public IniItem IniItem => iniItem;
public Color SelectColor { get => selectColor; set { selectColor = value; this.BackColor = value; } }
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.BackColor = SelectColor;
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.BackColor = Color.LightGray;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
if (IniItem.IsRemarkLine)
{
var valueRec = new RectangleF(0, 0, Width, Height);
g.DrawString(IniItem.Value, Font, Brushes.Green, valueRec, StringConters);
}
else
{
var nameRec = new RectangleF(0, 0, 145, Height);
var valueRec = new RectangleF(150, 0, Width - 150, Height);
g.DrawString(IniItem.Name, Font, Brushes.DodgerBlue, nameRec, StringConters);
g.DrawString(IniItem.Value, Font, Brushes.Black, valueRec, StringConters);
}
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (IniItem.IsRemarkLine)
{
ShowTextBox(Width, 0);
}
else
{
if (new RectangleF(0, 0, 145, Height).Contains(e.Location))
{
ShowTextBox(145, 0, false);
}
else
{
ShowTextBox(Width - 150, 150);
}
}
}
private void ShowTextBox(int width, int x, bool isValue = true)
{
var tb = new TextBox()
{
Width = width,
Text = isValue ? IniItem.Value : IniItem.Name,
ForeColor = IniItem.IsRemarkLine ? Color.Green : Color.Black,
};
tb.Location = new Point(x, (this.Height - tb.Height) / 2);
tb.LostFocus += (s, e) =>
{
tb.Dispose();
};
tb.TextChanged += (s, e) =>
{
if (isValue)
IniItem.Value = tb.Text;
else
IniItem.Name = tb.Text;
};
tb.KeyDown += (s, e) =>
{
if (e.KeyCode == Keys.Enter)
{
tb.Dispose();
}
};
this.Controls.Add(tb);
tb.Select();
}
}
}