diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index d5912988701..3cf944fa236 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -88,6 +88,7 @@ void IDP_UnlinkID(struct IDProperty *prop); /** Sync values from one group to another, only where they match */ void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL(); +void IDP_SyncGroupTypes(struct IDProperty *dest, const struct IDProperty *src, const bool do_arraylen) ATTR_NONNULL(); void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL(); void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL(); diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 785069cd150..0596c5109dd 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -506,6 +506,34 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src) } } +void IDP_SyncGroupTypes(IDProperty *dst, const IDProperty *src, const bool do_arraylen) +{ + IDProperty *prop_dst, *prop_dst_next; + const IDProperty *prop_src; + + for (prop_dst = dst->data.group.first; prop_dst; prop_dst = prop_dst_next) { + prop_dst_next = prop_dst->next; + if ((prop_src = IDP_GetPropertyFromGroup((IDProperty *)src, prop_dst->name))) { + /* check of we should replace? */ + if ((prop_dst->type != prop_src->type || prop_dst->subtype != prop_src->subtype) || + (do_arraylen && ELEM(prop_dst->type, IDP_ARRAY, IDP_IDPARRAY) && (prop_src->len != prop_dst->len))) + { + IDP_FreeFromGroup(dst, prop_dst); + prop_dst = IDP_CopyProperty(prop_src); + + dst->len++; + BLI_insertlinkbefore(&dst->data.group, prop_dst_next, prop_dst); + } + else if (prop_dst->type == IDP_GROUP) { + IDP_SyncGroupTypes(prop_dst, prop_src, do_arraylen); + } + } + else { + IDP_FreeFromGroup(dst, prop_dst); + } + } +} + /** * Replaces all properties with the same name in a destination group from a source group. */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 74c066d1d86..71d6d25c9a0 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -121,6 +121,21 @@ void WM_operator_type_set(wmOperator *op, wmOperatorType *ot) op->type = ot; op->ptr->type = ot->srna; + + /* ensure compatible properties */ + if (op->properties) { + PointerRNA ptr; + + WM_operator_properties_create_ptr(&ptr, ot); + + WM_operator_properties_default(&ptr, false); + + if (ptr.data) { + IDP_SyncGroupTypes(op->properties, ptr.data, true); + } + + WM_operator_properties_free(&ptr); + } } static void wm_reports_free(wmWindowManager *wm)