#region Disclaimer / License // Copyright (C) 2009, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Reflection; using System.Resources; using System.Collections; using System.Globalization; namespace OSGeo.MapGuide.Maestro { /// /// Class that enables globalization of a form /// public class Globalizator : IDisposable { /// /// A global list of translated objects /// private static Hashtable _LocalizedObjects = new Hashtable(); /// /// The current culture /// private static CultureInfo _CurrentCulture = CultureInfo.CurrentUICulture; /// /// Changes the global cultureinfo on all registered objects /// public static CultureInfo CurrentCulture { get { return _CurrentCulture; } set { _CurrentCulture = value; foreach(Globalizator g in _LocalizedObjects.Keys) g.Culture = value; } } /// /// Object that can be localized /// private object m_obj; /// /// The Culture used to translate the item /// private CultureInfo m_culture; /// /// The name (path) to the resource file, excluding the extension /// private string m_resourceName; /// /// The resource manager /// private ResourceManager m_rm; /// /// Constructs a globalizer, this method is made for the Maestro project, and the resource path construction may differ in other projects. /// /// The object to localize public Globalizator(object obj) : this(obj, obj.GetType().Namespace + ".Localization." + obj.GetType().Name) { } /// /// Constructs a new globalization object /// /// The object to localize /// The name (path) to the resource file, excluding the extension /// The culture to use as default public Globalizator(object obj, string resourceName) : this(obj, resourceName, Globalizator.CurrentCulture) { //We add the item here, so an overriden culture is not updated _LocalizedObjects.Add(this, null); } /// /// Constructs a new globalization object /// /// The object to localize /// The name (path) to the resource file, excluding the extension /// The culture to use as default public Globalizator(object obj, string resourceName, CultureInfo culture) { m_obj = obj; m_culture = culture; m_resourceName = resourceName; m_rm = new ResourceManager(resourceName, obj.GetType().Assembly); Translate(); } /// /// Gets or sets the current culture /// public CultureInfo Culture { get { return m_culture; } set { m_culture = value; Translate(); } } /// /// (Re-)translate the current object /// public void Translate() { Translate(m_obj, "", m_culture, m_resourceName, null, null, m_rm); } public string Translate(string text) { string x = m_rm.GetString(text.Replace("\n", "\\n").Replace("\"", "\\\"").Trim(), m_culture); if (x == null) return text; else return x.Replace("\\n", "\n"); } public static string Translate(string resourceName, Assembly asm, string text) { ResourceManager rm = new ResourceManager(resourceName, asm); return rm.GetString(resourceName + '.' + text, Globalizator.CurrentCulture); } public static void Translate(object obj, string resourceName) { Translate(obj, "", Globalizator.CurrentCulture, resourceName, null, null, null); } public static void Translate(object obj, string resourceName, CultureInfo culture) { Translate(obj, "", culture, resourceName, null, null, null); } private static void Translate(object obj, string baseName, CultureInfo culture, string resourceName, object parent, System.Collections.ArrayList alreadyDone, ResourceManager rm) { if (null == obj) return ; Type t = obj.GetType(); string str; if (alreadyDone == null || rm == null) { alreadyDone = new System.Collections.ArrayList(); rm = new ResourceManager(resourceName, t.Assembly); } str = parent == null ? t.FullName : baseName; //Currently, these are the only localized values TranslateProperty(str, rm, obj, culture, "Text", typeof(System.String)); TranslateProperty(str, rm, obj, culture, "Width", typeof(System.Int32)); TranslateProperty(str, rm, obj, culture, "Height", typeof(System.Int32)); TranslateProperty(str, rm, obj, culture, "Top", typeof(System.Int32)); TranslateProperty(str, rm, obj, culture, "Left", typeof(System.Int32)); if (obj.GetType().GetProperty("ToolTipText") != null) TranslateProperty(str, rm, obj, culture, "ToolTipText", typeof(System.String)); FieldInfo [] fi = t.GetFields(BindingFlags.GetField | BindingFlags.Instance | BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public); foreach (FieldInfo f in fi) { System.ComponentModel.Component c = f.GetValue(obj) as System.ComponentModel.Component; if (c != null && !alreadyDone.Contains(c)) { alreadyDone.Add(obj); Translate(f.GetValue(obj), str + "." + f.Name, culture, resourceName , parent == null ? obj: parent, alreadyDone, rm); } } } private static void TranslateProperty(string resName, ResourceManager rm, object obj, CultureInfo culture, string propname, System.Type returnType) { try { PropertyInfo p = obj.GetType().GetProperty(propname, returnType); if (p != null && p.CanWrite) { object resObj = rm.GetObject(resName + '.' + p.Name, culture); if (resObj != null) p.SetValue(obj, resObj, null); //When debuggin, this drops the current values into the console for grabbing #if DEBUG else { if (p.PropertyType == typeof(string)) { string s = Convert.ToString(p.GetValue(obj, null)); Console.WriteLine(""); Console.WriteLine("\t" + s + ""); Console.WriteLine(""); } } #endif } } #if DEBUG catch (Exception ex) { Console.WriteLine("Failed on " + ex.Message); } #else catch { } #endif } #region IDisposable Members public void Dispose() { if (_LocalizedObjects.ContainsKey(this)) _LocalizedObjects.Remove(this); } #endregion } }