private void showAutoCompleteList() { hideAutoCompleteList(); TextUtils.WordInfo currentWordInfo = getCurrentWord(textBoxAutoComplete); if (!currentWordInfo.IsValid || currentWordInfo.Word.Length < 2) { return; } bool doesWordContainWord(string container, string containee) => container.ToLower().Contains(containee.ToLower()); object[] objects = _users? .Where(user => doesWordContainWord(user.Name, currentWordInfo.Word) || doesWordContainWord(user.Username, currentWordInfo.Word)) .Cast <object>() .ToArray() ?? Array.Empty <object>(); if (objects.Length == 0) { return; } ListBox listBox = createListBox(); fillListBox(listBox, objects); resizeListBox(listBox, objects); createPopupWindow(listBox); showPopupWindow(); _listBoxAutoComplete = listBox; Focus(); }
private void applyAutoCompleteListSelection() { TextUtils.WordInfo currentWordInfo = getCurrentWord(textBoxAutoComplete); if (_listBoxAutoComplete.SelectedItem == null || !currentWordInfo.IsValid) { return; } string substitutionWord = ((User)(_listBoxAutoComplete.SelectedItem)).Username; textBoxAutoComplete.Text = TextUtils.ReplaceWord(textBoxAutoComplete.Text, currentWordInfo, substitutionWord); textBoxAutoComplete.SelectionStart = currentWordInfo.Start + substitutionWord.Length; }
private void showPopupWindow() { TextUtils.WordInfo currentWordInfo = getCurrentWord(textBoxAutoComplete); if (!currentWordInfo.IsValid) { return; } Point position = textBoxAutoComplete.GetPositionFromCharIndex(currentWordInfo.Start); Point pt = PointToScreen(new Point(position.X, position.Y + textBoxAutoComplete.Height)); _popupWindow.Show(pt); }
/// <summary> /// Extends functionality. /// Trims result of TextUtils.GetCurrentWord(): /// - removes all non-letter characters before '@' character. /// - removes all non-letter characters after a series of letter characters (after '@') /// e.g. "[@abcd]" converted to "abcd" /// The following strings are considered incorrect: /// - strings without '@' /// - strings with letter-characters prior to '@' /// - strings where there is a non-letter character next to '@' /// </summary> private TextUtils.WordInfo getCurrentWord(RichTextBox txt) { int selectionStartPosition = txt.SelectionStart - 1; TextUtils.WordInfo word = TextUtils.GetCurrentWord(txt.Text, selectionStartPosition); if (!word.IsValid) { return(word); } int?firstLabelPrefixPosition = null; int?firstLetterPosition = null; int?firstNonLetterAfterLabelPrefixPosition = null; for (int iPosition = 0; iPosition < word.Word.Length; ++iPosition) { char currentChar = word.Word[iPosition]; if (Char.IsLetter(currentChar)) { if (!firstLetterPosition.HasValue) { firstLetterPosition = iPosition; } } else if (currentChar == GitLabLabelPrefixChar) { if (!firstLabelPrefixPosition.HasValue) { firstLabelPrefixPosition = iPosition; } } else if (!firstNonLetterAfterLabelPrefixPosition.HasValue && firstLabelPrefixPosition.HasValue) { firstNonLetterAfterLabelPrefixPosition = iPosition; } } if (!firstLetterPosition.HasValue || !firstLabelPrefixPosition.HasValue || firstLetterPosition.Value < firstLabelPrefixPosition.Value) { return(TextUtils.WordInfo.Invalid); } int firstCharAfterLabelPrefixPosition = firstLabelPrefixPosition.Value + 1; int textLength = firstNonLetterAfterLabelPrefixPosition.HasValue ? firstNonLetterAfterLabelPrefixPosition.Value - firstCharAfterLabelPrefixPosition : word.Word.Length - firstCharAfterLabelPrefixPosition; if (textLength == 0) { return(TextUtils.WordInfo.Invalid); } int startPosition = word.Start + firstCharAfterLabelPrefixPosition; string trimmedWord = word.Word.Substring(firstCharAfterLabelPrefixPosition, textLength); if (selectionStartPosition < startPosition || selectionStartPosition >= startPosition + trimmedWord.Length) { return(TextUtils.WordInfo.Invalid); } return(new TextUtils.WordInfo(startPosition, trimmedWord)); }