From dcc5997527df32dfbb71874e3099b3790d8e9b4a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 3 Jan 2015 21:55:16 +0100 Subject: [PATCH] FileBrowser: add search field in header bar. Not much to add, pretty straightforward... --- .../startup/bl_ui/space_filebrowser.py | 4 ++++ source/blender/editors/space_file/filelist.c | 23 +++++++++++++++++-- source/blender/editors/space_file/filelist.h | 3 ++- .../blender/editors/space_file/space_file.c | 3 ++- source/blender/makesdna/DNA_space_types.h | 2 ++ source/blender/makesrna/intern/rna_space.c | 5 ++++ 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index b90eb7a89c3..794c8baa1ed 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -77,5 +77,9 @@ class FILEBROWSER_HT_header(Header): row.prop(params, "use_filter_sound", text="") row.prop(params, "use_filter_text", text="") + row.separator() + row.prop(params, "filter_search", text="") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index abfa1ed5666..5f25636ba4a 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -46,6 +46,7 @@ #include "BLI_blenlib.h" #include "BLI_fileops_types.h" +#include "BLI_fnmatch.h" #include "BLI_linklist.h" #include "BLI_utildefines.h" @@ -209,6 +210,7 @@ typedef struct FileListFilter { bool hide_parent; unsigned int filter; char filter_glob[64]; + char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */ } FileListFilter; typedef struct FileList { @@ -494,6 +496,11 @@ static bool is_filtered_file(struct direntry *file, const char *UNUSED(root), Fi if (!(file->type & S_IFDIR) && !(file->flags & filter->filter)) { is_filtered = false; } + if (is_filtered && (filter->filter_search[0] != '\0')) { + if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) { + is_filtered = false; + } + } } return is_filtered; @@ -506,6 +513,13 @@ static bool is_filtered_lib(struct direntry *file, const char *root, FileListFil if (BLO_is_a_library(root, dir, group)) { is_filtered = !is_hidden_file(file->relname, filter); + if (is_filtered && filter->filter && !FILENAME_IS_BREADCRUMBS(file->relname)) { + if (is_filtered && (filter->filter_search[0] != '\0')) { + if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) { + is_filtered = false; + } + } + } } else { is_filtered = is_filtered_file(file, root, filter); @@ -560,19 +574,24 @@ void filelist_filter(FileList *filelist) } void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent, - const unsigned int filter, const char *filter_glob) + const unsigned int filter, + const char *filter_glob, const char *filter_search) { if ((filelist->filter_data.hide_dot != hide_dot) || (filelist->filter_data.hide_parent != hide_parent) || (filelist->filter_data.filter != filter) || - (!STREQ(filelist->filter_data.filter_glob, filter_glob))) + !STREQ(filelist->filter_data.filter_glob, filter_glob) || + (BLI_strcmp_ignore_pad(filelist->filter_data.filter_search, filter_search, '*') != 0)) { filelist->filter_data.hide_dot = hide_dot; filelist->filter_data.hide_parent = hide_parent; filelist->filter_data.filter = filter; BLI_strncpy(filelist->filter_data.filter_glob, filter_glob, sizeof(filelist->filter_data.filter_glob)); + BLI_strncpy_ensure_pad(filelist->filter_data.filter_search, filter_search, '*', + sizeof(filelist->filter_data.filter_search)); + /* And now, free filtered data so that we now we have to filter again. */ filelist_filter_clear(filelist); } } diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index f2b03c059f2..797d54a89b1 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -74,7 +74,8 @@ bool filelist_need_sorting(struct FileList *filelist); void filelist_sort(struct FileList *filelist); void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent, - const unsigned int filter, const char *filter_glob); + const unsigned int filter, + const char *filter_glob, const char *filter_search); void filelist_filter(struct FileList *filelist); void filelist_init_icons(void); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 3f21e561546..76d3746c3d9 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -205,7 +205,8 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa)) filelist_setfilter_options(sfile->files, params->flag & FILE_HIDE_DOT, false, /* TODO hide_parent, should be controllable? */ params->flag & FILE_FILTER ? params->filter : 0, - params->filter_glob); + params->filter_glob, + params->filter_search); if (filelist_empty(sfile->files)) { thumbnails_stop(wm, sfile->files); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 339b232f8a0..d7cfd361b9b 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -585,6 +585,8 @@ typedef struct FileSelectParams { char filter_glob[64]; /* list of filetypes to filter */ + char filter_search[64]; /* text items' name must match to be shown. */ + int active_file; int sel_first; int sel_last; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 72fd7bf7909..49275b15488 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3290,6 +3290,11 @@ static void rna_def_fileselect_params(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Extension Filter", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL); + prop = RNA_def_property(srna, "filter_search", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "filter_search"); + RNA_def_property_ui_text(prop, "Name Filter", "Filter by name, supports '*' wilcard"); + RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } static void rna_def_space_filebrowser(BlenderRNA *brna)