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/windowmanager/intern/wm_files.c')
-rw-r--r--source/blender/windowmanager/intern/wm_files.c166
1 files changed, 73 insertions, 93 deletions
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index a301b17227d..1d3fa158ac1 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -111,6 +111,7 @@
#include "ED_fileselect.h"
#include "ED_image.h"
#include "ED_outliner.h"
+#include "ED_render.h"
#include "ED_screen.h"
#include "ED_undo.h"
#include "ED_util.h"
@@ -170,9 +171,6 @@ void WM_file_tag_modified(void)
}
}
-/**
- * Check if there is data that would be lost when closing the current file without saving.
- */
bool wm_file_or_session_data_has_unsaved_changes(const Main *bmain, const wmWindowManager *wm)
{
return !wm->file_saved || ED_image_should_save_modified(bmain) ||
@@ -620,6 +618,8 @@ static void wm_file_read_pre(bContext *C, bool use_data, bool UNUSED(use_userdef
/* Always do this as both startup and preferences may have loaded in many font's
* at a different zoom level to the file being loaded. */
UI_view2d_zoom_cache_reset();
+
+ ED_preview_restart_queue_free();
}
/**
@@ -955,16 +955,6 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* #BKE_blendfile_read_result_setup sets new Main into context. */
Main *bmain = CTX_data_main(C);
- /* When recovering a session from an unsaved file, this can have a blank path. */
- if (BKE_main_blendfile_path(bmain)[0] != '\0') {
- G.save_over = 1;
- G.relbase_valid = 1;
- }
- else {
- G.save_over = 0;
- G.relbase_valid = 0;
- }
-
/* match the read WM with current WM */
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
WM_check(C); /* opens window(s), checks keymaps */
@@ -1032,12 +1022,6 @@ static struct {
bool override;
} wm_init_state_app_template = {{0}};
-/**
- * Used for setting app-template from the command line:
- * - non-empty string: overrides.
- * - empty string: override, using no app template.
- * - NULL: clears override.
- */
void WM_init_state_app_template_set(const char *app_template)
{
if (app_template) {
@@ -1061,16 +1045,6 @@ const char *WM_init_state_app_template_get(void)
/** \name Read Startup & Preferences Blend-File API
* \{ */
-/**
- * Called on startup, (context entirely filled with NULLs)
- * or called for 'New File' both `startup.blend` and `userpref.blend` are checked.
- *
- * \param r_params_file_read_post: Support postponed initialization,
- * needed for initial startup when only some sub-systems have been initialized.
- * When non-null, #wm_file_read_post doesn't run, instead it's arguments are stored
- * in this return argument.
- * The caller is responsible for calling #wm_homefile_read_post with this return argument.
- */
void wm_homefile_read_ex(bContext *C,
const struct wmHomeFileRead_Params *params_homefile,
ReportList *reports,
@@ -1167,8 +1141,6 @@ void wm_homefile_read_ex(bContext *C,
wm_file_read_pre(C, use_data, use_userdef);
if (use_data) {
- G.relbase_valid = 0;
-
/* put aside screens to match with persistent windows later */
wm_window_match_init(C, &wmbase);
}
@@ -1372,10 +1344,7 @@ void wm_homefile_read_ex(bContext *C,
if (use_data) {
WM_check(C); /* opens window(s), checks keymaps */
- bmain->name[0] = '\0';
-
- /* start with save preference untitled.blend */
- G.save_over = 0;
+ bmain->filepath[0] = '\0';
}
{
@@ -1406,10 +1375,6 @@ void wm_homefile_read(bContext *C,
wm_homefile_read_ex(C, params_homefile, reports, NULL);
}
-/**
- * Special case, support deferred execution of #wm_file_read_post,
- * Needed when loading for the first time to workaround order of initialization bug, see T89046.
- */
void wm_homefile_read_post(struct bContext *C,
const struct wmFileReadPost_Params *params_file_read_post)
{
@@ -1417,6 +1382,8 @@ void wm_homefile_read_post(struct bContext *C,
MEM_freeN((void *)params_file_read_post);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Blend-File History API
* \{ */
@@ -1514,18 +1481,18 @@ static void wm_history_file_write(void)
static void wm_history_file_update(void)
{
RecentFile *recent;
- const char *blendfile_name = BKE_main_blendfile_path_from_global();
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
- /* no write history for recovered startup files */
- if (blendfile_name[0] == '\0') {
+ /* No write history for recovered startup files. */
+ if (blendfile_path[0] == '\0') {
return;
}
recent = G.recent_files.first;
/* refresh recent-files.txt of recent opened files, when current file was changed */
- if (!(recent) || (BLI_path_cmp(recent->filepath, blendfile_name) != 0)) {
+ if (!(recent) || (BLI_path_cmp(recent->filepath, blendfile_path) != 0)) {
- recent = wm_file_history_find(blendfile_name);
+ recent = wm_file_history_find(blendfile_path);
if (recent) {
BLI_remlink(&G.recent_files, recent);
}
@@ -1536,7 +1503,7 @@ static void wm_history_file_update(void)
recent_next = recent->next;
wm_history_file_free(recent);
}
- recent = wm_history_file_new(blendfile_name);
+ recent = wm_history_file_new(blendfile_path);
}
/* add current file to the beginning of list */
@@ -1546,7 +1513,7 @@ static void wm_history_file_update(void)
wm_history_file_write();
/* also update most recent files on System */
- GHOST_addToSystemRecentFiles(blendfile_name);
+ GHOST_addToSystemRecentFiles(blendfile_path);
}
}
@@ -1721,7 +1688,6 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C,
return ibuf;
}
-/* easy access from gdb */
bool write_crash_blend(void)
{
char path[FILE_MAX];
@@ -1817,8 +1783,9 @@ static bool wm_file_write(bContext *C,
if (file_preview_type == USER_FILE_PREVIEW_AUTO) {
Scene *scene = CTX_data_scene(C);
- bool do_render = (scene != NULL && scene->camera != NULL &&
- (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL));
+ bScreen *screen = CTX_wm_screen(C);
+ bool do_render = (scene != NULL && scene->camera != NULL && screen != NULL &&
+ (BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0) != NULL));
file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT;
}
@@ -1846,16 +1813,10 @@ static bool wm_file_write(bContext *C,
ED_editors_flush_edits(bmain);
- /* First time saving. */
- /* XXX(ton): temp solution to solve bug, real fix coming. */
- if ((BKE_main_blendfile_path(bmain)[0] == '\0') && (use_save_as_copy == false)) {
- BLI_strncpy(bmain->name, filepath, sizeof(bmain->name));
- }
-
/* XXX(ton): temp solution to solve bug, real fix coming. */
bmain->recovered = 0;
- if (BLO_write_file(CTX_data_main(C),
+ if (BLO_write_file(bmain,
filepath,
fileflags,
&(const struct BlendFileWriteParams){
@@ -1869,10 +1830,7 @@ static bool wm_file_write(bContext *C,
(CTX_wm_manager(C)->op_undo_depth == 0);
if (use_save_as_copy == false) {
- G.relbase_valid = 1;
- BLI_strncpy(bmain->name, filepath, sizeof(bmain->name)); /* is guaranteed current file */
-
- G.save_over = 1; /* disable untitled.blend convention */
+ STRNCPY(bmain->filepath, filepath); /* is guaranteed current file */
}
SET_FLAG_FROM_TEST(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS);
@@ -1923,8 +1881,13 @@ static void wm_autosave_location(char *filepath)
const char *savedir;
#endif
- if (G_MAIN && G.relbase_valid) {
- const char *basename = BLI_path_basename(BKE_main_blendfile_path_from_global());
+ /* Normally there is no need to check for this to be NULL,
+ * however this runs on exit when it may be cleared. */
+ Main *bmain = G_MAIN;
+ const char *blendfile_path = bmain ? BKE_main_blendfile_path(bmain) : NULL;
+
+ if (blendfile_path && (blendfile_path[0] != '\0')) {
+ const char *basename = BLI_path_basename(blendfile_path);
int len = strlen(basename) - 6;
BLI_snprintf(path, sizeof(path), "%.*s_%d_autosave.blend", len, basename, pid);
}
@@ -2006,9 +1969,6 @@ void WM_autosave_init(wmWindowManager *wm)
wm_autosave_timer_begin(wm);
}
-/**
- * Run the auto-save timer action.
- */
void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer *UNUSED(wt))
{
wm_autosave_timer_end(wm);
@@ -2137,7 +2097,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
fileflags,
&(const struct BlendFileWriteParams){
/* Make all paths absolute when saving the startup file.
- * On load the `G.relbase_valid` will be false so the paths
+ * On load the `G.main->filepath` will be empty so the paths
* won't have a base for resolving the relative paths. */
.remap_mode = BLO_WRITE_PATH_REMAP_ABSOLUTE,
/* Don't apply any path changes to the current blend file. */
@@ -2150,7 +2110,6 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
printf("ok\n");
BKE_report(op->reports, RPT_INFO, "Startup file saved");
- G.save_over = 0;
BKE_callback_exec_null(bmain, BKE_CB_EVT_SAVE_POST);
@@ -2637,7 +2596,7 @@ static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op)
set_next_operator_state(op, OPEN_MAINFILE_STATE_OPEN);
Main *bmain = CTX_data_main(C);
- const char *openname = BKE_main_blendfile_path(bmain);
+ const char *blendfile_path = BKE_main_blendfile_path(bmain);
if (CTX_wm_window(C) == NULL) {
/* in rare cases this could happen, when trying to invoke in background
@@ -2650,10 +2609,10 @@ static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op)
/* if possible, get the name of the most recently used .blend file */
if (G.recent_files.first) {
struct RecentFile *recent = G.recent_files.first;
- openname = recent->filepath;
+ blendfile_path = recent->filepath;
}
- RNA_string_set(op->ptr, "filepath", openname);
+ RNA_string_set(op->ptr, "filepath", blendfile_path);
wm_open_init_load_ui(op, true);
wm_open_init_use_scripts(op, true);
op->customdata = NULL;
@@ -2876,7 +2835,8 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
static bool wm_revert_mainfile_poll(bContext *UNUSED(C))
{
- return G.relbase_valid;
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
+ return (blendfile_path[0] != '\0');
}
void WM_OT_revert_mainfile(wmOperatorType *ot)
@@ -3033,9 +2993,9 @@ void WM_OT_recover_auto_save(wmOperatorType *ot)
* Both #WM_OT_save_as_mainfile & #WM_OT_save_mainfile.
* \{ */
-static void wm_filepath_default(char *filepath)
+static void wm_filepath_default(const Main *bmain, char *filepath)
{
- if (G.save_over == false) {
+ if (bmain->filepath[0] == '\0') {
BLI_path_filename_ensure(filepath, FILE_MAX, "untitled.blend");
}
}
@@ -3046,7 +3006,8 @@ static void save_set_compress(wmOperator *op)
prop = RNA_struct_find_property(op->ptr, "compress");
if (!RNA_property_is_set(op->ptr, prop)) {
- if (G.save_over) { /* keep flag for existing file */
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
+ if (blendfile_path[0] != '\0') { /* Keep flag for existing file. */
RNA_property_boolean_set(op->ptr, prop, (G.fileflags & G_FILE_COMPRESS) != 0);
}
else { /* use userdef for new file */
@@ -3059,21 +3020,22 @@ static void save_set_filepath(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
- char name[FILE_MAX];
+ char filepath[FILE_MAX];
prop = RNA_struct_find_property(op->ptr, "filepath");
if (!RNA_property_is_set(op->ptr, prop)) {
+ const char *blendfile_path = BKE_main_blendfile_path(bmain);
/* if not saved before, get the name of the most recently used .blend file */
- if (BKE_main_blendfile_path(bmain)[0] == '\0' && G.recent_files.first) {
+ if ((blendfile_path[0] == '\0') && G.recent_files.first) {
struct RecentFile *recent = G.recent_files.first;
- BLI_strncpy(name, recent->filepath, FILE_MAX);
+ STRNCPY(filepath, recent->filepath);
}
else {
- BLI_strncpy(name, bmain->name, FILE_MAX);
+ STRNCPY(filepath, blendfile_path);
}
- wm_filepath_default(name);
- RNA_property_string_set(op->ptr, prop, name);
+ wm_filepath_default(bmain, filepath);
+ RNA_property_string_set(op->ptr, prop, filepath);
}
}
@@ -3105,12 +3067,32 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
BLO_WRITE_PATH_REMAP_NONE;
save_set_compress(op);
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
+ const bool is_filepath_set = RNA_struct_property_is_set(op->ptr, "filepath");
+ if (is_filepath_set) {
RNA_string_get(op->ptr, "filepath", path);
}
else {
- BLI_strncpy(path, BKE_main_blendfile_path(bmain), FILE_MAX);
- wm_filepath_default(path);
+ STRNCPY(path, BKE_main_blendfile_path(bmain));
+ }
+
+ if (path[0] == '\0') {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Unable to save an unsaved file with an empty or unset \"filepath\" property");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* NOTE(@campbellbarton): only check this for file-path properties so saving an already
+ * saved file never fails with an error.
+ * Even though this should never happen, there may be some corner case where a malformed
+ * path is stored in `G.main->filepath`: when the file path is initialized from recovering
+ * a blend file - for example, so in this case failing to save isn't ideal. */
+ if (is_filepath_set && !BLI_path_is_abs_from_cwd(path)) {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "The \"filepath\" property was not an absolute path: \"%s\"",
+ path);
+ return OPERATOR_CANCELLED;
}
const int fileflags_orig = G.fileflags;
@@ -3227,14 +3209,15 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
/* if we're saving for the first time and prefer relative paths -
* any existing paths will be absolute,
* enable the option to remap paths to avoid confusion T37240. */
- if ((G.relbase_valid == false) && (U.flag & USER_RELPATHS)) {
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
+ if ((blendfile_path[0] == '\0') && (U.flag & USER_RELPATHS)) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "relative_remap");
if (!RNA_property_is_set(op->ptr, prop)) {
RNA_property_boolean_set(op->ptr, prop, true);
}
}
- if (G.save_over) {
+ if (blendfile_path[0] != '\0') {
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);
@@ -3336,6 +3319,7 @@ static uiBlock *block_create_autorun_warning(struct bContext *C,
struct ARegion *region,
void *UNUSED(arg1))
{
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
wmWindowManager *wm = CTX_wm_manager(C);
uiBlock *block = UI_block_begin(C, region, "autorun_warning_popup", UI_EMBOSS);
@@ -3383,7 +3367,7 @@ static uiBlock *block_create_autorun_warning(struct bContext *C,
/* Allow reload if we have a saved file.
* Otherwise just enable scripts and reset the depsgraphs. */
- if (G.relbase_valid && wm->file_saved) {
+ if ((blendfile_path[0] != '\0') && wm->file_saved) {
but = uiDefIconTextBut(block,
UI_BTYPE_BUT,
0,
@@ -3640,10 +3624,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C,
uiItemL_ex(layout, TIP_("Save changes before closing?"), ICON_NONE, true, false);
/* Filename. */
- const char *blendfile_pathpath = BKE_main_blendfile_path(CTX_data_main(C));
+ const char *blendfile_path = BKE_main_blendfile_path(CTX_data_main(C));
char filename[FILE_MAX];
- if (blendfile_pathpath[0] != '\0') {
- BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename));
+ if (blendfile_path[0] != '\0') {
+ BLI_split_file_part(blendfile_path, filename, sizeof(filename));
}
else {
STRNCPY(filename, "untitled.blend");
@@ -3810,10 +3794,6 @@ static void wm_free_operator_properties_callback(void *user_data)
IDP_FreeProperty(properties);
}
-/**
- * \return True if the dialog was created, the calling operator should return #OPERATOR_INTERFACE
- * then.
- */
bool wm_operator_close_file_dialog_if_needed(bContext *C,
wmOperator *op,
wmGenericCallbackFn post_action_fn)