/// ------------------------------------------------------------------------------------
        private void SetPhoneticValue(string origPhonetic)
        {
            string phonetic = origPhonetic;

            if (!string.IsNullOrEmpty(phonetic))
            {
                // Normalize the phonetic string.
                phonetic = FFNormalizer.Normalize(phonetic);

                if (Project.TranscriptionChanges != null)
                {
                    // Convert experimental transcriptions within the phonetic string.
                    phonetic = Project.TranscriptionChanges.Convert(
                        phonetic, out m_experimentalTranscriptionList);

                    // Save this for displaying in the record view.
                    if (origPhonetic != phonetic)
                    {
                        _origPhoneticValue = origPhonetic;
                    }
                }
            }

            _phoneticValue.Value = phonetic;
        }
예제 #2
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Formats the search pattern.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public string formatFindPattern(string findWhatText)
        {
            string orginalFindPattern = FFNormalizer.Normalize(findWhatText);

            // Check if regular expression or simple search
            if (chkRegEx.Checked)
            {
                return(orginalFindPattern);
            }

            var findPattern = new StringBuilder();

            // Change all special characters to literals
            foreach (char c in orginalFindPattern)
            {
                if (m_reservedRegexChars.Contains(c))
                {
                    findPattern.Append('\\');
                }
                findPattern.Append(c);
            }

            // 'Starts With' option
            if (chkStartsWith.Checked)
            {
                findPattern.Insert(0, "^");
                findPattern.Append(".*$");
            }

            // 'Match Entire Word' option
            if (chkMatchEntireWord.Checked)
            {
                //findPattern.Insert(0, @"\s[\[\{\(]?");
                //findPattern.Append(@"[\]\}\)\.]?\s");
                findPattern.Insert(0, "\\b");
                findPattern.Append("\\b");
            }

            // 'Match Case' option
            if (chkMatchCase.Checked)
            {
                findPattern.Insert(0, "(?-i)");             // Turn OFF case INsensitivity
            }
            else
            {
                findPattern.Insert(0, "(?i)");             // Turn ON case INsensitivity
            }
            return(findPattern.ToString());
        }
예제 #3
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Scans the phonetic transcription, checking for possible ambiguous sequences at the
        /// beginning of each "word" within the transcription. These are the only ambiguous
        /// sequences the program will find automatically.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public List <string> FindAmbiguousSequences(string phonetic)
        {
            // Return an empty array if there's nothing in the phonetic.
            if (string.IsNullOrEmpty(phonetic))
            {
                return(null);
            }

            phonetic = FFNormalizer.Normalize(phonetic);
            phonetic = _transcriptionChanges.Convert(phonetic);
            string[] words     = phonetic.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            var      bldr      = new StringBuilder();
            var      ambigSeqs = new List <string>();

            foreach (var word in words.Where(w => w.Length > 0))
            {
                foreach (char c in word)
                {
                    var ci = App.IPASymbolCache[c];

                    if (ci == null || ci.IsBase || ci.IsUndefined)
                    {
                        // If there's already something in the builder it means
                        // we've previously found some non base characters before
                        // the current one that we assume belong to the current one.
                        if (bldr.Length > 0)
                        {
                            bldr.Append(c);
                        }

                        break;
                    }

                    bldr.Append(c);
                }

                if (bldr.Length > 0)
                {
                    ambigSeqs.Add(bldr.ToString());
                    bldr.Length = 0;
                }
            }

            return(ambigSeqs.Count > 0 ? ambigSeqs : null);
        }
예제 #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Find the cell query for a match and reposition the matching cell's row to the middle.
        /// </summary>
        /// <param name="cell">DataGridViewCell</param>
        /// <param name="findPattern">string</param>
        /// <returns>true if there is a match</returns>
        /// ------------------------------------------------------------------------------------
        private static bool SearchCellDataForMatch(DataGridViewCell cell, string findPattern)
        {
            // There is NOT a match if the cell is NOT visible (i.e. group(s) collapsed) AND
            // searching collapsed groups AND (the grid is grouped on a sorted field OR minimal pairs).
            if (!cell.Visible && !s_searchCollapsedGroups &&
                (s_grid.IsGroupedByField || s_grid.Cache.IsMinimalPair || s_grid.Cache.IsSimilarEnvironment))
            {
                return(false);
            }

            string cellValue = cell.Value as string;

            if (cellValue == null)
            {
                return(false);
            }

            var field =
                App.Project.GetFieldForName(s_grid.Columns[cell.ColumnIndex].Name);

            if (field.Type != FieldType.Phonetic)
            {
                cellValue = FFNormalizer.Normalize(cellValue);
            }

            try
            {
                if (!Regex.IsMatch(cellValue, findPattern))
                {
                    return(false);
                }

                if (DoneSearching(cell))
                {
                    return(true);
                }

                if (!cell.Visible && s_searchCollapsedGroups &&
                    (s_grid.IsGroupedByField || s_grid.Cache.IsMinimalPair || s_grid.Cache.IsSimilarEnvironment))
                {
                    if (s_findBackwards)
                    {
                        ExpandPreviousHierarchicalGridRow();
                    }
                    else
                    {
                        // s_silHierarchicalGridRow will only be null when the user
                        // Groups by Sorted Field in the middle of a Find and then
                        // does a Find Next
                        if (s_silHierarchicalGridRow == null)
                        {
                            ExpandPreviousHierarchicalGridRow();
                        }
                        else if (!s_silHierarchicalGridRow.Expanded)
                        {
                            s_silHierarchicalGridRow.Expanded = true;
                        }
                    }
                }

                s_numberOfFinds++;

                // If the cell is off the screen, move the cell's row to the screen's
                // middle. s_showMessages will only be false if running tests.
                if (!cell.Displayed && ShowMessages)
                {
                    s_grid.ScrollRowToMiddleOfGrid(cell.RowIndex);
                }

                if (cell.Visible)
                {
                    s_grid.CurrentCell = cell;
                }
            }
            catch (Exception ex)
            {
                if (ShowMessages)
                {
                    Utils.MsgBox(ex.Message);
                }
            }

            // Done searching
            return(true);
        }
