Page MenuHome
Paste P2103

(An Untitled Masterwork)
ActivePublic

Authored by Germano Cavalcante (mano-wii) on May 4 2021, 6:28 PM.
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index d0d63192ebf..8dbecc75c1f 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1715,7 +1715,6 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
*/
sfile->folders_prev = sfile->folders_next = NULL;
BLI_listbase_clear(&sfile->folder_histories);
- sfile->files = NULL;
sfile->layout = NULL;
sfile->op = NULL;
sfile->previews_timer = NULL;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index c1dcf2e56d3..8c7b2d9f476 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -110,7 +110,7 @@ void ED_file_path_button(bScreen *screen,
/* TODO, directory editing is non-functional while a library is loaded
* until this is properly supported just disable it. */
- if (sfile && sfile->files && filelist_lib(sfile->files)) {
+ if (sfile && sfile->runtime && sfile->runtime->files && filelist_lib(sfile->runtime->files)) {
UI_but_flag_enable(but, UI_BUT_DISABLED);
}
@@ -796,7 +796,7 @@ void file_draw_list(const bContext *C, ARegion *region)
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
View2D *v2d = &region->v2d;
- struct FileList *files = sfile->files;
+ struct FileList *files = sfile->runtime->files;
struct FileDirEntry *file;
const char *root = filelist_dir(files);
ImBuf *imb;
@@ -888,7 +888,7 @@ void file_draw_list(const bContext *C, ARegion *region)
sy = (int)(v2d->tot.ymax - sy);
file = filelist_file(files, i);
- file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
+ file_selflag = filelist_entry_select_get(files, file, CHECK_ALL);
BLI_join_dirfile(path, sizeof(path), root, file->relpath);
@@ -977,7 +977,7 @@ void file_draw_list(const bContext *C, ARegion *region)
UI_but_flag_disable(but, UI_BUT_UNDO);
if (false == UI_but_active_only(C, region, block, but)) {
file_selflag = filelist_entry_select_set(
- sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
+ files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
}
}
@@ -1066,7 +1066,7 @@ bool file_draw_hint_if_invalid(const SpaceFile *sfile, const ARegion *region)
}
/* Check if the library exists. */
if ((asset_params->asset_library.type == FILE_ASSET_LIBRARY_LOCAL) ||
- filelist_is_dir(sfile->files, asset_params->base_params.dir)) {
+ filelist_is_dir(sfile->runtime->files, asset_params->base_params.dir)) {
return false;
}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 309b280177c..150ad81ce95 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -116,6 +116,12 @@ void file_params_renamefile_activate(struct SpaceFile *sfile, struct FileSelectP
typedef void *onReloadFnData;
typedef void (*onReloadFn)(struct SpaceFile *space_data, onReloadFnData custom_data);
typedef struct SpaceFile_Runtime {
+ /**
+ * Holds the list of files to show.
+ * Currently recreated when browse-mode changes. Could be per browse-mode to avoid refreshes.
+ */
+ struct FileList *files;
+
/* Called once after the file browser has reloaded. Reset to NULL after calling.
* Use file_on_reload_callback_register() to register a callback. */
onReloadFn on_reload;
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 856bd5b1bc3..c8f64111b6c 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -106,11 +106,13 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile,
static void file_deselect_all(SpaceFile *sfile, uint flag)
{
+ struct FileList *filelist = sfile->runtime->files;
+
FileSelection sel;
sel.first = 0;
- sel.last = filelist_files_ensure(sfile->files) - 1;
+ sel.last = filelist_files_ensure(filelist) - 1;
- filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
+ filelist_entries_select_index_range_set(filelist, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
}
typedef enum FileSelect {
@@ -149,7 +151,8 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- int numfiles = filelist_files_ensure(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ int numfiles = filelist_files_ensure(filelist);
FileSelection sel;
sel = find_file_mouse_rect(sfile, region, rect);
@@ -162,7 +165,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
int f;
/* Try to find a smaller-index selected item. */
for (f = sel.last; f >= 0; f--) {
- if (filelist_entry_select_index_get(sfile->files, f, CHECK_ALL)) {
+ if (filelist_entry_select_index_get(filelist, f, CHECK_ALL)) {
break;
}
}
@@ -172,7 +175,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
/* If none found, try to find a higher-index selected item. */
else {
for (f = sel.first; f < numfiles; f++) {
- if (filelist_entry_select_index_get(sfile->files, f, CHECK_ALL)) {
+ if (filelist_entry_select_index_get(filelist, f, CHECK_ALL)) {
break;
}
}
@@ -189,13 +192,14 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
Main *bmain = CTX_data_main(C);
FileSelect retval = FILE_SELECT_NOTHING;
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- int numfiles = filelist_files_ensure(sfile->files);
+ int numfiles = filelist_files_ensure(filelist);
const FileDirEntry *file;
/* make the selected file active */
if ((selected_idx >= 0) && (selected_idx < numfiles) &&
- (file = filelist_file(sfile->files, selected_idx))) {
+ (file = filelist_file(filelist, selected_idx))) {
params->highlight_file = selected_idx;
params->active_file = selected_idx;
@@ -217,7 +221,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
params->recursion_level = 0;
- filelist_setrecursion(sfile->files, params->recursion_level);
+ filelist_setrecursion(filelist, params->recursion_level);
}
}
else {
@@ -348,14 +352,14 @@ static FileSelect file_select(
bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen)
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelect retval = FILE_SELECT_NOTHING;
FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */
const FileCheckType check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
/* flag the files as selected in the filelist */
- filelist_entries_select_index_range_set(
- sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
+ filelist_entries_select_index_range_set(filelist, &sel, select, FILE_SEL_SELECTED, check_type);
/* Don't act on multiple selected files */
if (sel.first != sel.last) {
@@ -365,12 +369,12 @@ static FileSelect file_select(
/* Do we have a valid selection and are we actually selecting */
if ((sel.last >= 0) && (select != FILE_SEL_REMOVE)) {
/* Check last selection, if selected, act on the file or dir */
- if (filelist_entry_select_index_get(sfile->files, sel.last, check_type)) {
+ if (filelist_entry_select_index_get(filelist, sel.last, check_type)) {
retval = file_select_do(C, sel.last, do_diropen);
}
}
- if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files)) {
+ if (select != FILE_SEL_ADD && !file_is_any_selected(filelist)) {
params->active_file = -1;
}
else if (sel.last >= 0) {
@@ -427,6 +431,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
rcti rect;
@@ -446,16 +451,16 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
filelist_entries_select_index_range_set(
- sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
+ filelist, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
for (idx = sel.last; idx >= 0; idx--) {
- const FileDirEntry *file = filelist_file(sfile->files, idx);
+ const FileDirEntry *file = filelist_file(filelist, idx);
/* Don't highlight read-only file (".." or ".") on box select. */
if (FILENAME_IS_CURRPAR(file->relpath)) {
filelist_entry_select_set(
- sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
+ filelist, file, FILE_SEL_REMOVE, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
}
/* make sure highlight_file is no readonly file */
@@ -483,6 +488,7 @@ static int file_box_select_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
rcti rect;
FileSelect ret;
@@ -500,7 +506,7 @@ static int file_box_select_exec(bContext *C, wmOperator *op)
/* unselect '..' parent entry - it's not supposed to be selected if more than
* one file is selected */
- filelist_entry_parent_select_set(sfile->files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
+ filelist_entry_parent_select_set(filelist, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
if (FILE_SELECT_DIR == ret) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -540,6 +546,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelect ret;
rcti rect;
const bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -561,7 +568,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (sfile && params) {
int idx = params->highlight_file;
- int numfiles = filelist_files_ensure(sfile->files);
+ int numfiles = filelist_files_ensure(filelist);
if ((idx >= 0) && (idx < numfiles)) {
/* single select, deselect all selected first */
@@ -576,7 +583,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (extend) {
/* unselect '..' parent entry - it's not supposed to be selected if more
* than one file is selected */
- filelist_entry_parent_select_set(sfile->files, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
+ filelist_entry_parent_select_set(filelist, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
}
if (ret == FILE_SELECT_NOTHING) {
@@ -652,7 +659,7 @@ static bool file_walk_select_selection_set(wmWindow *win,
const bool fill)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- struct FileList *files = sfile->files;
+ struct FileList *files = sfile->runtime->files;
const int last_sel = params->active_file; /* store old value */
int active = active_old; /* could use active_old instead, just for readability */
bool deselect = false;
@@ -766,7 +773,7 @@ static bool file_walk_select_do(bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
- struct FileList *files = sfile->files;
+ struct FileList *files = sfile->runtime->files;
const int numfiles = filelist_files_ensure(files);
const bool has_selection = file_is_any_selected(files);
const int active_old = params->active_file;
@@ -891,13 +898,14 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
- const int numfiles = filelist_files_ensure(sfile->files);
+ const int numfiles = filelist_files_ensure(filelist);
int action = RNA_enum_get(op->ptr, "action");
if (action == SEL_TOGGLE) {
- action = file_is_any_selected(sfile->files) ? SEL_DESELECT : SEL_SELECT;
+ action = file_is_any_selected(filelist) ? SEL_DESELECT : SEL_SELECT;
}
sel.first = 0;
@@ -925,12 +933,12 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
}
filelist_entries_select_index_range_set(
- sfile->files, &sel, filesel_type, FILE_SEL_SELECTED, check_type);
+ filelist, &sel, filesel_type, FILE_SEL_SELECTED, check_type);
params->active_file = -1;
if (action != SEL_DESELECT) {
for (int i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, check_type)) {
+ if (filelist_entry_select_index_get(filelist, i, check_type)) {
params->active_file = i;
break;
}
@@ -968,7 +976,8 @@ void FILE_OT_select_all(wmOperatorType *ot)
static int file_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelection sel = file_current_selection_range_get(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ FileSelection sel = file_current_selection_range_get(filelist);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (sel.first == -1 && sel.last == -1 && params->active_file == -1) {
@@ -1354,15 +1363,17 @@ void FILE_OT_reset_recent(wmOperatorType *ot)
int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my)
{
+ struct FileList *filelist = sfile->runtime->files;
+
View2D *v2d = &region->v2d;
FileSelectParams *params;
int numfiles, origfile;
- if (sfile == NULL || sfile->files == NULL) {
+ if (sfile == NULL || filelist == NULL) {
return 0;
}
- numfiles = filelist_files_ensure(sfile->files);
+ numfiles = filelist_files_ensure(filelist);
params = ED_fileselect_get_active_params(sfile);
origfile = params->highlight_file;
@@ -1549,15 +1560,16 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
/* this is called on operators check() so clear collections first since
* they may be already set. */
{
- int i, numfiles = filelist_files_ensure(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ int i, numfiles = filelist_files_ensure(filelist);
if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
PointerRNA itemptr;
int num_files = 0;
RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
- FileDirEntry *file = filelist_file(sfile->files, i);
+ if (filelist_entry_select_index_get(filelist, i, CHECK_FILES)) {
+ FileDirEntry *file = filelist_file(filelist, i);
/* Cannot (currently) mix regular items and alias/shortcuts in multiple selection. */
if (!file->redirection_path) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
@@ -1579,8 +1591,8 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
int num_dirs = 0;
RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_DIRS)) {
- FileDirEntry *file = filelist_file(sfile->files, i);
+ if (filelist_entry_select_index_get(filelist, i, CHECK_DIRS)) {
+ FileDirEntry *file = filelist_file(filelist, i);
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relpath);
num_dirs++;
@@ -1716,8 +1728,9 @@ static int file_exec(bContext *C, wmOperator *exec_op)
Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- struct FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ struct FileDirEntry *file = filelist_file(filelist, params->active_file);
char filepath[FILE_MAX];
if (file && file->redirection_path) {
@@ -1756,11 +1769,11 @@ static int file_exec(bContext *C, wmOperator *exec_op)
/* When used as a macro, for double-click, to prevent closing when double-clicking on item. */
if (RNA_boolean_get(exec_op->ptr, "need_active")) {
- const int numfiles = filelist_files_ensure(sfile->files);
+ const int numfiles = filelist_files_ensure(filelist);
int i, active = 0;
for (i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
+ if (filelist_entry_select_index_get(filelist, i, CHECK_ALL)) {
active = 1;
break;
}
@@ -1890,7 +1903,7 @@ static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
params->recursion_level = 0;
- filelist_setrecursion(sfile->files, params->recursion_level);
+ filelist_setrecursion(sfile->runtime->files, params->recursion_level);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -1993,6 +2006,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
ARegion *region, *region_ctx = CTX_wm_region(C);
const bool is_horizontal = (sfile->layout->flag & FILE_LAYOUT_HOR) != 0;
int i;
@@ -2002,7 +2016,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
return OPERATOR_PASS_THROUGH;
}
- const int numfiles = filelist_files_ensure(sfile->files);
+ const int numfiles = filelist_files_ensure(filelist);
/* Due to async nature of file listing, we may execute this code before `file_refresh()`
* editing entry is available in our listing,
@@ -2016,7 +2030,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
/* check if we are editing a name */
int edit_idx = -1;
for (i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL) &
+ if (filelist_entry_select_index_get(filelist, i, CHECK_ALL) &
(FILE_SEL_EDITING | FILE_SEL_HIGHLIGHTED)) {
edit_idx = i;
break;
@@ -2078,7 +2092,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
/* Check if we have reached our final scroll position. */
/* Filelist has to be ready, otherwise it makes no sense to stop scrolling yet. */
- const bool is_ready = filelist_is_ready(sfile->files);
+ const bool is_ready = filelist_is_ready(filelist);
/* Edited item must be in the 'middle' of shown area (kind of approximated).
* Note that we have to do the check in 'block space', not in 'item space' here. */
const bool is_centered = (abs(middle_offset / items_block_size -
@@ -2426,6 +2440,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
@@ -2436,7 +2451,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
file_expand_directory(C);
/* special case, user may have pasted a filepath into the directory */
- if (!filelist_is_dir(sfile->files, params->dir)) {
+ if (!filelist_is_dir(filelist, params->dir)) {
char tdir[FILE_MAX_LIBEXTRA];
char *group, *name;
@@ -2462,7 +2477,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
- if (filelist_is_dir(sfile->files, params->dir)) {
+ if (filelist_is_dir(filelist, params->dir)) {
if (!STREQ(params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */
/* if directory exists, enter it immediately */
ED_file_change_dir(C);
@@ -2516,6 +2531,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
uiBut *but = arg_but;
char matched_file[FILE_MAX];
@@ -2545,7 +2561,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
BLI_join_dirfile(filepath, sizeof(params->dir), params->dir, params->file);
/* if directory, open it and empty filename field */
- if (filelist_is_dir(sfile->files, filepath)) {
+ if (filelist_is_dir(filelist, filepath)) {
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath);
BLI_strncpy(params->dir, filepath, sizeof(params->dir));
params->file[0] = '\0';
@@ -2683,17 +2699,18 @@ void FILE_OT_filenum(struct wmOperatorType *ot)
static void file_rename_state_activate(SpaceFile *sfile, int file_idx, bool require_selected)
{
- const int numfiles = filelist_files_ensure(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ const int numfiles = filelist_files_ensure(filelist);
if ((file_idx >= 0) && (file_idx < numfiles)) {
- FileDirEntry *file = filelist_file(sfile->files, file_idx);
+ FileDirEntry *file = filelist_file(filelist, file_idx);
if ((require_selected == false) ||
- (filelist_entry_select_get(sfile->files, file, CHECK_ALL) & FILE_SEL_SELECTED)) {
+ (filelist_entry_select_get(filelist, file, CHECK_ALL) & FILE_SEL_SELECTED)) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
filelist_entry_select_index_set(
- sfile->files, file_idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
+ filelist, file_idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
BLI_strncpy(params->renamefile, file->relpath, FILE_MAXFILE);
/* We can skip the pending state,
* as we can directly set FILE_SEL_EDITING on the expected entry here. */
@@ -2757,15 +2774,16 @@ static bool file_delete_poll(bContext *C)
if (sfile && params) {
char dir[FILE_MAX_LIBEXTRA];
- int numfiles = filelist_files_ensure(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ int numfiles = filelist_files_ensure(filelist);
int i;
int num_selected = 0;
- if (filelist_islibrary(sfile->files, dir, NULL)) {
+ if (filelist_islibrary(filelist, dir, NULL)) {
poll = 0;
}
for (i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
+ if (filelist_entry_select_index_get(filelist, i, CHECK_ALL)) {
num_selected++;
}
}
@@ -2807,15 +2825,16 @@ static int file_delete_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- int numfiles = filelist_files_ensure(sfile->files);
+ int numfiles = filelist_files_ensure(filelist);
const char *error_message = NULL;
bool report_error = false;
errno = 0;
for (int i = 0; i < numfiles; i++) {
- if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
- FileDirEntry *file = filelist_file(sfile->files, i);
+ if (filelist_entry_select_index_get(filelist, i, CHECK_ALL)) {
+ FileDirEntry *file = filelist_file(filelist, i);
if (!file_delete_single(params, file, &error_message)) {
report_error = true;
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 038b9c11bca..a9f261eee6b 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -461,7 +461,7 @@ struct ID *ED_fileselect_active_asset_get(const SpaceFile *sfile)
}
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ const FileDirEntry *file = filelist_file(sfile->runtime->files, params->active_file);
if (file == NULL) {
return NULL;
}
@@ -484,7 +484,8 @@ void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool def
/* If there are filelist operations running now ("pending" true) or soon ("force reset" true),
* there is a fair chance that the to-be-activated ID will only be present after these operations
* have completed. Defer activation until then. */
- if (deferred || filelist_pending(sfile->files) || filelist_needs_force_reset(sfile->files)) {
+ struct FileList *files = sfile->runtime->files;
+ if (deferred || filelist_pending(files) || filelist_needs_force_reset(files)) {
/* This should be thread-safe, as this function is likely called from the main thread, and
* notifiers (which cause a call to the on-reload callback function) are handled on the main
* thread as well. */
@@ -493,7 +494,6 @@ void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool def
}
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- struct FileList *files = sfile->files;
const int num_files_filtered = filelist_files_ensure(files);
for (int file_index = 0; file_index < num_files_filtered; ++file_index) {
@@ -624,7 +624,7 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
*/
void fileselect_file_set(SpaceFile *sfile, const int index)
{
- const struct FileDirEntry *file = filelist_file(sfile->files, index);
+ const struct FileDirEntry *file = filelist_file(sfile->runtime->files, index);
if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
BLI_strncpy(params->file, file->relpath, FILE_MAXFILE);
@@ -953,7 +953,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region)
return;
}
- numfiles = filelist_files_ensure(sfile->files);
+ numfiles = filelist_files_ensure(sfile->runtime->files);
textheight = (int)file_font_pointsize();
layout = sfile->layout;
layout->textheight = textheight;
@@ -1066,11 +1066,12 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
params->filter_search[0] = '\0';
params->active_file = -1;
- if (!filelist_is_dir(sfile->files, params->dir)) {
- BLI_strncpy(params->dir, filelist_dir(sfile->files), sizeof(params->dir));
+ struct FileList *filelist = sfile->runtime->files;
+ if (!filelist_is_dir(filelist, params->dir)) {
+ BLI_strncpy(params->dir, filelist_dir(filelist), sizeof(params->dir));
/* could return but just refresh the current dir */
}
- filelist_setdir(sfile->files, params->dir);
+ filelist_setdir(filelist, params->dir);
if (folderlist_clear_next(sfile)) {
folderlist_free(sfile->folders_next);
@@ -1092,18 +1093,19 @@ void ED_file_change_dir(bContext *C)
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
{
int match = 0;
+ struct FileList *filelist = sfile->runtime->files;
- int n = filelist_files_ensure(sfile->files);
+ int n = filelist_files_ensure(filelist);
/* select any file that matches the pattern, this includes exact match
* if the user selects a single file by entering the filename
*/
for (int i = 0; i < n; i++) {
- FileDirEntry *file = filelist_file(sfile->files, i);
+ FileDirEntry *file = filelist_file(filelist, i);
/* Do not check whether file is a file or dir here! Causes T44243
* (we do accept dirs at this stage). */
if (fnmatch(pattern, file->relpath, 0) == 0) {
- filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
+ filelist_entry_select_set(filelist, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
if (!match) {
BLI_strncpy(matched_file, file->relpath, FILE_MAX);
}
@@ -1120,7 +1122,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
int match = AUTOCOMPLETE_NO_MATCH;
/* search if str matches the beginning of name */
- if (str[0] && sfile->files) {
+ if (str[0] && sfile->runtime->files) {
char dirname[FILE_MAX];
DIR *dir;
@@ -1165,15 +1167,16 @@ int autocomplete_directory(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);
+ struct FileList *filelist = sfile->runtime->files;
int match = AUTOCOMPLETE_NO_MATCH;
/* search if str matches the beginning of name */
- if (str[0] && sfile->files) {
+ if (str[0] && filelist) {
AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX);
- int nentries = filelist_files_ensure(sfile->files);
+ int nentries = filelist_files_ensure(filelist);
for (int i = 0; i < nentries; i++) {
- FileDirEntry *file = filelist_file(sfile->files, i);
+ FileDirEntry *file = filelist_file(filelist, i);
UI_autocomplete_update_name(autocpl, file->relpath);
}
match = UI_autocomplete_end(autocpl, str);
@@ -1184,11 +1187,12 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
{
+ struct FileList *filelist = sfile->runtime->files;
/* only NULL in rare cases - T29734. */
- if (sfile->files) {
+ if (filelist) {
filelist_readjob_stop(wm, owner_scene);
- filelist_freelib(sfile->files);
- filelist_clear(sfile->files);
+ filelist_freelib(filelist);
+ filelist_clear(filelist);
}
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
@@ -1222,11 +1226,12 @@ void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfil
folder_history_list_free(sfile);
- if (sfile->files) {
+ struct FileList *filelist = sfile->runtime->files;
+ if (filelist) {
ED_fileselect_clear(wm, owner_scene, sfile);
- filelist_free(sfile->files);
- MEM_freeN(sfile->files);
- sfile->files = NULL;
+ filelist_free(filelist);
+ MEM_freeN(filelist);
+ sfile->runtime->files = NULL;
}
}
@@ -1245,24 +1250,25 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params)
BLI_assert(params->renamefile[0] != '\0');
- const int idx = filelist_file_findpath(sfile->files, params->renamefile);
+ struct FileList *filelist = sfile->runtime->files;
+ const int idx = filelist_file_findpath(filelist, params->renamefile);
if (idx >= 0) {
- FileDirEntry *file = filelist_file(sfile->files, idx);
+ FileDirEntry *file = filelist_file(filelist, idx);
BLI_assert(file != NULL);
if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) {
- filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
+ filelist_entry_select_set(filelist, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
}
else if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_PENDING) != 0) {
- filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
+ filelist_entry_select_set(filelist, file, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
params->renamefile[0] = '\0';
params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE;
}
}
/* File listing is now async, only reset renaming if matching entry is not found
* when file listing is not done. */
- else if (filelist_is_ready(sfile->files)) {
+ else if (filelist_is_ready(filelist)) {
params->renamefile[0] = '\0';
params->rename_flag = 0;
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 4422a685af1..c1ea790e986 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -161,19 +161,22 @@ static void file_free(SpaceLink *sl)
BLI_assert(sfile->previews_timer == NULL);
- if (sfile->files) {
- /* XXX would need to do thumbnails_stop here, but no context available */
- filelist_freelib(sfile->files);
- filelist_free(sfile->files);
- MEM_freeN(sfile->files);
- sfile->files = NULL;
+ if (sfile->runtime) {
+ if (sfile->runtime->files) {
+ /* XXX would need to do thumbnails_stop here, but no context available */
+ struct FileList *filelist = sfile->runtime->files;
+ filelist_freelib(filelist);
+ filelist_free(filelist);
+ MEM_freeN(filelist);
+ }
+ MEM_freeN(sfile->runtime);
+ sfile->runtime = NULL;
}
folder_history_list_free(sfile);
MEM_SAFE_FREE(sfile->params);
MEM_SAFE_FREE(sfile->asset_params);
- MEM_SAFE_FREE(sfile->runtime);
if (sfile->layout) {
MEM_freeN(sfile->layout);
@@ -223,8 +226,9 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
FileSelectParams *active_params_old = ED_fileselect_get_active_params(sfileo);
if (active_params_old) {
- sfilen->files = filelist_new(active_params_old->type);
- filelist_setdir(sfilen->files, active_params_old->dir);
+ sfilen->runtime = MEM_callocN(sizeof(*sfilen->runtime), __func__);
+ sfilen->runtime->files = filelist_new(active_params_old->type);
+ filelist_setdir(sfilen->runtime->files, active_params_old->dir);
}
if (sfileo->params) {
@@ -310,7 +314,7 @@ static void file_ensure_valid_region_state(bContext *C,
*/
static void file_tag_reset_list(ScrArea *area, SpaceFile *sfile)
{
- filelist_tag_force_reset(sfile->files);
+ filelist_tag_force_reset(sfile->runtime->files);
ED_area_tag_refresh(area);
}
@@ -326,23 +330,24 @@ static void file_refresh(const bContext *C, ScrArea *area)
fileselect_refresh_params(sfile);
folder_history_list_ensure_for_active_browse_mode(sfile);
- if (sfile->files && (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES) &&
- filelist_needs_reset_on_main_changes(sfile->files)) {
- filelist_tag_force_reset(sfile->files);
+ struct FileList *filelist = sfile->runtime->files;
+ if (filelist && (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES) &&
+ filelist_needs_reset_on_main_changes(filelist)) {
+ filelist_tag_force_reset(filelist);
}
sfile->tags &= ~FILE_TAG_REBUILD_MAIN_FILES;
- if (!sfile->files) {
- sfile->files = filelist_new(params->type);
+ if (!filelist) {
+ filelist = sfile->runtime->files = filelist_new(params->type);
params->highlight_file = -1; /* added this so it opens nicer (ton) */
}
- filelist_settype(sfile->files, params->type);
- filelist_setdir(sfile->files, params->dir);
- filelist_setrecursion(sfile->files, params->recursion_level);
- filelist_setsorting(sfile->files, params->sort, params->flag & FILE_SORT_INVERT);
- filelist_setlibrary(sfile->files, asset_params ? &asset_params->asset_library : NULL);
+ filelist_settype(filelist, params->type);
+ filelist_setdir(filelist, params->dir);
+ filelist_setrecursion(filelist, params->recursion_level);
+ filelist_setsorting(filelist, params->sort, params->flag & FILE_SORT_INVERT);
+ filelist_setlibrary(filelist, asset_params ? &asset_params->asset_library : NULL);
filelist_setfilter_options(
- sfile->files,
+ filelist,
(params->flag & FILE_FILTER) != 0,
(params->flag & FILE_HIDE_DOT) != 0,
true, /* Just always hide parent, prefer to not add an extra user option for this. */
@@ -359,25 +364,25 @@ static void file_refresh(const bContext *C, ScrArea *area)
sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir);
sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
- if (filelist_needs_force_reset(sfile->files)) {
+ if (filelist_needs_force_reset(filelist)) {
filelist_readjob_stop(wm, CTX_data_scene(C));
- filelist_clear(sfile->files);
+ filelist_clear(filelist);
}
- if (filelist_needs_reading(sfile->files)) {
- if (!filelist_pending(sfile->files)) {
- filelist_readjob_start(sfile->files, C);
+ if (filelist_needs_reading(filelist)) {
+ if (!filelist_pending(filelist)) {
+ filelist_readjob_start(filelist, C);
}
}
- filelist_sort(sfile->files);
- filelist_filter(sfile->files);
+ filelist_sort(filelist);
+ filelist_filter(filelist);
if (params->display == FILE_IMGDISPLAY) {
- filelist_cache_previews_set(sfile->files, true);
+ filelist_cache_previews_set(filelist, true);
}
else {
- filelist_cache_previews_set(sfile->files, false);
+ filelist_cache_previews_set(filelist, false);
if (sfile->previews_timer) {
WM_event_remove_timer_notifier(wm, win, sfile->previews_timer);
sfile->previews_timer = NULL;
@@ -422,7 +427,8 @@ static void file_on_reload_callback_call(SpaceFile *sfile)
static void file_reset_filelist_showing_main_data(ScrArea *area, SpaceFile *sfile)
{
- if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) {
+ if (sfile->runtime && sfile->runtime->files &&
+ filelist_needs_reset_on_main_changes(sfile->runtime->files)) {
/* Full refresh of the file list if local asset data was changed. Refreshing this view
* is cheap and users expect this to be updated immediately. */
file_tag_reset_list(area, sfile);
@@ -434,6 +440,7 @@ static void file_listener(const wmSpaceTypeListenerParams *params)
ScrArea *area = params->area;
wmNotifier *wmn = params->notifier;
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
+ struct FileList *filelist = sfile->runtime->files;
/* context changes */
switch (wmn->category) {
@@ -446,7 +453,7 @@ static void file_listener(const wmSpaceTypeListenerParams *params)
ED_area_tag_refresh(area);
break;
case ND_SPACE_FILE_PREVIEW:
- if (sfile->files && filelist_cache_previews_update(sfile->files)) {
+ if (filelist && filelist_cache_previews_update(filelist)) {
ED_area_tag_refresh(area);
}
break;
@@ -573,12 +580,13 @@ static void file_main_region_message_subscribe(const wmRegionMessageSubscribePar
static bool file_main_region_needs_refresh_before_draw(SpaceFile *sfile)
{
/* Needed, because filelist is not initialized on loading */
- if (!sfile->files || filelist_needs_reading(sfile->files)) {
+ struct FileList *filelist = sfile->runtime->files;
+ if (!filelist || filelist_needs_reading(filelist)) {
return true;
}
/* File reading tagged the space because main data changed that may require a filelist reset. */
- if (filelist_needs_reset_on_main_changes(sfile->files) &&
+ if (filelist_needs_reset_on_main_changes(filelist) &&
(sfile->tags & FILE_TAG_REBUILD_MAIN_FILES)) {
return true;
}
@@ -864,6 +872,7 @@ static int /*eContextResult*/ file_context(const bContext *C,
{
bScreen *screen = CTX_wm_screen(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FileList *filelist = sfile->runtime->files;
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
BLI_assert(!ED_area_is_global(CTX_wm_area(C)));
@@ -879,7 +888,7 @@ static int /*eContextResult*/ file_context(const bContext *C,
}
if (CTX_data_equals(member, "active_file")) {
- FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ FileDirEntry *file = filelist_file(filelist, params->active_file);
if (file == NULL) {
return CTX_RESULT_NO_DATA;
}
@@ -888,7 +897,7 @@ static int /*eContextResult*/ file_context(const bContext *C,
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "id")) {
- const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ const FileDirEntry *file = filelist_file(filelist, params->active_file);
if (file == NULL) {
return CTX_RESULT_NO_DATA;
}
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index de1ba2211b1..02eb86b88b5 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -823,12 +823,6 @@ typedef struct SpaceFile {
void *_pad2;
- /**
- * Holds the list of files to show.
- * Currently recreated when browse-mode changes. Could be per browse-mode to avoid refreshes.
- */
- struct FileList *files;
-
/**
* Holds the list of previous directories to show. Owned by `folder_histories` below.
*/