Fix T53274: Saving template prefs overwrites default prefs

This commit is contained in:
Campbell Barton 2017-11-23 03:10:58 +11:00
parent d749320e3b
commit 326efb4319
Notes: blender-bot 2023-02-14 06:49:54 +01:00
Referenced by issue #53683, 2.79a release
Referenced by issue #53274, Saving Preferences on a App template, overwrites the default preferences also
6 changed files with 103 additions and 44 deletions

View File

@ -48,10 +48,17 @@ void BKE_blender_version_string(
char *version_str, size_t maxncpy,
short version, short subversion, bool v_prefix, bool include_subversion);
void BKE_blender_userdef_set_data(struct UserDef *userdef);
void BKE_blender_userdef_free_data(struct UserDef *userdef);
void BKE_blender_userdef_data_swap(struct UserDef *userdef_dst, struct UserDef *userdef_src);
void BKE_blender_userdef_data_set(struct UserDef *userdef);
void BKE_blender_userdef_data_set_and_free(struct UserDef *userdef);
void BKE_blender_userdef_set_app_template(struct UserDef *userdef);
void BKE_blender_userdef_app_template_data_swap(struct UserDef *userdef_dst, struct UserDef *userdef_src);
void BKE_blender_userdef_app_template_data_set(struct UserDef *userdef);
void BKE_blender_userdef_app_template_data_set_and_free(struct UserDef *userdef);
void BKE_blender_userdef_data_duplicate(struct UserDef *userdef_dst, struct UserDef *userdef_src);
void BKE_blender_userdef_data_free(struct UserDef *userdef, bool clear_fonts);
/* set this callback when a UI is running */
void BKE_blender_callback_test_break_set(void (*func)(void));

View File

@ -59,6 +59,7 @@ struct UserDef *BKE_blendfile_userdef_read_from_memory(
struct ReportList *reports);
bool BKE_blendfile_userdef_write(const char *filepath, struct ReportList *reports);
bool BKE_blendfile_userdef_write_app_template(const char *filepath, struct ReportList *reports);
/* partial blend file writing */
void BKE_blendfile_write_partial_tag_ID(struct ID *id, bool set);

View File