예제 #5
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Parses the specified phonetic string into an array of phones.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public string[] Parse(string phonetic, bool normalize,
                              bool convertExperimentalTranscriptions, out Dictionary <int, string[]> uncertainPhones)
        {
            uncertainPhones = null;

            // Return an empty array if there's nothing in the phonetic.
            if (string.IsNullOrEmpty(phonetic))
            {
                return(null);
            }

            var       phones = new List <string>(phonetic.Length);
            IPASymbol ciPrev = null;

            // Normalize the string if necessary.
            if (normalize)
            {
                phonetic = FFNormalizer.Normalize(phonetic);
            }

            var origPhoneticRunBeingParsed = phonetic;

            if (convertExperimentalTranscriptions)
            {
                phonetic = _transcriptionChanges.Convert(phonetic);
            }

            phonetic = MarkAmbiguousSequences(phonetic);

            int  phoneStart  = 0;
            bool hasBaseChar = false;

            for (int i = 0; i < phonetic.Length; i++)
            {
                char c       = phonetic[i];
                char badChar = '\0';

                // Check if we've run into a marker indicating
                // the beginning of an ambiguous sequence.
                if (c == kParseTokenMarker)
                {
                    // First, close the previous phone if there is one.
                    if (i > phoneStart)
                    {
                        phones.Add(phonetic.Substring(phoneStart, i - phoneStart));
                    }

                    var ambigPhone =
                        _sortedAmbiguousSeqList.GetAmbigSeqForToken(phonetic[++i]);

                    if (!string.IsNullOrEmpty(ambigPhone))
                    {
                        phones.Add(ambigPhone);
                    }

                    phoneStart = i + 1;
                    continue;
                }

                // Get the information for the current codepoint.
                var ciCurr = App.IPASymbolCache[c];

                // If there's no information for a code point or there is but there isn't
                // any for the previous character and the current character isn't a base
                // character, then treat the character as it's own phone.
                if (ciCurr == null || ciCurr.Type == IPASymbolType.notApplicable)
                {
                    if (i > phoneStart)
                    {
                        phones.Add(phonetic.Substring(phoneStart, i - phoneStart));
                    }

                    // Check if we're at the beginning of an uncertain phone group
                    if (c != '(')
                    {
                        phoneStart = i + 1;
                        badChar    = c;
                    }
                    else
                    {
                        int index        = i + 1;
                        var primaryPhone = GetUncertainties(phonetic, ref index,
                                                            phones.Count, ref uncertainPhones, origPhoneticRunBeingParsed);

                        // Primary phone should only be null when no slash was found
                        // between the parentheses. In that situation, the parentheses are
                        // not considered to be surrounding a group of uncertain phones.
                        if (primaryPhone == null)
                        {
                            badChar = c;
                        }
                        else
                        {
                            phones.Add(primaryPhone);
                            i = index;
                        }

                        phoneStart = i + 1;
                    }

                    ciPrev = null;

                    if (badChar != '\0')
                    {
                        // Log the undefined character.
                        if (LogUndefinedCharactersWhenParsing && App.IPASymbolCache.UndefinedCharacters != null)
                        {
                            App.IPASymbolCache.UndefinedCharacters.Add(c, origPhoneticRunBeingParsed);
                        }

                        phones.Add(c.ToString());
                    }

                    continue;
                }

                // If we've encountered a non base character but nothing precedes it,
                // then it must be a diacritic at the beginning of the phonetic
                // transcription so just put it with the following characters.
                if (ciPrev == null && !ciCurr.IsBase)
                {
                    continue;
                }

                // Is the previous codepoint special in that it's not a base character
                // but a base character must follow it in the same phone (e.g. a tie bar)?
                // If yes, then make sure the current codepoint is a base character or
                // throw it away.
                if (ciPrev != null && (!hasBaseChar || ciPrev.CombinesBaseCharacters) && ciPrev.CanPrecedeBase)
                {
                    ciPrev = ciCurr;
                    continue;
                }

                // At this point, if the current codepoint is a base character and
                // it's not the first in the string, close the previous phone. If
                // ciCurr.IsBase && i > phoneStart but ciPrev == null then it means
                // we've run across some non base characters at the beginning of the
                // transcription that aren't attached to a base character. Therefore,
                // attach them to the first base character that's found. In that case,
                // we don't want to add the phone to the collection yet. We'll wait
                // until we come across the beginning of the next phone.
                if (ciCurr.IsBase && i > phoneStart && ciPrev != null)
                {
                    phones.Add(phonetic.Substring(phoneStart, i - phoneStart));
                    phoneStart  = i;
                    hasBaseChar = false;
                }

                ciPrev       = ciCurr;
                hasBaseChar |= ciCurr.IsBase;
            }

            // Save the last phone
            if (phoneStart < phonetic.Length)
            {
                phones.Add(phonetic.Substring(phoneStart));
            }

            return(phones.ToArray());
        }