pascalabcnet/Localization/StringResources.cs

619 lines
24 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Resources;
using System.Reflection;
using System.ComponentModel;
namespace PascalABCCompiler
{
public class StringResourcesObject
{
public delegate string[] GetStringsDelegate(object obj);
public delegate void SetStringsDelegate(object obj, string[] strings);
public delegate object[] GetChildrenDelegate(object obj);
internal GetStringsDelegate GetStrings;
internal SetStringsDelegate SetStrings;
internal GetChildrenDelegate GetChildren;
internal Type ObjectType;
public StringResourcesObject(Type ObjectType, GetStringsDelegate GetStrings, SetStringsDelegate SetStrings, GetChildrenDelegate GetChildren)
{
this.ObjectType = ObjectType;
this.GetStrings = GetStrings;
this.SetStrings = SetStrings;
this.GetChildren = GetChildren;
}
}
public class SourceFileInfo
{
public string FileName;
public int Line;
public int Column;
public SourceFileInfo(string FileName, int Line, int Column)
{
this.FileName = FileName;
this.Line = Line;
this.Column = Column;
}
}
public class BreakpointInfo
{
public string FileName;
public int Line;
public bool IsConditional;
public string Expression;
public int ConcreteCondition;
public BreakpointInfo(string fileName, int line, bool isConditional, string expression, int concreteCondition)
{
this.FileName = fileName;
this.Line = line;
this.IsConditional = isConditional;
this.Expression = expression;
this.ConcreteCondition = concreteCondition;
}
}
public class BookmarkInfo
{
public string FileName;
public int Line;
public BookmarkInfo(string FileName, int Line)
{
this.FileName = FileName;
this.Line = Line;
}
}
public class AdvancedOptions
{
public List<string> watch_list = new List<string>();
public List<SourceFileInfo> open_files = new List<SourceFileInfo>();
public List<BreakpointInfo> breakpoints = new List<BreakpointInfo>();
public List<BookmarkInfo> bookmarks = new List<BookmarkInfo>();
}
public class StringResources
{
private static Hashtable ObjectsHashtable = new Hashtable();
private static Dictionary<Type, StringResourcesObject> StringResourcesObjects = new Dictionary<Type, StringResourcesObject>();
private static Dictionary<Type, List<PropertyInfo>> StringPropertis = new Dictionary<Type, List<PropertyInfo>>();
private static Dictionary<Type, List<FieldInfo>> StringFields = new Dictionary<Type, List<FieldInfo>>();
private static Dictionary<Type, List<PropertyInfo>> ChildrenCollections = new Dictionary<Type, List<PropertyInfo>>();
public static void AddStringResourcesObject(StringResourcesObject obj)
{
StringResourcesObjects[obj.ObjectType] = obj;
}
public static void UpdateObjectsText()
{
foreach (object obj in ObjectsHashtable.Keys)
{
string[] objstrings = (string[])ObjectsHashtable[obj];
string[] resstrings = new string[objstrings.Length];
for (int i = 0; i < objstrings.Length; i++)
resstrings[i] = Get(objstrings[i]);
SetObjectStrings(obj, resstrings);
}
}
public static void ReadStringsFromStreamAsXml(string FileName, StreamReader sr, Hashtable Strings, AdvancedOptions adv_opt)
{
XmlReaderSettings xrs = new XmlReaderSettings();
//xrs.IgnoreWhitespace = true;
xrs.CloseInput = true;
XmlReader reader = XmlTextReader.Create(new StreamReader(FileName,System.Text.Encoding.UTF8),xrs);
try
{
reader.Read();
}
catch
{
System.Text.Encoding enc = sr.CurrentEncoding;
reader.Close();
sr.Close();
ReadStringsFromStream(new StreamReader(FileName,enc),Strings);
return;
}
//reader.ReadStartElement("options");
reader.ReadStartElement("general_options");
string prefix = "";
while (reader.ReadToNextSibling("option"))
{
string option_name = reader.GetAttribute("name");
string option_value = reader.ReadString();
if (option_name == "%PREFIX%")
prefix = option_value;
else
{
Strings[prefix + option_name] = option_value;
}
}
reader.ReadEndElement();
/*reader.ReadEndElement();
if (!reader.EOF)
{
reader.ReadStartElement("advanced_options");
if (!reader.IsEmptyElement)
{
reader.ReadStartElement("open_files");
while (reader.ReadToNextSibling("open_file"))
{
adv_opt.open_files.Add(new SourceFileInfo(reader.GetAttribute("file_name"),
Convert.ToInt32(reader.GetAttribute("line")),Convert.ToInt32(reader.GetAttribute("column"))));
}
reader.ReadEndElement();
}
else
reader.ReadStartElement("open_files");
reader.ReadStartElement("watch_list");
if (!reader.IsEmptyElement)
{
while (reader.ReadToNextSibling("watch_expr"))
{
adv_opt.watch_list.Add(reader.GetAttribute("expr"));
}
reader.ReadEndElement();
}
reader.ReadStartElement("breakpoints_list");
if (!reader.IsEmptyElement)
{
while (reader.ReadToNextSibling("breakpoint"))
{
adv_opt.breakpoints.Add(new BreakpointInfo(reader.GetAttribute("file_name"),
Convert.ToInt32(reader.GetAttribute("line")),Convert.ToBoolean(reader.GetAttribute("is_conditional")),
reader.GetAttribute("expression"),Convert.ToInt32(reader.GetAttribute("concrete_condition"))));
}
reader.ReadEndElement();
}
if (!reader.IsEmptyElement)
{
reader.ReadStartElement("bookmarks_list");
while (reader.ReadToNextSibling("bookmark"))
{
adv_opt.bookmarks.Add(new BookmarkInfo(reader.GetAttribute("file_name"),
Convert.ToInt32(reader.GetAttribute("line"))));
}
reader.ReadEndElement();
}
reader.ReadEndElement();
}
reader.ReadEndElement();*/
reader.Close();
sr.Close();
}
public static void ReadStringsFromStream(StreamReader sr, Hashtable Strings)
{
string line, value, ident;
string prefix = "";
int ind;
while (!sr.EndOfStream)
{
line = sr.ReadLine();
if (line != "" && line.IndexOf("//") != 0 && (ind = line.IndexOf("=")) > 0)
{
ident = line.Substring(0, ind);
value = line.Substring(ind + 1, line.Length - ind - 1);
if (ident == "%PREFIX%")
prefix = value;
else
{
if ((ind = value.IndexOf("LINES")) > 0)
try
{
int n = Convert.ToInt32(value.Substring(0, ind)) - 1;
value = sr.ReadLine();
for (int i = 0; i < n; i++)
value += Environment.NewLine + sr.ReadLine();
}
catch (Exception)
{
}
Strings[prefix + ident] = value;
}
}
}
sr.Close();
}
public static void WriteStringsToStreamAsXml(StreamWriter sw, Hashtable Strings, AdvancedOptions adv_opt)
{
XmlWriterSettings xwr = new XmlWriterSettings();
xwr.Indent = true;
xwr.OmitXmlDeclaration = false;
xwr.Encoding = sw.Encoding;
xwr.CloseOutput = true;
XmlWriter writer = XmlWriter.Create(sw.BaseStream,xwr);
//writer.WriteStartElement("options");
writer.WriteStartElement("general_options");
foreach (string key in Strings.Keys)
{
writer.WriteStartElement("option");
writer.WriteAttributeString("name",key);
writer.WriteString(Convert.ToString(Strings[key]));
writer.WriteEndElement();
}
writer.WriteEndElement();
/*writer.WriteStartElement("advanced_options");
writer.WriteStartElement("open_files");
foreach (SourceFileInfo fi in adv_opt.open_files)
{
writer.WriteStartElement("open_file");
writer.WriteAttributeString("name",fi.FileName);
writer.WriteAttributeString("line",Convert.ToString(fi.Line.ToString()));
writer.WriteAttributeString("column",Convert.ToString(fi.Column.ToString()));
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteStartElement("watch_list");
foreach (string s in adv_opt.watch_list)
{
writer.WriteStartElement("watch_expr");
writer.WriteAttributeString("expr",s);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteStartElement("breakpoints_list");
foreach (BreakpointInfo br in adv_opt.breakpoints)
{
writer.WriteStartElement("breakpoint");
writer.WriteAttributeString("file_name",br.FileName);
writer.WriteAttributeString("line",br.Line.ToString());
writer.WriteAttributeString("is_conditional",br.IsConditional.ToString());
writer.WriteAttributeString("expression",br.Expression);
writer.WriteAttributeString("concrete_condition",br.ConcreteCondition.ToString());
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteStartElement("bookmarks_list");
foreach (BookmarkInfo br in adv_opt.bookmarks)
{
writer.WriteStartElement("bookmark");
writer.WriteAttributeString("file_name",br.FileName);
writer.WriteAttributeString("line",br.Line.ToString());
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();*/
writer.Close();
}
public static void WriteStringsToStream(StreamWriter sw, Hashtable Strings)
{
foreach (string key in Strings.Keys)
sw.WriteLine(string.Format("{0}={1}",key,Strings[key]));
sw.Close();
}
private static string[] GetObjectStrings(object obj)
{
List<PropertyInfo> SetStringProperties = GetStringProperties(obj.GetType());
string[] res = new string[SetStringProperties.Count];
for (int i = 0; i < SetStringProperties.Count; i++)
res[i] = (string)SetStringProperties[i].GetValue(obj, noIndex);
return res;
}
private static string[] GetWPFObjectStrings(object obj)
{
List<FieldInfo> SetStringFields = GetStringFields(obj, obj.GetType());
string[] res = new string[SetStringFields.Count];
for (int i = 0; i < SetStringFields.Count; i++)
res[i] = (string)SetStringFields[i].GetValue(obj);
return res;
}
private static object[] noIndex = new object[0];
private static List<PropertyInfo> GetStringProperties(Type type)
{
if (StringPropertis.ContainsKey(type))
return StringPropertis[type];
PropertyInfo[] Propertis = type.GetProperties();
List<PropertyInfo> SetStringProperty = new List<PropertyInfo>();
foreach (PropertyInfo pi in Propertis)
if (pi.PropertyType == typeof(string) && pi.CanRead && pi.CanWrite && pi.GetIndexParameters().Length == 0)
SetStringProperty.Add(pi);
StringPropertis.Add(type, SetStringProperty);
return SetStringProperty;
}
private static List<FieldInfo> GetStringFields(object obj, Type type)
{
if (StringFields.ContainsKey(type))
return StringFields[type];
FieldInfo[] Fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
List<FieldInfo> SetStringField = new List<FieldInfo>();
foreach (FieldInfo fi in Fields)
//if (fi.GetValue(obj) != null && fi.GetValue(obj).GetType() == typeof(string) && !fi.IsInitOnly)
if (fi.Name == "Header")
SetStringField.Add(fi);
StringFields.Add(type, SetStringField);
return SetStringField;
}
private static void SetObjectStrings(object obj, string[] strings)
{
List<PropertyInfo> SetStringProperties = GetStringProperties(obj.GetType());
for (int i = 0; i < SetStringProperties.Count; i++)
if(strings[i]!=null)
SetStringProperties[i].SetValue(obj, strings[i], noIndex);
}
private static void SetWPFObjectStrings(object obj, string[] strings)
{
List<FieldInfo> SetStringFields = GetStringFields(obj, obj.GetType());
for (int i = 0; i < SetStringFields.Count; i++)
if (strings[i] != null)
SetStringFields[i].SetValue(obj, strings[i]);
}
public static void SetTextForObject(object obj, string prefix)
{
string[] objstrings = GetObjectStrings(obj);
if (objstrings == null) return;
string[] resstrings = new string[objstrings.Length];
string text;
bool nonekeys = true;
for (int i = 0; i < objstrings.Length; i++)
{
if ((text = objstrings[i]) != null)
{
if (prefix != null && text.Length > 0 && text[0] != '!' && text != "")
{
string gets, s = prefix + text;
if ((gets = Get(s)) != s)
{
objstrings[i] = s;
resstrings[i] = gets;
}
else
{
resstrings[i] = null;
objstrings[i] = null;
}
}
else
{
resstrings[i] = Get(text);
if (resstrings[i] == objstrings[i])
resstrings[i] = objstrings[i] = null;
}
}
if (nonekeys && resstrings[i] != null)
nonekeys = false;
}
if (!nonekeys)
{
ObjectsHashtable[obj] = objstrings;
SetObjectStrings(obj, resstrings);
}
}
public static void SetTextForWPFObject(object obj, string prefix)
{
string[] objstrings = GetWPFObjectStrings(obj);
if (objstrings == null) return;
string[] resstrings = new string[objstrings.Length];
string text;
bool nonekeys = true;
for (int i = 0; i < objstrings.Length; i++)
{
if ((text = objstrings[i]) != null)
{
if (prefix != null && text.Length > 0 && text[0] != '!' && text != "")
{
string gets, s = prefix + text;
if ((gets = Get(s)) != s)
{
objstrings[i] = s;
resstrings[i] = gets;
}
else
{
resstrings[i] = null;
objstrings[i] = null;
}
}
else
{
resstrings[i] = Get(text);
if (resstrings[i] == objstrings[i])
resstrings[i] = objstrings[i] = null;
}
}
if (nonekeys && resstrings[i] != null)
nonekeys = false;
}
if (!nonekeys)
{
ObjectsHashtable[obj] = objstrings;
SetWPFObjectStrings(obj, resstrings);
}
}
public static void SetTextForAllWPFObjects(object obj, string prefix)
{
SetTextForWPFObject(obj, prefix);
List<PropertyInfo> childComponentLists = GetWPFChildren(obj.GetType());
foreach (PropertyInfo pi in childComponentLists)
{
try
{
object val = pi.GetValue(obj, noIndex);
if (val is IEnumerator)
{
IEnumerator col = pi.GetValue(obj, noIndex) as IEnumerator;
col.Reset();
while (col.MoveNext())
SetTextForAllWPFObjects(col.Current, prefix);
}
}
catch (Exception)
{
}
}
}
public static void SetTextForAllObjects(object obj, string prefix)
{
SetTextForObject(obj, prefix);
List<PropertyInfo> childComponentLists = GetChildren(obj.GetType());
foreach (PropertyInfo pi in childComponentLists)
{
try
{
object val = pi.GetValue(obj, noIndex);
if (val is ICollection)
{
ICollection col = pi.GetValue(obj, noIndex) as ICollection;
if (col != null)
foreach (object ob in col)
//не расматриваем формы
if (ob.GetType().FullName != "System.Windows.Forms.Form")
SetTextForAllObjects(ob, prefix);
}
if (val is IContainer)
{
IContainer cont = pi.GetValue(obj, noIndex) as IContainer;
if (cont != null)
foreach (object ob in cont.Components)
//не расматриваем формы
if (ob.GetType().FullName != "System.Windows.Forms.Form")
SetTextForAllObjects(ob, prefix);
}
}
catch (Exception)
{
}
}
}
private static List<PropertyInfo> GetChildren(Type type)
{
if (ChildrenCollections.ContainsKey(type))
return ChildrenCollections[type];
PropertyInfo[] propertis = type.GetProperties();
List<PropertyInfo> childComponentLists = new List<PropertyInfo>();
foreach (PropertyInfo pi in propertis)
if (pi.PropertyType.GetInterface("ICollection") != null || pi.PropertyType.GetInterface("IContainer") != null)
childComponentLists.Add(pi);
ChildrenCollections.Add(type, childComponentLists);
return childComponentLists;
}
private static List<PropertyInfo> GetWPFChildren(Type type)
{
if (ChildrenCollections.ContainsKey(type))
return ChildrenCollections[type];
PropertyInfo property = type.GetProperty("LogicalChildren", BindingFlags.Instance | BindingFlags.NonPublic);
List<PropertyInfo> childComponentLists = new List<PropertyInfo>();
if (property != null)
childComponentLists.Add(property);
ChildrenCollections.Add(type, childComponentLists);
return childComponentLists;
}
public static void SetTextForAllObjects(object obj)
{
SetTextForAllObjects(obj, null);
}
private static string resDirectoyName=null;
public static string ResDirectoryName
{
get
{
return resDirectoyName;
}
set
{
resDirectoyName = value;
Load();
}
}
private static Hashtable Strings = new Hashtable();
private static void LoadFile(string FileName)
{
if (!File.Exists(FileName))
return;
// throw new
LoadFile(new StreamReader(FileName, System.Text.Encoding.GetEncoding(1251)));
}
private static void LoadFile(StreamReader sr)
{
ReadStringsFromStream(sr, Strings);
}
private static void Load()
{
//try
{
//Strings.Clear();
DirectoryInfo di = new DirectoryInfo(ResDirectoryName);
if (!di.Exists)
return;
FileInfo[] files = di.GetFiles("*.*");
foreach (FileInfo fi in files)
LoadFile(fi.FullName);
}
//catch (Exception e)
{
}
}
public static string Get(string keyName)
{
if (keyName == null || keyName == "") return keyName;
string res = Strings[keyName] as string;
if (res != null)
return res;
else
return keyName;
}
public static void Set(string keyName,string value)
{
Strings.Add(keyName,value);
}
static StringResources()
{
//TODO: сделать так чтобы язык поумолчанию был в ресурсе
/*StringResourcesLanguage.ConfigFileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName) + "\\lng\\languages.dat";
if (StringResourcesLanguage.AccessibleLanguages.Count > 0)
StringResourcesLanguage.CurrentLanguageName = StringResourcesLanguage.AccessibleLanguages[0];
*/
if (Strings.Count == 0)
{
ResourceManager ResourceManager = new ResourceManager("PascalABCCompiler.DefaultLang", System.Reflection.Assembly.GetExecutingAssembly());
MemoryStream ms = new MemoryStream((byte[])ResourceManager.GetObject("DefaultLanguage", System.Threading.Thread.CurrentThread.CurrentCulture));
ms.Seek(0, SeekOrigin.Begin);
LoadFile(new StreamReader(ms,Encoding.GetEncoding(1251)));
}
}
}
}