diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 877a993..6d8f849 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -258,9 +258,11 @@ static void UI_OT_unset_property_button(wmOperatorType *ot) /* Copy To Selected Operator ------------------------ */ -static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, bool *use_path) +static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, PropertyRNA *prop, ListBase *lb, + bool *use_path_from_id, char **path) { - *use_path = false; + *use_path_from_id = false; + *path = NULL; if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) *lb = CTX_data_collection_get(C, "selected_editable_bones"); @@ -271,15 +273,44 @@ static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, bo else { ID *id = ptr->id.data; - if (id && GS(id->name) == ID_OB) { - *lb = CTX_data_collection_get(C, "selected_editable_objects"); - *use_path = true; - } - else { - return false; + if (id) { + if (GS(id->name) == ID_OB) { + *lb = CTX_data_collection_get(C, "selected_editable_objects"); + *use_path_from_id = true; + *path = RNA_path_from_ID_to_property(ptr, prop); + } + else { + /* Try to recursively find an RNA_Sequence ancestor, to handle situations like T41062... */ + PointerRNA idptr, tptr; + PropertyRNA *tprop; + char *full_path = RNA_path_from_ID_to_property(ptr, prop); + char *path_t1 = RNA_path_back(full_path); /* We remove property... */ + char *path_t2 = RNA_path_back(path_t1); /* ... and first struct, which we already know as 'invalid'. */ + MEM_SAFE_FREE(path_t1); + path_t1 = path_t2; + + RNA_id_pointer_create(ptr->id.data, &idptr); + + while (path_t1 && RNA_path_resolve(&idptr, path_t1, &tptr, &tprop)) { + if (RNA_struct_is_a(tptr.type, &RNA_Sequence)) { + *lb = CTX_data_collection_get(C, "selected_editable_sequences"); + *path = BLI_strdup(full_path + strlen(path_t1) + 1); /* +1 for the linking '.' */ + MEM_SAFE_FREE(path_t1); + break; + } + + path_t2 = RNA_path_back(path_t1); + MEM_SAFE_FREE(path_t1); + path_t1 = path_t2; + } + + MEM_SAFE_FREE(full_path); + } + return (*path != NULL); } + return false; } - + return true; } @@ -303,47 +334,54 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) /* if there is a valid property that is editable... */ if (ptr.data && prop) { char *path = NULL; - bool use_path; + bool use_path_from_id; CollectionPointerLink *link; ListBase lb; - if (!copy_to_selected_list(C, &ptr, &lb, &use_path)) + if (!copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) return success; - if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) { - for (link = lb.first; link; link = link->next) { - if (link->ptr.data != ptr.data) { - if (use_path) { - lprop = NULL; - RNA_id_pointer_create(link->ptr.id.data, &idptr); - RNA_path_resolve_property(&idptr, path, &lptr, &lprop); - } - else { - lptr = link->ptr; - lprop = prop; - } + for (link = lb.first; link; link = link->next) { + if (link->ptr.data != ptr.data) { + if (use_path_from_id) { + /* Path relative to ID. */ + lprop = NULL; + RNA_id_pointer_create(link->ptr.id.data, &idptr); + RNA_path_resolve_property(&idptr, path, &lptr, &lprop); + } + else if (path) { + /* Path relative to elements from list. */ + lprop = NULL; + RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop); + } + else { + lptr = link->ptr; + lprop = prop; + } - if (lprop == prop) { - if (RNA_property_editable(&lptr, lprop)) { - if (poll) { + if (lptr.data == ptr.data) { + /* lptr might not be the same as link->ptr! */ + continue; + } + + if (lprop == prop) { + if (RNA_property_editable(&lptr, lprop)) { + if (poll) { + success = true; + break; + } + else { + if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) { + RNA_property_update(C, &lptr, prop); success = true; - break; - } - else { - if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) { - RNA_property_update(C, &lptr, prop); - success = true; - } } } } } } - - if (path) - MEM_freeN(path); } + MEM_SAFE_FREE(path); BLI_freelistN(&lb); }