diff --git a/SunnyUI/Common/UControl.cs b/SunnyUI/Common/UControl.cs index 9f592998..2b7fd2bd 100644 --- a/SunnyUI/Common/UControl.cs +++ b/SunnyUI/Common/UControl.cs @@ -387,7 +387,7 @@ namespace Sunny.UI /// 接口名称 /// /// 控件列表 - public static List GetInterfaceControls(this Control ctrl, bool includeChild = false, bool includeUIPage = true) + public static List GetInterfaceControls(this Control ctrl, bool includeChild = false) { List values = new(); if (ctrl.IsNull()) return values; @@ -401,8 +401,29 @@ namespace Sunny.UI if (includeChild && obj.Controls.Count > 0) { - if (obj is not UIPage || includeUIPage) - values.AddRange(obj.GetInterfaceControls(includeChild, includeUIPage)); + values.AddRange(obj.GetInterfaceControls(includeChild)); + } + } + + return values; + } + + internal static List GetTranslateControls(this Control ctrl) + { + List values = new(); + if (ctrl.IsNull()) return values; + + foreach (Control obj in ctrl.Controls) + { + if (obj is T it && it != null) + { + values.Add(it); + } + + if (obj.Controls.Count > 0) + { + if (obj is UIPage) continue; + values.AddRange(obj.GetTranslateControls()); } } diff --git a/SunnyUI/Style/UTranslate.cs b/SunnyUI/Style/UTranslate.cs index 5da70846..c3338204 100644 --- a/SunnyUI/Style/UTranslate.cs +++ b/SunnyUI/Style/UTranslate.cs @@ -19,9 +19,12 @@ * 2021-07-23: V3.0.5 增加文件说明 ******************************************************************************/ +using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Windows.Forms; +using System.Xml; namespace Sunny.UI { @@ -61,19 +64,147 @@ namespace Sunny.UI public static class TranslateHelper { + private static List Ingores = + [ + "UIContextMenuStrip", + "UIStyleManager", + "UILogo", + "UIPagination", + "UIMiniPagination" + ]; + + private static List Needs = + [ + "System.Windows.Forms.ToolStripMenuItem" + ]; + + public static void LoadCsproj(string csprojFile) + { + List files = new List(); + XmlDocument xml = new XmlDocument(); + xml.Load(csprojFile); + if (xml.DocumentElement == null) return; + + foreach (XmlNode group in xml.DocumentElement.ChildNodes) + { + if (group.Name != "ItemGroup") continue; + + foreach (XmlNode node in group.ChildNodes) + { + if (node.Name != "Compile") continue; + if (node.Attributes == null) continue; + if (node.Attributes["Include"] == null) continue; + if (node.ChildNodes.Count == 1 && node.ChildNodes[0].Name == "SubType" && node.ChildNodes[0].InnerText == "Form") + { + string fileName = Path.Combine(Path.GetDirectoryName(csprojFile) ?? string.Empty, node.Attributes["Include"].InnerText); + string path = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".Designer.cs"); + if (File.Exists(path)) + { + files.Add(path); + } + } + } + } + + Dir.CreateDir(Dir.CurrentDir() + "Language"); + List names = new List(); + Dictionary ctrladds = new Dictionary(); + foreach (var file in files) + { + string[] lines = File.ReadAllLines(file); + names.Clear(); + ctrladds.Clear(); + bool isStart = false; + string inifile = ""; + foreach (var line in lines) + { + if (line.Trim().StartsWith("namespace")) + { + inifile = line.Trim().Replace("namespace", "").Trim() + "."; + } + + if (line.Trim().Contains("partial class")) + { + inifile += line.Trim().Replace("partial class", "").Trim(); + } + + if (line.Contains("private void InitializeComponent()")) isStart = true; + + if (isStart) + { + if (line.Contains(".Controls.Add")) + ctrladds.Add( + line.Between("(", ")"), + line.SplitBeforeLast(".Controls.Add").Replace("this.", "").Trim()); + } + + if (isStart && line.Trim().StartsWith("private") && line.Trim().EndsWith(";")) + { + string[] items = line.Trim().Split(" "); + string name = items[2].Replace(";", ""); + string classname = items[1]; + + if (Ingores.Contains(classname)) continue; + + if (classname.SplitLast(".").StartsWith("UI") || Needs.Contains(classname)) + { + ctrladds.TryGetValue("this." + name, out string parent); + if (parent.IsValid()) + names.Add($"{parent},{classname},{name}"); + else + names.Add($"{classname},{name}"); + } + } + } + + foreach (var line in lines) + { + for (int i = 0; i < names.Count; i++) + { + if (names[i].SplitSeparatorCount(",") >= 1) continue; + string add = $".Controls.Add(this.{names[i]});"; + if (line.Contains(add)) + { + names[i] = line.Replace(add, "").Replace("this.", "").Trim() + "," + names[i]; + } + } + } + + if (names.Count > 0) + { + inifile = Dir.CurrentDir() + "Language\\" + inifile + ".ini"; + IniFile ini = new IniFile(inifile, System.Text.Encoding.UTF8); + string section = "Info"; + const string warning = "注意:请先关闭应用程序,然后再修改此文档。否则修改可能会应用程序生成代码覆盖。"; + if (ini.Read(section, "Warning", "") != warning) + ini.Write(section, "Warning", warning); + ini.Write(section, "Controls", string.Join(";", names.ToArray())); + ini.UpdateFile(); + } + } + } + + public struct CtrlInfo + { + public string Name; + public string ClassName; + public string Parent; + } + public static void TranslateOther(this Form form) { if (!UIStyles.MultiLanguageSupport) return; if (!(form is UIBaseForm || form is UIPage)) return; + Dir.CreateDir(Dir.CurrentDir() + "Language"); string thisFullName = form.GetType().FullName; string section = "Info"; - const string warning = "注意:请先关闭应用程序,然后再修改此文档。否则修改可能会应用程序生成代码覆盖。"; - var formControls = form.GetInterfaceControls(true, false).Where(p => p.FormTranslatorProperties != null); - Dir.CreateDir(Dir.CurrentDir() + "Language"); + string inifile = Dir.CurrentDir() + "Language\\" + thisFullName + ".ini"; + if (!File.Exists(inifile)) return; IniFile ini = new IniFile(Dir.CurrentDir() + "Language\\" + thisFullName + ".ini", System.Text.Encoding.UTF8); - if (ini.Read(section, "Warning", "") != warning) - ini.Write(section, "Warning", warning); + string controls = ini.Read(section, "Controls", ""); + if (controls.IsNullOrEmpty()) return; + string key = UIStyles.CultureInfo.LCID.ToString() + ".DisplayName"; if (ini.Read(section, key, "") != UIStyles.CultureInfo.DisplayName) ini.Write(section, key, UIStyles.CultureInfo.DisplayName); @@ -81,29 +212,51 @@ namespace Sunny.UI if (ini.Read(section, key, "") != UIStyles.CultureInfo.EnglishName) ini.Write(section, UIStyles.CultureInfo.LCID.ToString() + ".EnglishName", UIStyles.CultureInfo.EnglishName); + Dictionary Ctrls2 = new Dictionary(); + Dictionary Ctrls3 = new Dictionary(); + foreach (var item in controls.Split(';')) + { + string[] strs = item.Split(","); + if (strs.Length == 0) continue; + + if (strs.Length == 2) + { + Ctrls2.Add(strs[1], new CtrlInfo() { ClassName = strs[0], Name = strs[1], Parent = "" }); + } + + if (strs.Length == 3) + { + Ctrls3.Add(strs[2], new CtrlInfo() { ClassName = strs[1], Name = strs[2], Parent = strs[0] }); + } + } + + var formControls = form.GetTranslateControls().Where(p => p.FormTranslatorProperties != null); ; section = UIStyles.CultureInfo.LCID + ".Form"; foreach (var control in formControls) { if (control.ShowBuiltInResources) continue; - - foreach (var propertyName in control.FormTranslatorProperties) + Control ctrl = (Control)control; + if (ctrl.Name.IsNullOrEmpty()) continue; + if (Ctrls3.NotContainsKey(ctrl.Name)) continue; + if (ctrl.Parent.Name == form.Name || ctrl.Parent.Name == Ctrls3[ctrl.Name].Parent) { - Control ctrl = (Control)control; - if (ctrl.Name.IsNullOrEmpty()) continue; - PropertyInfo pt = ctrl.GetType().GetProperty(propertyName); - if (pt == null || !pt.CanWrite) continue; - - key = ctrl.Name + "." + propertyName; - string langStr = ini.Read(section, key, ""); - string ctrlStr = pt.GetValue(ctrl, null)?.ToString(); - - if (langStr.IsNullOrEmpty()) + foreach (var propertyName in control.FormTranslatorProperties) { - if (ctrlStr.IsValid()) ini.Write(section, key, ctrlStr); - } - else - { - pt.SetValue(ctrl, langStr, null); + PropertyInfo pt = ctrl.GetType().GetProperty(propertyName); + if (pt == null || !pt.CanWrite) continue; + + key = ctrl.Name + "." + propertyName; + string langStr = ini.Read(section, key, ""); + string ctrlStr = pt.GetValue(ctrl, null)?.ToString(); + + if (langStr.IsNullOrEmpty()) + { + if (ctrlStr.IsValid()) ini.Write(section, key, ctrlStr); + } + else + { + pt.SetValue(ctrl, langStr, null); + } } } }