Changeset View
Standalone View
source/blender/editors/space_file/filesel.c
| Show First 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | if (op) { | ||||
| } | } | ||||
| else { | else { | ||||
| params->flag &= ~FILE_DIRSEL_ONLY; | params->flag &= ~FILE_DIRSEL_ONLY; | ||||
| } | } | ||||
| params->filter = 0; | params->filter = 0; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) | if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) | ||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0; | params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_blenlib"))) | |||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDERLIB : 0; | |||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_backup"))) | if ((prop = RNA_struct_find_property(op->ptr, "filter_backup"))) | ||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0; | params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_image"))) | if ((prop = RNA_struct_find_property(op->ptr, "filter_image"))) | ||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0; | params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_movie"))) | if ((prop = RNA_struct_find_property(op->ptr, "filter_movie"))) | ||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0; | params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "filter_python"))) | if ((prop = RNA_struct_find_property(op->ptr, "filter_python"))) | ||||
| params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0; | params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0; | ||||
| Show All 21 Lines | if (params->filter != 0) { | ||||
| if (U.uiflag & USER_FILTERFILEEXTS) { | if (U.uiflag & USER_FILTERFILEEXTS) { | ||||
| params->flag |= FILE_FILTER; | params->flag |= FILE_FILTER; | ||||
| } | } | ||||
| else { | else { | ||||
| params->flag &= ~FILE_FILTER; | params->flag &= ~FILE_FILTER; | ||||
| } | } | ||||
| } | } | ||||
| /* For now, always init filterid to 'all true' */ | |||||
| params->filter_id = FILTER_ID_AC | FILTER_ID_AR | FILTER_ID_BR | FILTER_ID_CA | FILTER_ID_CU | FILTER_ID_GD | | |||||
sergey: Do we really need that granularity level for filtering?
We had really similar discussion in… | |||||
Not Done Inline ActionsIts a tricky one - but think it could be worth not hard-coding in filter categories. Asset browsers are going to have to their own kinds of categories anyway. Couldn't there be a more generic tagging system? (so browsing blend files loads in one set of tags that can be swapped out for other kinds of asset browsers). Tags (asset categories) can have icons, descriptions for tooltips. Think it could be better not to include the filtering code in this patch. Then add some filtering/tagging system separately. campbellbarton: Its a tricky one - but think it could be worth not hard-coding in filter categories.
Asset… | |||||
Not Done Inline ActionsI would not add tagging system to 'simple' filebrowser. Asset Engines are responsible of filtering and sorting items anyway, so they handle this themselves (Amber does have tag system in asset-engine branch, e.g.). And adding this to core filebrowser would mean we need to store those tags in .blend file, with a way to edit them, and then read them while listing datablocks in file, etc. Would really want to keep 'basic mode' as simple as possible. However, a way to sort datablocks by type is mandatory if we want flat view, otherwise your fileview explode under brushes and other 'useless' IDs like that. So if we really do not want a per-ID filtering, I’d rather follow Sergey's idea and define more 'global' filter types (we'd still need per-ID values internally anyway), something like that:
mont29: I would not add tagging system to 'simple' filebrowser. Asset Engines are responsible of… | |||||
| FILTER_ID_GR | FILTER_ID_IM | FILTER_ID_LA | FILTER_ID_LS | FILTER_ID_LT | FILTER_ID_MA | | |||||
| FILTER_ID_MB | FILTER_ID_MC | FILTER_ID_ME | FILTER_ID_MSK | FILTER_ID_NT | FILTER_ID_OB | | |||||
| FILTER_ID_PAL | FILTER_ID_PC | FILTER_ID_SCE | FILTER_ID_SPK | FILTER_ID_SO | FILTER_ID_TE | | |||||
| FILTER_ID_TXT | FILTER_ID_VF | FILTER_ID_WO; | |||||
| if (U.uiflag & USER_HIDE_DOT) { | if (U.uiflag & USER_HIDE_DOT) { | ||||
| params->flag |= FILE_HIDE_DOT; | params->flag |= FILE_HIDE_DOT; | ||||
| } | } | ||||
| else { | else { | ||||
| params->flag &= ~FILE_HIDE_DOT; | params->flag &= ~FILE_HIDE_DOT; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | #if 0 | ||||
| return style->widget.points; | return style->widget.points; | ||||
| #else | #else | ||||
| uiStyle *style = UI_style_get(); | uiStyle *style = UI_style_get(); | ||||
| UI_fontstyle_set(&style->widget); | UI_fontstyle_set(&style->widget); | ||||
| return style->widget.points * UI_DPI_FAC; | return style->widget.points * UI_DPI_FAC; | ||||
| #endif | #endif | ||||
| } | } | ||||
| static void column_widths(struct FileList *files, struct FileLayout *layout) | static void column_widths(FileSelectParams *params, struct FileLayout *layout) | ||||
| { | { | ||||
| int i; | int i; | ||||
| int numfiles = filelist_numfiles(files); | const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size); | ||||
| for (i = 0; i < MAX_FILE_COLUMN; ++i) { | for (i = 0; i < MAX_FILE_COLUMN; ++i) { | ||||
| layout->column_widths[i] = 0; | layout->column_widths[i] = 0; | ||||
| } | } | ||||
| for (i = 0; (i < numfiles); ++i) { | layout->column_widths[COLUMN_NAME] = ((float)params->thumbnail_size / 8.0f) * UI_UNIT_X;; | ||||
| struct direntry *file = filelist_file(files, i); | /* Biggest possible reasonable values... */ | ||||
| if (file) { | layout->column_widths[COLUMN_DATE] = file_string_width(small_size ? "23/08/89" : "23-Dec-89"); | ||||
| float len; | layout->column_widths[COLUMN_TIME] = file_string_width("23:59"); | ||||
| len = file_string_width(file->relname); | layout->column_widths[COLUMN_SIZE] = file_string_width(small_size ? "98.7 M" : "98.7 MiB"); | ||||
| if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len; | |||||
| len = file_string_width(file->date); | |||||
| if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len; | |||||
| len = file_string_width(file->time); | |||||
| if (len > layout->column_widths[COLUMN_TIME]) layout->column_widths[COLUMN_TIME] = len; | |||||
| len = file_string_width(file->size); | |||||
| if (len > layout->column_widths[COLUMN_SIZE]) layout->column_widths[COLUMN_SIZE] = len; | |||||
| len = file_string_width(file->mode1); | |||||
| if (len > layout->column_widths[COLUMN_MODE1]) layout->column_widths[COLUMN_MODE1] = len; | |||||
| len = file_string_width(file->mode2); | |||||
| if (len > layout->column_widths[COLUMN_MODE2]) layout->column_widths[COLUMN_MODE2] = len; | |||||
| len = file_string_width(file->mode3); | |||||
| if (len > layout->column_widths[COLUMN_MODE3]) layout->column_widths[COLUMN_MODE3] = len; | |||||
| len = file_string_width(file->owner); | |||||
| if (len > layout->column_widths[COLUMN_OWNER]) layout->column_widths[COLUMN_OWNER] = len; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar) | void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar) | ||||
| { | { | ||||
| FileSelectParams *params = ED_fileselect_get_params(sfile); | FileSelectParams *params = ED_fileselect_get_params(sfile); | ||||
| FileLayout *layout = NULL; | FileLayout *layout = NULL; | ||||
| View2D *v2d = &ar->v2d; | View2D *v2d = &ar->v2d; | ||||
| int maxlen = 0; | int maxlen = 0; | ||||
| int numfiles; | int numfiles; | ||||
| int textheight; | int textheight; | ||||
| if (sfile->layout == NULL) { | if (sfile->layout == NULL) { | ||||
| sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout"); | sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout"); | ||||
| sfile->layout->dirty = true; | sfile->layout->dirty = true; | ||||
| } | } | ||||
| else if (sfile->layout->dirty == false) { | else if (sfile->layout->dirty == false) { | ||||
| return; | return; | ||||
| } | } | ||||
| numfiles = filelist_numfiles(sfile->files); | numfiles = filelist_files_ensure(sfile->files); | ||||
| textheight = (int)file_font_pointsize(); | textheight = (int)file_font_pointsize(); | ||||
| layout = sfile->layout; | layout = sfile->layout; | ||||
| layout->textheight = textheight; | layout->textheight = textheight; | ||||
| if (params->display == FILE_IMGDISPLAY) { | if (params->display == FILE_IMGDISPLAY) { | ||||
| layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X; | layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X; | ||||
| layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y; | layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y; | ||||
| layout->tile_border_x = 0.3f * UI_UNIT_X; | layout->tile_border_x = 0.3f * UI_UNIT_X; | ||||
| Show All 22 Lines | else { | ||||
| layout->tile_border_x = 0.4f * UI_UNIT_X; | layout->tile_border_x = 0.4f * UI_UNIT_X; | ||||
| layout->tile_border_y = 0.1f * UI_UNIT_Y; | layout->tile_border_y = 0.1f * UI_UNIT_Y; | ||||
| layout->prv_border_x = 0; | layout->prv_border_x = 0; | ||||
| layout->prv_border_y = 0; | layout->prv_border_y = 0; | ||||
| layout->tile_h = textheight * 3 / 2; | layout->tile_h = textheight * 3 / 2; | ||||
| layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y); | layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y); | ||||
| layout->rows = layout->height / (layout->tile_h + 2 * layout->tile_border_y); | layout->rows = layout->height / (layout->tile_h + 2 * layout->tile_border_y); | ||||
| column_widths(sfile->files, layout); | column_widths(params, layout); | ||||
| if (params->display == FILE_SHORTDISPLAY) { | if (params->display == FILE_SHORTDISPLAY) { | ||||
| maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space + | maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space + | ||||
| (int)layout->column_widths[COLUMN_NAME] + column_space + | (int)layout->column_widths[COLUMN_NAME] + column_space + | ||||
| (int)layout->column_widths[COLUMN_SIZE] + column_space; | (int)layout->column_widths[COLUMN_SIZE] + column_space; | ||||
| } | } | ||||
| else { | else { | ||||
| maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space + | maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space + | ||||
| (int)layout->column_widths[COLUMN_NAME] + column_space + | (int)layout->column_widths[COLUMN_NAME] + column_space + | ||||
| #ifndef WIN32 | |||||
| (int)layout->column_widths[COLUMN_MODE1] + column_space + | |||||
| (int)layout->column_widths[COLUMN_MODE2] + column_space + | |||||
| (int)layout->column_widths[COLUMN_MODE3] + column_space + | |||||
| (int)layout->column_widths[COLUMN_OWNER] + column_space + | |||||
| #endif | |||||
| (int)layout->column_widths[COLUMN_DATE] + column_space + | (int)layout->column_widths[COLUMN_DATE] + column_space + | ||||
| (int)layout->column_widths[COLUMN_TIME] + column_space + | (int)layout->column_widths[COLUMN_TIME] + column_space + | ||||
| (int)layout->column_widths[COLUMN_SIZE] + column_space; | (int)layout->column_widths[COLUMN_SIZE] + column_space; | ||||
| } | } | ||||
| layout->tile_w = maxlen; | layout->tile_w = maxlen; | ||||
| if (layout->rows > 0) | if (layout->rows > 0) | ||||
| layout->columns = numfiles / layout->rows + 1; // XXX dirty, modulo is zero | layout->columns = numfiles / layout->rows + 1; // XXX dirty, modulo is zero | ||||
| Show All 14 Lines | FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar) | ||||
| } | } | ||||
| return sfile->layout; | return sfile->layout; | ||||
| } | } | ||||
| void ED_file_change_dir(bContext *C, const bool checkdir) | void ED_file_change_dir(bContext *C, const bool checkdir) | ||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | SpaceFile *sfile = CTX_wm_space_file(C); | ||||
| ScrArea *sa = CTX_wm_area(C); | |||||
| if (sfile->params) { | if (sfile->params) { | ||||
| ED_fileselect_clear(wm, sfile); | ED_fileselect_clear(wm, sa, sfile); | ||||
| /* Clear search string, it is very rare to want to keep that filter while changing dir, | /* Clear search string, it is very rare to want to keep that filter while changing dir, | ||||
| * and usually very annoying to keep it actually! */ | * and usually very annoying to keep it actually! */ | ||||
| sfile->params->filter_search[0] = '\0'; | sfile->params->filter_search[0] = '\0'; | ||||
| if (checkdir && !BLI_is_dir(sfile->params->dir)) { | if (checkdir && !BLI_is_dir(sfile->params->dir)) { | ||||
| BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); | BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); | ||||
| /* could return but just refresh the current dir */ | /* could return but just refresh the current dir */ | ||||
| Show All 9 Lines | void ED_file_change_dir(bContext *C, const bool checkdir) | ||||
| } | } | ||||
| } | } | ||||
| int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file) | int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file) | ||||
| { | { | ||||
| int match = 0; | int match = 0; | ||||
| int i; | int i; | ||||
| struct direntry *file; | FileDirEntry *file; | ||||
| int n = filelist_numfiles(sfile->files); | int n = filelist_files_ensure(sfile->files); | ||||
| /* select any file that matches the pattern, this includes exact match | /* select any file that matches the pattern, this includes exact match | ||||
| * if the user selects a single file by entering the filename | * if the user selects a single file by entering the filename | ||||
| */ | */ | ||||
| for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | ||||
| file = filelist_file(sfile->files, i); | file = filelist_file(sfile->files, i); | ||||
| /* Do not check wether file is a file or dir here! Causes T44243 (we do accept dirs at this stage). */ | /* Do not check wether file is a file or dir here! Causes T44243 (we do accept dirs at this stage). */ | ||||
| if (fnmatch(pattern, file->relname, 0) == 0) { | if (fnmatch(pattern, file->relpath, 0) == 0) { | ||||
| file->selflag |= FILE_SEL_SELECTED; | filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); | ||||
| if (!match) { | if (!match) { | ||||
| BLI_strncpy(matched_file, file->relname, FILE_MAX); | BLI_strncpy(matched_file, file->relpath, FILE_MAX); | ||||
| } | } | ||||
| match++; | match++; | ||||
| } | } | ||||
| } | } | ||||
| return match; | return match; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
| int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) | int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) | ||||
| { | { | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | SpaceFile *sfile = CTX_wm_space_file(C); | ||||
| int match = AUTOCOMPLETE_NO_MATCH; | int match = AUTOCOMPLETE_NO_MATCH; | ||||
| /* search if str matches the beginning of name */ | /* search if str matches the beginning of name */ | ||||
| if (str[0] && sfile->files) { | if (str[0] && sfile->files) { | ||||
| AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); | AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); | ||||
| int nentries = filelist_numfiles(sfile->files); | int nentries = filelist_files_ensure(sfile->files); | ||||
| int i; | int i; | ||||
| for (i = 0; i < nentries; ++i) { | for (i = 0; i < nentries; ++i) { | ||||
| struct direntry *file = filelist_file(sfile->files, i); | FileDirEntry *file = filelist_file(sfile->files, i); | ||||
| if (file && (S_ISREG(file->type) || S_ISDIR(file->type))) { | UI_autocomplete_update_name(autocpl, file->relpath); | ||||
| UI_autocomplete_update_name(autocpl, file->relname); | |||||
| } | |||||
| } | } | ||||
| match = UI_autocomplete_end(autocpl, str); | match = UI_autocomplete_end(autocpl, str); | ||||
| } | } | ||||
| return match; | return match; | ||||
| } | } | ||||
| void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile) | void ED_fileselect_clear(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) | ||||
| { | { | ||||
| /* only NULL in rare cases - [#29734] */ | /* only NULL in rare cases - [#29734] */ | ||||
| if (sfile->files) { | if (sfile->files) { | ||||
| thumbnails_stop(wm, sfile->files); | filelist_readjob_stop(wm, sa); | ||||
| filelist_freelib(sfile->files); | filelist_freelib(sfile->files); | ||||
| filelist_free(sfile->files); | filelist_clear(sfile->files); | ||||
| } | } | ||||
| sfile->params->highlight_file = -1; | sfile->params->highlight_file = -1; | ||||
| WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL); | WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL); | ||||
| } | } | ||||
| void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile) | void ED_fileselect_exit(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) | ||||
| { | { | ||||
| if (!sfile) return; | if (!sfile) return; | ||||
| if (sfile->op) { | if (sfile->op) { | ||||
| WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL); | WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL); | ||||
| sfile->op = NULL; | sfile->op = NULL; | ||||
| } | } | ||||
| folderlist_free(sfile->folders_prev); | folderlist_free(sfile->folders_prev); | ||||
| folderlist_free(sfile->folders_next); | folderlist_free(sfile->folders_next); | ||||
| if (sfile->files) { | if (sfile->files) { | ||||
| ED_fileselect_clear(wm, sfile); | ED_fileselect_clear(wm, sa, sfile); | ||||
| filelist_free(sfile->files); | |||||
| MEM_freeN(sfile->files); | MEM_freeN(sfile->files); | ||||
| sfile->files = NULL; | sfile->files = NULL; | ||||
| } | } | ||||
| } | } | ||||
Do we really need that granularity level for filtering?
We had really similar discussion in the outliner filtering task, and the agreed way to go there was to use less granular filter flags (like Shading, Geometry, Light).