diff options
Diffstat (limited to 'source/blender/editors/space_file')
-rw-r--r-- | source/blender/editors/space_file/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_intern.h | 23 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 174 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.cc (renamed from source/blender/editors/space_file/filelist.c) | 407 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 11 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 30 | ||||
-rw-r--r-- | source/blender/editors/space_file/folder_history.cc | 199 | ||||
-rw-r--r-- | source/blender/editors/space_file/fsmenu.c | 21 | ||||
-rw-r--r-- | source/blender/editors/space_file/fsmenu.h | 7 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 8 |
11 files changed, 486 insertions, 412 deletions
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index b8c28e354da..fb9d5ab9b13 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -15,7 +15,6 @@ set(INC ../../render ../../windowmanager ../../../../intern/atomic - ../../../../intern/glew-mx ../../../../intern/guardedalloc # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna @@ -28,8 +27,9 @@ set(SRC file_ops.c file_panels.c file_utils.c - filelist.c + filelist.cc filesel.c + folder_history.cc fsmenu.c space_file.c diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index f3359336b14..93eb5938301 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -378,7 +378,7 @@ static void file_draw_preview(const SpaceFile *sfile, GPU_blend(GPU_BLEND_ALPHA_PREMULT); } - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR); immDrawPixelsTexTiled_scaling(&state, (float)xco, (float)yco, @@ -463,7 +463,7 @@ static void file_draw_preview(const SpaceFile *sfile, if (show_outline) { GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); float border_color[4] = {1.0f, 1.0f, 1.0f, 0.4f}; float bgcolor[4]; UI_GetThemeColor4fv(TH_BACK, bgcolor); @@ -581,7 +581,7 @@ static void draw_background(FileLayout *layout, View2D *v2d) int sy; uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); float col_alternating[4]; UI_GetThemeColor4fv(TH_ROW_ALTERNATE, col_alternating); immUniformThemeColorBlend(TH_BACK, TH_ROW_ALTERNATE, col_alternating[3]); @@ -631,7 +631,7 @@ static void draw_dividers(FileLayout *layout, View2D *v2d) uint color = GPU_vertformat_attr_add( format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); immBegin(GPU_PRIM_LINES, vertex_len); sx = (int)v2d->tot.xmin; @@ -660,7 +660,7 @@ static void draw_columnheader_background(const FileLayout *layout, const View2D { uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, 11); immRectf(pos, @@ -712,7 +712,7 @@ static void draw_columnheader_columns(const FileSelectParams *params, uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, -10); immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, sx - 1, sy - divider_pad); @@ -727,7 +727,7 @@ static void draw_columnheader_columns(const FileSelectParams *params, /* Vertical separator lines line */ { uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, -10); immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, v2d->cur.xmin, sy); diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 655a7983e2b..eac72af00ab 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -95,11 +95,15 @@ int file_highlight_set(struct SpaceFile *sfile, struct ARegion *region, int mx, * Use to set the file selector path from some arbitrary source. */ void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath); -void file_sfile_to_operator_ex(struct Main *bmain, +void file_sfile_to_operator_ex(struct bContext *C, + struct Main *bmain, struct wmOperator *op, struct SpaceFile *sfile, char *filepath); -void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct SpaceFile *sfile); +void file_sfile_to_operator(struct bContext *C, + struct Main *bmain, + struct wmOperator *op, + struct SpaceFile *sfile); void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op); @@ -113,7 +117,7 @@ void fileselect_refresh_params(struct SpaceFile *sfile); /** * Sets #FileSelectParams.file (name of selected file) */ -void fileselect_file_set(SpaceFile *sfile, int index); +void fileselect_file_set(struct bContext *C, SpaceFile *sfile, int index); bool file_attribute_column_type_enabled(const FileSelectParams *params, FileAttributeColumnType column); /** @@ -181,6 +185,19 @@ void file_on_reload_callback_register(struct SpaceFile *sfile, onReloadFn callback, onReloadFnData custom_data); +/* folder_history.cc */ + +/* not listbase itself */ +void folderlist_free(struct ListBase *folderlist); +void folderlist_popdir(struct ListBase *folderlist, char *dir); +void folderlist_pushdir(struct ListBase *folderlist, const char *dir); +const char *folderlist_peeklastdir(struct ListBase *folderlist); +bool folderlist_clear_next(struct SpaceFile *sfile); + +void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile); +void folder_history_list_free(struct SpaceFile *sfile); +struct ListBase folder_history_list_duplicate(struct ListBase *listbase); + /* file_panels.c */ void file_tool_props_region_panels_register(struct ARegionType *art); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 59d9a15fbab..3f671fd44a1 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -213,7 +213,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen) else { retval = FILE_SELECT_FILE; } - fileselect_file_set(sfile, selected_idx); + fileselect_file_set(C, sfile, selected_idx); } return retval; } @@ -367,6 +367,39 @@ static FileSelect file_select( /** \} */ /* -------------------------------------------------------------------- */ +/** \name Bookmark Utilities + * \{ */ + +/** + * Local utility to write #BLENDER_BOOKMARK_FILE, reporting an error on failure. + */ +static bool fsmenu_write_file_and_refresh_or_report_error(struct FSMenu *fsmenu, + ScrArea *area, + ReportList *reports) +{ + /* NOTE: use warning instead of error here, because the bookmark operation may be part of + * other actions which should not cause the operator to fail entirely. */ + const char *cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL); + if (UNLIKELY(!cfgdir)) { + BKE_report(reports, RPT_ERROR, "Unable to create configuration directory to write bookmarks"); + return false; + } + + char filepath[FILE_MAX]; + BLI_join_dirfile(filepath, sizeof(filepath), cfgdir, BLENDER_BOOKMARK_FILE); + if (UNLIKELY(!fsmenu_write_file(fsmenu, filepath))) { + BKE_reportf(reports, RPT_ERROR, "Unable to open or write bookmark file \"%s\"", filepath); + return false; + } + + ED_area_tag_refresh(area); + ED_area_tag_redraw(area); + return true; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Box Select Operator * \{ */ @@ -451,7 +484,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve else { params->highlight_file = -1; params->sel_first = params->sel_last = -1; - fileselect_file_set(sfile, params->active_file); + fileselect_file_set(C, sfile, params->active_file); file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } @@ -669,7 +702,8 @@ void FILE_OT_select(wmOperatorType *ot) /** * \returns true if selection has changed */ -static bool file_walk_select_selection_set(wmWindow *win, +static bool file_walk_select_selection_set(struct bContext *C, + wmWindow *win, ARegion *region, SpaceFile *sfile, const int direction, @@ -775,7 +809,7 @@ static bool file_walk_select_selection_set(wmWindow *win, } BLI_assert(IN_RANGE(active, -1, numfiles)); - fileselect_file_set(sfile, params->active_file); + fileselect_file_set(C, sfile, params->active_file); /* ensure newly selected file is inside viewbounds */ file_ensure_inside_viewbounds(region, sfile, params->active_file); @@ -856,7 +890,8 @@ static bool file_walk_select_do(bContext *C, } } - return file_walk_select_selection_set(win, + return file_walk_select_selection_set(C, + win, region, sfile, direction, @@ -1053,19 +1088,17 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); SpaceFile *sfile = CTX_wm_space_file(C); - PropertyRNA *prop; - if ((prop = RNA_struct_find_property(op->ptr, "dir"))) { - FileSelectParams *params = ED_fileselect_get_active_params(sfile); - char entry[256]; + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "dir"); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + char entry[256]; - RNA_property_string_get(op->ptr, prop, entry); - BLI_strncpy(params->dir, entry, sizeof(params->dir)); - BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir); - ED_file_change_dir(C); + RNA_property_string_get(op->ptr, prop, entry); + BLI_strncpy(params->dir, entry, sizeof(params->dir)); + BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir); + ED_file_change_dir(C); - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); - } + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; } @@ -1095,7 +1128,7 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) /** \name Add Bookmark Operator * \{ */ -static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) +static int bookmark_add_exec(bContext *C, wmOperator *op) { ScrArea *area = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); @@ -1103,19 +1136,11 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) struct FileSelectParams *params = ED_fileselect_get_active_params(sfile); if (params->dir[0] != '\0') { - char name[FILE_MAX]; fsmenu_insert_entry( fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, ICON_FILE_FOLDER, FS_INSERT_SAVE); - BLI_join_dirfile(name, - sizeof(name), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu, name); + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); } - - ED_area_tag_refresh(area); - ED_area_tag_redraw(area); return OPERATOR_FINISHED; } @@ -1146,27 +1171,11 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) int nentries = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index"); - - if (prop) { - int index; - if (RNA_property_is_set(op->ptr, prop)) { - index = RNA_property_int_get(op->ptr, prop); - } - else { /* if index unset, use active bookmark... */ - index = sfile->bookmarknr; - } - if ((index > -1) && (index < nentries)) { - char name[FILE_MAX]; - - fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); - BLI_join_dirfile(name, - sizeof(name), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu, name); - ED_area_tag_refresh(area); - ED_area_tag_redraw(area); - } + const int index = RNA_property_is_set(op->ptr, prop) ? RNA_property_int_get(op->ptr, prop) : + sfile->bookmarknr; + if ((index > -1) && (index < nentries)) { + fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); } return OPERATOR_FINISHED; @@ -1197,7 +1206,7 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot) /** \name Cleanup Bookmark Operator * \{ */ -static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op)) +static int bookmark_cleanup_exec(bContext *C, wmOperator *op) { ScrArea *area = CTX_wm_area(C); struct FSMenu *fsmenu = ED_fsmenu_get(); @@ -1218,16 +1227,8 @@ static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op)) } if (changed) { - char name[FILE_MAX]; - - BLI_join_dirfile(name, - sizeof(name), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu, name); + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); fsmenu_refresh_bookmarks_status(CTX_wm_manager(C), fsmenu); - ED_area_tag_refresh(area); - ED_area_tag_redraw(area); } return OPERATOR_FINISHED; @@ -1269,8 +1270,6 @@ static int bookmark_move_exec(bContext *C, wmOperator *op) struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); const struct FSMenuEntry *fsmentry_org = fsmentry; - char fname[FILE_MAX]; - const int direction = RNA_enum_get(op->ptr, "direction"); const int totitems = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); const int act_index = sfile->bookmarknr; @@ -1306,13 +1305,8 @@ static int bookmark_move_exec(bContext *C, wmOperator *op) /* Need to update active bookmark number. */ sfile->bookmarknr = new_index; - BLI_join_dirfile(fname, - sizeof(fname), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu, fname); + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); - ED_area_tag_redraw(area); return OPERATOR_FINISHED; } @@ -1352,21 +1346,16 @@ void FILE_OT_bookmark_move(wmOperatorType *ot) /** \name Reset Recent Blend Files Operator * \{ */ -static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) +static int reset_recent_exec(bContext *C, wmOperator *op) { ScrArea *area = CTX_wm_area(C); - char name[FILE_MAX]; struct FSMenu *fsmenu = ED_fsmenu_get(); while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) { fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0); } - BLI_join_dirfile(name, - sizeof(name), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu, name); - ED_area_tag_redraw(area); + + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); return OPERATOR_FINISHED; } @@ -1568,7 +1557,8 @@ void FILE_OT_cancel(struct wmOperatorType *ot) /** \name Operator Utilities * \{ */ -void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath) +void file_sfile_to_operator_ex( + bContext *C, Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath) { FileSelectParams *params = ED_fileselect_get_active_params(sfile); PropertyRNA *prop; @@ -1582,14 +1572,27 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch } } + char value[FILE_MAX]; if ((prop = RNA_struct_find_property(op->ptr, "filename"))) { + RNA_property_string_get(op->ptr, prop, value); RNA_property_string_set(op->ptr, prop, params->file); + if (RNA_property_update_check(prop) && !STREQ(params->file, value)) { + RNA_property_update(C, op->ptr, prop); + } } if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { + RNA_property_string_get(op->ptr, prop, value); RNA_property_string_set(op->ptr, prop, params->dir); + if (RNA_property_update_check(prop) && !STREQ(params->dir, value)) { + RNA_property_update(C, op->ptr, prop); + } } if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { + RNA_property_string_get(op->ptr, prop, value); RNA_property_string_set(op->ptr, prop, filepath); + if (RNA_property_update_check(prop) && !STREQ(filepath, value)) { + RNA_property_update(C, op->ptr, prop); + } } /* some ops have multiple files to select */ @@ -1643,11 +1646,11 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch } } } -void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile) +void file_sfile_to_operator(bContext *C, Main *bmain, wmOperator *op, SpaceFile *sfile) { char filepath_dummy[FILE_MAX]; - file_sfile_to_operator_ex(bmain, op, sfile, filepath_dummy); + file_sfile_to_operator_ex(C, bmain, op, sfile, filepath_dummy); } void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op) @@ -1708,7 +1711,7 @@ void file_draw_check_ex(bContext *C, ScrArea *area) if (op) { /* fail on reload */ if (op->type->check) { Main *bmain = CTX_data_main(C); - file_sfile_to_operator(bmain, op, sfile); + file_sfile_to_operator(C, bmain, op, sfile); /* redraw */ if (op->type->check(C, op)) { @@ -1795,15 +1798,17 @@ static bool file_execute(bContext *C, SpaceFile *sfile) } /* Opening file, sends events now, so things get handled on window-queue level. */ else if (sfile->op) { + ScrArea *area = CTX_wm_area(C); + struct FSMenu *fsmenu = ED_fsmenu_get(); wmOperator *op = sfile->op; char filepath[FILE_MAX]; sfile->op = NULL; - file_sfile_to_operator_ex(bmain, op, sfile, filepath); + file_sfile_to_operator_ex(C, bmain, op, sfile, filepath); if (BLI_exists(params->dir)) { - fsmenu_insert_entry(ED_fsmenu_get(), + fsmenu_insert_entry(fsmenu, FS_CATEGORY_RECENT, params->dir, NULL, @@ -1811,11 +1816,8 @@ static bool file_execute(bContext *C, SpaceFile *sfile) FS_INSERT_SAVE | FS_INSERT_FIRST); } - BLI_join_dirfile(filepath, - sizeof(filepath), - BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), - BLENDER_BOOKMARK_FILE); - fsmenu_write_file(ED_fsmenu_get(), filepath); + fsmenu_write_file_and_refresh_or_report_error(fsmenu, area, op->reports); + WM_event_fileselect_event(CTX_wm_manager(C), op, EVT_FILESELECT_EXEC); } @@ -2268,7 +2270,7 @@ static int filepath_drop_exec(bContext *C, wmOperator *op) file_sfile_filepath_set(sfile, filepath); if (sfile->op) { - file_sfile_to_operator(bmain, sfile->op, sfile); + file_sfile_to_operator(C, bmain, sfile->op, sfile); file_draw_check(C); } @@ -2327,7 +2329,6 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) char name[FILE_MAXFILE]; char path[FILE_MAX]; bool generate_name = true; - PropertyRNA *prop; wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); @@ -2341,7 +2342,8 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) path[0] = '\0'; - if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { + { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "directory"); RNA_property_string_get(op->ptr, prop, path); if (path[0] != '\0') { generate_name = false; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.cc index 24e1faaf4c9..daf04aa5f41 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.cc @@ -7,11 +7,11 @@ /* global includes */ -#include <math.h> -#include <stdlib.h> -#include <string.h> +#include <cmath> +#include <cstdlib> +#include <cstring> +#include <ctime> #include <sys/stat.h> -#include <time.h> #ifndef WIN32 # include <unistd.h> @@ -79,183 +79,14 @@ #define FILEDIR_NBR_ENTRIES_UNSET -1 -/* ----------------- FOLDERLIST (previous/next) -------------- */ - -typedef struct FolderList { - struct FolderList *next, *prev; - char *foldername; -} FolderList; - -void folderlist_popdir(struct ListBase *folderlist, char *dir) -{ - const char *prev_dir; - struct FolderList *folder; - folder = folderlist->last; - - if (folder) { - /* remove the current directory */ - MEM_freeN(folder->foldername); - BLI_freelinkN(folderlist, folder); - - folder = folderlist->last; - if (folder) { - prev_dir = folder->foldername; - BLI_strncpy(dir, prev_dir, FILE_MAXDIR); - } - } - /* delete the folder next or use setdir directly before PREVIOUS OP */ -} - -void folderlist_pushdir(ListBase *folderlist, const char *dir) -{ - if (!dir[0]) { - return; - } - - struct FolderList *folder, *previous_folder; - previous_folder = folderlist->last; - - /* check if already exists */ - if (previous_folder && previous_folder->foldername) { - if (BLI_path_cmp(previous_folder->foldername, dir) == 0) { - return; - } - } - - /* create next folder element */ - folder = MEM_mallocN(sizeof(*folder), __func__); - folder->foldername = BLI_strdup(dir); - - /* add it to the end of the list */ - BLI_addtail(folderlist, folder); -} - -const char *folderlist_peeklastdir(ListBase *folderlist) -{ - struct FolderList *folder; - - if (!folderlist->last) { - return NULL; - } - - folder = folderlist->last; - return folder->foldername; -} - -int folderlist_clear_next(struct SpaceFile *sfile) -{ - const FileSelectParams *params = ED_fileselect_get_active_params(sfile); - struct FolderList *folder; - - /* if there is no folder_next there is nothing we can clear */ - if (BLI_listbase_is_empty(sfile->folders_next)) { - return 0; - } - - /* if previous_folder, next_folder or refresh_folder operators are executed - * it doesn't clear folder_next */ - folder = sfile->folders_prev->last; - if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) { - return 0; - } - - /* eventually clear flist->folders_next */ - return 1; -} - -void folderlist_free(ListBase *folderlist) -{ - if (folderlist) { - FolderList *folder; - for (folder = folderlist->first; folder; folder = folder->next) { - MEM_freeN(folder->foldername); - } - BLI_freelistN(folderlist); - } -} - -static ListBase folderlist_duplicate(ListBase *folderlist) -{ - ListBase folderlistn = {NULL}; - - BLI_duplicatelist(&folderlistn, folderlist); - - for (FolderList *folder = folderlistn.first; folder; folder = folder->next) { - folder->foldername = MEM_dupallocN(folder->foldername); - } - return folderlistn; -} - -/* ----------------- Folder-History (wraps/owns file list above) -------------- */ - -static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode) -{ - LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) { - if (history->browse_mode == browse_mode) { - return history; - } - } - - return NULL; -} - -void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile) -{ - FileFolderHistory *history = folder_history_find(sfile, sfile->browse_mode); - - if (!history) { - history = MEM_callocN(sizeof(*history), __func__); - history->browse_mode = sfile->browse_mode; - BLI_addtail(&sfile->folder_histories, history); - } - - sfile->folders_next = &history->folders_next; - sfile->folders_prev = &history->folders_prev; -} - -static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history) -{ - if (sfile->folders_prev == &history->folders_prev) { - sfile->folders_prev = NULL; - } - if (sfile->folders_next == &history->folders_next) { - sfile->folders_next = NULL; - } - folderlist_free(&history->folders_prev); - folderlist_free(&history->folders_next); - BLI_freelinkN(&sfile->folder_histories, history); -} - -void folder_history_list_free(SpaceFile *sfile) -{ - LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) { - folder_history_entry_free(sfile, history); - } -} - -ListBase folder_history_list_duplicate(ListBase *listbase) -{ - ListBase histories = {NULL}; - - LISTBASE_FOREACH (FileFolderHistory *, history, listbase) { - FileFolderHistory *history_new = MEM_dupallocN(history); - history_new->folders_prev = folderlist_duplicate(&history->folders_prev); - history_new->folders_next = folderlist_duplicate(&history->folders_next); - BLI_addtail(&histories, history_new); - } - - return histories; -} - /* ------------------FILELIST------------------------ */ -typedef struct FileListInternEntry { - struct FileListInternEntry *next, *prev; +struct FileListInternEntry { + FileListInternEntry *next, *prev; FileUID uid; - /** eFileSel_File_Types */ - int typeflag; + eFileSel_File_Types typeflag; /** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */ int blentype; @@ -287,18 +118,18 @@ typedef struct FileListInternEntry { /** Defined in BLI_fileops.h */ eFileAttributes attributes; BLI_stat_t st; -} FileListInternEntry; +}; -typedef struct FileListIntern { +struct FileListIntern { /** FileListInternEntry items. */ ListBase entries; FileListInternEntry **filtered; FileUID curr_uid; /* Used to generate UID during internal listing. */ -} FileListIntern; +}; #define FILELIST_ENTRYCACHESIZE_DEFAULT 1024 /* Keep it a power of two! */ -typedef struct FileListEntryCache { +struct FileListEntryCache { size_t size; /* The size of the cache... */ int flags; @@ -327,7 +158,7 @@ typedef struct FileListEntryCache { * previews either in `previews_pool` or `previews_done`. #filelist_cache_previews_update() makes * previews in `preview_done` ready for display, so the counter is decremented there. */ int previews_todo_count; -} FileListEntryCache; +}; /** #FileListCache.flags */ enum { @@ -335,21 +166,21 @@ enum { FLC_PREVIEWS_ACTIVE = 1 << 1, }; -typedef struct FileListEntryPreview { +struct FileListEntryPreview { char filepath[FILE_MAX]; uint flags; int index; int attributes; /* from FileDirEntry. */ int icon_id; -} FileListEntryPreview; +}; /* Dummy wrapper around FileListEntryPreview to ensure we do not access freed memory when freeing * tasks' data (see T74609). */ -typedef struct FileListEntryPreviewTaskData { +struct FileListEntryPreviewTaskData { FileListEntryPreview *preview; -} FileListEntryPreviewTaskData; +}; -typedef struct FileListFilter { +struct FileListFilter { uint64_t filter; uint64_t filter_id; char filter_glob[FILE_MAXFILE]; @@ -357,7 +188,7 @@ typedef struct FileListFilter { short flags; FileAssetCatalogFilterSettingsHandle *asset_catalog_filter; -} FileListFilter; +}; /** #FileListFilter.flags */ enum { @@ -369,13 +200,13 @@ enum { }; struct FileListReadJob; -typedef struct FileList { +struct FileList { FileDirEntryArr filelist; eFileSelectType type; /* The library this list was created for. Stored here so we know when to re-read. */ AssetLibraryReference *asset_library_ref; - struct AssetLibrary *asset_library; /* Non-owning pointer. */ + AssetLibrary *asset_library; /* Non-owning pointer. */ short flags; @@ -386,24 +217,24 @@ typedef struct FileList { /** * File indexer to use. Attribute is always set. */ - const struct FileIndexerType *indexer; + const FileIndexerType *indexer; - struct FileListIntern filelist_intern; + FileListIntern filelist_intern; - struct FileListEntryCache filelist_cache; + FileListEntryCache filelist_cache; /* We need to keep those info outside of actual filelist items, * because those are no more persistent * (only generated on demand, and freed as soon as possible). * Persistent part (mere list of paths + stat info) - * is kept as small as possible, and filebrowser-agnostic. + * is kept as small as possible, and file-browser agnostic. */ GHash *selection_state; short max_recursion; short recursion_level; - struct BlendHandle *libfiledata; + BlendHandle *libfiledata; /* Set given path as root directory, * if last bool is true may change given string in place to a valid value. @@ -419,7 +250,7 @@ typedef struct FileList { void (*prepare_filter_fn)(const struct FileList *, FileListFilter *); short tags; /* FileListTags */ -} FileList; +}; /** #FileList.flags */ enum { @@ -459,23 +290,23 @@ enum { static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX]; -static void filelist_readjob_main(struct FileListReadJob *job_params, +static void filelist_readjob_main(FileListReadJob *job_params, short *stop, short *do_update, float *progress); -static void filelist_readjob_lib(struct FileListReadJob *job_params, +static void filelist_readjob_lib(FileListReadJob *job_params, short *stop, short *do_update, float *progress); -static void filelist_readjob_dir(struct FileListReadJob *job_params, +static void filelist_readjob_dir(FileListReadJob *job_params, short *stop, short *do_update, float *progress); -static void filelist_readjob_asset_library(struct FileListReadJob *job_params, +static void filelist_readjob_asset_library(FileListReadJob *job_params, short *stop, short *do_update, float *progress); -static void filelist_readjob_main_assets(struct FileListReadJob *job_params, +static void filelist_readjob_main_assets(FileListReadJob *job_params, short *stop, short *do_update, float *progress); @@ -493,7 +324,7 @@ struct FileSortData { bool inverted; }; -static int compare_apply_inverted(int val, const struct FileSortData *sort_data) +static int compare_apply_inverted(int val, const FileSortData *sort_data) { return sort_data->inverted ? -val : val; } @@ -602,9 +433,9 @@ static int compare_direntry_generic(const FileListInternEntry *entry1, static int compare_name(void *user_data, const void *a1, const void *a2) { - const FileListInternEntry *entry1 = a1; - const FileListInternEntry *entry2 = a2; - const struct FileSortData *sort_data = user_data; + const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1); + const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2); + const FileSortData *sort_data = static_cast<const FileSortData *>(user_data); int ret; if ((ret = compare_direntry_generic(entry1, entry2))) { @@ -616,9 +447,9 @@ static int compare_name(void *user_data, const void *a1, const void *a2) static int compare_date(void *user_data, const void *a1, const void *a2) { - const FileListInternEntry *entry1 = a1; - const FileListInternEntry *entry2 = a2; - const struct FileSortData *sort_data = user_data; + const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1); + const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2); + const FileSortData *sort_data = static_cast<const FileSortData *>(user_data); int64_t time1, time2; int ret; @@ -640,9 +471,9 @@ static int compare_date(void *user_data, const void *a1, const void *a2) static int compare_size(void *user_data, const void *a1, const void *a2) { - const FileListInternEntry *entry1 = a1; - const FileListInternEntry *entry2 = a2; - const struct FileSortData *sort_data = user_data; + const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1); + const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2); + const FileSortData *sort_data = static_cast<const FileSortData *>(user_data); uint64_t size1, size2; int ret; @@ -664,9 +495,9 @@ static int compare_size(void *user_data, const void *a1, const void *a2) static int compare_extension(void *user_data, const void *a1, const void *a2) { - const FileListInternEntry *entry1 = a1; - const FileListInternEntry *entry2 = a2; - const struct FileSortData *sort_data = user_data; + const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1); + const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2); + const FileSortData *sort_data = static_cast<const FileSortData *>(user_data); int ret; if ((ret = compare_direntry_generic(entry1, entry2))) { @@ -720,7 +551,7 @@ static int compare_extension(void *user_data, const void *a1, const void *a2) void filelist_sort(struct FileList *filelist) { if (filelist->flags & FL_NEED_SORTING) { - void *sort_cb = NULL; + int (*sort_cb)(void *, const void *, const void *) = nullptr; switch (filelist->sort) { case FILE_SORT_ALPHA: @@ -740,10 +571,10 @@ void filelist_sort(struct FileList *filelist) BLI_assert(0); break; } - BLI_listbase_sort_r( - &filelist->filelist_intern.entries, - sort_cb, - &(struct FileSortData){.inverted = (filelist->flags & FL_SORT_INVERT) != 0}); + + FileSortData sort_data{0}; + sort_data.inverted = (filelist->flags & FL_SORT_INVERT) != 0; + BLI_listbase_sort_r(&filelist->filelist_intern.entries, sort_cb, &sort_data); filelist_tag_needs_filtering(filelist); filelist->flags &= ~FL_NEED_SORTING; @@ -1062,7 +893,7 @@ void filelist_filter(FileList *filelist) { int num_filtered = 0; const int num_files = filelist->filelist.entries_num; - FileListInternEntry **filtered_tmp, *file; + FileListInternEntry **filtered_tmp; if (ELEM(filelist->filelist.entries_num, FILEDIR_NBR_ENTRIES_UNSET, 0)) { return; @@ -1087,10 +918,11 @@ void filelist_filter(FileList *filelist) filelist->prepare_filter_fn(filelist, &filelist->filter_data); } - filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__); + filtered_tmp = static_cast<FileListInternEntry **>( + MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__)); /* Filter remap & count how many files are left after filter in a single loop. */ - for (file = filelist->filelist_intern.entries.first; file; file = file->next) { + LISTBASE_FOREACH (FileListInternEntry *, file, &filelist->filelist_intern.entries) { if (filelist->filter_fn(file, filelist->filelist.root, &filelist->filter_data)) { filtered_tmp[num_filtered++] = file; } @@ -1099,8 +931,8 @@ void filelist_filter(FileList *filelist) if (filelist->filelist_intern.filtered) { MEM_freeN(filelist->filelist_intern.filtered); } - filelist->filelist_intern.filtered = MEM_mallocN( - sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered, __func__); + filelist->filelist_intern.filtered = static_cast<FileListInternEntry **>( + MEM_mallocN(sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered, __func__)); memcpy(filelist->filelist_intern.filtered, filtered_tmp, sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered); @@ -1228,8 +1060,7 @@ void filelist_setlibrary(FileList *filelist, const AssetLibraryReference *asset_ } if (!filelist->asset_library_ref) { - filelist->asset_library_ref = MEM_mallocN(sizeof(*filelist->asset_library_ref), - "filelist asset library"); + filelist->asset_library_ref = MEM_new<AssetLibraryReference>("filelist asset library"); *filelist->asset_library_ref = *asset_library_ref; filelist->flags |= FL_FORCE_RESET; @@ -1335,7 +1166,7 @@ static int filelist_geticon_ex(const FileDirEntry *file, const bool is_main, const bool ignore_libdir) { - const eFileSel_File_Types typeflag = file->typeflag; + const eFileSel_File_Types typeflag = (eFileSel_File_Types)file->typeflag; if ((typeflag & FILE_TYPE_DIR) && !(ignore_libdir && (typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER)))) { @@ -1581,10 +1412,7 @@ static void filelist_intern_entry_free(FileListInternEntry *entry) static void filelist_intern_free(FileListIntern *filelist_intern) { - FileListInternEntry *entry, *entry_next; - - for (entry = filelist_intern->entries.first; entry; entry = entry_next) { - entry_next = entry->next; + LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) { filelist_intern_entry_free(entry); } BLI_listbase_clear(&filelist_intern->entries); @@ -1614,11 +1442,14 @@ static int filelist_intern_free_main_files(FileListIntern *filelist_intern) static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata) { - FileListEntryCache *cache = BLI_task_pool_user_data(pool); - FileListEntryPreviewTaskData *preview_taskdata = taskdata; + FileListEntryCache *cache = static_cast<FileListEntryCache *>(BLI_task_pool_user_data(pool)); + FileListEntryPreviewTaskData *preview_taskdata = static_cast<FileListEntryPreviewTaskData *>( + taskdata); FileListEntryPreview *preview = preview_taskdata->preview; - ThumbSource source = 0; + /* XXX #THB_SOURCE_IMAGE for "historic" reasons. The case of an undefined source should be + * handled better. */ + ThumbSource source = THB_SOURCE_IMAGE; // printf("%s: Start (%d)...\n", __func__, threadid); @@ -1662,7 +1493,8 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat static void filelist_cache_preview_freef(TaskPool *__restrict UNUSED(pool), void *taskdata) { - FileListEntryPreviewTaskData *preview_taskdata = taskdata; + FileListEntryPreviewTaskData *preview_taskdata = static_cast<FileListEntryPreviewTaskData *>( + taskdata); /* In case the preview wasn't moved to the "done" queue yet. */ if (preview_taskdata->preview) { @@ -1689,7 +1521,8 @@ static void filelist_cache_previews_clear(FileListEntryCache *cache) BLI_task_pool_cancel(cache->previews_pool); FileListEntryPreview *preview; - while ((preview = BLI_thread_queue_pop_timeout(cache->previews_done, 0))) { + while ((preview = static_cast<FileListEntryPreview *>( + BLI_thread_queue_pop_timeout(cache->previews_done, 0)))) { // printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path, // preview->img); if (preview->icon_id) { @@ -1749,7 +1582,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry filelist_cache_preview_ensure_running(cache); entry->flags |= FILE_ENTRY_PREVIEW_LOADING; - FileListEntryPreview *preview = MEM_mallocN(sizeof(*preview), __func__); + FileListEntryPreview *preview = MEM_new<FileListEntryPreview>(__func__); preview->index = index; preview->flags = entry->typeflag; preview->attributes = entry->attributes; @@ -1775,8 +1608,8 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry } // printf("%s: %d - %s\n", __func__, preview->index, preview->filepath); - FileListEntryPreviewTaskData *preview_taskdata = MEM_mallocN(sizeof(*preview_taskdata), - __func__); + FileListEntryPreviewTaskData *preview_taskdata = MEM_new<FileListEntryPreviewTaskData>( + __func__); preview_taskdata->preview = preview; BLI_task_pool_push(cache->previews_pool, filelist_cache_preview_runf, @@ -1793,11 +1626,12 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size) cache->block_cursor = cache->block_start_index = cache->block_center_index = cache->block_end_index = 0; - cache->block_entries = MEM_mallocN(sizeof(*cache->block_entries) * cache_size, __func__); + cache->block_entries = static_cast<FileDirEntry **>( + MEM_mallocN(sizeof(*cache->block_entries) * cache_size, __func__)); cache->misc_entries = BLI_ghash_ptr_new_ex(__func__, cache_size); - cache->misc_entries_indices = MEM_mallocN(sizeof(*cache->misc_entries_indices) * cache_size, - __func__); + cache->misc_entries_indices = static_cast<int *>( + MEM_mallocN(sizeof(*cache->misc_entries_indices) * cache_size, __func__)); copy_vn_i(cache->misc_entries_indices, cache_size, -1); cache->misc_cursor = 0; @@ -1815,8 +1649,6 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size) static void filelist_cache_free(FileListEntryCache *cache) { - FileDirEntry *entry, *entry_next; - if (!(cache->flags & FLC_IS_INIT)) { return; } @@ -1830,8 +1662,7 @@ static void filelist_cache_free(FileListEntryCache *cache) BLI_ghash_free(cache->uids, NULL, NULL); - for (entry = cache->cached_entries.first; entry; entry = entry_next) { - entry_next = entry->next; + LISTBASE_FOREACH_MUTABLE (FileDirEntry *, entry, &cache->cached_entries) { filelist_entry_free(entry); } BLI_listbase_clear(&cache->cached_entries); @@ -1839,8 +1670,6 @@ static void filelist_cache_free(FileListEntryCache *cache) static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size) { - FileDirEntry *entry, *entry_next; - if (!(cache->flags & FLC_IS_INIT)) { return; } @@ -1850,14 +1679,14 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size) cache->block_cursor = cache->block_start_index = cache->block_center_index = cache->block_end_index = 0; if (new_size != cache->size) { - cache->block_entries = MEM_reallocN(cache->block_entries, - sizeof(*cache->block_entries) * new_size); + cache->block_entries = static_cast<FileDirEntry **>( + MEM_reallocN(cache->block_entries, sizeof(*cache->block_entries) * new_size)); } BLI_ghash_clear_ex(cache->misc_entries, NULL, NULL, new_size); if (new_size != cache->size) { - cache->misc_entries_indices = MEM_reallocN(cache->misc_entries_indices, - sizeof(*cache->misc_entries_indices) * new_size); + cache->misc_entries_indices = static_cast<int *>(MEM_reallocN( + cache->misc_entries_indices, sizeof(*cache->misc_entries_indices) * new_size)); } copy_vn_i(cache->misc_entries_indices, new_size, -1); @@ -1865,8 +1694,7 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size) cache->size = new_size; - for (entry = cache->cached_entries.first; entry; entry = entry_next) { - entry_next = entry->next; + LISTBASE_FOREACH_MUTABLE (FileDirEntry *, entry, &cache->cached_entries) { filelist_entry_free(entry); } BLI_listbase_clear(&cache->cached_entries); @@ -1874,7 +1702,7 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size) FileList *filelist_new(short type) { - FileList *p = MEM_callocN(sizeof(*p), __func__); + FileList *p = MEM_cnew<FileList>(__func__); filelist_cache_init(&p->filelist_cache, FILELIST_ENTRYCACHESIZE_DEFAULT); @@ -1891,7 +1719,7 @@ void filelist_settype(FileList *filelist, short type) return; } - filelist->type = type; + filelist->type = (eFileSelectType)type; filelist->tags = 0; filelist->indexer = &file_indexer_noop; switch (filelist->type) { @@ -2181,7 +2009,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in FileListEntryCache *cache = &filelist->filelist_cache; FileDirEntry *ret; - ret = MEM_callocN(sizeof(*ret), __func__); + ret = MEM_cnew<FileDirEntry>(__func__); ret->size = (uint64_t)entry->st.st_size; ret->time = (int64_t)entry->st.st_mtime; @@ -2240,7 +2068,8 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const return cache->block_entries[idx]; } - if ((ret = BLI_ghash_lookup(cache->misc_entries, POINTER_FROM_INT(index)))) { + if ((ret = static_cast<FileDirEntry *>( + BLI_ghash_lookup(cache->misc_entries, POINTER_FROM_INT(index))))) { return ret; } @@ -2253,7 +2082,8 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const /* Else, we have to add new entry to 'misc' cache - and possibly make room for it first! */ ret = filelist_file_create_entry(filelist, index); old_index = cache->misc_entries_indices[cache->misc_cursor]; - if ((old = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(old_index), NULL))) { + if ((old = static_cast<FileDirEntry *>( + BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(old_index), NULL)))) { BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(old->uid), NULL, NULL); filelist_file_release_entry(filelist, old); } @@ -2371,7 +2201,8 @@ static bool filelist_file_cache_block_create(FileList *filelist, FileDirEntry *entry; /* That entry might have already been requested and stored in misc cache... */ - if ((entry = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(idx), NULL)) == NULL) { + if ((entry = static_cast<FileDirEntry *>( + BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(idx), NULL))) == NULL) { entry = filelist_file_create_entry(filelist, idx); BLI_ghash_insert(cache->uids, POINTER_FROM_UINT(entry->uid), entry); } @@ -2660,7 +2491,8 @@ bool filelist_cache_previews_update(FileList *filelist) // printf("%s: Update Previews...\n", __func__); while (!BLI_thread_queue_is_empty(cache->previews_done)) { - FileListEntryPreview *preview = BLI_thread_queue_pop(cache->previews_done); + FileListEntryPreview *preview = static_cast<FileListEntryPreview *>( + BLI_thread_queue_pop(cache->previews_done)); FileDirEntry *entry; /* Paranoid (should never happen currently @@ -3050,8 +2882,8 @@ static int filelist_readjob_list_dir(const char *root, continue; } - entry = MEM_callocN(sizeof(*entry), __func__); - entry->relpath = MEM_dupallocN(files[i].relname); + entry = MEM_cnew<FileListInternEntry>(__func__); + entry->relpath = static_cast<char *>(MEM_dupallocN(files[i].relname)); entry->st = files[i].s; BLI_join_dirfile(full_path, FILE_MAX, root, entry->relpath); @@ -3069,14 +2901,14 @@ static int filelist_readjob_list_dir(const char *root, /* Is this a file that points to another file? */ if (entry->attributes & FILE_ATTR_ALIAS) { - entry->redirection_path = MEM_callocN(FILE_MAXDIR, __func__); + entry->redirection_path = MEM_cnew_array<char>(FILE_MAXDIR, __func__); if (BLI_file_alias_target(full_path, entry->redirection_path)) { if (BLI_is_dir(entry->redirection_path)) { entry->typeflag = FILE_TYPE_DIR; BLI_path_slash_ensure(entry->redirection_path); } else { - entry->typeflag = ED_path_extension_type(entry->redirection_path); + entry->typeflag = (eFileSel_File_Types)ED_path_extension_type(entry->redirection_path); } target = entry->redirection_path; #ifdef WIN32 @@ -3101,7 +2933,7 @@ static int filelist_readjob_list_dir(const char *root, } } else { - entry->typeflag = ED_path_extension_type(target); + entry->typeflag = (eFileSel_File_Types)ED_path_extension_type(target); if (filter_glob[0] && BLI_path_extension_check_glob(target, filter_glob)) { entry->typeflag |= FILE_TYPE_OPERATOR; } @@ -3124,6 +2956,8 @@ static int filelist_readjob_list_dir(const char *root, } typedef enum ListLibOptions { + LIST_LIB_OPTION_NONE = 0, + /* Will read both the groups + actual ids from the library. Reduces the amount of times that * a library needs to be opened. */ LIST_LIB_RECURSIVE = (1 << 0), @@ -3134,11 +2968,12 @@ typedef enum ListLibOptions { /* Add given root as result. */ LIST_LIB_ADD_PARENT = (1 << 2), } ListLibOptions; +ENUM_OPERATORS(ListLibOptions, LIST_LIB_ADD_PARENT); static FileListInternEntry *filelist_readjob_list_lib_group_create(const int idcode, const char *group_name) { - FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__); + FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__); entry->relpath = BLI_strdup(group_name); entry->typeflag |= FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR; entry->blentype = idcode; @@ -3151,7 +2986,7 @@ static void filelist_readjob_list_lib_add_datablock(ListBase *entries, const int idcode, const char *group_name) { - FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__); + FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__); if (prefix_relpath_with_group_name) { entry->relpath = BLI_sprintfN("%s/%s", group_name, datablock_info->name); } @@ -3175,7 +3010,7 @@ static void filelist_readjob_list_lib_add_datablocks(ListBase *entries, const char *group_name) { for (LinkNode *ln = datablock_infos; ln; ln = ln->next) { - struct BLODataBlockInfo *datablock_info = ln->link; + struct BLODataBlockInfo *datablock_info = static_cast<BLODataBlockInfo *>(ln->link); filelist_readjob_list_lib_add_datablock( entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name); } @@ -3199,7 +3034,7 @@ static void filelist_readjob_list_lib_add_from_indexer_entries( static FileListInternEntry *filelist_readjob_list_lib_navigate_to_parent_entry_create(void) { - FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__); + FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__); entry->relpath = BLI_strdup(FILENAME_PARENT); entry->typeflag |= (FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR); return entry; @@ -3279,7 +3114,7 @@ static int filelist_readjob_list_lib(const char *root, } /* Open the library file. */ - BlendFileReadReport bf_reports = {.reports = NULL}; + BlendFileReadReport bf_reports{}; libfiledata = BLO_blendhandle_from_file(dir, &bf_reports); if (libfiledata == NULL) { return 0; @@ -3310,7 +3145,7 @@ static int filelist_readjob_list_lib(const char *root, group_len = BLI_linklist_count(groups); for (LinkNode *ln = groups; ln; ln = ln->next) { - const char *group_name = ln->link; + const char *group_name = static_cast<char *>(ln->link); const int idcode = groupname_to_code(group_name); FileListInternEntry *group_entry = filelist_readjob_list_lib_group_create(idcode, group_name); @@ -3615,7 +3450,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, int dirs_done_count = 0, dirs_todo_count = 1; todo_dirs = BLI_stack_new(sizeof(*td_dir), __func__); - td_dir = BLI_stack_push_r(todo_dirs); + td_dir = static_cast<TodoDir *>(BLI_stack_push_r(todo_dirs)); td_dir->level = 1; BLI_strncpy(dir, filelist->filelist.root, sizeof(dir)); @@ -3625,13 +3460,13 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, td_dir->dir = BLI_strdup(dir); /* Init the file indexer. */ - FileIndexer indexer_runtime = {.callbacks = filelist->indexer}; + FileIndexer indexer_runtime{}; + indexer_runtime.callbacks = filelist->indexer; if (indexer_runtime.callbacks->init_user_data) { indexer_runtime.user_data = indexer_runtime.callbacks->init_user_data(dir, sizeof(dir)); } while (!BLI_stack_is_empty(todo_dirs) && !(*stop)) { - FileListInternEntry *entry; int entries_num = 0; char *subdir; @@ -3639,7 +3474,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, int recursion_level; bool skip_currpar; - td_dir = BLI_stack_peek(todo_dirs); + td_dir = static_cast<TodoDir *>(BLI_stack_peek(todo_dirs)); subdir = td_dir->dir; recursion_level = td_dir->level; skip_currpar = (recursion_level > 1); @@ -3657,7 +3492,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, bool is_lib = false; if (do_lib) { - ListLibOptions list_lib_options = 0; + ListLibOptions list_lib_options = LIST_LIB_OPTION_NONE; if (!skip_currpar) { list_lib_options |= LIST_LIB_ADD_PARENT; } @@ -3684,7 +3519,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, subdir, &entries, filter_glob, do_lib, job_params->main_name, skip_currpar); } - for (entry = entries.first; entry; entry = entry->next) { + LISTBASE_FOREACH (FileListInternEntry *, entry, &entries) { entry->uid = filelist_uid_generate(filelist); /* When loading entries recursive, the rel_path should be relative from the root dir. @@ -3701,7 +3536,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, /* We have a directory we want to list, add it to todo list! */ BLI_join_dirfile(dir, sizeof(dir), root, entry->relpath); BLI_path_normalize_dir(job_params->main_name, dir); - td_dir = BLI_stack_push_r(todo_dirs); + td_dir = static_cast<TodoDir *>(BLI_stack_push_r(todo_dirs)); td_dir->level = recursion_level + 1; td_dir->dir = BLI_strdup(dir); dirs_todo_count++; @@ -3727,7 +3562,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, /* If we were interrupted by stop, stack may not be empty and we need to free * pending dir paths. */ while (!BLI_stack_is_empty(todo_dirs)) { - td_dir = BLI_stack_peek(todo_dirs); + td_dir = static_cast<TodoDir *>(BLI_stack_peek(todo_dirs)); MEM_freeN(td_dir->dir); BLI_stack_discard(todo_dirs); } @@ -3831,7 +3666,7 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, const char *id_code_name = BKE_idtype_idcode_to_name(GS(id_iter->name)); - entry = MEM_callocN(sizeof(*entry), __func__); + entry = MEM_cnew<FileListInternEntry>(__func__); entry->relpath = BLI_strdup(id_code_name); entry->name = id_iter->name + 2; entry->free_name = false; @@ -3935,7 +3770,7 @@ static bool filelist_readjob_is_partial_read(const FileListReadJob *read_job) */ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update, float *progress) { - FileListReadJob *flrj = flrjv; + FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv); // printf("START filelist reading (%d files, main thread: %d)\n", // flrj->filelist->filelist.entries_num, BLI_thread_is_main()); @@ -3944,7 +3779,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist); - flrj->tmp_filelist = MEM_dupallocN(flrj->filelist); + flrj->tmp_filelist = static_cast<FileList *>(MEM_dupallocN(flrj->filelist)); BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries); flrj->tmp_filelist->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET; @@ -3976,7 +3811,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update */ static void filelist_readjob_update(void *flrjv) { - FileListReadJob *flrj = flrjv; + FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv); FileListIntern *fl_intern = &flrj->filelist->filelist_intern; ListBase new_entries = {NULL}; int entries_num, new_entries_num = 0; @@ -4019,7 +3854,7 @@ static void filelist_readjob_update(void *flrjv) static void filelist_readjob_endjob(void *flrjv) { - FileListReadJob *flrj = flrjv; + FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv); /* In case there would be some dangling update... */ filelist_readjob_update(flrjv); @@ -4030,7 +3865,7 @@ static void filelist_readjob_endjob(void *flrjv) static void filelist_readjob_free(void *flrjv) { - FileListReadJob *flrj = flrjv; + FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv); // printf("END filelist reading (%d files)\n", flrj->filelist->filelist.entries_num); @@ -4060,7 +3895,7 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const } /* prepare job data */ - flrj = MEM_callocN(sizeof(*flrj), __func__); + flrj = MEM_cnew<FileListReadJob>(__func__); flrj->filelist = filelist; flrj->current_main = bmain; BLI_strncpy(flrj->main_name, BKE_main_blendfile_path(bmain), sizeof(flrj->main_name)); diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 4c1ae79eb22..89831483fdf 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -35,17 +35,6 @@ typedef enum FileCheckType { CHECK_ALL = 3, } FileCheckType; -/* not listbase itself */ -void folderlist_free(struct ListBase *folderlist); -void folderlist_popdir(struct ListBase *folderlist, char *dir); -void folderlist_pushdir(struct ListBase *folderlist, const char *dir); -const char *folderlist_peeklastdir(struct ListBase *folderlist); -int folderlist_clear_next(struct SpaceFile *sfile); - -void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile); -void folder_history_list_free(struct SpaceFile *sfile); -struct ListBase folder_history_list_duplicate(struct ListBase *listbase); - void filelist_setsorting(struct FileList *filelist, short sort, bool invert_sort); void filelist_sort(struct FileList *filelist); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index e42e1e98660..93aa5cf992d 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -665,12 +665,17 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile, } } -void fileselect_file_set(SpaceFile *sfile, const int index) +void fileselect_file_set(struct bContext *C, SpaceFile *sfile, const int index) { const struct FileDirEntry *file = filelist_file(sfile->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); + if (sfile->op) { + /* Update the filepath properties of the operator. */ + Main *bmain = CTX_data_main(C); + file_sfile_to_operator(C, bmain, sfile->op, sfile); + } } } @@ -1041,7 +1046,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) layout->attribute_column_header_h = 0; layout->offset_top = layout->attribute_column_header_h; layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y); - /* Padding by full scrollbar H is too much, can overlap tile border Y. */ + /* Padding by full scroll-bar H is too much, can overlap tile border Y. */ layout->rows = (layout->height - V2D_SCROLL_HEIGHT + layout->tile_border_y) / (layout->tile_h + 2 * layout->tile_border_y); layout->tile_w = VERTLIST_MAJORCOLUMN_WIDTH; @@ -1385,3 +1390,24 @@ ScrArea *ED_fileselect_handler_area_find_any_with_op(const wmWindow *win) return NULL; } + +void ED_fileselect_ensure_default_filepath(struct bContext *C, + struct wmOperator *op, + const char *extension) +{ + if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) { + struct Main *bmain = CTX_data_main(C); + char filepath[FILE_MAX]; + const char *blendfile_path = BKE_main_blendfile_path(bmain); + + if (blendfile_path[0] == '\0') { + BLI_strncpy(filepath, DATA_("untitled"), sizeof(filepath)); + } + else { + BLI_strncpy(filepath, blendfile_path, sizeof(filepath)); + } + + BLI_path_extension_replace(filepath, sizeof(filepath), extension); + RNA_string_set(op->ptr, "filepath", filepath); + } +} diff --git a/source/blender/editors/space_file/folder_history.cc b/source/blender/editors/space_file/folder_history.cc new file mode 100644 index 00000000000..1cb8fa279c5 --- /dev/null +++ b/source/blender/editors/space_file/folder_history.cc @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2007 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup spfile + * + * Storage for a list of folders for history backward and forward navigation. + */ + +#include <cstring> + +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "BKE_context.h" + +#include "DNA_space_types.h" + +#include "ED_fileselect.h" + +#include "MEM_guardedalloc.h" + +#include "file_intern.h" + +/* -------------------------------------------------------------------- */ +/** \name FOLDERLIST (previous/next) + * \{ */ + +typedef struct FolderList { + struct FolderList *next, *prev; + char *foldername; +} FolderList; + +void folderlist_popdir(struct ListBase *folderlist, char *dir) +{ + const char *prev_dir; + struct FolderList *folder; + folder = static_cast<FolderList *>(folderlist->last); + + if (folder) { + /* remove the current directory */ + MEM_freeN(folder->foldername); + BLI_freelinkN(folderlist, folder); + + folder = static_cast<FolderList *>(folderlist->last); + if (folder) { + prev_dir = folder->foldername; + BLI_strncpy(dir, prev_dir, FILE_MAXDIR); + } + } + /* Delete the folder next or use set-directory directly before PREVIOUS OP. */ +} + +void folderlist_pushdir(ListBase *folderlist, const char *dir) +{ + if (!dir[0]) { + return; + } + + struct FolderList *folder, *previous_folder; + previous_folder = static_cast<FolderList *>(folderlist->last); + + /* check if already exists */ + if (previous_folder && previous_folder->foldername) { + if (BLI_path_cmp(previous_folder->foldername, dir) == 0) { + return; + } + } + + /* create next folder element */ + folder = MEM_new<FolderList>(__func__); + folder->foldername = BLI_strdup(dir); + + /* add it to the end of the list */ + BLI_addtail(folderlist, folder); +} + +const char *folderlist_peeklastdir(ListBase *folderlist) +{ + struct FolderList *folder; + + if (!folderlist->last) { + return NULL; + } + + folder = static_cast<FolderList *>(folderlist->last); + return folder->foldername; +} + +bool folderlist_clear_next(struct SpaceFile *sfile) +{ + const FileSelectParams *params = ED_fileselect_get_active_params(sfile); + struct FolderList *folder; + + /* if there is no folder_next there is nothing we can clear */ + if (BLI_listbase_is_empty(sfile->folders_next)) { + return false; + } + + /* if previous_folder, next_folder or refresh_folder operators are executed + * it doesn't clear folder_next */ + folder = static_cast<FolderList *>(sfile->folders_prev->last); + if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) { + return false; + } + + /* eventually clear flist->folders_next */ + return true; +} + +void folderlist_free(ListBase *folderlist) +{ + if (folderlist) { + LISTBASE_FOREACH (FolderList *, folder, folderlist) { + MEM_freeN(folder->foldername); + } + BLI_freelistN(folderlist); + } +} + +static ListBase folderlist_duplicate(ListBase *folderlist) +{ + ListBase folderlistn = {NULL}; + + BLI_duplicatelist(&folderlistn, folderlist); + + LISTBASE_FOREACH (FolderList *, folder, &folderlistn) { + folder->foldername = (char *)MEM_dupallocN(folder->foldername); + } + return folderlistn; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Folder-History (wraps/owns file list above) + * \{ */ + +static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode) +{ + LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) { + if (history->browse_mode == browse_mode) { + return history; + } + } + + return NULL; +} + +void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile) +{ + FileFolderHistory *history = folder_history_find(sfile, (eFileBrowse_Mode)sfile->browse_mode); + + if (!history) { + history = MEM_cnew<FileFolderHistory>(__func__); + history->browse_mode = sfile->browse_mode; + BLI_addtail(&sfile->folder_histories, history); + } + + sfile->folders_next = &history->folders_next; + sfile->folders_prev = &history->folders_prev; +} + +static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history) +{ + if (sfile->folders_prev == &history->folders_prev) { + sfile->folders_prev = NULL; + } + if (sfile->folders_next == &history->folders_next) { + sfile->folders_next = NULL; + } + folderlist_free(&history->folders_prev); + folderlist_free(&history->folders_next); + BLI_freelinkN(&sfile->folder_histories, history); +} + +void folder_history_list_free(SpaceFile *sfile) +{ + LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) { + folder_history_entry_free(sfile, history); + } +} + +ListBase folder_history_list_duplicate(ListBase *listbase) +{ + ListBase histories = {NULL}; + + LISTBASE_FOREACH (FileFolderHistory *, history, listbase) { + FileFolderHistory *history_new = static_cast<FileFolderHistory *>(MEM_dupallocN(history)); + history_new->folders_prev = folderlist_duplicate(&history->folders_prev); + history_new->folders_next = folderlist_duplicate(&history->folders_next); + BLI_addtail(&histories, history_new); + } + + return histories; +} + +/** \} */ diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 310c688383b..35ce7ef364c 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -443,7 +443,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, if (STREQ(tfsm->path, fsm_iter->path)) { icon = tfsm->icon; if (tfsm->name[0] && (!name || !name[0])) { - name = tfsm->name; + name = DATA_(tfsm->name); } break; } @@ -519,7 +519,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx } } -void fsmenu_write_file(struct FSMenu *fsmenu, const char *filepath) +bool fsmenu_write_file(struct FSMenu *fsmenu, const char *filepath) { FSMenuEntry *fsm_iter = NULL; char fsm_name[FILE_MAX]; @@ -527,33 +527,36 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filepath) FILE *fp = BLI_fopen(filepath, "w"); if (!fp) { - return; + return false; } - fprintf(fp, "[Bookmarks]\n"); + bool has_error = false; + has_error |= (fprintf(fp, "[Bookmarks]\n") < 0); for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { if (fsm_iter->path && fsm_iter->save) { fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { - fprintf(fp, "!%s\n", fsm_iter->name); + has_error |= (fprintf(fp, "!%s\n", fsm_iter->name) < 0); } - fprintf(fp, "%s\n", fsm_iter->path); + has_error |= (fprintf(fp, "%s\n", fsm_iter->path) < 0); } } - fprintf(fp, "[Recent]\n"); + has_error = (fprintf(fp, "[Recent]\n") < 0); for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, nwritten++) { if (fsm_iter->path && fsm_iter->save) { fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { - fprintf(fp, "!%s\n", fsm_iter->name); + has_error |= (fprintf(fp, "!%s\n", fsm_iter->name) < 0); } - fprintf(fp, "%s\n", fsm_iter->path); + has_error |= (fprintf(fp, "%s\n", fsm_iter->path) < 0); } } fclose(fp); + + return !has_error; } void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filepath) diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h index 6e980a326fc..f4f0dafbc73 100644 --- a/source/blender/editors/space_file/fsmenu.h +++ b/source/blender/editors/space_file/fsmenu.h @@ -37,8 +37,11 @@ short fsmenu_can_save(struct FSMenu *fsmenu, enum FSMenuCategory category, int i /** Removes the fsmenu entry at the given \a index. */ void fsmenu_remove_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, int idx); -/** saves the 'bookmarks' to the specified file */ -void fsmenu_write_file(struct FSMenu *fsmenu, const char *filepath); +/** + * Saves the 'bookmarks' to the specified file. + * \return true on success. + */ +bool fsmenu_write_file(struct FSMenu *fsmenu, const char *filepath); /** reads the 'bookmarks' from the specified file */ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filepath); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index a462476aae0..bba0c27bb4d 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -426,7 +426,7 @@ static void file_reset_filelist_showing_main_data(ScrArea *area, SpaceFile *sfil static void file_listener(const wmSpaceTypeListenerParams *listener_params) { ScrArea *area = listener_params->area; - wmNotifier *wmn = listener_params->notifier; + const wmNotifier *wmn = listener_params->notifier; SpaceFile *sfile = (SpaceFile *)area->spacedata.first; /* context changes */ @@ -514,7 +514,7 @@ static void file_main_region_init(wmWindowManager *wm, ARegion *region) static void file_main_region_listener(const wmRegionListenerParams *listener_params) { ARegion *region = listener_params->region; - wmNotifier *wmn = listener_params->notifier; + const wmNotifier *wmn = listener_params->notifier; /* context changes */ switch (wmn->category) { @@ -820,7 +820,7 @@ static void file_execution_region_draw(const bContext *C, ARegion *region) static void file_ui_region_listener(const wmRegionListenerParams *listener_params) { ARegion *region = listener_params->region; - wmNotifier *wmn = listener_params->notifier; + const wmNotifier *wmn = listener_params->notifier; /* context changes */ switch (wmn->category) { @@ -992,7 +992,7 @@ void ED_spacetype_file(void) ARegionType *art; st->spaceid = SPACE_FILE; - strncpy(st->name, "File", BKE_ST_MAXNAME); + STRNCPY(st->name, "File"); st->create = file_create; st->free = file_free; |