diff options
Diffstat (limited to 'source/blender/editors/interface/interface_ops.c')
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 63 |
1 files changed, 47 insertions, 16 deletions
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index e170cb46925..3a5ba9acaac 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -820,19 +820,26 @@ static int override_idtemplate_make_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - if (ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) { - PointerRNA idptr; - /* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it - * to ensure remapping of the owner property from the linked data to the newly created - * liboverride (note that in theory this remapping has already been done by code above), but - * only in case owner ID was already an existing liboverride. - * - * Otherwise, owner ID will also have been overridden, and remapped already to use it's - * override of the data too. */ + PointerRNA idptr; + /* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it + * to ensure remapping of the owner property from the linked data to the newly created + * liboverride (note that in theory this remapping has already been done by code above), but + * only in case owner ID was already local ID (override or pure local data). + * + * Otherwise, owner ID will also have been overridden, and remapped already to use it's + * override of the data too. */ + if (!ID_IS_LINKED(owner_id)) { RNA_id_pointer_create(id_override, &idptr); RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL); - RNA_property_update(C, &owner_ptr, prop); } + RNA_property_update(C, &owner_ptr, prop); + + /* 'Security' extra tagging, since this process may also affect the owner ID and not only the + * used ID, relying on the property update code only is not always enough. */ + DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); return OPERATOR_FINISHED; } @@ -881,6 +888,9 @@ static int override_idtemplate_reset_exec(bContext *C, wmOperator *UNUSED(op)) RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL); RNA_property_update(C, &owner_ptr, prop); + /* No need for 'security' extra tagging here, since this process will never affect the owner ID. + */ + return OPERATOR_FINISHED; } @@ -919,24 +929,45 @@ static int override_idtemplate_clear_exec(bContext *C, wmOperator *UNUSED(op)) } Main *bmain = CTX_data_main(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Scene *scene = CTX_data_scene(C); ID *id_new = id; + if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) { id_new = id->override_library->reference; + bool do_remap_active = false; + if (OBACT(view_layer) == (Object *)id) { + BLI_assert(GS(id->name) == ID_OB); + BLI_assert(GS(id_new->name) == ID_OB); + do_remap_active = true; + } BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE); + if (do_remap_active) { + Object *ref_object = (Object *)id_new; + Base *basact = BKE_view_layer_base_find(view_layer, ref_object); + if (basact != NULL) { + view_layer->basact = basact; + } + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + } BKE_id_delete(bmain, id); } else { BKE_lib_override_library_id_reset(bmain, id, true); } - PointerRNA idptr; - /* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it to - * ensure remapping of the owner property from the linked data to the newly created liboverride - * (note that in theory this remapping has already been done by code above). */ - RNA_id_pointer_create(id_new, &idptr); - RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL); + /* Here the affected ID may remain the same, or be replaced by its linked reference. In either + * case, the owner ID remains unchanged, and remapping is already handled by internal code, so + * calling `RNA_property_update` on it is enough to ensure proper notifiers are sent. */ RNA_property_update(C, &owner_ptr, prop); + /* 'Security' extra tagging, since this process may also affect the owner ID and not only the + * used ID, relying on the property update code only is not always enough. */ + DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + return OPERATOR_FINISHED; } |