Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_files_link.c')
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c206
1 files changed, 131 insertions, 75 deletions
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index c8574a5a7fb..31d36603505 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -34,6 +34,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_key_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
@@ -50,8 +51,10 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -694,6 +697,92 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
return OPERATOR_CANCELLED;
}
+static void lib_relocate_do_remap(Main *bmain,
+ ID *old_id,
+ ID *new_id,
+ ReportList *reports,
+ const bool do_reload,
+ const short remap_flags)
+{
+ BLI_assert(old_id);
+ if (do_reload) {
+ /* Since we asked for placeholders in case of missing IDs,
+ * we expect to always get a valid one. */
+ BLI_assert(new_id);
+ }
+ if (new_id) {
+#ifdef PRINT_DEBUG
+ printf("before remap of %s, old_id users: %d, new_id users: %d\n",
+ old_id->name,
+ old_id->us,
+ new_id->us);
+#endif
+ BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
+
+ if (old_id->flag & LIB_FAKEUSER) {
+ id_fake_user_clear(old_id);
+ id_fake_user_set(new_id);
+ }
+
+#ifdef PRINT_DEBUG
+ printf("after remap of %s, old_id users: %d, new_id users: %d\n",
+ old_id->name,
+ old_id->us,
+ new_id->us);
+#endif
+
+ /* In some cases, new_id might become direct link, remove parent of library in this case. */
+ if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) {
+ if (do_reload) {
+ BLI_assert(0); /* Should not happen in 'pure' reload case... */
+ }
+ new_id->lib->parent = NULL;
+ }
+ }
+
+ if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
+ /* Note that this *should* not happen - but better be safe than sorry in this area,
+ * at least until we are 100% sure this cannot ever happen.
+ * Also, we can safely assume names were unique so far,
+ * so just replacing '.' by '~' should work,
+ * but this does not totally rules out the possibility of name collision. */
+ size_t len = strlen(old_id->name);
+ size_t dot_pos;
+ bool has_num = false;
+
+ for (dot_pos = len; dot_pos--;) {
+ char c = old_id->name[dot_pos];
+ if (c == '.') {
+ break;
+ }
+ else if (c < '0' || c > '9') {
+ has_num = false;
+ break;
+ }
+ has_num = true;
+ }
+
+ if (has_num) {
+ old_id->name[dot_pos] = '~';
+ }
+ else {
+ len = MIN2(len, MAX_ID_NAME - 7);
+ BLI_strncpy(&old_id->name[len], "~000", 7);
+ }
+
+ id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, NULL);
+
+ BKE_reportf(
+ reports,
+ RPT_WARNING,
+ "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
+ "old one (%d remaining users) had to be kept and was renamed to '%s'",
+ new_id->name,
+ old_id->us,
+ old_id->name);
+ }
+}
+
static void lib_relocate_do(Main *bmain,
Library *library,
WMLinkAppendData *lapp_data,
@@ -725,6 +814,12 @@ static void lib_relocate_do(Main *bmain,
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitly linked here... */
BLI_remlink(lbarray[lba_idx], id);
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key *old_key = BKE_key_from_id(id);
+ if (old_key != NULL) {
+ BLI_remlink(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
+ }
+
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_bitmap_set_all(item->libraries, true, lapp_data->num_libraries);
@@ -757,6 +852,12 @@ static void lib_relocate_do(Main *bmain,
BLI_assert(old_id);
BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
+
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key *old_key = BKE_key_from_id(old_id);
+ if (old_key != NULL) {
+ BLI_addtail(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
+ }
}
/* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
@@ -773,82 +874,20 @@ static void lib_relocate_do(Main *bmain,
ID *old_id = item->customdata;
ID *new_id = item->new_id;
- BLI_assert(old_id);
- if (do_reload) {
- /* Since we asked for placeholders in case of missing IDs,
- * we expect to always get a valid one. */
- BLI_assert(new_id);
- }
- if (new_id) {
-#ifdef PRINT_DEBUG
- printf("before remap of %s, old_id users: %d, new_id users: %d\n",
- old_id->name,
- old_id->us,
- new_id->us);
-#endif
- BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
-
- if (old_id->flag & LIB_FAKEUSER) {
- id_fake_user_clear(old_id);
- id_fake_user_set(new_id);
- }
-
-#ifdef PRINT_DEBUG
- printf("after remap of %s, old_id users: %d, new_id users: %d\n",
- old_id->name,
- old_id->us,
- new_id->us);
-#endif
-
- /* In some cases, new_id might become direct link, remove parent of library in this case. */
- if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) {
- if (do_reload) {
- BLI_assert(0); /* Should not happen in 'pure' reload case... */
- }
- new_id->lib->parent = NULL;
- }
+ lib_relocate_do_remap(bmain, old_id, new_id, reports, do_reload, remap_flags);
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key **old_key_p = BKE_key_from_id_p(old_id);
+ if (old_key_p == NULL) {
+ continue;
}
-
- if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
- /* Note that this *should* not happen - but better be safe than sorry in this area,
- * at least until we are 100% sure this cannot ever happen.
- * Also, we can safely assume names were unique so far,
- * so just replacing '.' by '~' should work,
- * but this does not totally rules out the possibility of name collision. */
- size_t len = strlen(old_id->name);
- size_t dot_pos;
- bool has_num = false;
-
- for (dot_pos = len; dot_pos--;) {
- char c = old_id->name[dot_pos];
- if (c == '.') {
- break;
- }
- else if (c < '0' || c > '9') {
- has_num = false;
- break;
- }
- has_num = true;
- }
-
- if (has_num) {
- old_id->name[dot_pos] = '~';
- }
- else {
- len = MIN2(len, MAX_ID_NAME - 7);
- BLI_strncpy(&old_id->name[len], "~000", 7);
- }
-
- id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, NULL);
-
- BKE_reportf(
- reports,
- RPT_WARNING,
- "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
- "old one (%d remaining users) had to be kept and was renamed to '%s'",
- new_id->name,
- old_id->us,
- old_id->name);
+ Key *old_key = *old_key_p;
+ Key *new_key = BKE_key_from_id(new_id);
+ if (old_key != NULL) {
+ *old_key_p = NULL;
+ id_us_min(&old_key->id);
+ lib_relocate_do_remap(bmain, &old_key->id, &new_key->id, reports, do_reload, remap_flags);
+ *old_key_p = old_key;
+ id_us_plus_no_lib(&old_key->id);
}
}
@@ -900,6 +939,23 @@ static void lib_relocate_do(Main *bmain,
}
}
+ /* Update overrides of reloaded linked data-blocks.
+ * Note that this will not necessarily fully update the override, it might need to be manually
+ * 're-generated' depending on changes in linked data. */
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (ID_IS_LINKED(id) || !ID_IS_OVERRIDE_LIBRARY_REAL(id) ||
+ (id->tag & LIB_TAG_PRE_EXISTING) == 0) {
+ continue;
+ }
+ if (id->override_library->reference->lib == library) {
+ BKE_lib_override_library_update(bmain, id);
+ }
+ }
+ FOREACH_MAIN_ID_END;
+
+ BKE_main_collection_sync(bmain);
+
BKE_main_lib_objects_recalc_all(bmain);
IMB_colormanagement_check_file_config(bmain);