Click here to Skip to main content
15,896,118 members
Articles / Desktop Programming / Windows Forms

LocaleManager - A Practical Tool to Manage Resources Files of Different Locales for Java/Flex and .NET

Rate me:
Please Sign up or sign in to vote.
4.82/5 (4 votes)
2 Aug 2009CPOL6 min read 39.5K   624   24  
Implementation of a software tool in C# to help to manage *.resx files for .NET or *.properties files for Java or AS3 of different locales.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace LocaleManager
{
    public partial class WorkSheetForm : Form
    {
        public enum Columns
        {
            No = 0, File, Name, Base
        };

        public enum XmlParsingSteps
        {
            ParsingName = 0, ParsingValueTag, ParsingValue
        };

        private int _numOfCols;

        private bool _isDirty = false;


        public WorkSheetForm()
        {
            InitializeComponent();
        }

        private void WorkSheetForm_Load(object sender, EventArgs e)
        {
            FileInfo[] files = Global.BaseDir.GetFiles("*"+ Global.Extension);
            if (null == files || files.Length == 0)
            {
                MessageBox.Show("There are no files in the base folder.");
                this.Close();
                return;
            }

            m_files.Items.Add("SelectAll");
            foreach (FileInfo file in files)
                m_files.Items.Add(file.Name);

            m_grid.ColumnCount = Global.Locales.Length + (int)Columns.Base + 1;
            _numOfCols = m_grid.ColumnCount;

            m_grid.Columns[(int)Columns.No].Name = "no.";
            m_grid.Columns[(int)Columns.No].ValueType = typeof(int);

            m_grid.Columns[(int)Columns.File].Name = "file";
            m_grid.Columns[(int)Columns.Name].Name = "name";
            m_grid.Columns[(int)Columns.Base].Name = Global.BaseDir.Name;

            int i = (int)Columns.Base + 1;
            foreach (string locale in Global.Locales)
                m_grid.Columns[i++].Name = locale;

            if (m_files.Items.Count > 0)
                m_files.SelectedIndex = 0;
            else
                MessageBox.Show("There are no .properties files in the base locale folder.");

            if (Global.Extension == Global.NetExtension)
                m_save.Enabled = false; //not implemented yet
        }

        private void m_files_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_grid.Rows.Clear();

            string file = (string)m_files.SelectedItem;
            if (file.EndsWith(Global.Extension))
                loadFile(0, file);
            else
            {//all files
                int i = 0;
                foreach (object item in m_files.Items)
                {
                    file = (string)item;

                    if (!file.EndsWith(Global.Extension))
                        continue;

                    i = loadFile(i, (string)item);
                }
            }
        }

        private int loadFile(int rowIndex, string file)
        {
            int rowsIndexNew=rowIndex;

            if (Global.Extension == Global.JavaExtension)
            {
                //load base
                rowIndex = LoadPropertiesFile(file, rowIndex, -1);

                //load file for all selected target locales
                for (int i = 0; i < Global.Locales.Length; i++)
                {
                    LoadPropertiesFile(file, rowIndex, i);
                }
            }
            else if (Global.Extension == Global.NetExtension)
            {
                //load base
                rowIndex = LoadResourceFile(file, rowIndex, -1);

                //load file for all selected target locales
                for (int i = 0; i < Global.Locales.Length; i++)
                {
                    LoadResourceFile(file, rowIndex, i);
                }
            }
            else
                throw new Exception("Not supported: " + Global.Extension);

            return rowsIndexNew;
        }

        private int LoadResourceFile(string file, int rowIndex, int localeIndex)
        {
            string path = GetPath(file, localeIndex);
            bool isBase = (localeIndex < 0) ? true : false;

            if (!File.Exists(path))
            {
                Global.Log(Global.ErrLog, "File doesn't exist:  " + path);
                return rowIndex;
            }

            using (XmlTextReader rd = new XmlTextReader(path))
            {
                XmlParsingSteps step = XmlParsingSteps.ParsingName;
                string name = "";
                string value = "";

                while (rd.Read())
                {
                    switch (rd.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (step == XmlParsingSteps.ParsingName && rd.Name == "data")
                            {

                                while (rd.MoveToNextAttribute())
                                {
                                    if (rd.Name == "name")
                                    {
                                        name = rd.Value;
                                        step = XmlParsingSteps.ParsingValueTag;
                                        break;
                                    }
                                }
                            }
                            else if (step == XmlParsingSteps.ParsingValueTag && rd.Name == "value")
                            {
                                step = XmlParsingSteps.ParsingValue;
                            }
                            break;
                        case XmlNodeType.Text:
                            if (step == XmlParsingSteps.ParsingValue)
                            {
                                value = rd.Value;

                                if (isBase)
                                {
                                    AddRowToGrid(file, rowIndex, name, value);
                                    rowIndex++;
                                }
                                else
                                {
                                    rowIndex = findRowNo(file, name.Trim());
                                    if (rowIndex < 0)
                                    {//property not found in base
                                        Global.Log(Global.MismatchLog, name + "-" + value);
                                    }
                                    else
                                        AddToRow(rowIndex, localeIndex, value);
                                }
                                //reset name and value strings
                                step = XmlParsingSteps.ParsingName;
                                name = "";
                                value = "";
                            }
                            break;
                        default: 
                            break;
                    }
                }
            }
            return rowIndex;
        }

        private static string GetPath(string file, int localeIndex)
        {
            if (localeIndex < 0)
                return Global.BaseDir.FullName + "\\" + file;
            else
                return Global.RootDir.FullName + "\\" + Global.Locales[localeIndex] + "\\" + file;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="file">file to load</param>
        /// <param name="rowIndex">starting row index, only used if is base locale</param>
        /// <param name="localeIndex">-1: base locale</param>
        /// <returns>new row index when isBase, otherwise is not used</returns>
        private int LoadPropertiesFile(string file, int rowIndex, int localeIndex)
        {
            string path = GetPath(file, localeIndex);
            bool isBase = (localeIndex < 0)? true:false;

            if (!File.Exists(path))
            {
                Global.Log(Global.ErrLog, "File doesn't exist:  " + path);
                return rowIndex;
            }

            using (StreamReader rs = new StreamReader(path))
            {
                string line;
                string[] tokens;

                while ((line = rs.ReadLine()) != null)
                {
                    string name = "";
                    string value = "";

                    line.Trim();
                    if (line.Length == 0 || line.StartsWith("#"))
                        continue;

                    tokens = line.Split('=');

                    if (null != tokens)
                    {
                        if (tokens.Length > 0)
                            name = tokens[0];

                        if (tokens.Length > 1)
                            value = tokens[1];

                        if (isBase)
                        {
                            AddRowToGrid(file, rowIndex, name, value);
                            rowIndex++;
                        }
                        else
                        {
                            rowIndex = findRowNo(file, name.Trim());
                            if (rowIndex<0)
                            {//property not found in base
                                Global.Log(Global.MismatchLog, line);
                            }
                            else
                                AddToRow(rowIndex, localeIndex, value);
                        }
                    }
                }
            }
            return rowIndex;
        }

        private void AddRowToGrid(string file, int i, string name, string value)
        {
            string[] row;
            row = new string[_numOfCols];
            row[(int)Columns.No] = i.ToString();
            row[(int)Columns.File] = file;
            row[(int)Columns.Name] = name.Trim();
            row[(int)Columns.Base] = value.Trim();

            m_grid.Rows.Add(row);
        }

        private void AddToRow(int i, int localeIndex, string value)
        {
            if (null!= value && i>=0)
                m_grid.Rows[i].Cells[getColumnNo(localeIndex)].Value = value;
        }
        
        private int getColumnNo(int localeIndex)
        {
            return (int)Columns.Base + localeIndex + 1;
        }

        //value is for saving to the log.  It won't be displayed
        private int findRowNo(string file, string name)
        {
            foreach (DataGridViewRow row in m_grid.Rows)
            {
                string baseFile=null;
                string baseName=null;
                if (null!=row.Cells[(int)Columns.File].Value)
                    baseFile = row.Cells[(int)Columns.File].Value.ToString();

                if (null != row.Cells[(int)Columns.Name].Value)
                    baseName = row.Cells[(int)Columns.Name].Value.ToString();

                if (file == baseFile && name == baseName)
                    return row.Index;
            }
            return -1;
        }

        private void saveChangesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show(
                "Properties will be saved as the order displayed in the table.  Your exising locale files will be overwritten.\ncontinue?", 
                "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

            if (dr != DialogResult.Yes)
                return;

            string file = (string)m_files.SelectedItem;

            if (file.EndsWith(Global.Extension))
            {//save for a single property file
                saveLocaleFiles(file);
            }
            else
            {//save all files
                foreach (object item in m_files.Items)
                {
                    file = (string)item;
                    if (!file.EndsWith(Global.Extension))
                        continue;

                    saveLocaleFiles(file);
                }
            }
        }

        private void saveLocaleFiles(string file)
        {
            for (int i = 0; i < Global.Locales.Length; i++)
                saveFile(file, i);

            _isDirty = false;
        }

        private void saveFile(string file, int localeIndex)
        {
            string path = Global.RootDir.FullName + "\\" + Global.Locales[localeIndex] + "\\" + file;
            using (StreamWriter wr = new StreamWriter(path))
            {
                foreach (DataGridViewRow row in m_grid.Rows)
                {
                    string baseFile = null;
                    string baseName = null;
                    string line = null;

                    if (null != row.Cells[(int)Columns.File].Value)
                        baseFile = row.Cells[(int)Columns.File].Value.ToString();

                    if (null != row.Cells[(int)Columns.Name].Value)
                        baseName = row.Cells[(int)Columns.Name].Value.ToString();

                    if (file == baseFile)
                    {
                        line = baseName + "=";
                        if (null != row.Cells[getColumnNo(localeIndex)].Value)
                            line += row.Cells[getColumnNo(localeIndex)].Value;
                        wr.WriteLine(line);
                    }
                }
                wr.Flush();
                wr.Close();
            }
        }

        private void WorkSheetForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!_isDirty)
                return;

            DialogResult dr = MessageBox.Show(
                "Are you sure you want to close without saving changes?", "Warning",
                MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

            if (dr != DialogResult.Yes)
            {
                e.Cancel = true;
                return;
            }
        }

        private void m_grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            _isDirty = true;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States

Comments and Discussions