CodeResourceControl.cs 12.7 KB
using log4net;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.Layout;

namespace OnlineStore
{
    public class crc : CodeResourceControl
    {
        
    }
    public class CodeResourceControl
    {
        public static readonly ILog LOG = LogManager.GetLogger("LngResource");
        public static bool OpenResourceLog = false;
        public static string China = "zh-CN";

        private static Dictionary<string,Dictionary<string, string>> LangMap = new Dictionary<string, Dictionary<string, string>>();

        public delegate string GetLanguageDelegate();
        public static event GetLanguageDelegate GetLanguageEvent;

        public delegate void RefreshLanguageDelegate();
        public static event RefreshLanguageDelegate RefreshLanguageEvent;

        public static event EventHandler LanguageChangeEvent;


        static CodeResourceControl() {


            LoadData();
            var lngjson = JsonHelper.SerializeObject(LangMap);

        }

        private static char spilt = '\t';
        private static string rPath = Application.StartupPath + @"\resources\";
        private static void LoadData(bool loadserverdir = false)
        {
            string loadpath = rPath;
            if (loadserverdir)
                loadpath = Path.Combine(rPath, "server");
            Directory.CreateDirectory(loadpath);
            string[] lngresfiles = Directory.GetFiles(loadpath, "*.lngres");
            foreach (var lngresfile in lngresfiles)
            {
                Dictionary<string, string> lngMap;
                var lngname = Path.GetFileNameWithoutExtension(lngresfile);
                if (!LangMap.ContainsKey(lngname))
                {
                    LangMap.Add(lngname, new Dictionary<string, string>());
                }
                lngMap = LangMap[lngname];
                string[] lines = File.ReadAllLines(lngresfile);
                foreach (string line in lines)
                {
                    if (string.IsNullOrEmpty(line))
                        continue;

                    string[] array = line.Split(spilt);
                    if (array.Length >= 3)
                    {
                        string key = array[0].Trim();
                        string value = array[2];
                        if (lngMap.ContainsKey(key))
                            lngMap[key] = value;
                        else
                            lngMap.Add(key, value);

                    }
                }
            }
        }
        static Dictionary<string, string> LangName = new Dictionary<string, string>() {
            {"zh-CN","简体中文" },
            {"zh-TW","繁體中文" },
            { "en-US", "English" },
            { "ja-JP", "日本語" },
            { "fr-FR", "Français" },
            { "de-DE", "Deutsche" },
        };

        public static Dictionary<string, string> GetLangList()
        {
            Dictionary<string, string> LangList = new Dictionary<string, string>();
            foreach (var v in LangName)
            {
                if (LangMap.ContainsKey(v.Key))
                {
                    if (!LangList.ContainsKey(v.Key))
                        LangList.Add(v.Key, v.Value);
                }
            }
            return LangList;
        }



        public static void LanguageChange() {
            LanguageChangeEvent?.Invoke(null, EventArgs.Empty);
        }
        public static string GetLanguage()
        {
            if (GetLanguageEvent == null)
            {
                return China;
            }
            string result = GetLanguageEvent?.Invoke();
            if (result == null)
            {
                return "";
            }
            return result;
        }

        private static string spiltStr = "_";
        private static string Text = "Text";
        public static string GetTextIdStr(string className, string controlName)
        {
            return className + spiltStr + controlName + spiltStr + Text;
        }
        //public static CrcObject GetString(object id, string defaultStr, params string[] param)
        //{
        //    return GetString(id.ToString(), defaultStr, param);
        //}
        public static CrcObject GetString(string id, string defaultStr, params string[] param)
        {

            string strCurLanguage = defaultStr;
            var haslang = getLangRes(CurrLanguage);
            if (!haslang)
            {
                return new CrcObject(id, strCurLanguage, param);
            }
            try
            {
                LangMap[CurrLanguage].TryGetValue(id, out strCurLanguage);

                if ((strCurLanguage == null || strCurLanguage.Equals("")) && (!defaultStr.Equals("")))
                {
                    strCurLanguage = defaultStr;
                    if (HasChinese(defaultStr))
                        NoIdLog(id, defaultStr);
                }
            }
            catch (Exception ex)
            {
                if (defaultStr.Equals(""))
                {
                }
                else
                {
                    strCurLanguage = "No id:[" + id + "], please add.";
                    strCurLanguage = defaultStr;
                    NoIdLog(id, defaultStr);
                }
            }
            if (strCurLanguage == null)
            {
                strCurLanguage = "";
            }
            return new CrcObject(id, strCurLanguage, param);
        }
        static bool HasChinese(string txt)
        {
            return Regex.IsMatch(txt.ToString(), @"[\u4E00-\u9FA5]+");
        }
        static HashSet<string> hss = new HashSet<string>();
        private static void NoIdLog(string id, string defaultStr)
        {
            if (OpenResourceLog)
            {
                getLangRes("zh-CN");
                if (!LangMap["zh-CN"].ContainsKey(id) && checkInterid(id) && !hss.Contains(id))
                {
                    hss.Add(id);
                    LOG.Info("" + id + "\t" + defaultStr);
                }
                    
            }
        
        }
        private static bool checkInterid(string id) {
            return true;
            string[] interstring = new string[] { "_txt", "_lbl" };
            var x = from a in interstring
                    where id.IndexOf(a) > -1
                    select a;
            return x.Count() == 0;
        } 



