LibOverride: support inserting items in py-defined (IDProp-based) collections.

Supporting IDProperty-based data storage here in a generic way is fairly
simple, unlike actual RNA data (DNA-based), for which getting a proper
generic way to duplicate them from within RNA is currently not really
possible.

Part of T79562.
This commit is contained in:
Bastien Montagne 2020-09-18 15:17:42 +02:00
parent 5e509a3aa9
commit db314ee7a4
Notes: blender-bot 2023-02-13 23:16:02 +01:00
Referenced by issue #79562, LibOverride: Support edition of lists (colletions) of ID properties/py-defined RNA collections
1 changed files with 69 additions and 2 deletions

View File

@ -128,6 +128,7 @@ const EnumPropertyItem rna_enum_property_unit_items[] = {
# include "BLI_string.h"
# include "MEM_guardedalloc.h"
# include "BKE_idprop.h"
# include "BKE_lib_override.h"
/* Struct */
@ -2528,8 +2529,74 @@ bool rna_property_override_apply_default(Main *UNUSED(bmain),
return true;
}
case PROP_COLLECTION: {
BLI_assert(!"You need to define a specific override apply callback for enums.");
return false;
/* We only support IDProperty-based collection insertion here. */
const bool is_src_idprop = (prop_src->magic != RNA_MAGIC) ||
(prop_src->flag & PROP_IDPROPERTY) != 0;
const bool is_dst_idprop = (prop_dst->magic != RNA_MAGIC) ||
(prop_dst->flag & PROP_IDPROPERTY) != 0;
if (!(is_src_idprop && is_dst_idprop)) {
BLI_assert(0 && "You need to define a specific override apply callback for collections");
return false;
}
switch (override_op) {
case IDOVERRIDE_LIBRARY_OP_INSERT_AFTER: {
PointerRNA item_ptr_src, item_ptr_ref, item_ptr_dst;
int item_index_dst;
bool is_valid = false;
if (opop->subitem_local_name != NULL && opop->subitem_local_name[0] != '\0') {
/* Find from name. */
int item_index_src, item_index_ref;
if (RNA_property_collection_lookup_string_index(
ptr_src, prop_src, opop->subitem_local_name, &item_ptr_src, &item_index_src) &&
RNA_property_collection_lookup_int(
ptr_src, prop_src, item_index_src + 1, &item_ptr_src) &&
RNA_property_collection_lookup_string_index(
ptr_dst, prop_dst, opop->subitem_local_name, &item_ptr_ref, &item_index_ref)) {
is_valid = true;
item_index_dst = item_index_ref + 1;
}
}
if (!is_valid && opop->subitem_local_index >= 0) {
/* Find from index. */
if (RNA_property_collection_lookup_int(
ptr_src, prop_src, opop->subitem_local_index + 1, &item_ptr_src) &&
RNA_property_collection_lookup_int(
ptr_dst, prop_dst, opop->subitem_local_index, &item_ptr_ref)) {
item_index_dst = opop->subitem_local_index + 1;
is_valid = true;
}
}
if (!is_valid) {
/* Assume it is inserted in first position. */
if (RNA_property_collection_lookup_int(ptr_src, prop_src, 0, &item_ptr_src)) {
item_index_dst = 0;
is_valid = true;
}
}
if (!is_valid) {
return false;
}
RNA_property_collection_add(ptr_dst, prop_dst, &item_ptr_dst);
const int item_index_added = RNA_property_collection_length(ptr_dst, prop_dst) - 1;
BLI_assert(item_index_added >= 0);
/* This is the section of code that makes it specific to IDProperties (the rest could be
* used with some regular RNA/DNA data too).
* Currently it is close to impossible to copy arbitrary 'real' RNA data between
* Collection items. */
IDProperty *item_idprop_src = item_ptr_src.data;
IDProperty *item_idprop_dst = item_ptr_dst.data;
IDP_CopyPropertyContent(item_idprop_dst, item_idprop_src);
return RNA_property_collection_move(ptr_dst, prop_dst, item_index_added, item_index_dst);
break;
}
default:
BLI_assert(0 && "Unsupported RNA override operation on collection");
return false;
}
}
default:
BLI_assert(0);