Mercurial > repos > IBBoard
view Lang/Translation.cs @ 3:3dab3db95e4a
Fix SimpleSet so that the enumerator works over the values in the set
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Tue, 23 Dec 2008 14:21:03 +0000 |
parents | 961030992bd2 |
children | f9ec2be467fe |
line wrap: on
line source
using System; using System.IO; using System.Xml; using System.Xml.Schema; using System.Collections.Generic; using System.Windows.Forms; using System.Reflection; using System.ComponentModel; using IBBoard.IO; using IBBoard.Logging; using IBBoard.Xml; namespace IBBoard.Lang { /// <summary> /// Summary description for Translation. /// </summary> public class Translation { private static string lang = ""; private static DirectoryInfo translationDir = null; private static Dictionary<string, string> translationsLocal = null; private static Dictionary<string, string> translationsDefault = null; public static void InitialiseTranslations(string appPath, string language) { string translationPath = appPath+Constants.DirectoryString+"translations"; if (Directory.Exists(translationPath)) { translationDir = new DirectoryInfo(translationPath); FileInfo file = new FileInfo(translationDir.FullName.TrimEnd(Constants.DirectoryChar)+Constants.DirectoryString+"en.translation"); if (!File.Exists(file.FullName)) { throw new FileNotFoundException("en.translation could not be found in "+translationDir.FullName); } translationsDefault = new Dictionary<string,string>(); XmlDocument doc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.XmlResolver = new IBBXmlResolver(appPath); settings.ValidationType = ValidationType.DTD; settings.ProhibitDtd = false; settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); XmlReader valReader = XmlReader.Create(file.FullName, settings); doc.Load(valReader); valReader.Close(); try { XmlNodeList translations = doc.GetElementsByTagName("translation"); if (translations.Count==0) { throw new InvalidFileException("No translations found in "+language+".translation"); } foreach (XmlNode node in translations) { translationsDefault.Add(node.Attributes["id"].Value, node.InnerText); } } catch(Exception ex) { throw new XmlParseException("Error while parsing "+file.FullName+": "+ex.Message); } translationsLocal = null; LoadTranslation(lang); } else { throw new ArgumentException("Translation path must exist ("+translationPath+")"); } } private static void ValidationEventMethod(object sender, ValidationEventArgs e) { //TODO: Fire a validation failure event LogNotifier.Error(typeof(Translation), "Validation Error", e.Exception); } public static void LoadTranslation(string translationLang) { checkInitialisation(); if (translationLang!="" && translationLang!="en") { FileInfo file = new FileInfo(translationDir.FullName.TrimEnd(Constants.DirectoryChar)+Constants.DirectoryString+translationLang+".translation"); if (!File.Exists(file.FullName)) { throw new FileNotFoundException(translationLang+".translation could not be found in "+translationDir.FullName); } XmlDocument doc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.XmlResolver = new IBBXmlResolver(translationDir.Parent.FullName); settings.ValidationType = ValidationType.DTD; settings.ProhibitDtd = false; settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); XmlReader valReader = XmlReader.Create(file.FullName, settings); doc.Load(valReader); valReader.Close(); Dictionary<string, string> tempTranslations = new Dictionary<string, string>(); try { XmlNodeList translations = doc.GetElementsByTagName("translation"); if (translations.Count==0) { throw new InvalidFileException("No translations found in "+translationLang+".translation"); } foreach (XmlNode node in translations) { tempTranslations.Add(node.Attributes["id"].Value, node.InnerText); } } catch(XmlParseException) { throw; } catch(Exception ex) { throw new XmlParseException("Error while parsing "+file.FullName+": "+ex.Message); } translationsLocal = tempTranslations; lang = translationLang; } else { lang = translationLang; } } public static string GetTranslation(string translationID, params object[] replacements) { return GetTranslation(translationID, false, replacements); } public static string GetTranslation(string translationID, bool returnNullOnFail, params object[] replacements) { return GetTranslation(translationID, returnNullOnFail ? null : "", replacements); } public static string GetTranslation(string translationID, string defaultTranslation, params object[] replacements) { checkInitialisation(); string trans = null; if (translationsLocal!=null) { translationsLocal.TryGetValue(translationID, out trans); } if (trans == null) { translationsDefault.TryGetValue(translationID, out trans); } if (trans == null) { //no translation so fall back to the provided default if not an empty string if (defaultTranslation!="") { trans = defaultTranslation; } else { trans = "++ Missing Translation "+translationID+" ++"; } } if (trans != null) { if (replacements!=null && replacements.Length > 0) { trans = String.Format(trans, replacements); } //else no need to do anything } return trans; } private static void checkInitialisation() { if (translationDir==null) { throw new InvalidOperationException("Translation class has not been initialised"); } } public static void Translate(ITranslatable item, params object[] replacements) { if (item.Text=="" || item.Text=="-") { //if it doesn't need translating - either no text for the Dev or it's a hyphen for a divider - then bail early return; } item.Text = GetTranslation(item.Name, replacements); } public static void TranslateControl(Control ctrl, params object[] replacements) { TranslateControl(ctrl, true, replacements); } public static void TranslateControl(Control ctrl, bool cascadeTranslate, params object[] replacements) { if (ctrl is ITranslatable) { Translate((ITranslatable)ctrl, replacements); } if (cascadeTranslate) { cascadeControlTranslation(ctrl, replacements); } } private static void cascadeControlTranslation(Control ctrl, params object[] replacements) { if (ctrl is ToolBar) { foreach(ToolBarButton bttn in ((ToolBar)ctrl).Buttons) { TranslateComponent(bttn, true, replacements); } } else { foreach (Control subctr in ctrl.Controls) { TranslateControl(subctr, true, replacements); } } } public static void TranslateComponent(Component comp, params object[] replacements) { TranslateComponent(comp, true, replacements); } public static void TranslateComponent(Component comp, bool cascadeTranslate, params object[] replacements) { if (comp is ITranslatable) { Translate((ITranslatable)comp, replacements); } else if (comp is FileDialog) { //HACK: We can't override SWF dialogs in .Net 1.1, so put in a special condition check for them FileDialog dialog = (FileDialog)comp; if (dialog.Title.StartsWith("Translatable:")) { dialog.Title = GetTranslation(dialog.Title.Substring(13), replacements); } } if (cascadeTranslate) { cascadeComponentTranslations(comp, cascadeTranslate, replacements); } } private static void cascadeComponentTranslations(Component comp, params object[] replacements) { if (comp is Menu) { foreach(MenuItem mi in ((Menu)comp).MenuItems) { TranslateComponent(mi, true, replacements); } } } } }