* 重构多语翻译类
This commit is contained in:
parent
7bdde150c2
commit
2daddaef65
@ -387,7 +387,7 @@ namespace Sunny.UI
|
||||
/// <param name="interfaceName">接口名称</param>
|
||||
/// <param name="includeChild"></param>
|
||||
/// <returns>控件列表</returns>
|
||||
public static List<T> GetInterfaceControls<T>(this Control ctrl, bool includeChild = false, bool includeUIPage = true)
|
||||
public static List<T> GetInterfaceControls<T>(this Control ctrl, bool includeChild = false)
|
||||
{
|
||||
List<T> 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<T>(includeChild, includeUIPage));
|
||||
values.AddRange(obj.GetInterfaceControls<T>(includeChild));
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
internal static List<T> GetTranslateControls<T>(this Control ctrl)
|
||||
{
|
||||
List<T> 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<T>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<string> Ingores =
|
||||
[
|
||||
"UIContextMenuStrip",
|
||||
"UIStyleManager",
|
||||
"UILogo",
|
||||
"UIPagination",
|
||||
"UIMiniPagination"
|
||||
];
|
||||
|
||||
private static List<string> Needs =
|
||||
[
|
||||
"System.Windows.Forms.ToolStripMenuItem"
|
||||
];
|
||||
|
||||
public static void LoadCsproj(string csprojFile)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
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<string> names = new List<string>();
|
||||
Dictionary<string, string> ctrladds = new Dictionary<string, string>();
|
||||
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<IFormTranslator>(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<string, CtrlInfo> Ctrls2 = new Dictionary<string, CtrlInfo>();
|
||||
Dictionary<string, CtrlInfo> Ctrls3 = new Dictionary<string, CtrlInfo>();
|
||||
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<IFormTranslator>().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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user