Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 22 Nov 2017 16:26:00 +0000 (03:26 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 22 Nov 2017 16:26:00 +0000 (03:26 +1100)
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_blendfile.h
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/blendfile.c
source/blender/blenlib/BLI_utildefines.h
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_init_exit.c

index ec0bfa6f5faafacb6bbf54ad33fbaf5a3bc0cb7f..647291382efcfb88a66adbbea8a2c44b489c6134 100644 (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));
index 0a8eac7961a11a0f5939540aee1b801b688eb0e5..a9a7e2045f01805d4a8332bbc8a7b5b455080b68 100644 (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);
 
 struct WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath, struct ReportList *reports);
 bool BKE_blendfile_workspace_config_write(struct Main *bmain, const char *filepath, struct ReportList *reports);
index 1f75c85291dae3c3fcd19433bcf609ea9bb259b4..05c1a675f4775a3f530861b4575cfd0c4b931efd 100644 (file)
@@ -154,11 +154,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)
@@ -205,7 +215,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 */
@@ -214,12 +224,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);
@@ -233,38 +244,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); \
-} ((void)0)
+#define DATA_SWAP(id) \
+       SWAP(userdef_a->id, userdef_b->id);
 
-#define MEMCPY_OVERRIDE(id) \
-       memcpy(U.id, userdef->id, sizeof(U.id));
+#define LIST_SWAP(id) { \
+       SWAP(ListBase, userdef_a->id, userdef_b->id); \
+} ((void)0)
 
        /* for some types we need custom free functions */
-       userdef_free_addons(&U);
-       userdef_free_keymaps(&U);
+       LIST_SWAP(addons);
+       LIST_SWAP(user_keymaps);
+
+       LIST_SWAP(uistyles);
+       LIST_SWAP(uifonts);
+       LIST_SWAP(themes);
+       LIST_SWAP(addons);
+       LIST_SWAP(user_keymaps);
+
+       DATA_SWAP(light);
 
-       LIST_OVERRIDE(uistyles);
-       LIST_OVERRIDE(uifonts);
-       LIST_OVERRIDE(themes);
-       LIST_OVERRIDE(addons);
-       LIST_OVERRIDE(user_keymaps);
+       DATA_SWAP(font_path_ui);
+       DATA_SWAP(font_path_ui_mono);
 
-       MEMCPY_OVERRIDE(light);
+#undef SWAP_TYPELESS
+#undef LIST_SWAP
+#undef DATA_SWAP
+}
 
-       MEMCPY_OVERRIDE(font_path_ui);
-       MEMCPY_OVERRIDE(font_path_ui_mono);
+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);
+}
 
-#undef LIST_OVERRIDE
-#undef MEMCPY_OVERRIDE
+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 ************* */
index 6df008e7ac9f8235386b72ed993302e2f1bc6341..f6dfb7f922c36ff448912b0b730b9f7ae825f3be 100644 (file)
@@ -243,9 +243,8 @@ static void setup_app_data(
        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.
                 *
@@ -256,8 +255,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 */
@@ -539,6 +536,29 @@ 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;
+}
+
 WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath, ReportList *reports)
 {
        BlendFileData *bfd;
index 8f8d7cc3b7fd4933b08a6cee42a3ae7c8eef7790..ec6042637aa2ea52a30db7f69276114447122b14 100644 (file)
@@ -140,16 +140,25 @@ extern "C" {
 
 /* some math and copy defines */
 
-
-#define SWAP(type, a, b)  {    \
-       type sw_ap;                \
-       CHECK_TYPE(a, type);       \
-       CHECK_TYPE(b, type);       \
-       sw_ap = (a);               \
-       (a) = (b);                 \
-       (b) = sw_ap;               \
+#define _VA_SWAP3(type, a, b) { \
+       CHECK_TYPE(a, type); \
+       CHECK_TYPE(b, type); \
+       type SWAP = (a); \
+       (a) = (b); \
+       (b) = SWAP; \
 } (void)0
 
+#define _VA_SWAP2(a, b) { \
+       CHECK_TYPE_PAIR(a, b); \
+       struct { char a_[sizeof(a)]; } SWAP, *a_ = (void *)&(a), *b_ = (void *)&(b); \
+       SWAP = *a_; \
+       *a_ = *b_; \
+       *b_ = SWAP; \
+} ((void)0)
+
+/* SWAP with two or three args (initial type argument is optional) */
+#define SWAP(...) VA_NARGS_CALL_OVERLOAD(_VA_SWAP, __VA_ARGS__)
+
 /* swap with a temp value */
 #define SWAP_TVAL(tval, a, b)  {  \
        CHECK_TYPE_PAIR(tval, a);     \
index f9bf47daf30d4975d7169e27f38bce77605cb2fe..aaaf5f8f8dda4159d1268186985b59334d904859 100644 (file)
@@ -715,8 +715,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);
@@ -826,9 +826,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;
                        }
                }
        }
@@ -1484,9 +1483,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 {
index 8346535cd6a9a0d4d307a58adec57630719d5483..fc1805e102f0a7acac2e0529de8ddac7cd9fafcb 100644 (file)
@@ -579,7 +579,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 */