From 2a24b3aaf4c846a5d98f783fef69946584865df9 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 7 Jul 2020 10:08:42 +0200 Subject: Fix T78084: Search does not accept text fragments everywhere This was reported for the "Add Node" search functionality, but is relevant in other searches as well. So e.g. when searching for "Separate XYZ", typing "sep", then " " (with the intention to type "X" next) would clear the search field. Now use the same method (matching against all search words) as in F3 searching ('menu_search_update_fn') in other searches as well [searching IDs, property objects, finding nodes,...] This should give a much nicer search experience in general. Note: this does not touch other searches in the Dopesheet, Outliner, Filebrowser or User Preferences that have other search implementations. Maniphest Tasks: T78084 Differential Revision: https://developer.blender.org/D8232 --- source/blender/blenlib/BLI_string.h | 7 ++++++ source/blender/blenlib/intern/string.c | 33 +++++++++++++++++++++++++ source/blender/blenlib/tests/BLI_string_test.cc | 10 ++++++++ 3 files changed, 50 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index d1fab065959..4968b4ee159 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -133,6 +133,13 @@ size_t BLI_str_partition_ex(const char *str, const char **suf, const bool from_right) ATTR_NONNULL(1, 3, 4, 5); +int BLI_string_max_possible_word_count(const int str_len); +bool BLI_string_has_word_prefix(const char *haystack, const char *needle, size_t needle_len); +bool BLI_string_all_words_matched(const char *name, + const char *str, + int (*words)[2], + const int words_len); + int BLI_string_find_split_words(const char *str, const size_t len, const char delim, diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 755637ac274..02d12d2df9b 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -524,6 +524,39 @@ char *BLI_strcasestr(const char *s, const char *find) return ((char *)s); } +int BLI_string_max_possible_word_count(const int str_len) +{ + return (str_len / 2) + 1; +} + +bool BLI_string_has_word_prefix(const char *haystack, const char *needle, size_t needle_len) +{ + const char *match = BLI_strncasestr(haystack, needle, needle_len); + if (match) { + if ((match == haystack) || (*(match - 1) == ' ') || ispunct(*(match - 1))) { + return true; + } + return BLI_string_has_word_prefix(match + 1, needle, needle_len); + } + return false; +} + +bool BLI_string_all_words_matched(const char *name, + const char *str, + int (*words)[2], + const int words_len) +{ + int index; + for (index = 0; index < words_len; index++) { + if (!BLI_string_has_word_prefix(name, str + words[index][0], (size_t)words[index][1])) { + break; + } + } + const bool all_words_matched = (index == words_len); + + return all_words_matched; +} + /** * Variation of #BLI_strcasestr with string length limited to \a len */ diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc index 1760b7966e3..a5fd3e31c31 100644 --- a/source/blender/blenlib/tests/BLI_string_test.cc +++ b/source/blender/blenlib/tests/BLI_string_test.cc @@ -570,6 +570,16 @@ TEST(string, StringStrncasestr) EXPECT_EQ(res, (void *)NULL); } +/* BLI_string_max_possible_word_count */ +TEST(string, StringMaxPossibleWordCount) +{ + EXPECT_EQ(BLI_string_max_possible_word_count(0), 1); + EXPECT_EQ(BLI_string_max_possible_word_count(1), 1); + EXPECT_EQ(BLI_string_max_possible_word_count(2), 2); + EXPECT_EQ(BLI_string_max_possible_word_count(3), 2); + EXPECT_EQ(BLI_string_max_possible_word_count(10), 6); +} + /* BLI_string_is_decimal */ TEST(string, StrIsDecimal) { -- cgit v1.2.3