diff options
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 248 |
1 files changed, 212 insertions, 36 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index f0d201ea3f7..3aa425bdbb9 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -80,8 +80,11 @@ #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_sound.h" + #include "RE_pipeline.h" +#include "BLF_api.h" + #include "BLO_undofile.h" #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -230,6 +233,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* but use new Scene pointer */ curscene = bfd->curscene; if (curscene == NULL) curscene = bfd->main->scene.first; + /* empty file, we add a scene to make Blender work */ + if (curscene == NULL) curscene = BKE_main_scene_add(bfd->main, "Empty"); + /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ @@ -270,7 +276,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); - CTX_data_scene_set(C, bfd->curscreen->scene); + CTX_data_scene_set(C, bfd->curscene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); @@ -310,22 +316,23 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); - if (recover && bfd->filename[0] && G.relbase_valid) { + G.main->recovered = 0; + + /* startup.blend or recovered startup */ + if (bfd->filename[0] == 0) { + G.main->name[0] = 0; + } + else if (recover && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */ filepath = bfd->filename; + G.main->recovered = 1; + + /* these are the same at times, should never copy to the same location */ + if (G.main->name != filepath) + BLI_strncpy(G.main->name, filepath, FILE_MAX); } -#if 0 - else if (!G.relbase_valid) { - /* otherwise, use an empty string as filename, rather than <memory2> */ - filepath = ""; - } -#endif - /* these are the same at times, should never copy to the same location */ - if (G.main->name != filepath) - BLI_strncpy(G.main->name, filepath, FILE_MAX); - /* baseflags, groups, make depsgraph, etc */ BKE_scene_set_background(G.main, CTX_data_scene(C)); @@ -334,7 +341,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath } MEM_freeN(bfd); - + (void)curscene; /* quiet warning */ } @@ -393,6 +400,14 @@ void BKE_userdef_free(void) BLI_freelistN(&U.addons); } +/* handle changes in settings that need recalc */ +void BKE_userdef_state(void) +{ + BLF_default_dpi(U.pixelsize * U.dpi); + U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; + +} + int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) { BlendFileData *bfd; @@ -439,14 +454,57 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report BlendFileData *bfd; bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports); - if (bfd) + if (bfd) { + /* remove the unused screens and wm */ + while (bfd->main->wm.first) + BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first); + while (bfd->main->screen.first) + BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first); + setup_app_data(C, bfd, "<memory1>"); + } else BKE_reports_prepend(reports, "Loading failed: "); return (bfd ? 1 : 0); } +/* only read the userdef from a .blend */ +int BKE_read_file_userdef(const char *filepath, ReportList *reports) +{ + BlendFileData *bfd; + int retval = 0; + + bfd = BLO_read_from_file(filepath, reports); + if (bfd->user) { + retval = BKE_READ_FILE_OK_USERPREFS; + + /* only here free userdef themes... */ + BKE_userdef_free(); + + U = *bfd->user; + MEM_freeN(bfd->user); + } + free_main(bfd->main); + MEM_freeN(bfd); + + return retval; +} + +/* only write the userdef in a .blend */ +int BKE_write_file_userdef(const char *filepath, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "empty main"); + int retval = 0; + + if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) { + retval = 1; + } + + MEM_freeN(mainb); + + return retval; +} /* ***************** testing for break ************* */ @@ -728,48 +786,39 @@ char *BKE_undo_menu_string(void) return menu; } -/* saves quit.blend */ -void BKE_undo_save_quit(void) +/* saves .blend using undo buffer, returns 1 == success */ +int BKE_undo_save_file(const bContext *C, char *filename) { UndoElem *uel; MemFileChunk *chunk; - char str[FILE_MAX]; const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL; int file; if ((U.uiflag & USER_GLOBALUNDO) == 0) { - return; + return 0; } uel = curundo; if (uel == NULL) { fprintf(stderr, "No undo buffer to save recovery file\n"); - return; + return 0; } - /* no undo state to save */ - if (undobase.first == undobase.last) { - return; - } - - /* save the undo state as quit.blend */ - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); - /* first try create the file, if it exists call without 'O_CREAT', * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ errno = 0; - file = BLI_open(str, flag, 0666); + file = BLI_open(filename, flag, 0666); if (file == -1) { if (errno == EEXIST) { errno = 0; - file = BLI_open(str, flag & ~O_CREAT, 0666); + file = BLI_open(filename, flag & ~O_CREAT, 0666); } } if (file == -1) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error opening file"); - return; + filename, errno ? strerror(errno) : "Unknown error opening file"); + return 0; } for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { @@ -777,16 +826,15 @@ void BKE_undo_save_quit(void) break; } } - + close(file); if (chunk) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error writing file"); - } - else { - printf("Saved session recovery to '%s'\n", str); + filename, errno ? strerror(errno) : "Unknown error writing file"); + return 0; } + return 1; } /* sets curscene */ @@ -806,3 +854,131 @@ Main *BKE_undo_get_main(Scene **scene) return mainp; } +/* ************** copy paste .blend, partial saves ********** */ + +/* assumes data is in G.main */ + +void BKE_copybuffer_begin(void) +{ + /* set all id flags to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); +} + +void BKE_copybuffer_tag_ID(ID *id) +{ + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; +} + +static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) +{ + if (vid) { + ID *id = vid; + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; + } +} + +/* frees main in end */ +int BKE_copybuffer_save(char *filename, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "copybuffer"); + ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY]; + int a, retval; + + BLO_main_expander(copybuffer_doit); + BLO_expand_main(NULL, G.main); + + /* move over all tagged blocks */ + set_listbasepointers(G.main, fromarray); + a = set_listbasepointers(mainb, lbarray); + while (a--) { + ID *id, *nextid; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + for (id = lb2->first; id; id= nextid) { + nextid = id->next; + if (id->flag & LIB_DOIT) { + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + } + } + } + + + /* save the buffer */ + retval = BLO_write_file(mainb, filename, 0, reports, NULL); + + /* move back the main, now sorted again */ + set_listbasepointers(G.main, lbarray); + a = set_listbasepointers(mainb, fromarray); + while (a--) { + ID *id; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + while (lb2->first) { + id = lb2->first; + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + id_sort_by_name(lb1, id); + } + } + + MEM_freeN(mainb); + + /* set id flag to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); + + return retval; +} + +/* return success (1) */ +int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Main *mainl = NULL; + Library *lib; + BlendHandle *bh; + + bh = BLO_blendhandle_from_file(libname, reports); + + if (bh == NULL) { + /* error reports will have been made by BLO_blendhandle_from_file() */ + return 0; + } + + BKE_scene_base_deselect_all(scene); + + /* tag everything, all untagged data can be made local + * its also generally useful to know what is new + * + * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 1); + + /* here appending/linking starts */ + mainl = BLO_library_append_begin(bmain, &bh, libname); + + BLO_library_append_all(mainl, bh); + + BLO_library_append_end(C, mainl, &bh, 0, 0); + + /* mark all library linked objects to be updated */ + recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); + + /* append, rather than linking */ + lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); + BKE_library_make_local(bmain, lib, 1); + + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 0); + + /* recreate dependency graph to include new objects */ + DAG_scene_sort(bmain, scene); + DAG_ids_flush_update(bmain, 0); + + BLO_blendhandle_close(bh); + /* remove library... */ + + return 1; +} |