        private static bool getLangRes(string lang) {
            if (!LangMap.ContainsKey(lang)) {
                string path = Application.StartupPath + @"\resources\"+lang+ ".lngres";
                if (!File.Exists(path))
                {
                    return false;
                }
                string[] lines = File.ReadAllLines(path);
                var map = new Dictionary<string, string>();
                foreach (string line in lines)
                {
                    string[] array = line.Split('\t');
                    if (array.Length >= 3)
                    {
                        string key = array[0];
                        string chinese = array[1];
                        string english = array[2];
                        if (map.ContainsKey(key))
                        {
                            map.Remove(key);
                        }
                        map.Add(key, english);
                        
                    }
                }
                LangMap.Add(lang, map);
                return true;
            }
            return true;

        }
        public static string CurrLanguage = "";

        public static void LanguageProcess(ContainerControl cc, string className="")
        {
            if (string.IsNullOrEmpty(className))
                className = cc.GetType().Name;

            if (CurrLanguage.Equals(CodeResourceControl.GetLanguage()))
            {
                //return;
            }
            //string className = cc.ClassName;
            CurrLanguage = CodeResourceControl.GetLanguage();
            string name = CodeResourceControl.GetString(className, cc.Text);
            if (!name.Equals("")) { cc.Text = name; }

            PreControlLanaguage(cc, className);
            RefreshLanguageEvent?.Invoke();

        }
        private static void PreControlLanaguage(Control partentControl, string className)
        {
            string newStr = "";
            //Con_GetTxt(partentControl, out string title);
            //string newStr = GetString(GetTextIdStr(className, partentControl.Name), title);
            //if (!newStr.Equals(""))
            //{
            //Con_SetTxt(partentControl, newStr.Replace("\\n", "\n"));
            //}
            foreach (Control con in partentControl.Controls)
            {
                string txt = "";
                bool haslang = false;

                if (con.Tag != null && con.Tag.ToString() == "not")
                {
                    continue;
                }

                if (Con_GetTxt(con, out txt))
                {
                    newStr = GetString(GetTextIdStr(className, con.Name), txt);
                    if (!newStr.Equals(""))
                    {
                        Con_SetTxt(con, newStr.Replace("\\n", "\n"));
                        //haslang = true;
                    }
                }

                if (con.Tag !=null && con.Tag.ToString() == "nochiled")
                {
                    continue;
                }
                if (con.Controls.Count > 0 && !haslang)
                {
                    PreControlLanaguage(con, className+"_"+ con.Name);
                }
                //Console.WriteLine(con is IList<Component>);
                //Console.WriteLine(con is IList<Component>);

            }
        }
        public static void ProcessListItem<T>(T con,string ClassName) where T: ToolStripItemCollection
        {
            for (int i = 0; i < con.Count; i++) {
                if (con[i].Tag != null && con[i].Tag.ToString() == "not")
                {
                    continue;
                }

                string txt = con[i].Text;
                string newStr = GetString(GetTextIdStr(ClassName, con[i].Name), txt);
                if (!newStr.Equals(""))
                {
                    con[i].Text= newStr.Replace("\\n", "\n");
                    //haslang = true;
                }
                if (con[i] is ToolStripMenuItem) {
                    var tt = ((ToolStripMenuItem)con[i]);
                    ProcessListItem(tt.DropDownItems, tt.Name);
                }
            }
        }
        static bool Con_GetTxt(Control con, out string txt)
        {
            txt = "";
            if (con is Label || con is Button || con is RadioButton || con is CheckBox)
            {
                txt = con.Text;
                return true;
            }
            string methodname = getMethodname(con);

            var t = con.GetType();
            var p = t.GetProperty(methodname);

            if (p != null)
            {
                txt = p.GetValue(con, null).ToString();
                return true;
            }
            return false;
        }
        static void Con_SetTxt(Control con, string txt)
        {
            if (con is Label || con is Button || con is RadioButton || con is CheckBox)
            {
                con.Text = txt;
                return;
            }
            string methodname = getMethodname(con);

            var t = con.GetType();
            var p = t.GetProperty(methodname);
            if (p == null)
                return;
            else
                p.SetValue(con, txt,null);
        }
        static string getMethodname(Control con) {
            string methodname = "Text";

            //if (con is UCBtnExt) methodname = "BtnText";
            //if (con is UCTextBoxEx) methodname = "InputText";
            //if (con is UCCheckBox) methodname = "TextValue";
            //if (con is UCPanelTitle || con is FrmWithTitle) methodname = "Title";
            //if (con is Form) methodname = "Title";
            return methodname;
        }
    }

    public class CrcObject
    {
        public string msg;
        public string key;
        public string[] param;

        public CrcObject(string key, string msg, params string[] param)
        {
            this.key = key;
            this.msg = msg;
            this.param = param;
        }

        public override string ToString()
        {
            return string.Format(msg.ToString(),param);
        }
        public static implicit operator string(CrcObject m1)
        {
            if (m1 == null)
                return null;
            return m1.msg;
        }
    }
}