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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_file')
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_file/file_draw.c14
-rw-r--r--source/blender/editors/space_file/file_intern.h23
-rw-r--r--source/blender/editors/space_file/file_ops.c174
-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.h11
-rw-r--r--source/blender/editors/space_file/filesel.c30
-rw-r--r--source/blender/editors/space_file/folder_history.cc199
-rw-r--r--source/blender/editors/space_file/fsmenu.c21
-rw-r--r--source/blender/editors/space_file/fsmenu.h7
-rw-r--r--source/blender/editors/space_file/space_file.c8
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;