Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py3
-rw-r--r--source/blender/editors/animation/anim_filter.c39
-rw-r--r--source/blender/makesdna/DNA_action_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_action.c8
4 files changed, 49 insertions, 5 deletions
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 47775251955..af40f1f070c 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -51,11 +51,13 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
row.prop(dopesheet, "show_only_matching_fcurves", text="")
if dopesheet.show_only_matching_fcurves:
row.prop(dopesheet, "filter_fcurve_name", text="")
+ row.prop(dopesheet, "use_multi_word_filter", text="")
else:
row = layout.row(align=True)
row.prop(dopesheet, "use_filter_text", text="")
if dopesheet.use_filter_text:
row.prop(dopesheet, "filter_text", text="")
+ row.prop(dopesheet, "use_multi_word_filter", text="")
if not genericFiltersOnly:
row = layout.row(align=True)
@@ -151,6 +153,7 @@ class DOPESHEET_HT_header(Header):
row.prop(st.dopesheet, "use_filter_text", text="")
if st.dopesheet.use_filter_text:
row.prop(st.dopesheet, "filter_text", text="")
+ row.prop(st.dopesheet, "use_multi_word_filter", text="")
row = layout.row(align=True)
row.prop(toolsettings, "use_proportional_action",
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 2778a458ca0..910e195173c 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -76,7 +76,9 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "BLI_ghash.h"
+#include "BLI_string.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -986,6 +988,35 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
return false;
}
+/* Helper for name-based filtering - Perform "partial/fuzzy matches" (as in 80a7efd) */
+static bool name_matches_dopesheet_filter(bDopeSheet *ads, char *name)
+{
+ if (ads->flag & ADS_FLAG_FUZZY_NAMES) {
+ /* full fuzzy, multi-word, case insensitive matches */
+ const size_t str_len = strlen(ads->searchstr);
+ const int words_max = (str_len / 2) + 1;
+
+ int (*words)[2] = BLI_array_alloca(words, words_max);
+ const int words_len = BLI_string_find_split_words(ads->searchstr, str_len, ' ', words, words_max);
+ bool found = false;
+
+ /* match name against all search words */
+ for (int index = 0; index < words_len; index++) {
+ if (BLI_strncasestr(name, ads->searchstr + words[index][0], words[index][1])) {
+ found = true;
+ break;
+ }
+ }
+
+ /* if we have a match somewhere, this returns true */
+ return found;
+ }
+ else {
+ /* fallback/default - just case insensitive, but starts from start of word */
+ return BLI_strcasestr(name, ads->searchstr) != NULL;
+ }
+}
+
/* (Display-)Name-based F-Curve filtering
* NOTE: when this function returns true, the F-Curve is to be skipped
*/
@@ -1010,7 +1041,7 @@ static bool skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id)
/* check for partial match with the match string, assuming case insensitive filtering
* if match, this channel shouldn't be ignored!
*/
- return BLI_strcasestr(name, ads->searchstr) == NULL;
+ return !name_matches_dopesheet_filter(ads, name);
}
/* just let this go... */
@@ -1315,12 +1346,12 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
bool track_ok = false, strip_ok = false;
/* check if the name of the track, or the strips it has are ok... */
- track_ok = BLI_strcasestr(nlt->name, ads->searchstr);
+ track_ok = name_matches_dopesheet_filter(ads, nlt->name);
if (track_ok == false) {
NlaStrip *strip;
for (strip = nlt->strips.first; strip; strip = strip->next) {
- if (BLI_strcasestr(strip->name, ads->searchstr)) {
+ if (name_matches_dopesheet_filter(ads, strip->name)) {
strip_ok = true;
break;
}
@@ -1520,7 +1551,7 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee
if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
/* skip layer if the name doesn't match the filter string */
if ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) {
- if (BLI_strcasestr(gpl->info, ads->searchstr) == NULL)
+ if (name_matches_dopesheet_filter(ads, gpl->info) == false)
continue;
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 9c17a1f4f5b..96d7ec3128c 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -606,7 +606,9 @@ typedef enum eDopeSheet_FilterFlag {
/* DopeSheet general flags */
typedef enum eDopeSheet_Flag {
ADS_FLAG_SUMMARY_COLLAPSED = (1 << 0), /* when summary is shown, it is collapsed, so all other channels get hidden */
- ADS_FLAG_SHOW_DBFILTERS = (1 << 1) /* show filters for datablocks */
+ ADS_FLAG_SHOW_DBFILTERS = (1 << 1), /* show filters for datablocks */
+
+ ADS_FLAG_FUZZY_NAMES = (1 << 2), /* use fuzzy/partial string matches when ADS_FILTER_BY_FCU_NAME is enabled (WARNING: expensive operation) */
/* NOTE: datablock filter flags continued (1 << 10) onwards... */
} eDopeSheet_Flag;
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 5d90b9fcae8..7c21ce95a1d 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -357,6 +357,14 @@ static void rna_def_dopesheet(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* Multi-word fuzzy search option for name/text filters */
+ prop = RNA_def_property(srna, "use_multi_word_filter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ADS_FLAG_FUZZY_NAMES);
+ RNA_def_property_ui_text(prop, "Multi-Word Fuzzy Filter",
+ "Perform fuzzy/multi-word matching (WARNING: May be slow)");
+ RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
+ RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
/* NLA Specific Settings */
prop = RNA_def_property(srna, "show_missing_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NLA_NOACT);