diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_files.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 170 |
1 files changed, 106 insertions, 64 deletions
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index f0b8577be47..644320b0566 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -49,6 +49,7 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" +#include "BLI_utildefines.h" #include "DNA_anim_types.h" #include "DNA_ipo_types.h" // XXX old animation system @@ -72,7 +73,7 @@ #include "BKE_report.h" #include "BKE_sound.h" #include "BKE_texture.h" -#include "BKE_utildefines.h" + #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -91,12 +92,13 @@ #include "ED_util.h" #include "GHOST_C-api.h" +#include "GHOST_Path-api.h" #include "UI_interface.h" #include "GPU_draw.h" -#ifndef DISABLE_PYTHON +#ifdef WITH_PYTHON #include "BPY_extern.h" #endif @@ -116,7 +118,7 @@ static void write_history(void); */ static void wm_window_match_init(bContext *C, ListBase *wmlist) { - wmWindowManager *wm= G.main->wm.first; + wmWindowManager *wm; wmWindow *win, *active_win; *wmlist= G.main->wm; @@ -195,7 +197,7 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) else win->screen= ED_screen_duplicate(win, screen); - BLI_strncpy(win->screenname, win->screen->id.name+2, 21); + BLI_strncpy(win->screenname, win->screen->id.name+2, sizeof(win->screenname)); win->screen->winid= win->winid; } } @@ -250,8 +252,6 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* in case UserDef was read, we re-initialize all, and do versioning */ static void wm_init_userdef(bContext *C) { - extern char btempdir[]; - UI_init_userdef(); MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024); sound_init(CTX_data_main(C)); @@ -259,24 +259,25 @@ static void wm_init_userdef(bContext *C) /* set the python auto-execute setting from user prefs */ /* disabled by default, unless explicitly enabled in the command line */ if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) G.f |= G_SCRIPT_AUTOEXEC; - - if(U.tempdir[0]) strncpy(btempdir, U.tempdir, FILE_MAXDIR+FILE_MAXFILE); + if(U.tempdir[0]) BLI_where_is_temp(btempdir, 1); } -void WM_read_file(bContext *C, char *name, ReportList *reports) +void WM_read_file(bContext *C, const char *name, ReportList *reports) { int retval; /* so we can get the error message */ errno = 0; + WM_cursor_wait(1); + /* first try to append data from exotic file formats... */ /* it throws error box when file doesnt exist and returns -1 */ /* note; it should set some error message somewhere... (ton) */ retval= BKE_read_exotic(CTX_data_scene(C), name); /* we didn't succeed, now try to read Blender file */ - if (retval== 0) { + if (retval == BKE_READ_EXOTIC_OK_BLEND) { int G_f= G.f; ListBase wmbase; @@ -284,7 +285,7 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) /* also exit screens and editors */ wm_window_match_init(C, &wmbase); - retval= BKE_read_file(C, name, NULL, reports); + retval= BKE_read_file(C, name, reports); G.save_over = 1; /* this flag is initialized by the operator but overwritten on read. @@ -298,17 +299,14 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) // XXX mainwindow_set_filename_to_title(G.main->name); - if(retval==2) wm_init_userdef(C); // in case a userdef is read from regular .blend + if(retval == BKE_READ_FILE_OK_USERPREFS) wm_init_userdef(C); // in case a userdef is read from regular .blend - if (retval!=0) { + if (retval != BKE_READ_FILE_FAIL) { G.relbase_valid = 1; if(!G.background) /* assume automated tasks with background, dont write recent file list */ write_history(); } -// XXX undo_editmode_clear(); - BKE_reset_undo(); - BKE_write_undo(C, "original"); /* save current state */ WM_event_add_notifier(C, NC_WM|ND_FILEREAD, NULL); // refresh_interface_font(); @@ -316,35 +314,49 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); ED_editors_init(C); - DAG_on_load_update(CTX_data_main(C)); + DAG_on_load_update(CTX_data_main(C), TRUE); -#ifndef DISABLE_PYTHON +#ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ - BPY_load_user_modules(C); + BPY_driver_reset(); + BPY_modules_load_user(C); #endif CTX_wm_window_set(C, NULL); /* exits queues */ + + // XXX undo_editmode_clear(); + BKE_reset_undo(); + BKE_write_undo(C, "original"); /* save current state */ + } - else if(retval==1) + else if(retval == BKE_READ_EXOTIC_OK_OTHER) BKE_write_undo(C, "Import file"); - else if(retval == -1) { - if(reports) - BKE_reportf(reports, RPT_ERROR, "Can't read file: \"%s\", %s.", name, errno ? strerror(errno) : "Incompatible file format"); + else if(retval == BKE_READ_EXOTIC_FAIL_OPEN) { + BKE_reportf(reports, RPT_ERROR, "Can't read file: \"%s\", %s.", name, errno ? strerror(errno) : "Unable to open the file"); + } + else if(retval == BKE_READ_EXOTIC_FAIL_FORMAT) { + BKE_reportf(reports, RPT_ERROR, "File format is not supported in file: \"%s\".", name); } + else if(retval == BKE_READ_EXOTIC_FAIL_PATH) { + BKE_reportf(reports, RPT_ERROR, "File path invalid: \"%s\".", name); + } + else { + BKE_reportf(reports, RPT_ERROR, "Unknown error loading: \"%s\".", name); + BLI_assert(!"invalid 'retval'"); + } + + WM_cursor_wait(0); + } /* called on startup, (context entirely filled with NULLs) */ /* or called for 'New File' */ /* op can be NULL */ -/* note: G.sce is used to store the last saved path so backup and restore after loading - * G.main->name is similar to G.sce but when loading from memory set the name to startup.blend - * ...this could be changed but seems better then setting to "" */ -int WM_read_homefile(bContext *C, wmOperator *op) +int WM_read_homefile(bContext *C, ReportList *reports, short from_memory) { ListBase wmbase; - char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR]; - int from_memory= op?RNA_boolean_get(op->ptr, "factory"):0; - int success; + char tstr[FILE_MAXDIR+FILE_MAXFILE]; + int success= 0; free_ttfont(); /* still weird... what does it here? */ @@ -352,16 +364,13 @@ int WM_read_homefile(bContext *C, wmOperator *op) if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { - BLI_make_file_string(G.sce, tstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); } else { tstr[0] = '\0'; from_memory = 1; - if (op) { - BKE_report(op->reports, RPT_INFO, "Config directory with startup.blend file found."); - } + BKE_report(reports, RPT_INFO, "Config directory with "STRINGIFY(BLENDER_STARTUP_FILE)" file not found."); } } - strcpy(scestr, G.sce); /* temporary store */ /* prevent loading no UI */ G.fileflags &= ~G_FILE_NO_UI; @@ -370,9 +379,15 @@ int WM_read_homefile(bContext *C, wmOperator *op) wm_window_match_init(C, &wmbase); if (!from_memory && BLI_exists(tstr)) { - success = BKE_read_file(C, tstr, NULL, NULL); - } else { - success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, NULL); + success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); + + if(U.themes.first==NULL) { + printf("\nError: No valid "STRINGIFY(BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); + success = 0; + } + } + if(success==0) { + success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); } @@ -384,7 +399,6 @@ int WM_read_homefile(bContext *C, wmOperator *op) wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ - strcpy(G.sce, scestr); /* restore */ G.main->name[0]= '\0'; wm_init_userdef(C); @@ -404,21 +418,33 @@ int WM_read_homefile(bContext *C, wmOperator *op) BKE_write_undo(C, "original"); /* save current state */ ED_editors_init(C); - DAG_on_load_update(CTX_data_main(C)); + DAG_on_load_update(CTX_data_main(C), TRUE); -#ifndef DISABLE_PYTHON +#ifdef WITH_PYTHON if(CTX_py_init_get(C)) { /* sync addons, these may have changed from the defaults */ - BPY_eval_string(C, "__import__('bpy').utils.addon_reset_all()"); + BPY_string_exec(C, "__import__('bpy').utils.addon_reset_all()"); + + BPY_driver_reset(); + BPY_modules_load_user(C); } #endif - + WM_event_add_notifier(C, NC_WM|ND_FILEREAD, NULL); - CTX_wm_window_set(C, NULL); /* exits queues */ - return OPERATOR_FINISHED; + /* in background mode the scene will stay NULL */ + if(!G.background) { + CTX_wm_window_set(C, NULL); /* exits queues */ + } + + return TRUE; } +int WM_read_homefile_exec(bContext *C, wmOperator *op) +{ + int from_memory= strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0; + return WM_read_homefile(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; +} void read_history(void) { @@ -441,9 +467,6 @@ void read_history(void) for (l= lines, num= 0; l && (num<U.recent_files); l= l->next) { line = l->link; if (line[0] && BLI_exists(line)) { - if (num==0) - strcpy(G.sce, line); /* note: this seems highly dodgy since the file isnt actually read. please explain. - campbell */ - recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile"); BLI_addtail(&(G.recent_files), recent); recent->filepath = (char*)MEM_mallocN(sizeof(char)*(strlen(line)+1), "name of file"); @@ -462,21 +485,27 @@ static void write_history(void) { struct RecentFile *recent, *next_recent; char name[FILE_MAXDIR+FILE_MAXFILE]; + char *user_config_dir; FILE *fp; int i; - BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_HISTORY_FILE); + /* will be NULL in background mode */ + user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); + if(!user_config_dir) + return; + + BLI_make_file_string("/", name, user_config_dir, BLENDER_HISTORY_FILE); recent = G.recent_files.first; /* refresh recent-files.txt of recent opened files, when current file was changed */ - if(!(recent) || (strcmp(recent->filepath, G.sce)!=0)) { + if(!(recent) || (strcmp(recent->filepath, G.main->name)!=0)) { fp= fopen(name, "w"); if (fp) { /* add current file to the beginning of list */ recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile"); - recent->filepath = (char*)MEM_mallocN(sizeof(char)*(strlen(G.sce)+1), "name of file"); + recent->filepath = (char*)MEM_mallocN(sizeof(char)*(strlen(G.main->name)+1), "name of file"); recent->filepath[0] = '\0'; - strcpy(recent->filepath, G.sce); + strcpy(recent->filepath, G.main->name); BLI_addhead(&(G.recent_files), recent); /* write current file to recent-files.txt */ fprintf(fp, "%s\n", recent->filepath); @@ -485,7 +514,7 @@ static void write_history(void) /* write rest of recent opened files to recent-files.txt */ while((i<U.recent_files) && (recent)){ /* this prevents to have duplicities in list */ - if (strcmp(recent->filepath, G.sce)!=0) { + if (strcmp(recent->filepath, G.main->name)!=0) { fprintf(fp, "%s\n", recent->filepath); recent = recent->next; } @@ -499,6 +528,9 @@ static void write_history(void) } fclose(fp); } + + /* also update most recent files on System */ + GHOST_addToSystemRecentFiles(G.main->name); } } @@ -527,7 +559,7 @@ static void do_history(char *name, ReportList *reports) BKE_report(reports, RPT_ERROR, "Unable to make version backup"); } -static ImBuf *blend_file_thumb(const char *path, Scene *scene, int **thumb_pt) +static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -573,7 +605,7 @@ static ImBuf *blend_file_thumb(const char *path, Scene *scene, int **thumb_pt) int write_crash_blend(void) { char path[FILE_MAX]; - BLI_strncpy(path, G.sce, sizeof(path)); + BLI_strncpy(path, G.main->name, sizeof(path)); BLI_replace_extension(path, sizeof(path), "_crash.blend"); if(BLO_write_file(G.main, path, G.fileflags, NULL, NULL)) { printf("written: %s\n", path); @@ -613,7 +645,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re /* send the OnSave event */ for (li= G.main->library.first; li; li= li->id.next) { if (strcmp(li->filepath, di) == 0) { - BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%f'", di); + BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.200s'", di); return -1; } } @@ -627,15 +659,17 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re ED_object_exit_editmode(C, EM_DO_UNDO); ED_sculpt_force_update(C); + /* don't forget not to return without! */ + WM_cursor_wait(1); + /* blend file thumbnail */ - ibuf_thumb= blend_file_thumb(di, CTX_data_scene(C), &thumb); + ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb); /* rename to .blend1, do this as last before write */ do_history(di, reports); if (BLO_write_file(CTX_data_main(C), di, fileflags, reports, thumb)) { if(!copy) { - strcpy(G.sce, di); G.relbase_valid = 1; strcpy(G.main->name, di); /* is guaranteed current file */ @@ -661,10 +695,13 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re else { if(ibuf_thumb) IMB_freeImBuf(ibuf_thumb); if(thumb) MEM_freeN(thumb); + + WM_cursor_wait(0); return -1; } -// XXX waitcursor(0); + WM_cursor_wait(0); + return 0; } @@ -677,19 +714,24 @@ int WM_write_homefile(bContext *C, wmOperator *op) int fileflags; /* check current window and close it if temp */ - if(win->screen->full == SCREENTEMP) + if(win->screen->temp) wm_window_close(C, wm, win); BLI_make_file_string("/", tstr, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); - printf("trying to save homefile at %s \n", tstr); + printf("trying to save homefile at %s ", tstr); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN); - BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL); + if(BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL) == 0) { + printf("fail\n"); + return OPERATOR_CANCELLED; + } + printf("ok\n"); + G.save_over= 0; - + return OPERATOR_FINISHED; } @@ -731,7 +773,7 @@ void WM_autosave_init(wmWindowManager *wm) wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0); } -void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) +void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(wt)) { wmWindow *win; wmEventHandler *handler; |