private static bool Matches(ProteinMetadata proteinMetadata, ProteinMatchType matchType, string ltext) { return ContainsLowerCase(proteinMetadata.TextForMatchTypes(matchType), ltext); }
[MethodImpl(MethodImplOptions.NoOptimization)] // TODO(nicksh): reenable optimizations after we track down a NullReferenceException public static IList <ListViewItem> CreateListViewItems(IList <ProteinMatch> matches, String searchText, ProteinMatchTypes matchTypes, PeptideSettings peptideSettings, int maxCount) { var listItems = new SortedList <string, ListViewItem>(); var setUsedMatches = new HashSet <string>(); // First check for matching by sequence foreach (var match in matches) { if (matchTypes.Contains(ProteinMatchType.sequence)) { HashSet <String> addedPeptideSequences = new HashSet <string>(); FastaSequence fastaSequence; try { fastaSequence = new FastaSequence("name", "description", new ProteinMetadata[0], match.Protein.Sequence); // Not L10N } catch (InvalidDataException) { // It's possible that the peptide sequence in the fasta file was bogus, in which case we just don't digest it. continue; } foreach (Peptide peptide in peptideSettings.Enzyme.Digest(fastaSequence, peptideSettings.DigestSettings)) { if (!peptide.Sequence.StartsWith(searchText)) { continue; } if (!addedPeptideSequences.Add(peptide.Sequence)) { continue; } var listItem = new ListViewItem { Text = peptide.Sequence, Tag = new StatementCompletionItem { Peptide = peptide.Sequence, ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }, }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes), null); setUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.peptide; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes)); foreach (var name in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(name.TextForMatchTypes(matchTypes)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // Note the leading space in this sort key - we'd like to list sequence matches first var key = TextUtil.SpaceSeparate(" ", listItem.Text, listItem.ToolTipText); // Not L10N if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Decide which field not to display on righthand side, based on what's already showing on the left due to View|Targets|By* menu ProteinMatchTypes displayMatchTypes = ProteinMatchTypes.ALL; switch (SequenceTree.ProteinsDisplayMode) { case ProteinMetadataManager.ProteinDisplayMode.ByName: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.name); break; case ProteinMetadataManager.ProteinDisplayMode.ByAccession: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.accession); break; case ProteinMetadataManager.ProteinDisplayMode.ByGene: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.gene); break; case ProteinMetadataManager.ProteinDisplayMode.ByPreferredName: displayMatchTypes = displayMatchTypes.Except(ProteinMatchType.preferredName); break; } ProteinMatchTypes secondPassMatchTypes = matchTypes.Except( ProteinMatchType.sequence, // We already did sequence ProteinMatchType.description); // And aren't ready for description foreach (var match in matches) { if (setUsedMatches.Contains(match.Protein.Name)) { continue; } // Try matching on name, accession etc - cycle through name, accession, preferredName, gene foreach (ProteinMatchType tryType in secondPassMatchTypes) { if (match.MatchTypes.Contains(tryType)) { var listItem = new ListViewItem(); // Show description, and any other fields we were searching on if (match.AlternativeName != null) { listItem.Text = ProteinMetadataManager.ProteinModalDisplayText(match.AlternativeName, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.AlternativeName, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.AlternativeName.TextForMatchTypes(displayMatchTypes.Except(ProteinMatchType.name)), searchText); } else { listItem.Text = ProteinMetadataManager.ProteinModalDisplayText(match.Protein.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchTypes), searchText); } setUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.protein; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchTypes)); foreach (var altName in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchTypes)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // We want the sort to be on the particular bit of metadata that we matched var key = TextUtil.SpaceSeparate(match.Protein.ProteinMetadata.TextForMatchTypes(ProteinMatchTypes.Singleton(tryType)), listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } break; } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Any matches by description? foreach (var match in matches) { if (setUsedMatches.Contains(match.Protein.Name)) { continue; } if (match.MatchTypes.Contains(ProteinMatchType.description)) { ProteinMetadata mainName = match.AlternativeDescription; string matchName = match.Protein.Name; var proteinInfo = match.Protein.ProteinMetadata; if (matchName != null && matchName.Length > MAX_NAME_LENGTH) { proteinInfo = proteinInfo.ChangeName(matchName.Substring(0, MAX_NAME_LENGTH) + "..."); // Not L10N } var alternativeNames = new List <ProteinMetadata>(); if (mainName == null) { mainName = proteinInfo; } else { alternativeNames.Add(proteinInfo); } var listItem = new ListViewItem { Text = ProteinMetadataManager.ProteinModalDisplayText(mainName, Settings.Default.ShowPeptidesDisplayMode), ImageIndex = (int)ImageId.protein, Tag = new StatementCompletionItem { ProteinInfo = proteinInfo, SearchText = searchText } }; StatementCompletionForm.AddDescription(listItem, mainName.TextForMatchTypes(displayMatchTypes), searchText); if (match.Protein.AlternativeNames.Count > 0) { alternativeNames.AddRange(match.Protein.AlternativeNames); StringBuilder tooltip = new StringBuilder(Resources.StatementCompletionTextBox_CreateListViewItems_Alternative_Names); foreach (var altName in alternativeNames) { if (altName.Name == mainName.Name) { continue; } tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchTypes.Union(ProteinMatchType.name))); } listItem.ToolTipText = StripTabs(tooltip.ToString()); } // We want the sort to be on what we matched in the description, and what follows. var remains = match.Protein.ProteinMetadata.Description ?? string.Empty; int pos = remains.ToLower().IndexOf(searchText.ToLower(), StringComparison.Ordinal); if (pos > 0) { remains = remains.Substring(pos); } var key = TextUtil.SpaceSeparate(remains, listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } return(new List <ListViewItem>(listItems.Values)); }
/// <summary> /// Create the ordered list of dropdown items, with a rational sort order: /// First present any sequence matches, sorted by sequence /// Then present any name, accession, gene, preferredname, or species metadata matches, sorted by the matched metadata field /// Then present any matches against the description field, sorted by the description text starting at the match location /// </summary> public static IList <ListViewItem> CreateListViewItems(IList <ProteinMatch> matches, String searchText, ProteinMatchType matchTypes, int maxCount) { var listItems = new SortedList <string, ListViewItem>(); var listUsedMatches = new List <string>(); // First check for matching by sequence foreach (var match in matches) { if (0 != (matchTypes & match.MatchType & ProteinMatchType.sequence)) { foreach (DigestedPeptide digestedPeptide in match.DigestedPeptides) { var listItem = new ListViewItem { Text = digestedPeptide.Sequence, Tag = new StatementCompletionItem { Peptide = digestedPeptide.Sequence, ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }, }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes), null); listUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.peptide; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes)); foreach (var name in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(name.TextForMatchTypes(matchTypes)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // Note the leading space in this sort key - we'd like to list sequence matches first var key = TextUtil.SpaceSeparate(" ", listItem.Text, listItem.ToolTipText); // Not L10N if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Decide which field not to display on righthand side, based on what's already showing on the left due to View|Targets|By* menu ProteinMatchType displayMatchType = ProteinMatchType.all; switch (SequenceTree.ProteinsDisplayMode) { case ProteinDisplayMode.ByName: displayMatchType &= ~ProteinMatchType.name; break; case ProteinDisplayMode.ByAccession: displayMatchType &= ~ProteinMatchType.accession; break; case ProteinDisplayMode.ByGene: displayMatchType &= ~ProteinMatchType.gene; break; case ProteinDisplayMode.ByPreferredName: displayMatchType &= ~ProteinMatchType.preferredName; break; } foreach (var match in matches) { // Try matching on name, accession etc - cycle through name, accession, preferredName, gene for (int bit = 1; bit < (int)ProteinMatchType.all; bit = bit << 1) { ProteinMatchType tryType = (ProteinMatchType)bit; if ((tryType != ProteinMatchType.sequence) && // We already did sequence (tryType != ProteinMatchType.description) && // And aren't ready for description (0 != (matchTypes & match.MatchType & tryType) && !listUsedMatches.Contains(match.Protein.Name))) { var listItem = new ListViewItem(); // Show description, and any other fields we were searching on if (match.AlternativeName != null) { listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.AlternativeName, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.AlternativeName, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.AlternativeName.TextForMatchTypes(displayMatchType & ~ProteinMatchType.name), searchText); } else { listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.Protein.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode); listItem.Tag = new StatementCompletionItem { ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText }; StatementCompletionForm.AddDescription(listItem, match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType), searchText); } listUsedMatches.Add(match.Protein.Name); listItem.ImageIndex = (int)ImageId.protein; var tooltip = new StringBuilder(); tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions) .Append(match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType)); foreach (var altName in match.Protein.AlternativeNames) { tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); // We want the sort to be on the particular bit of metadata that we matched var key = TextUtil.SpaceSeparate(match.Protein.ProteinMetadata.TextForMatchTypes(tryType), listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } break; } } } if (listItems.Count >= maxCount) { return(new List <ListViewItem>(listItems.Values)); // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence } // Any matches by description? foreach (var match in matches) { if ((0 != (match.MatchType & ProteinMatchType.description)) && !listUsedMatches.Contains(match.Protein.Name)) { ProteinMetadata mainName = match.AlternativeDescription; string matchName = match.Protein.Name; var proteinInfo = match.Protein.ProteinMetadata; if (matchName.Length > MAX_NAME_LENGTH) { proteinInfo = proteinInfo.ChangeName(matchName.Substring(0, MAX_NAME_LENGTH) + "..."); // Not L10N } var alternativeNames = new List <ProteinMetadata>(); if (mainName == null) { mainName = proteinInfo; } else { alternativeNames.Add(proteinInfo); } var listItem = new ListViewItem { Text = PeptideGroupTreeNode.ProteinModalDisplayText(mainName, Settings.Default.ShowPeptidesDisplayMode), ImageIndex = (int)ImageId.protein, Tag = new StatementCompletionItem { ProteinInfo = proteinInfo, SearchText = searchText } }; StatementCompletionForm.AddDescription(listItem, mainName.TextForMatchTypes(displayMatchType), searchText); if (match.Protein.AlternativeNames.Count > 0) { alternativeNames.AddRange(match.Protein.AlternativeNames); StringBuilder tooltip = new StringBuilder(Resources.StatementCompletionTextBox_CreateListViewItems_Alternative_Names); foreach (var altName in alternativeNames) { if (altName.Name == mainName.Name) { continue; } tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType | ProteinMatchType.name)); } listItem.ToolTipText = StripTabs(tooltip.ToString()); } // We want the sort to be on what we matched in the description, and what follows. var remains = match.Protein.ProteinMetadata.Description; int pos = remains.ToLower().IndexOf(searchText.ToLower(), StringComparison.Ordinal); if (pos > 0) { remains = remains.Substring(pos); } var key = TextUtil.SpaceSeparate(remains, listItem.Text, listItem.ToolTipText); if (!listItems.ContainsKey(key)) { listItems.Add(key, listItem); } } } return(new List <ListViewItem>(listItems.Values)); }