Revision: 23332
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23332
Author:   blendix
Date:     2009-09-18 15:02:20 +0200 (Fri, 18 Sep 2009)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/release/io/export_ply.py
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/interface/interface_templates.c
    trunk/blender/source/blender/editors/space_view3d/view3d_toolbar.c
    trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
    trunk/blender/source/blender/python/intern/bpy_operator.c
    trunk/blender/source/blender/python/intern/bpy_operator_wrap.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: trunk/blender/release/io/export_ply.py
===================================================================
--- trunk/blender/release/io/export_ply.py      2009-09-18 12:43:36 UTC (rev 
23331)
+++ trunk/blender/release/io/export_ply.py      2009-09-18 13:02:20 UTC (rev 
23332)
@@ -250,7 +250,6 @@
        ]
        
        def poll(self, context):
-               print("Poll")
                return context.active_object != None
        
        def execute(self, context):

Modified: trunk/blender/source/blender/editors/interface/interface.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface.c  2009-09-18 
12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/editors/interface/interface.c  2009-09-18 
13:02:20 UTC (rev 23332)
@@ -597,7 +597,7 @@
                        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;
                        }

Modified: trunk/blender/source/blender/editors/interface/interface_templates.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_templates.c        
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/editors/interface/interface_templates.c        
2009-09-18 13:02:20 UTC (rev 23332)
@@ -2064,7 +2064,7 @@
        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);
                                

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_toolbar.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_toolbar.c  
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_toolbar.c  
2009-09-18 13:02:20 UTC (rev 23332)
@@ -163,7 +163,7 @@
        
        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 @@
        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;

Modified: trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h     
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h     
2009-09-18 13:02:20 UTC (rev 23332)
@@ -228,6 +228,7 @@
        /* 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;
 

Modified: trunk/blender/source/blender/python/intern/bpy_operator.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_operator.c   2009-09-18 
12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/python/intern/bpy_operator.c   2009-09-18 
13:02:20 UTC (rev 23332)
@@ -65,7 +65,7 @@
                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;
        }

Modified: trunk/blender/source/blender/python/intern/bpy_operator_wrap.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_operator_wrap.c      
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/python/intern/bpy_operator_wrap.c      
2009-09-18 13:02:20 UTC (rev 23332)
@@ -81,9 +81,9 @@
        
 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 @@
                
                
                /* Assign instance attributes from operator properties */
-               {
+               if(op) {
                        const char *arg_name;
 
                        RNA_STRUCT_BEGIN(op->ptr, prop) {
@@ -121,10 +121,12 @@
                }
 
                /* 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 @@
                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 @@
        }
        
        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_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 @@
        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;
        

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h 2009-09-18 12:43:36 UTC 
(rev 23331)
+++ trunk/blender/source/blender/windowmanager/WM_api.h 2009-09-18 13:02:20 UTC 
(rev 23332)
@@ -162,6 +162,7 @@
 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);

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c 
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c 
2009-09-18 13:02:20 UTC (rev 23332)
@@ -259,20 +259,23 @@
 
 /* ********************* 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 @@
        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 @@
        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)

Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c    
2009-09-18 12:43:36 UTC (rev 23331)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c    
2009-09-18 13:02:20 UTC (rev 23332)
@@ -682,7 +682,7 @@
        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);
                                


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to