int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports) { Library *li; int len; int *thumb = NULL; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); return -1; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); return -1; } /* note: used to replace the file extension (to ensure '.blend'), * no need to now because the operator ensures, * its handy for scripts to save to a predefined name without blender editing it */ /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return -1; } } /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { packAll(G.main, reports); } ED_object_editmode_load(CTX_data_edit_object(C)); ED_sculpt_force_update(C); /* don't forget not to return without! */ WM_cursor_wait(1); fileflags |= G_FILE_HISTORY; /* write file history */ /* first time saving */ /* XXX temp solution to solve bug, real fix coming (ton) */ if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) { BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); } /* XXX temp solution to solve bug, real fix coming (ton) */ G.main->recovered = 0; if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */ G.save_over = 1; /* disable untitled.blend convention */ } if (fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS; else G.fileflags &= ~G_FILE_COMPRESS; if (fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY; else G.fileflags &= ~G_FILE_AUTOPLAY; /* prevent background mode scripts from clobbering history */ if (!G.background) { write_history(); } BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); /* run this function after because the file cant be written before the blend is */ if (ibuf_thumb) { IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb); IMB_freeImBuf(ibuf_thumb); } if (thumb) MEM_freeN(thumb); } else { if (ibuf_thumb) IMB_freeImBuf(ibuf_thumb); if (thumb) MEM_freeN(thumb); WM_cursor_wait(0); return -1; } WM_cursor_wait(0); return 0; }
/** * \see #wm_homefile_write_exec wraps #BLO_write_file in a similar way. */ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports) { Library *li; int len; int ret = -1; BlendThumbnail *thumb, *main_thumb; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); return ret; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); return ret; } /* Check if file write permission is ok */ if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) { BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath); return ret; } /* note: used to replace the file extension (to ensure '.blend'), * no need to now because the operator ensures, * its handy for scripts to save to a predefined name without blender editing it */ /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return ret; } } /* Call pre-save callbacks befores writing preview, that way you can generate custom file thumbnail... */ BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */ main_thumb = thumb = CTX_data_main(C)->blen_thumb; if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { packAll(G.main, reports, false); } /* don't forget not to return without! */ WM_cursor_wait(1); ED_editors_flush_edits(C, false); fileflags |= G_FILE_HISTORY; /* write file history */ /* first time saving */ /* XXX temp solution to solve bug, real fix coming (ton) */ if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) { BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); } /* XXX temp solution to solve bug, real fix coming (ton) */ G.main->recovered = 0; if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0); if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */ G.save_over = 1; /* disable untitled.blend convention */ } BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS); BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_AUTOPLAY, G_FILE_AUTOPLAY); /* prevent background mode scripts from clobbering history */ if (do_history) { wm_history_file_update(); } BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); /* run this function after because the file cant be written before the blend is */ if (ibuf_thumb) { IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_LARGE, THB_SOURCE_BLEND, ibuf_thumb); } ret = 0; /* Success. */ } if (ibuf_thumb) { IMB_freeImBuf(ibuf_thumb); } if (thumb && thumb != main_thumb) { MEM_freeN(thumb); } WM_cursor_wait(0); return ret; }
int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *reports, int copy) { Library *li; int len; char filepath[FILE_MAX]; int *thumb = NULL; ImBuf *ibuf_thumb = NULL; len = strlen(target); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); return -1; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); return -1; } BLI_strncpy(filepath, target, FILE_MAX); BLI_replace_extension(filepath, FILE_MAX, ".blend"); /* don't use 'target' anymore */ /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath); return -1; } } /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ if (U.flag & USER_SAVE_PREVIEWS) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } BLI_exec_cb(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { packAll(G.main, reports); } ED_object_exit_editmode(C, EM_DO_UNDO); ED_sculpt_force_update(C); /* don't forget not to return without! */ WM_cursor_wait(1); fileflags |= G_FILE_HISTORY; /* write file history */ if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if (!copy) { G.relbase_valid = 1; BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */ G.save_over = 1; /* disable untitled.blend convention */ } if (fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS; else G.fileflags &= ~G_FILE_COMPRESS; if (fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY; else G.fileflags &= ~G_FILE_AUTOPLAY; /* prevent background mode scripts from clobbering history */ if (!G.background) { write_history(); } BLI_exec_cb(G.main, NULL, BLI_CB_EVT_SAVE_POST); /* run this function after because the file cant be written before the blend is */ if (ibuf_thumb) { IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb); IMB_freeImBuf(ibuf_thumb); } if (thumb) MEM_freeN(thumb); } else { if (ibuf_thumb) IMB_freeImBuf(ibuf_thumb); if (thumb) MEM_freeN(thumb); WM_cursor_wait(0); return -1; } WM_cursor_wait(0); return 0; }