Exemplo n.º 1
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;
}
Exemplo n.º 2
0
bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
{
	/* assume automated tasks with background, don't write recent file list */
	const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
	bool success = false;
	int retval;

	/* so we can get the error message */
	errno = 0;

	WM_cursor_wait(1);

	BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);

	UI_view2d_zoom_cache_reset();

	/* first try to append data from exotic file formats... */
	/* it throws error box when file doesn't exist and returns -1 */
	/* note; it should set some error message somewhere... (ton) */
	retval = wm_read_exotic(filepath);
	
	/* we didn't succeed, now try to read Blender file */
	if (retval == BKE_READ_EXOTIC_OK_BLEND) {
		int G_f = G.f;
		ListBase wmbase;

		/* put aside screens to match with persistent windows later */
		/* also exit screens and editors */
		wm_window_match_init(C, &wmbase); 
		
		/* confusing this global... */
		G.relbase_valid = 1;
		retval = BKE_read_file(C, filepath, reports);
		/* when loading startup.blend's, we can be left with a blank path */
		if (G.main->name[0]) {
			G.save_over = 1;
		}
		else {
			G.save_over = 0;
			G.relbase_valid = 0;
		}

		/* this flag is initialized by the operator but overwritten on read.
		 * need to re-enable it here else drivers + registered scripts wont work. */
		if (G.f != G_f) {
			const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF);
			G.f = (G.f & ~flags_keep) | (G_f & flags_keep);
		}

		/* match the read WM with current WM */
		wm_window_match_do(C, &wmbase);
		WM_check(C); /* opens window(s), checks keymaps */

		if (retval == BKE_READ_FILE_OK_USERPREFS) {
			/* in case a userdef is read from regular .blend */
			wm_init_userdef(C, false);
		}
		
		if (retval != BKE_READ_FILE_FAIL) {
			if (do_history) {
				wm_history_file_update();
			}
		}

		wm_file_read_post(C, false);

		success = true;
	}
#if 0
	else if (retval == BKE_READ_EXOTIC_OK_OTHER)
		BKE_undo_write(C, "Import file");
#endif
	else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) {
		BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath,
		            errno ? strerror(errno) : TIP_("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'", filepath);
	}
	else if (retval == BKE_READ_EXOTIC_FAIL_PATH) {
		BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath);
	}
	else {
		BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath);
		BLI_assert(!"invalid 'retval'");
	}


	if (success == false) {
		/* remove from recent files list */
		if (do_history) {
			RecentFile *recent = wm_file_history_find(filepath);
			if (recent) {
				wm_history_file_free(recent);
				wm_history_file_write();
			}
		}
	}

	WM_cursor_wait(0);

	return success;

}
Exemplo n.º 3
0
bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
{
	/* assume automated tasks with background, don't write recent file list */
	const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
	bool success = false;
	int retval;

	/* so we can get the error message */
	errno = 0;

	WM_cursor_wait(1);

	BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);

	UI_view2d_zoom_cache_reset();

	/* first try to append data from exotic file formats... */
	/* it throws error box when file doesn't exist and returns -1 */
	/* note; it should set some error message somewhere... (ton) */
	retval = wm_read_exotic(CTX_data_scene(C), filepath);
	
	/* we didn't succeed, now try to read Blender file */
	if (retval == BKE_READ_EXOTIC_OK_BLEND) {
		int G_f = G.f;
		ListBase wmbase;

		/* put aside screens to match with persistent windows later */
		/* also exit screens and editors */
		wm_window_match_init(C, &wmbase); 
		
		/* confusing this global... */
		G.relbase_valid = 1;
		retval = BKE_read_file(C, filepath, reports);
		/* when loading startup.blend's, we can be left with a blank path */
		if (G.main->name[0]) {
			G.save_over = 1;
		}
		else {
			G.save_over = 0;
			G.relbase_valid = 0;
		}

		/* this flag is initialized by the operator but overwritten on read.
		 * need to re-enable it here else drivers + registered scripts wont work. */
		if (G.f != G_f) {
			const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF);
			G.f = (G.f & ~flags_keep) | (G_f & flags_keep);
		}

		/* match the read WM with current WM */
		wm_window_match_do(C, &wmbase);
		WM_check(C); /* opens window(s), checks keymaps */

		if (retval == BKE_READ_FILE_OK_USERPREFS) {
			/* in case a userdef is read from regular .blend */
			wm_init_userdef(C, false);
		}
		
		if (retval != BKE_READ_FILE_FAIL) {
			if (do_history) {
				wm_history_file_update();
			}
		}


		WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL);
//		refresh_interface_font();

		CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);

		ED_editors_init(C);
		DAG_on_visible_update(CTX_data_main(C), true);

#ifdef WITH_PYTHON
		/* run any texts that were loaded in and flagged as modules */
		BPY_python_reset(C);
#endif

		WM_operatortype_last_properties_clear_all();

		/* important to do before NULL'ing the context */
		BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE);
		BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);

		if (!G.background) {
			/* in background mode this makes it hard to load
			 * a blend file and do anything since the screen
			 * won't be set to a valid value again */
			CTX_wm_window_set(C, NULL); /* exits queues */
		}

#if 0
		/* gives popups on windows but not linux, bug in report API
		 * but disable for now to stop users getting annoyed  */
		/* TODO, make this show in header info window */
		{
			Scene *sce;
			for (sce = G.main->scene.first; sce; sce = sce->id.next) {
				if (sce->r.engine[0] &&
				    BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL)
				{
					BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' "
					            "(an addon may need to be installed or enabled)",
					            sce->r.engine, sce->id.name + 2);
				}
			}
		}
#endif

		BKE_undo_reset();
		BKE_undo_write(C, "original");  /* save current state */

		success = true;
	}
	else if (retval == BKE_READ_EXOTIC_OK_OTHER)
		BKE_undo_write(C, "Import file");
	else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) {
		BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath,
		            errno ? strerror(errno) : TIP_("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'", filepath);
	}
	else if (retval == BKE_READ_EXOTIC_FAIL_PATH) {
		BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath);
	}
	else {
		BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath);
		BLI_assert(!"invalid 'retval'");
	}


	if (success == false) {
		/* remove from recent files list */
		if (do_history) {
			RecentFile *recent = wm_file_history_find(filepath);
			if (recent) {
				wm_history_file_free(recent);
				wm_history_file_write();
			}
		}
	}

	WM_cursor_wait(0);

	return success;

}