/// ------------------------------------------------------------------------------------ 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; }
/// ------------------------------------------------------------------------------------ /// <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()); }
/// ------------------------------------------------------------------------------------ /// <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); }
/// ------------------------------------------------------------------------------------ /// <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); }
/// ------------------------------------------------------------------------------------ /// <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()); }