diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_access.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 158 |
1 files changed, 131 insertions, 27 deletions
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 8327456f460..71a3be24810 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -41,12 +41,14 @@ #include "BLT_translation.h" #include "BKE_animsys.h" +#include "BKE_collection.h" #include "BKE_context.h" #include "BKE_idcode.h" #include "BKE_idprop.h" #include "BKE_fcurve.h" #include "BKE_main.h" #include "BKE_report.h" +#include "BKE_node.h" #include "DEG_depsgraph.h" @@ -2056,18 +2058,18 @@ int RNA_property_ui_icon(PropertyRNA *prop) return rna_ensure_property(prop)->icon; } -bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop) +bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop_orig) { ID *id = ptr->owner_id; int flag; const char *dummy_info; - prop = rna_ensure_property(prop); + PropertyRNA *prop = rna_ensure_property(prop_orig); flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag; return ((flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0 && (!id || ((!ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION)) && - (!id->override_library || RNA_property_overridable_get(ptr, prop))))); + (!id->override_library || RNA_property_overridable_get(ptr, prop_orig))))); } /** @@ -2079,15 +2081,15 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char * ID *id = ptr->owner_id; int flag; - prop = rna_ensure_property(prop); + PropertyRNA *prop_type = rna_ensure_property(prop); *r_info = ""; /* get flag */ - if (prop->editable) { - flag = prop->editable(ptr, r_info); + if (prop_type->editable) { + flag = prop_type->editable(ptr, r_info); } else { - flag = prop->flag; + flag = prop_type->flag; if ((flag & PROP_EDITABLE) == 0 || (flag & PROP_REGISTER)) { *r_info = N_("This property is for internal use only and can't be edited"); } @@ -2095,17 +2097,21 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char * /* property from linked data-block */ if (id) { - if (ID_IS_LINKED(id) && (prop->flag & PROP_LIB_EXCEPTION) == 0) { + if (ID_IS_LINKED(id) && (prop_type->flag & PROP_LIB_EXCEPTION) == 0) { if (!(*r_info)[0]) { *r_info = N_("Can't edit this property from a linked data-block"); } return false; } - if (id->override_library != NULL && !RNA_property_overridable_get(ptr, prop)) { - if (!(*r_info)[0]) { - *r_info = N_("Can't edit this property from an override data-block"); + if (id->override_library != NULL) { + /* We need the real data property in case of IDProperty here... */ + PropertyRNA *real_prop = rna_ensure_property_realdata(&prop, ptr); + if (real_prop == NULL || !RNA_property_overridable_get(ptr, real_prop)) { + if (!(*r_info)[0]) { + *r_info = N_("Can't edit this property from an override data-block"); + } + return false; } - return false; } } @@ -5757,6 +5763,74 @@ static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr) } } +/** + * Find the actual ID pointer and path from it to the given ID. + * + * \param id: ID reference to search the global owner for. + * \param[out] r_path: Path from the real ID to the initial ID. + * \return The ID pointer, or NULL in case of failure. + */ +ID *RNA_find_real_ID_and_path(Main *bmain, ID *id, const char **r_path) +{ + if (r_path) { + *r_path = ""; + } + + if ((id != NULL) && (id->flag & LIB_PRIVATE_DATA)) { + switch (GS(id->name)) { + case ID_NT: + if (r_path) { + *r_path = "node_tree"; + } + return BKE_node_tree_find_owner_ID(bmain, (bNodeTree *)id); + case ID_GR: + if (r_path) { + *r_path = "collection"; + } + return (ID *)BKE_collection_master_scene_search(bmain, (Collection *)id); + + default: + return NULL; + } + } + else { + return id; + } +} + +static char *rna_prepend_real_ID_path(Main *bmain, ID *id, char *path, ID **r_real_id) +{ + if (r_real_id != NULL) { + *r_real_id = NULL; + } + + const char *prefix; + ID *real_id = RNA_find_real_ID_and_path(bmain, id, &prefix); + + if (r_real_id != NULL) { + *r_real_id = real_id; + } + + if (path != NULL) { + char *new_path = NULL; + + if (real_id) { + if (prefix[0]) { + new_path = BLI_sprintfN("%s%s%s", prefix, path[0] == '[' ? "" : ".", path); + } + else { + return path; + } + } + + MEM_freeN(path); + return new_path; + } + else { + return prefix[0] != '\0' ? BLI_strdup(prefix) : NULL; + } +} + char *RNA_path_from_ID_to_struct(PointerRNA *ptr) { char *ptrpath = NULL; @@ -5799,6 +5873,14 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr) return ptrpath; } +char *RNA_path_from_real_ID_to_struct(Main *bmain, PointerRNA *ptr, struct ID **r_real) +{ + char *path = RNA_path_from_ID_to_struct(ptr); + + /* NULL path is valid in that case, when given struct is an ID one... */ + return rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real); +} + static void rna_path_array_multi_from_flat_index(const int dimsize[RNA_MAX_ARRAY_LENGTH], const int totdims, const int index_dim, @@ -5905,6 +5987,16 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) return RNA_path_from_ID_to_property_index(ptr, prop, 0, -1); } +char *RNA_path_from_real_ID_to_property_index( + Main *bmain, PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, ID **r_real_id) +{ + char *path = RNA_path_from_ID_to_property_index(ptr, prop, index_dim, index); + + /* NULL path is always an error here, in that case do not return the 'fake ID from real ID' part + * of the path either. */ + return path != NULL ? rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real_id) : NULL; +} + /** * \return the path to given ptr/prop from the closest ancestor of given type, * if any (else return NULL). @@ -5951,20 +6043,34 @@ char *RNA_path_resolve_from_type_to_property(PointerRNA *ptr, * Get the ID as a python representation, eg: * bpy.data.foo["bar"] */ -char *RNA_path_full_ID_py(ID *id) +char *RNA_path_full_ID_py(Main *bmain, ID *id) { + const char *path; + ID *id_real = RNA_find_real_ID_and_path(bmain, id, &path); + + if (id_real) { + id = id_real; + } + else { + path = ""; + } + char id_esc[(sizeof(id->name) - 2) * 2]; BLI_strescape(id_esc, id->name + 2, sizeof(id_esc)); - return BLI_sprintfN("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc); + return BLI_sprintfN("bpy.data.%s[\"%s\"]%s%s", + BKE_idcode_to_name_plural(GS(id->name)), + id_esc, + path[0] ? "." : "", + path); } /** * Get the ID.struct as a python representation, eg: * bpy.data.foo["bar"].some_struct */ -char *RNA_path_full_struct_py(struct PointerRNA *ptr) +char *RNA_path_full_struct_py(Main *bmain, struct PointerRNA *ptr) { char *id_path; char *data_path; @@ -5976,7 +6082,7 @@ char *RNA_path_full_struct_py(struct PointerRNA *ptr) } /* never fails */ - id_path = RNA_path_full_ID_py(ptr->owner_id); + id_path = RNA_path_full_ID_py(bmain, ptr->owner_id); data_path = RNA_path_from_ID_to_struct(ptr); @@ -5996,10 +6102,8 @@ char *RNA_path_full_struct_py(struct PointerRNA *ptr) * Get the ID.struct.property as a python representation, eg: * bpy.data.foo["bar"].some_struct.some_prop[10] */ -char *RNA_path_full_property_py_ex(PointerRNA *ptr, - PropertyRNA *prop, - int index, - bool use_fallback) +char *RNA_path_full_property_py_ex( + Main *bmain, PointerRNA *ptr, PropertyRNA *prop, int index, bool use_fallback) { char *id_path; const char *data_delim; @@ -6013,7 +6117,7 @@ char *RNA_path_full_property_py_ex(PointerRNA *ptr, } /* never fails */ - id_path = RNA_path_full_ID_py(ptr->owner_id); + id_path = RNA_path_full_ID_py(bmain, ptr->owner_id); data_path = RNA_path_from_ID_to_property(ptr, prop); if (data_path) { @@ -6046,9 +6150,9 @@ char *RNA_path_full_property_py_ex(PointerRNA *ptr, return ret; } -char *RNA_path_full_property_py(PointerRNA *ptr, PropertyRNA *prop, int index) +char *RNA_path_full_property_py(Main *bmain, PointerRNA *ptr, PropertyRNA *prop, int index) { - return RNA_path_full_property_py_ex(ptr, prop, index, false); + return RNA_path_full_property_py_ex(bmain, ptr, prop, index, false); } /** @@ -6646,16 +6750,16 @@ char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr) return cstring; } -static char *rna_pointer_as_string__bldata(PointerRNA *ptr) +static char *rna_pointer_as_string__bldata(Main *bmain, PointerRNA *ptr) { if (ptr->type == NULL || ptr->owner_id == NULL) { return BLI_strdup("None"); } else if (RNA_struct_is_ID(ptr->type)) { - return RNA_path_full_ID_py(ptr->owner_id); + return RNA_path_full_ID_py(bmain, ptr->owner_id); } else { - return RNA_path_full_struct_py(ptr); + return RNA_path_full_struct_py(bmain, ptr); } } @@ -6672,7 +6776,7 @@ char *RNA_pointer_as_string(bContext *C, return RNA_pointer_as_string_id(C, ptr_prop); } else { - return rna_pointer_as_string__bldata(ptr_prop); + return rna_pointer_as_string__bldata(CTX_data_main(C), ptr_prop); } } |