Ejemplo n.º 1
0
        /// <summary>
        /// A window that lists all codepages that are recognized by the user's
        /// OS.
        /// </summary>
        /// <param name="f"><c><see cref="CodePageDialog"/></c></param>
        /// <remarks>This dialog shall be allowed to remain open even if its
        /// caller <c>CodePageDialog</c> is closed.</remarks>
        internal CodePageList(CodePageDialog f)
        {
            // WARNING: CodePageList will hold a pointer to CodePageDialog even
            // if CodePageDialog is closed. The pointer will be released when
            // CodePageList is closed also.
            _f = f;

            InitializeComponent();
            Initialize(YataDialog.METRIC_FUL);

            var sb = new StringBuilder();

            EncodingInfo[] encs = Encoding.GetEncodings();
            for (int i = 0; i != encs.Length; ++i)
            {
                if (i != 0)
                {
                    sb.AppendLine();
                }

                sb.AppendLine(encs[i].Name);
                sb.AppendLine(encs[i].DisplayName);
                sb.AppendLine(encs[i].CodePage.ToString(CultureInfo.InvariantCulture));
            }
            tb_Codepages.Text = sb.ToString();

            tb_Codepages.Select();
            Show();             // no owner.
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Tries to load a 2da-file.
        /// </summary>
        /// <returns>
        /// <list type="bullet">
        /// <item><c><see cref="LOADRESULT_FALSE"/></c></item>
        /// <item><c><see cref="LOADRESULT_TRUE"/></c></item>
        /// <item><c><see cref="LOADRESULT_CHANGED"/></c></item>
        /// </list></returns>
        internal int LoadTable()
        {
/*			const string test = "The 2da-file contains double-quotes. Although that can be"
 + " valid in a 2da-file Yata's 2da Info-grope is not coded to cope."
 + " Format the 2da-file (in a texteditor) to not use double-quotes"
 + " if you want to access it for 2da Info.";
 +                      using (var ib = new Infobox(Infobox.Title_error,
 +                                                                              test,
 +                                                                              "A bunch of text. A bunch of text. A bunch of text. A bunch of text."
 + " A bunch of text. A bunch of text. A bunch of text. A bunch of text."
 + " A bunch of text. A bunch of text.",
 +                                                                              InfoboxType.Error))
 +                      {
 +                              ib.ShowDialog(_f);
 +                      } */
            // �
//			byte[] asciiBytes = Encoding.ASCII.GetBytes("�");
//			logfile.Log("� = " + asciiBytes);
//			foreach (var b in asciiBytes)
//				logfile.Log(((int)b).ToString());
//
//			byte[] utf8Bytes = Encoding.UTF8.GetBytes("�");
//			logfile.Log("� = " + utf8Bytes);
//			foreach (var b in utf8Bytes)
//				logfile.Log(((int)b).ToString());

//			logfile.Log();
//			logfile.Log("default encoding= " + Encoding.GetEncoding(0));
//			EncodingInfo[] encs = Encoding.GetEncodings();
//			foreach (var enc in encs)
//			{
//				logfile.Log();
//				logfile.Log(". enc= " + enc.Name);
//				logfile.Log(". DisplayName= " + enc.DisplayName);
//				logfile.Log(". CodePage= " + enc.CodePage);
//			}

            Lastwrite = File.GetLastWriteTime(Fullpath);

            _rows.Clear();

            int loadresult = LOADRESULT_TRUE;

            string[] lines = File.ReadAllLines(Fullpath);             // default decoding is UTF-8


            // 0. test character decoding ->

            for (int i = 0; i != lines.Length; ++i)
            {
                if (lines[i].Contains("�"))
                {
                    if (CodePage == -1)
                    {
                        CodePage = Settings._codepage;                         // init.
                    }
                    Encoding enc;

                    if (CodePage == 0 || CheckCodepage(CodePage))
                    {
                        // CodePage is default or user-valid.
                        enc = Encoding.GetEncoding(CodePage);
                    }
                    else
                    {
                        enc = null;
                    }


                    using (var cpd = new CodePageDialog(_f, enc))
                    {
                        int result;
                        if (cpd.ShowDialog(_f) == DialogResult.OK &&
                            Int32.TryParse(cpd.GetCodePage(), out result) &&
                            result > -1 && result < 65536 &&
                            CheckCodepage(result))
                        {
                            lines = File.ReadAllLines(Fullpath, Encoding.GetEncoding(result));
                        }
                        else
                        {
                            return(LOADRESULT_FALSE);                            // silently fail.
                        }
                    }
                    break;
                }
            }


            string line, head, copy;

            // 1. test for fatal errors ->

            if (lines.Length > LINE_VERSION)
            {
                line = lines[LINE_VERSION].Trim();
            }
            else
            {
                line = String.Empty;
            }

            if (line != gs.TwodaVer && line != "2DA\tV2.0")             // tab is not fatal - autocorrect it later
            {
                head = "The 2da-file contains an incorrect version header on its 1st line.";
                copy = Fullpath + Environment.NewLine + Environment.NewLine
                       + line;

                using (var ib = new Infobox(Infobox.Title_error,
                                            head,
                                            copy,
                                            InfoboxType.Error,
                                            InfoboxButtons.Abort))
                {
                    ib.ShowDialog(_f);
                }
                return(LOADRESULT_FALSE);
            }


            if (lines.Length > LINE_COLABEL)
            {
                line = lines[LINE_COLABEL].Trim();
            }
            else
            {
                line = String.Empty;
            }

            if (line.Length == 0)
            {
                head = "The 2da-file does not have any fields. Yata wants a file to have at least one colhead label on its 3rd line.";

                using (var ib = new Infobox(Infobox.Title_error,
                                            head,
                                            Fullpath,
                                            InfoboxType.Error,
                                            InfoboxButtons.Abort))
                {
                    ib.ShowDialog(_f);
                }
                return(LOADRESULT_FALSE);
            }



            bool quelch = false;             // bypass warnings and try to load the file directly.


            // 2. test for Tabs ->

            if (Settings._strict && Settings._alignoutput != Settings.AoTabs)
            {
                for (int i = 0; i != lines.Length; ++i)
                {
                    if (i != LINE_DEFAULT && lines[i].Contains("\t"))
                    {
                        head = "Tab characters are detected in the 2da-file. They will be replaced with space characters (or deleted where redundant) if the file is saved.";

                        switch (ShowLoadWarning(head, Fullpath))
                        {
                        case DialogResult.Cancel:
                            return(LOADRESULT_FALSE);

                        case DialogResult.OK:
                            quelch = true;
                            goto case DialogResult.Retry;

                        case DialogResult.Retry:
                            loadresult = LOADRESULT_CHANGED;
                            break;
                        }
                        break;
                    }
                }
            }


            bool autordered       = false;
            bool whitespacewarned = false;

            string tr;

            int id = -1;

            int total = lines.Length;

            if (total < LINE_COLABEL + 1)
            {
                total = LINE_COLABEL + 1;                                       // scan at least 3 'lines' in the file
            }
            // 3. test for ignorable/recoverable errors ->

            for (int i = LINE_VERSION; i != total; ++i)
            {
                if (i < lines.Length)
                {
                    line = lines[i];
                }
                else
                {
                    line = String.Empty;
                }

                switch (i)
                {
                case LINE_VERSION:
                    if (!quelch && Settings._strict)
                    {
                        if (line != (tr = line.Trim()))
                        {
                            head = "The 1st line (version header) has extraneous whitespace. It will be trimmed if the file is saved.";
                            copy = Fullpath + Environment.NewLine + Environment.NewLine
                                   + line;

                            switch (ShowLoadWarning(head, copy))
                            {
                            case DialogResult.Cancel:
                                return(LOADRESULT_FALSE);

                            case DialogResult.OK:
                                quelch = true;
                                goto case DialogResult.Retry;

                            case DialogResult.Retry:
                                loadresult = LOADRESULT_CHANGED;
                                break;
                            }
                        }

                        if (!quelch && tr.Contains("\t"))
                        {
                            head = "The 1st line (version header) contains a tab-character. It will be corrected if the file is saved.";
                            copy = Fullpath + Environment.NewLine + Environment.NewLine
                                   + tr;

                            switch (ShowLoadWarning(head, copy))
                            {
                            case DialogResult.Cancel:
                                return(LOADRESULT_FALSE);

                            case DialogResult.OK:
                                quelch = true;
                                goto case DialogResult.Retry;

                            case DialogResult.Retry:
                                loadresult = LOADRESULT_CHANGED;
                                break;
                            }
                        }

//							if (!quelch && tr.Contains("  ")) // don't bother. This is a fatal error above.
//							{
//								head = "The header on the first line contains redundant spaces. It will be corrected if the file is saved.";
//								copy = Fullpath + Environment.NewLine + Environment.NewLine
//									 + tr;
//
//								switch (ShowLoadWarning(head, copy))
//								{
//									case DialogResult.Cancel:
//										return LOADRESULT_FALSE;
//
//									case DialogResult.OK:
//										quelch = true;
//										goto case DialogResult.Retry;
//
//									case DialogResult.Retry:
//										loadresult = LOADRESULT_CHANGED;
//										break;
//								}
//							}
                    }
                    break;

                case LINE_DEFAULT:
                    tr = line.Trim();

                    if (!quelch && Settings._strict && line != tr)
                    {
                        head = "The 2nd line (default value) has extraneous whitespace. It will be trimmed if the file is saved.";
                        copy = Fullpath + Environment.NewLine + Environment.NewLine
                               + line;

                        switch (ShowLoadWarning(head, copy))
                        {
                        case DialogResult.Cancel:
                            return(LOADRESULT_FALSE);

                        case DialogResult.OK:
                            quelch = true;
                            goto case DialogResult.Retry;

                        case DialogResult.Retry:
                            loadresult = LOADRESULT_CHANGED;
                            break;
                        }
                    }

                    if (tr.StartsWith("DEFAULT:", StringComparison.Ordinal))                             // do not 'strict' this feedback ->
                    {
                        _defaultval = tr.Substring(8).TrimStart();

                        if (_defaultval.Length == 0)
                        {
                            if (!quelch)
                            {
                                head = "The Default is blank. The 2nd line (default value) will be cleared if the file is saved.";
                                copy = Fullpath + Environment.NewLine + Environment.NewLine
                                       + tr;

                                switch (ShowLoadWarning(head, copy))
                                {
                                case DialogResult.Cancel:
                                    return(LOADRESULT_FALSE);

                                case DialogResult.OK:
                                    quelch = true;
                                    goto case DialogResult.Retry;

                                case DialogResult.Retry:
                                    if (Settings._strict)
                                    {
                                        loadresult = LOADRESULT_CHANGED;
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            InputDialog.SpellcheckDefaultval(ref _defaultval, true);

                            if (!quelch && Settings._strict && tr != gs.Default + _defaultval)
                            {
                                head = "The Default on the 2nd line has been changed.";
                                copy = Fullpath + Environment.NewLine + Environment.NewLine
                                       + gs.Default + _defaultval;

                                switch (ShowLoadWarning(head, copy))
                                {
                                case DialogResult.Cancel:
                                    return(LOADRESULT_FALSE);

                                case DialogResult.OK:
                                    quelch = true;
                                    goto case DialogResult.Retry;

                                case DialogResult.Retry:
                                    loadresult = LOADRESULT_CHANGED;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        _defaultval = String.Empty;

                        if (!quelch && Settings._strict && tr.Length != 0)
                        {
                            head = "The 2nd line (default value) in the 2da contains garbage. It will be cleared if the file is saved.";
                            copy = Fullpath + Environment.NewLine + Environment.NewLine
                                   + line;                                       //.Replace("\t", "\u2192")

                            switch (ShowLoadWarning(head, copy))
                            {
                            case DialogResult.Cancel:
                                return(LOADRESULT_FALSE);

                            case DialogResult.OK:
                                quelch = true;
                                goto case DialogResult.Retry;

                            case DialogResult.Retry:
                                loadresult = LOADRESULT_CHANGED;
                                break;
                            }
                        }
                    }
                    break;

                case LINE_COLABEL:
                    tr = line.TrimEnd();

                    // TODO: check for redundant whitespace at the start of the line also
                    // flag Changed if found ...

                    if (!quelch && Settings._strict && line != tr)
                    {
                        head = "The 3nd line (colhead labels) has extraneous whitespace. It will be trimmed if the file is saved.";
                        copy = Fullpath + Environment.NewLine + Environment.NewLine
                               + line;

                        switch (ShowLoadWarning(head, copy))
                        {
                        case DialogResult.Cancel:
                            return(LOADRESULT_FALSE);

                        case DialogResult.OK:
                            quelch = true;
                            goto case DialogResult.Retry;

                        case DialogResult.Retry:
                            loadresult = LOADRESULT_CHANGED;
                            break;
                        }
                    }

                    if (!quelch &&
                        Settings._strict &&                                                                                     // line.Length shall not be 0
                        line[0] != 32 &&                                                                                        // space
                        !(line[0] == 9 && Settings._alignoutput == Settings.AoTabs))                                            // tab
                    {
                        // NOTE: This is an autocorrecting error and there was
                        // really no need for the Bioware spec. to indent the 3rd line.
                        // The fact it's the 3rd line alone is enough to signify
                        // that the line is the colhead fields.

                        head = "The 3rd line (colhead labels) is not indented properly. It will be corrected if the file is saved.";
                        copy = Fullpath + Environment.NewLine + Environment.NewLine
                               + line;

                        switch (ShowLoadWarning(head, copy))
                        {
                        case DialogResult.Cancel:
                            return(LOADRESULT_FALSE);

                        case DialogResult.OK:
                            quelch = true;
                            goto case DialogResult.Retry;

                        case DialogResult.Retry:
                            loadresult = LOADRESULT_CHANGED;
                            break;
                        }
                    }

                    tr = tr.TrimStart();

                    if (!quelch)
                    {
                        var chars = new List <char>();                                // warn only once per character

                        foreach (char character in tr)
                        {
                            // construct this condition in the positive and put a NOT in front of it
                            // to avoid logical pretzels ...

                            if (!chars.Contains(character) &&
                                !(character == 32 ||                                            // space
                                  (character == 9 &&                                                // tab
                                   (Settings._alignoutput == Settings.AoTabs ||
                                    !Settings._strict)) ||
                                  Util.isAsciiAlphanumericOrUnderscore(character) ||
                                  (!Settings._strict &&
                                   Util.isPrintableAsciiNotDoublequote(character))))
                            {
                                head = "Detected a suspect character in the colhead labels ...";
                                copy = Fullpath + Environment.NewLine + Environment.NewLine
                                       + character;
//										 + (character == 9 ? "\u2192" : character.ToString());

                                switch (ShowLoadWarning(head, copy))
                                {
                                case DialogResult.Cancel:
                                    return(LOADRESULT_FALSE);

                                case DialogResult.OK:
                                    quelch = true;
                                    break;

                                case DialogResult.Retry:
                                    chars.Add(character);
                                    break;
                                }
                            }
                            if (quelch)
                            {
                                break;
                            }
                        }
                    }

                    Fields = tr.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
                    break;

                default:                         // line #3+ datarows ->
                    tr = line.Trim();

                    if (tr.Length == 0)
                    {
                        if (!quelch && Settings._strict)
                        {
                            head = "A blank row is detected. It will be deleted if the file is saved.";
                            copy = Fullpath;

                            switch (ShowLoadWarning(head, copy))
                            {
                            case DialogResult.Cancel:
                                return(LOADRESULT_FALSE);

                            case DialogResult.OK:
                                quelch = true;
                                goto case DialogResult.Retry;

                            case DialogResult.Retry:
                                loadresult = LOADRESULT_CHANGED;
                                break;
                            }
                        }
                    }
                    else
                    {
                        ++id;

                        if (!quelch && Settings._strict && !whitespacewarned && line != tr)
                        {
                            whitespacewarned = true;

                            head = "At least one row has extraneous whitespace. This will be trimmed if the file is saved.";
                            copy = Fullpath + Environment.NewLine + Environment.NewLine
                                   + "id " + id;

                            switch (ShowLoadWarning(head, copy))
                            {
                            case DialogResult.Cancel:
                                return(LOADRESULT_FALSE);

                            case DialogResult.OK:
                                quelch = true;
                                goto case DialogResult.Retry;

                            case DialogResult.Retry:
                                loadresult = LOADRESULT_CHANGED;
                                break;
                            }
                        }

                        string[] celltexts = ParseTableRow(tr);

                        if (!quelch)                                 // show these warnings even if not Strict.
                        {
                            // test for id
                            int result;
                            if (!Int32.TryParse(celltexts[0], out result))
                            {
                                head = "The 2da-file contains an id that is not an integer.";
                            }
                            else if (result != id)
                            {
                                head = "The 2da-file contains an id that is out of order.";
                            }
                            else
                            {
                                head = null;
                            }

                            if (head != null)                                     // show this warning even if Autorder true - table shall be flagged Changed
                            {
                                copy = Fullpath + Environment.NewLine + Environment.NewLine
                                       + "id " + id + " \u2192 " + celltexts[0];

                                switch (ShowLoadWarning(head, copy))
                                {
                                case DialogResult.Cancel:
                                    return(LOADRESULT_FALSE);

                                case DialogResult.OK:
                                    quelch = true;
                                    break;
                                }
                            }

                            // test for matching cell-fields under cols
                            if (!quelch)
                            {
                                if (celltexts.Length != Fields.Length + 1)
                                {
                                    head = "The 2da-file contains fields that do not align with its cols.";
                                    copy = Fullpath + Environment.NewLine + Environment.NewLine
                                           + "Colcount " + (Fields.Length + 1) + Environment.NewLine
                                           + "id " + id + " fields \u2192 " + celltexts.Length;

                                    switch (ShowLoadWarning(head, copy))
                                    {
                                    case DialogResult.Cancel:
                                        return(LOADRESULT_FALSE);

                                    case DialogResult.OK:
                                        quelch = true;
                                        break;
                                    }
                                }
                            }

                            // test for an odd quantity of double-quote characters
                            if (!quelch)
                            {
                                int quotes = 0;
                                foreach (char character in tr)
                                {
                                    if (character == '"')
                                    {
                                        ++quotes;
                                    }
                                }

                                if (quotes % 2 == 1)
                                {
                                    head = "A row contains an odd quantity of double-quote characters. This could be bad ...";
                                    copy = Fullpath + Environment.NewLine + Environment.NewLine
                                           + "id " + id;

                                    switch (ShowLoadWarning(head, copy))
                                    {
                                    case DialogResult.Cancel:
                                        return(LOADRESULT_FALSE);

                                    case DialogResult.OK:
                                        quelch = true;
                                        break;
                                    }
                                }
                            }
                        }


                        if (Settings._autorder && id.ToString(CultureInfo.InvariantCulture) != celltexts[0])
                        {
                            celltexts[0] = id.ToString(CultureInfo.InvariantCulture);
                            autordered   = true;
                        }

                        // NOTE: Tests for well-formed fields will be done later so that their
                        //       respective cells can be flagged as loadchanged if applicable.

                        _rows.Add(celltexts);
                    }
                    break;
                }
            }

            if (autordered)
            {
                using (var ib = new Infobox(Infobox.Title_infor, "Row ids have been corrected."))
                    ib.ShowDialog(_f);

                loadresult = LOADRESULT_CHANGED;
            }


            if (_rows.Count == 0)                          // add a row of stars so grid is not left blank ->
            {
                var cells = new string[Fields.Length + 1]; // NOTE: 'Fields' does not contain the ID-col.

                int c = 0;
                if (Settings._autorder)
                {
                    cells[c++] = "0";
                }

                for (; c <= Fields.Length; ++c)
                {
                    cells[c] = gs.Stars;
                }

                _rows.Add(cells);
                return(LOADRESULT_CHANGED);                // flag the Table as changed
            }

            return(loadresult);
        }