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.
This commit is contained in:
2009-09-18 13:02:20 +00:00
parent 854ea35a24
commit 26836bf44f
10 changed files with 39 additions and 33 deletions

View File

@@ -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;