Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2017-09-08 03:18:39 +10:00
commit a133b74709
4 changed files with 171 additions and 109 deletions

View File

@ -59,8 +59,11 @@ class NodeItem:
return self._label
else:
# if no custom label is defined, fall back to the node type UI name
cls = next(cls for cls in bpy.types.Node.__subclasses__() if cls.bl_rna.identifier == self.nodetype)
return cls.bl_rna.name
cls = bpy.types.Node.bl_rna_get_subclass(self.nodetype)
if cls is not None:
return cls.bl_rna.name
else:
return "Unknown"
@property
def translation_context(self):
@ -68,8 +71,11 @@ class NodeItem:
return bpy.app.translations.contexts.default
else:
# if no custom label is defined, fall back to the node type UI name
cls = next(cls for cls in bpy.types.Node.__subclasses__() if cls.bl_rna.identifier == self.nodetype)
return cls.bl_rna.translation_context
cls = bpy.types.Node.bl_rna_get_subclass(self.nodetype)
if cls is not None:
return cls.bl_rna.translation_context
else:
return bpy.app.translations.contexts.default
# NB: is a staticmethod because called with an explicit self argument
# NodeItemCustom sets this as a variable attribute in __init__

View File

@ -1438,87 +1438,82 @@ static bool ui_selectcontext_begin(
const bool is_array = RNA_property_array_check(prop);
const int rna_type = RNA_property_type(prop);
if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) {
goto finally;
}
if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
!BLI_listbase_is_empty(&lb))
{
selctx_data->elems_len = BLI_listbase_count(&lb);
selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__);
selctx_data->elems_len = BLI_listbase_count(&lb);
if (selctx_data->elems_len == 0) {
goto finally;
}
selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__);
for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
uiSelectContextElem *other = &selctx_data->elems[i];
/* TODO,. de-duplicate copy_to_selected_button */
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;
}
/* lptr might not be the same as link->ptr! */
if ((lptr.data != ptr.data) &&
(lprop == prop) &&
RNA_property_editable(&lptr, lprop))
{
other->ptr = lptr;
if (is_array) {
if (rna_type == PROP_FLOAT) {
other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
}
else if (rna_type == PROP_INT) {
other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
}
/* ignored for now */
#if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
#endif
for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
uiSelectContextElem *other = &selctx_data->elems[i];
/* TODO,. de-duplicate copy_to_selected_button */
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 {
if (rna_type == PROP_FLOAT) {
other->val_f = RNA_property_float_get(&lptr, lprop);
}
else if (rna_type == PROP_INT) {
other->val_i = RNA_property_int_get(&lptr, lprop);
}
/* ignored for now */
#if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
#endif
lptr = link->ptr;
lprop = prop;
}
continue;
/* lptr might not be the same as link->ptr! */
if ((lptr.data != ptr.data) &&
(lprop == prop) &&
RNA_property_editable(&lptr, lprop))
{
other->ptr = lptr;
if (is_array) {
if (rna_type == PROP_FLOAT) {
other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
}
else if (rna_type == PROP_INT) {
other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
}
/* ignored for now */
#if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
#endif
}
else {
if (rna_type == PROP_FLOAT) {
other->val_f = RNA_property_float_get(&lptr, lprop);
}
else if (rna_type == PROP_INT) {
other->val_i = RNA_property_int_get(&lptr, lprop);
}
/* ignored for now */
#if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
#endif
}
continue;
}
}
selctx_data->elems_len -= 1;
i -= 1;
}
selctx_data->elems_len -= 1;
i -= 1;
success = (selctx_data->elems_len != 0);
}
}
success = (selctx_data->elems_len != 0);
finally:
if (selctx_data->elems_len == 0) {
MEM_SAFE_FREE(selctx_data->elems);
}

View File

@ -621,51 +621,51 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
char *path = NULL;
bool use_path_from_id;
CollectionPointerLink *link;
ListBase lb;
ListBase lb = {NULL};
if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path))
return success;
if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
!BLI_listbase_is_empty(&lb))
{
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;
}
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 (lptr.data == ptr.data) {
/* lptr might not be the same as link->ptr! */
continue;
}
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);
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;
}
}
}
}
}
}
}
MEM_SAFE_FREE(path);
BLI_freelistN(&lb);
}

View File

@ -3716,6 +3716,66 @@ static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
return pyrna_struct_CreatePyObject(&r_ptr);
}
/**
* \note Return value is borrowed, caller must incref.
*/
static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id)
{
PyObject *ret_test = NULL;
PyObject *subclasses = ((PyTypeObject *)cls)->tp_subclasses;
if (subclasses) {
/* Unfortunately we can't use the dict key because Python class names
* don't match the bl_idname used internally. */
BLI_assert(PyDict_CheckExact(subclasses));
PyObject *key = NULL;
Py_ssize_t pos = 0;
PyObject *value = NULL;
while (PyDict_Next(subclasses, &pos, &key, &value)) {
BLI_assert(PyWeakref_CheckRef(value));
PyObject *subcls = PyWeakref_GET_OBJECT(value);
if (subcls != Py_None) {
BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(
((PyTypeObject *)subcls)->tp_dict, bpy_intern_str_bl_rna);
if (py_srna) {
StructRNA *srna = py_srna->ptr.data;
if (STREQ(id, RNA_struct_identifier(srna))) {
ret_test = subcls;
break;
}
}
ret_test = pyrna_struct_bl_rna_find_subclass_recursive(subcls, id);
if (ret_test) {
break;
}
}
}
}
return ret_test;
}
PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc,
".. classmethod:: bl_rna_get_subclass(id, default=None)\n"
"\n"
" :arg id: The RNA type identifier.\n"
" :type vector: string\n"
" :return: The class or default when not found.\n"
" :rtype: type\n"
);
static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
{
char *id;
PyObject *ret_default = Py_None;
if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) {
return NULL;
}
PyObject *ret = pyrna_struct_bl_rna_find_subclass_recursive(cls, id);
if (ret == NULL) {
ret = ret_default;
}
return Py_INCREF_RET(ret);
}
static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict)
{
PyObject *list_tmp;
@ -5014,6 +5074,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
{"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc},
{"type_recast", (PyCFunction)pyrna_struct_type_recast, METH_NOARGS, pyrna_struct_type_recast_doc},
{"bl_rna_get_subclass", (PyCFunction) pyrna_struct_bl_rna_get_subclass, METH_VARARGS | METH_CLASS, pyrna_struct_bl_rna_get_subclass_doc},
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experimental */