Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/modules/bpy/ops.py4
-rw-r--r--release/scripts/modules/bpy_types.py7
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_wm.c52
-rw-r--r--source/blender/python/intern/bpy_operator.c6
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c184
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.h2
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c21
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c1
10 files changed, 278 insertions, 1 deletions
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 5b3009db2bf..c8218d6703c 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -23,6 +23,7 @@ from _bpy import ops as ops_module
op_add = ops_module.add
op_remove = ops_module.remove
+op_add_macro = ops_module.add_macro
op_dir = ops_module.dir
op_call = ops_module.call
op_as_string = ops_module.as_string
@@ -58,6 +59,9 @@ class bpy_ops(object):
def add(self, pyop):
op_add(pyop)
+
+ def add_macro(self, pyop):
+ op_add_macro(pyop)
def remove(self, pyop):
op_remove(pyop)
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 565f0e4da1b..5a8d6ceedf6 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -252,6 +252,13 @@ class OrderedMeta(type):
class Operator(StructRNA, metaclass=OrderedMeta):
pass
+class Macro(StructRNA, metaclass=OrderedMeta):
+ # bpy_types is imported before ops is defined
+ # so we have to do a local import on each run
+ @classmethod
+ def define(self, opname):
+ from _bpy import ops
+ return ops.macro_define(self, opname)
class Menu(StructRNA):
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 36653f8c06e..959109f7bbb 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -323,6 +323,7 @@ extern StructRNA RNA_OperatorFileListElement;
extern StructRNA RNA_OperatorMousePath;
extern StructRNA RNA_OperatorProperties;
extern StructRNA RNA_OperatorStrokeElement;
+extern StructRNA RNA_OperatorTypeMacro;
extern StructRNA RNA_OrController;
extern StructRNA RNA_OutflowFluidSettings;
extern StructRNA RNA_PackedFile;
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 10e27814236..35f2a31b7ef 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -309,6 +309,12 @@ static PointerRNA rna_Operator_properties_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, op->type->srna, op->properties);
}
+static PointerRNA rna_OperatorTypeMacro_properties_get(PointerRNA *ptr)
+{
+ wmOperatorTypeMacro *otmacro= (wmOperatorTypeMacro*)ptr->data;
+ wmOperatorType *ot = WM_operatortype_exists(otmacro->idname);
+ return rna_pointer_inherit_refine(ptr, ot->srna, otmacro->properties);
+}
static void rna_Event_ascii_get(PointerRNA *ptr, char *value)
{
@@ -593,6 +599,50 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_idproperties_func(srna, "rna_OperatorProperties_idproperties");
}
+static void rna_def_macro_operator(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "Macro", NULL);
+ RNA_def_struct_ui_text(srna, "Macro Operator", "Storage of a macro operator being executed, or registered after execution.");
+ RNA_def_struct_sdna(srna, "wmOperator");
+
+ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_string_funcs(prop, "rna_Operator_name_get", "rna_Operator_name_length", NULL);
+ RNA_def_property_ui_text(prop, "Name", "");
+ RNA_def_struct_name_property(srna, prop);
+
+ prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "OperatorProperties");
+ RNA_def_property_ui_text(prop, "Properties", "");
+ RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL);
+}
+
+static void rna_def_operator_type_macro(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "OperatorTypeMacro", NULL);
+ RNA_def_struct_ui_text(srna, "OperatorTypeMacro", "Storage of a sub operator in a macro after it has been added.");
+ RNA_def_struct_sdna(srna, "wmOperatorTypeMacro");
+
+// prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+// RNA_def_property_string_sdna(prop, NULL, "idname");
+// RNA_def_property_ui_text(prop, "Name", "Name of the sub operator.");
+// RNA_def_struct_name_property(srna, prop);
+
+ prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "OperatorProperties");
+ RNA_def_property_ui_text(prop, "Properties", "");
+ RNA_def_property_pointer_funcs(prop, "rna_OperatorTypeMacro_properties_get", NULL, NULL);
+}
+
static void rna_def_operator_utils(BlenderRNA *brna)
{
StructRNA *srna;
@@ -911,6 +961,8 @@ void RNA_def_wm(BlenderRNA *brna)
rna_def_operator(brna);
rna_def_operator_utils(brna);
rna_def_operator_filelist_element(brna);
+ rna_def_macro_operator(brna);
+ rna_def_operator_type_macro(brna);
rna_def_event(brna);
rna_def_window(brna);
rna_def_windowmanager(brna);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 6ae63f2ab65..b4a2fb36a97 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -60,7 +60,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
if (!PyArg_ParseTuple(args, "sO|O!i:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context))
return NULL;
- ot= WM_operatortype_find(opname, TRUE);
+ ot= WM_operatortype_exists(opname);
if (ot == NULL) {
PyErr_Format( PyExc_SystemError, "_bpy.ops.call: operator \"%s\"could not be found", opname);
@@ -245,6 +245,8 @@ PyObject *BPY_operator_module( void )
static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL};
static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL};
static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL};
+ static PyMethodDef pyop_add_macro_meth ={"add_macro", (PyCFunction) PYOP_wrap_add_macro, METH_O, NULL};
+ static PyMethodDef pyop_macro_def_meth ={"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL};
static PyMethodDef pyop_remove_meth = {"remove", (PyCFunction) PYOP_wrap_remove, METH_O, NULL};
PyObject *submodule = PyModule_New("_bpy.ops");
@@ -255,6 +257,8 @@ PyObject *BPY_operator_module( void )
PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) );
PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) );
PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) );
+ PyModule_AddObject( submodule, "add_macro", PyCFunction_New(&pyop_add_macro_meth, NULL) );
+ PyModule_AddObject( submodule, "macro_define",PyCFunction_New(&pyop_macro_def_meth, NULL) );
PyModule_AddObject( submodule, "remove", PyCFunction_New(&pyop_remove_meth, NULL) );
return submodule;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index ff49d381dd1..cd5b0756531 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -342,6 +342,80 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
}
}
+void PYTHON_OT_MACRO_wrapper(wmOperatorType *ot, void *userdata)
+{
+ PyObject *py_class = (PyObject *)userdata;
+ PyObject *item;
+
+ /* identifiers */
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
+ ot->idname= _PyUnicode_AsString(item);
+ Py_DECREF(item);
+
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
+ if (item) {
+ ot->name= _PyUnicode_AsString(item);
+ Py_DECREF(item);
+ }
+ else {
+ ot->name= ot->idname;
+ PyErr_Clear();
+ }
+
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
+ ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"undocumented python operator";
+ Py_XDECREF(item);
+
+ if (PyObject_HasAttrString(py_class, "poll"))
+ ot->pyop_poll= PYTHON_OT_poll;
+ if (PyObject_HasAttrString(py_class, "draw"))
+ ot->ui= PYTHON_OT_draw;
+
+ ot->pyop_data= userdata;
+
+ /* flags */
+ ot->flag= OPTYPE_MACRO; /* macro at least */
+
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
+ if (item) {
+ ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
+ Py_DECREF(item);
+ }
+ else {
+ PyErr_Clear();
+ }
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
+ if (item) {
+ ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
+ Py_DECREF(item);
+ }
+ else {
+ PyErr_Clear();
+ }
+
+ /* Can't use this because it returns a dict proxy
+ *
+ * item= PyObject_GetAttrString(py_class, "__dict__");
+ */
+ item= ((PyTypeObject*)py_class)->tp_dict;
+ if(item) {
+ /* only call this so pyrna_deferred_register_props gives a useful error
+ * WM_operatortype_append_macro_ptr will call RNA_def_struct_identifier
+ * later */
+ RNA_def_struct_identifier(ot->srna, ot->idname);
+
+ if(pyrna_deferred_register_props(ot->srna, item)!=0) {
+ /* failed to register operator props */
+ PyErr_Print();
+ PyErr_Clear();
+
+ }
+ }
+ else {
+ PyErr_Clear();
+ }
+}
+
/* pyOperators - Operators defined IN Python */
PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
@@ -407,6 +481,116 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
Py_RETURN_NONE;
}
+/* pyOperators - Macro Operators defined IN Python */
+PyObject *PYOP_wrap_add_macro(PyObject *self, PyObject *py_class)
+{
+ PyObject *base_class, *item;
+ wmOperatorType *ot;
+
+
+ char *idname= NULL;
+ char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
+
+ static struct BPY_class_attr_check pyop_class_attr_values[]= {
+ {PYOP_ATTR_IDNAME, 's', -1, OP_MAX_TYPENAME-3, 0}, /* -3 because a.b -> A_OT_b */
+ {PYOP_ATTR_UINAME, 's', -1,-1, BPY_CLASS_ATTR_OPTIONAL},
+ {PYOP_ATTR_DESCRIPTION, 's', -1,-1, BPY_CLASS_ATTR_NONE_OK},
+ {"poll", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
+ {"draw", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
+ {NULL, 0, 0, 0}
+ };
+
+ //PyObject bpy_mod= PyDict_GetItemString(PyEval_GetGlobals(), "bpy");
+ PyObject *bpy_mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
+ base_class = PyObject_GetAttrStringArgs(bpy_mod, 2, "types", "Macro");
+ Py_DECREF(bpy_mod);
+
+ if(BPY_class_validate("Macro", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
+ return NULL; /* BPY_class_validate sets the error */
+ }
+ Py_DECREF(base_class);
+
+ /* class name is used for operator ID - this can be changed later if we want */
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
+ idname = _PyUnicode_AsString(item);
+
+
+ /* annoying conversion! */
+ WM_operator_bl_idname(idname_bl, idname);
+ Py_DECREF(item);
+
+ item= PyUnicode_FromString(idname_bl);
+ PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
+ idname = _PyUnicode_AsString(item);
+ Py_DECREF(item);
+ /* end annoying conversion! */
+
+
+ /* remove if it already exists */
+ if ((ot=WM_operatortype_exists(idname))) {
+ if(ot->pyop_data) {
+ Py_XDECREF((PyObject*)ot->pyop_data);
+ }
+ WM_operatortype_remove(idname);
+ }
+
+ Py_INCREF(py_class);
+ WM_operatortype_append_macro_ptr(PYTHON_OT_MACRO_wrapper, py_class);
+
+ Py_RETURN_NONE;
+}
+
+PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args)
+{
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+ PyObject *macro;
+ PyObject *item;
+ PointerRNA ptr_otmacro;
+
+ char *opname;
+ char *macroname;
+
+ if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
+ return NULL;
+
+ if (WM_operatortype_exists(opname) == NULL) {
+ PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname);
+ return NULL;
+ }
+
+ /* identifiers */
+ item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME_BL);
+
+ if (!item) {
+ item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME);
+
+ if (!item) {
+ PyErr_Format(PyExc_ValueError, "Macro Define: not a valid Macro class");
+ } else {
+ macroname= _PyUnicode_AsString(item);
+ PyErr_Format(PyExc_ValueError, "Macro Define: '%s' hasn't been registered yet", macroname);
+ }
+ return NULL;
+ }
+
+ macroname= _PyUnicode_AsString(item);
+
+ ot = WM_operatortype_exists(macroname);
+
+ if (!ot) {
+ PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro or hasn't been registered yet", macroname);
+ return NULL;
+ }
+
+ otmacro = WM_operatortype_macro_define(ot, opname);
+
+ RNA_pointer_create(NULL, &RNA_OperatorTypeMacro, otmacro, &ptr_otmacro);
+
+ return pyrna_struct_CreatePyObject(&ptr_otmacro);
+}
+
+
PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
{
PyObject *py_class;
diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h
index 2929d57ab82..939fedd1f2b 100644
--- a/source/blender/python/intern/bpy_operator_wrap.h
+++ b/source/blender/python/intern/bpy_operator_wrap.h
@@ -29,6 +29,8 @@
/* these are used for operator methods, used by bpy_operator.c */
PyObject *PYOP_wrap_add(PyObject *self, PyObject *args);
+PyObject *PYOP_wrap_add_macro(PyObject *self, PyObject *args);
+PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args);
#endif
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index a270b75eea1..549ef11c14e 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -180,6 +180,7 @@ wmOperatorType *WM_operatortype_exists(const char *idname);
wmOperatorType *WM_operatortype_first(void);
void WM_operatortype_append (void (*opfunc)(wmOperatorType*));
void WM_operatortype_append_ptr (void (*opfunc)(wmOperatorType*, void *), void *userdata);
+void WM_operatortype_append_macro_ptr (void (*opfunc)(wmOperatorType*, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 9cee2140fc7..582410c4368 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -353,6 +353,27 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag)
return ot;
}
+void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), void *userdata)
+{
+ wmOperatorType *ot;
+
+ ot= MEM_callocN(sizeof(wmOperatorType), "operatortype");
+ ot->srna= RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+
+ ot->exec= wm_macro_exec;
+ ot->invoke= wm_macro_invoke;
+ ot->modal= wm_macro_modal;
+ ot->cancel= wm_macro_cancel;
+ ot->poll= NULL;
+
+ opfunc(ot, userdata);
+
+ RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)");
+ RNA_def_struct_identifier(ot->srna, ot->idname);
+
+ BLI_addtail(&global_ops, ot);
+}
+
wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
{
wmOperatorTypeMacro *otmacro= MEM_callocN(sizeof(wmOperatorTypeMacro), "wmOperatorTypeMacro");
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 7f9928262c3..9abd518ff6e 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -232,6 +232,7 @@ void WM_operator_properties_free(struct PointerRNA *ptr){}
void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){}
void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot){}
void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){}
+void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){}
void WM_operator_bl_idname(char *to, const char *from){}
void WM_operator_py_idname(char *to, const char *from){}
short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;}