@ -150,11 +150,21 @@ static void keymap_item_free(wmKeyMapItem *kmi)
MEM_freeN(kmi->ptr);
}
void BKE_blender_userdef_set_data(UserDef *userdef)
void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
{
/* only here free userdef themes... */
BKE_blender_userdef_free_data(&U);
U = *userdef;
SWAP(UserDef, *userdef_a, *userdef_b);
}
void BKE_blender_userdef_data_set(UserDef *userdef)
{
BKE_blender_userdef_data_swap(&U, userdef);
BKE_blender_userdef_data_free(userdef, true);
}
void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
{
BKE_blender_userdef_data_set(userdef);
MEM_freeN(userdef);
}
static void userdef_free_keymaps(UserDef *userdef)
@ -201,7 +211,7 @@ static void userdef_free_addons(UserDef *userdef)
* When loading a new userdef from file,
* or when exiting Blender.
*/
void BKE_blender_userdef_free_data(UserDef *userdef)
void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
{
#define U _invalid_access_ /* ensure no accidental global access */
#ifdef U /* quiet warning */
@ -210,12 +220,13 @@ void BKE_blender_userdef_free_data(UserDef *userdef)
userdef_free_keymaps(userdef);
userdef_free_addons(userdef);
for (uiFont *font = userdef->uifonts.first; font; font = font->next) {
BLF_unload_id(font->blf_id);
if (clear_fonts) {
for (uiFont *font = userdef->uifonts.first; font; font = font->next) {
BLF_unload_id(font->blf_id);
}
BLF_default_set(-1);
}
BLF_default_set(-1);
BLI_freelistN(&userdef->autoexec_paths);
BLI_freelistN(&userdef->uistyles);
@ -229,38 +240,50 @@ void BKE_blender_userdef_free_data(UserDef *userdef)
* Write U from userdef.
* This function defines which settings a template will override for the user preferences.
*/
void BKE_blender_userdef_set_app_template(UserDef *userdef)
void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
{
/* TODO:
* - keymaps
* - various minor settings (add as needed).
*/
#define LIST_OVERRIDE(id) { \
BLI_freelistN(&U.id); \
BLI_movelisttolist(&U.id, &userdef->id); \
#define DATA_SWAP(id) \
SWAP(userdef_a->id, userdef_b->id);
#define LIST_SWAP(id) { \
SWAP(ListBase, userdef_a->id, userdef_b->id); \
} ((void)0)
#define MEMCPY_OVERRIDE(id) \
memcpy(U.id, userdef->id, sizeof(U.id));
/* for some types we need custom free functions */
userdef_free_addons(&U);
userdef_free_keymaps(&U);
LIST_SWAP(addons);
LIST_SWAP(user_keymaps);
LIST_OVERRIDE(uistyles);
LIST_OVERRIDE(uifonts);
LIST_OVERRIDE(themes);
LIST_OVERRIDE(addons);
LIST_OVERRIDE(user_keymaps);
LIST_SWAP(uistyles);
LIST_SWAP(uifonts);
LIST_SWAP(themes);
LIST_SWAP(addons);
LIST_SWAP(user_keymaps);
MEMCPY_OVERRIDE(light);
DATA_SWAP(light);
MEMCPY_OVERRIDE(font_path_ui);
MEMCPY_OVERRIDE(font_path_ui_mono);
DATA_SWAP(font_path_ui);
DATA_SWAP(font_path_ui_mono);
#undef LIST_OVERRIDE
#undef MEMCPY_OVERRIDE
#undef SWAP_TYPELESS
#undef LIST_SWAP
#undef DATA_SWAP
}
void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
{
BKE_blender_userdef_app_template_data_swap(&U, userdef);
BKE_blender_userdef_data_free(userdef, true);
}
void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
{
BKE_blender_userdef_app_template_data_set(userdef);
MEM_freeN(userdef);
}
/* ***************** testing for break ************* */

View File

@ -226,11 +226,9 @@ static void setup_app_data(
CTX_data_main_set(C, G.main);
if (bfd->user) {
/* only here free userdef themes... */
BKE_blender_userdef_free_data(&U);
U = *bfd->user;
BKE_blender_userdef_data_set_and_free(bfd->user);
bfd->user = NULL;
/* Security issue: any blend file could include a USER block.
*
@ -241,8 +239,6 @@ static void setup_app_data(
* enable scripts auto-execution by loading a '.blend' file.
*/
U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
MEM_freeN(bfd->user);
}
/* case G_FILE_NO_UI or no screens in file */
@ -515,6 +511,30 @@ bool BKE_blendfile_userdef_write(const char *filepath, ReportList *reports)
return ok;
}
/**
* Only write the userdef in a .blend, merging with the existing blend file.
* \return success
*
* \note In the future we should re-evaluate user preferences,
* possibly splitting out system/hardware specific prefs.
*/
bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList *reports)
{
/* if it fails, overwrite is OK. */
UserDef *userdef_default = BKE_blendfile_userdef_read(filepath, NULL);
if (userdef_default == NULL) {
return BKE_blendfile_userdef_write(filepath, reports);
}
BKE_blender_userdef_app_template_data_swap(&U, userdef_default);
bool ok = BKE_blendfile_userdef_write(filepath, reports);
BKE_blender_userdef_app_template_data_swap(&U, userdef_default);
BKE_blender_userdef_data_free(userdef_default, false);
MEM_freeN(userdef_default);
return ok;
}
/** \} */

View File

@ -713,8 +713,8 @@ int wm_homefile_read(
if (!use_factory_settings && BLI_exists(filepath_userdef)) {
UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL);
if (userdef != NULL) {
BKE_blender_userdef_set_data(userdef);
MEM_freeN(userdef);
BKE_blender_userdef_data_set_and_free(userdef);
userdef = NULL;
skip_flags |= BLO_READ_SKIP_USERDEF;
printf("Read prefs: %s\n", filepath_userdef);
@ -824,9 +824,8 @@ int wm_homefile_read(
read_userdef_from_memory = true;
}
if (userdef_template) {
BKE_blender_userdef_set_app_template(userdef_template);
BKE_blender_userdef_free_data(userdef_template);
MEM_freeN(userdef_template);
BKE_blender_userdef_app_template_data_set_and_free(userdef_template);
userdef_template = NULL;
}
}
}
@ -1478,9 +1477,18 @@ static int wm_userpref_write_exec(bContext *C, wmOperator *op)
WM_keyconfig_update(wm);
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
bool ok_write;
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
printf("trying to save userpref at %s ", filepath);
if (BKE_blendfile_userdef_write(filepath, op->reports) != 0) {
if (U.app_template[0]) {
ok_write = BKE_blendfile_userdef_write_app_template(filepath, op->reports);
}
else {
ok_write = BKE_blendfile_userdef_write(filepath, op->reports);
}
if (ok_write) {
printf("ok\n");
}
else {

View File

@ -569,7 +569,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
ED_file_exit(); /* for fsmenu */
UI_exit();
BKE_blender_userdef_free_data(&U);
BKE_blender_userdef_data_free(&U, false);
RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */