diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-09-18 17:02:20 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-09-18 17:02:20 +0400 |
commit | 26836bf44f39d4c83d7b4de94dd742c84cf82eda (patch) | |
tree | fcada9d85208c899c4aa733333bc97af25416a97 | |
parent | 854ea35a2498cb35e7cce26e396fab775692196e (diff) |
2.5: Python operators now have a working poll() function,
solved by wrapping all polling in WM_operator_poll and
adding a special callback for python.
-rw-r--r-- | release/io/export_ply.py | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_toolbar.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_windowmanager_types.h | 1 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator.c | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator_wrap.c | 42 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 15 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 2 |
10 files changed, 39 insertions, 33 deletions
diff --git a/release/io/export_ply.py b/release/io/export_ply.py index 491ffe6b9df..b8fbe56f01c 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -250,7 +250,6 @@ class EXPORT_OT_ply(bpy.types.Operator): ] def poll(self, context): - print("Poll") return context.active_object != None def execute(self, context): diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2d4b2caa845..fbc3c859f20 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -597,7 +597,7 @@ void uiEndBlock(const bContext *C, uiBlock *block) if(but->context) CTX_store_set((bContext*)C, but->context); - if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) { + if(ot == NULL || WM_operator_poll((bContext*)C, ot)==0) { but->flag |= UI_BUT_DISABLED; but->lock = 1; } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b27425f958d..b15ddcfae17 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2064,7 +2064,7 @@ static void operator_search_cb(const bContext *C, void *arg, char *str, uiSearch for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { char name[256]; int len= strlen(ot->name); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 46341f53c26..e1c6f70bde0 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -163,7 +163,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) if(op==NULL) return; - if(op->type->poll && op->type->poll((bContext *)C)==0) + if(WM_operator_poll((bContext*)C, op->type) == 0) return; block= uiLayoutGetBlock(pa->layout); @@ -208,7 +208,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { if(0==uiSearchItemAdd(items, ot->name, ot, 0)) break; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 67a6b3153e4..ee2b0ab848f 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -228,6 +228,7 @@ typedef struct wmOperatorType { /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; + int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot); } wmOperatorType; diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 69a7e554452..f2e2dd77e6d 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -65,7 +65,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) return NULL; } - if(ot->poll && (ot->poll(C) == FALSE)) { + if(WM_operator_poll((bContext*)C, ot) == FALSE) { PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect"); return NULL; } diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 0a487a8dbe8..bbf657d8ce0 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -81,9 +81,9 @@ static struct BPY_flag_def pyop_ret_flags[] = { extern void BPY_update_modules( void ); //XXX temp solution -static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event) +static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event) { - PyObject *py_class = op->type->pyop_data; + PyObject *py_class = ot->pyop_data; PyObject *args; PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); @@ -105,7 +105,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve /* Assign instance attributes from operator properties */ - { + if(op) { const char *arg_name; RNA_STRUCT_BEGIN(op->ptr, prop) { @@ -121,10 +121,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } /* set operator pointer RNA as instance "__operator__" attribute */ - RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); - py_operator= pyrna_struct_CreatePyObject(&ptr_operator); - PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); - Py_DECREF(py_operator); + if(op) { + RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); + py_operator= pyrna_struct_CreatePyObject(&ptr_operator); + PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); + Py_DECREF(py_operator); + } RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); @@ -148,8 +150,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve else if (mode==PYOP_POLL) { item= PyObject_GetAttrString(py_class, "poll"); args = PyTuple_New(2); - //XXX Todo - wrap context in a useful way, None for now. - PyTuple_SET_ITEM(args, 1, Py_None); + PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); } PyTuple_SET_ITEM(args, 0, py_class_instance); @@ -160,21 +161,24 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } if (ret == NULL) { /* covers py_class_instance failing too */ - BPy_errors_to_report(op->reports); + if(op) + BPy_errors_to_report(op->reports); } else { if (mode==PYOP_POLL) { if (PyBool_Check(ret) == 0) { PyErr_SetString(PyExc_ValueError, "Python poll function return value "); - BPy_errors_to_report(op->reports); + if(op) + BPy_errors_to_report(op->reports); } else { ret_flag= ret==Py_True ? 1:0; } } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) { - /* the returned value could not be converted into a flag */ - BPy_errors_to_report(op->reports); + /* the returned value could not be converted into a flag */ + if(op) + BPy_errors_to_report(op->reports); ret_flag = OPERATOR_CANCELLED; } @@ -225,19 +229,17 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event) { - return PYTHON_OT_generic(PYOP_INVOKE, C, op, event); + return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event); } static int PYTHON_OT_execute(bContext *C, wmOperator *op) { - return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL); + return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL); } -static int PYTHON_OT_poll(bContext *C) +static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot) { - // XXX TODO - no way to get the operator type (and therefor class) from the poll function. - //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL); - return 1; + return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL); } void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) @@ -270,7 +272,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) if (PyObject_HasAttrString(py_class, "execute")) ot->exec= PYTHON_OT_execute; if (PyObject_HasAttrString(py_class, "poll")) - ot->poll= PYTHON_OT_poll; + ot->pyop_poll= PYTHON_OT_poll; ot->pyop_data= userdata; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index a757deb4a8a..69c96d0d89d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -162,6 +162,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag) wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname); +int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot); int WM_operator_call (struct bContext *C, struct wmOperator *op); int WM_operator_repeat (struct bContext *C, struct wmOperator *op); int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2a2e0141381..e570a733d89 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -259,20 +259,23 @@ void wm_event_do_notifiers(bContext *C) /* ********************* operators ******************* */ -static int wm_operator_poll(bContext *C, wmOperatorType *ot) +int WM_operator_poll(bContext *C, wmOperatorType *ot) { wmOperatorTypeMacro *otmacro; for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) { wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0); - if(0==wm_operator_poll(C, ot)) + if(0==WM_operator_poll(C, ot)) return 0; } - if(ot->poll) + /* python needs operator type, so we added exception for it */ + if(ot->pyop_poll) + return ot->pyop_poll(C, ot); + else if(ot->poll) return ot->poll(C); - + return 1; } @@ -284,7 +287,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) if(op==NULL || op->type==NULL) return retval; - if(0==wm_operator_poll(C, op->type)) + if(0==WM_operator_poll(C, op->type)) return retval; if(op->type->exec) @@ -397,7 +400,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P wmWindowManager *wm= CTX_wm_manager(C); int retval= OPERATOR_PASS_THROUGH; - if(wm_operator_poll(C, ot)) { + if(WM_operator_poll(C, ot)) { wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index f31d62967ae..a6fc575ce70 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -682,7 +682,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { char name[256]; int len= strlen(ot->name); |