Changes to functions from blender/windowmanager/intern/wm_event_system.c
authorCampbell Barton <ideasman42@gmail.com>
Sun, 18 Jan 2009 10:46:26 +0000 (10:46 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 18 Jan 2009 10:46:26 +0000 (10:46 +0000)
Python operator api was using WM_operator_name_call() which was confusing things too much.
Added WM_operator_call_py() which ended up being a very small function and split out operator creation into wm_operator_create()

Python operator now runs the poll() function and raises an error if it fails.

Eventually there should be error messages for poll that python can use to give the exact reason for failing (eg - library linked data, no active object...)

source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/object/object_edit.c
source/blender/editors/space_action/action_header.c
source/blender/editors/space_node/node_header.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/python/intern/bpy_operator.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c

index 011259dd9592d885769ed1351a7bdad05bc75e36..ef4398608d1f6087930ff87ac9bc40788fc90386 100644 (file)
@@ -222,7 +222,7 @@ static void ui_apply_but_funcs_after(bContext *C)
                        after->butm_func(C, after->butm_func_arg, after->a2);
 
                if(after->opname)
-                       WM_operator_name_call(C, after->opname, after->opcontext, after->opptr, NULL);
+                       WM_operator_name_call(C, after->opname, after->opcontext, after->opptr);
                if(after->opptr) {
                        WM_operator_properties_free(after->opptr);
                        MEM_freeN(after->opptr);
index 0d8a56ad728654a375fc410dcf313bac539e8a00..e9ef10648e94be55facb05542a1918bacac841dd 100644 (file)
@@ -1693,7 +1693,7 @@ static void operator_cb(bContext *C, void *arg, int retval)
        const char *opname= arg;
 
        if(opname && retval > 0)
-               WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL, NULL);
+               WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
 }
 
 static void vconfirm(bContext *C, char *opname, char *title, char *itemfmt, va_list ap)
index 7804f698c9b1426148d93cc5fe638c00cb247c71..997e1f5596743da18f6dd907583b55c9f4602e4f 100644 (file)
@@ -76,7 +76,7 @@ static int mesh_add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event
 {
        mesh_add_duplicate_exec(C, op);
        RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
-       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr, NULL);
+       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
        
        return OPERATOR_FINISHED;
 }
index fb4e50ab4ab5fafba6f234ba4ad6aea650b8ff36..f213e4f9cacc798dce1c4112ef281836bf46a0df 100644 (file)
@@ -5784,7 +5784,7 @@ static int add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
        add_duplicate_exec(C, op);
        
        RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
-       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr, NULL);
+       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
 
        return OPERATOR_FINISHED;
 }
index 65a2d956e11549b68d8d56767c3983861c5f7f4c..2695f77e902c1d0c30ee6b565abfdb4f70474aa2 100644 (file)
@@ -1543,10 +1543,10 @@ static void do_action_buttons(bContext *C, void *arg, int event)
                        break;
                        
                case B_ACTCOPYKEYS:
-                       WM_operator_name_call(C, "ACT_OT_keyframes_copy", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "ACT_OT_keyframes_copy", WM_OP_EXEC_REGION_WIN, NULL);
                        break;
                case B_ACTPASTEKEYS:
-                       WM_operator_name_call(C, "ACT_OT_keyframes_paste", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "ACT_OT_keyframes_paste", WM_OP_EXEC_REGION_WIN, NULL);
                        break;
        }
 }
index 6883affe0b21bdada4aee508fd0da1fe8bece55a..d239ebea4720b39f9eed1daf48f703a17d19eb3f 100644 (file)
@@ -75,7 +75,7 @@ static void do_node_selectmenu(bContext *C, void *arg, int event)
        
        switch(event) {
                case 1: /* border select */
-                       WM_operator_name_call(C, "NODE_OT_border_select", WM_OP_INVOKE_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "NODE_OT_border_select", WM_OP_INVOKE_REGION_WIN, NULL);
                        break;
                case 2: /* select/deselect all */
                        // XXX node_deselectall(snode, 1);
@@ -591,13 +591,13 @@ static void do_node_viewmenu(bContext *C, void *arg, int event)
        
        switch(event) {
                case 1: /* Zoom in */
-                       WM_operator_name_call(C, "View2D_OT_view_zoomin", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "View2D_OT_view_zoomin", WM_OP_EXEC_REGION_WIN, NULL);
                        break;
                case 2: /* View all */
-                       WM_operator_name_call(C, "View2D_OT_view_zoomout", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "View2D_OT_view_zoomout", WM_OP_EXEC_REGION_WIN, NULL);
                        break;
                case 3: /* View all */
-                       WM_operator_name_call(C, "NODE_OT_fit_all", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                       WM_operator_name_call(C, "NODE_OT_fit_all", WM_OP_EXEC_REGION_WIN, NULL);
                        break;
                case 4: /* Grease Pencil */
                        // XXX add_blockhandler(sa, NODES_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
index 71824b477baa5c973efdc5bada0fb58d4fadc870..7d3ae203cd206b0e8947e5117eefc7284a1b3a0a 100644 (file)
@@ -141,9 +141,9 @@ static int retopo_mesh_paint_check() {return 0;}
 void ED_view3d_exit_paint_modes(bContext *C)
 {
        if(G.f & G_VERTEXPAINT)
-               WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
        else if(G.f & G_WEIGHTPAINT)
-               WM_operator_name_call(C, "VIEW3D_OT_wpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_wpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
 
 //     if(G.f & G_TEXTUREPAINT) set_texturepaint();
 //     if(G.f & G_SCULPTMODE) set_sculptmode();
@@ -465,7 +465,7 @@ static void do_view3d_view_alignviewmenu(bContext *C, void *arg, int event)
 // XXX         mainqenter(PADASTERKEY, 1);
                break;
        case 6: /* Center View and Cursor to Origin */
-               WM_operator_name_call(C, "VIEW3D_OT_viewcenter", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_viewcenter", WM_OP_EXEC_REGION_WIN, NULL);
                curs= give_cursor(scene, v3d);
                curs[0]=curs[1]=curs[2]= 0.0;
                break;
@@ -550,10 +550,10 @@ static void do_view3d_viewmenu(bContext *C, void *arg, int event)
                endlocalview(scene, sa);
                break;
        case 9: /* View All (Home) */
-               WM_operator_name_call(C, "VIEW3D_OT_viewhome", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_viewhome", WM_OP_EXEC_REGION_WIN, NULL);
                break;
        case 11: /* View Selected */
-               WM_operator_name_call(C, "VIEW3D_OT_viewcenter", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_viewcenter", WM_OP_EXEC_REGION_WIN, NULL);
                break;
        case 13: /* Play Back Animation */
                play_anim(0);
@@ -565,7 +565,7 @@ static void do_view3d_viewmenu(bContext *C, void *arg, int event)
                add_blockhandler(sa, VIEW3D_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
                break;
        case 17: /* Set Clipping Border */
-               WM_operator_name_call(C, "VIEW3D_OT_clipping", WM_OP_INVOKE_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_clipping", WM_OP_INVOKE_REGION_WIN, NULL);
                break;
        case 18: /* render preview */
                toggle_blockhandler(sa, VIEW3D_HANDLER_PREVIEW, 0);
@@ -5333,7 +5333,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event)
 
        switch(event) {
        case B_HOME:
-               WM_operator_name_call(C, "VIEW3D_OT_viewhome", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+               WM_operator_name_call(C, "VIEW3D_OT_viewhome", WM_OP_EXEC_REGION_WIN, NULL);
                break;
        case B_REDR:
                ED_area_tag_redraw(sa);
@@ -5403,7 +5403,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event)
                                ED_view3d_exit_paint_modes(C);
                                if(obedit) ED_object_exit_editmode(C, EM_FREEUNDO|EM_FREEUNDO|EM_WAITCURSOR);   /* exit editmode and undo */
                                        
-                               WM_operator_name_call(C, "SCULPT_OT_toggle_mode", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                               WM_operator_name_call(C, "SCULPT_OT_toggle_mode", WM_OP_EXEC_REGION_WIN, NULL);
                        }
                }
                else if (v3d->modeselect == V3D_VERTEXPAINTMODE_SEL) {
@@ -5412,7 +5412,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event)
                                ED_view3d_exit_paint_modes(C);
                                if(obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);   /* exit editmode and undo */
                                
-                               WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                               WM_operator_name_call(C, "VIEW3D_OT_vpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
                        }
                } 
                else if (v3d->modeselect == V3D_TEXTUREPAINTMODE_SEL) {
@@ -5431,7 +5431,7 @@ static void do_view3d_buttons(bContext *C, void *arg, int event)
                                if(obedit) 
                                        ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);      /* exit editmode and undo */
                                
-                               WM_operator_name_call(C, "VIEW3D_OT_wpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL, NULL);
+                               WM_operator_name_call(C, "VIEW3D_OT_wpaint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
                        }
                } 
                else if (v3d->modeselect == V3D_POSEMODE_SEL) {
index f800b7d0d0438899906e43425d40564dc1258367..fb1040fac18182e5ff7ae33bd26c1f53f507a587 100644 (file)
@@ -194,6 +194,11 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
                return NULL;
        }
        
+       if(ot->poll && (ot->poll(self->C) == 0)) {
+               PyErr_SetString( PyExc_SystemError, "Operator poll() function failed, context is incorrect");
+               return NULL;
+       }
+       
        WM_operator_properties_create(&ptr, self->name);
        
        error_val= PYOP_props_from_dict(&ptr, kw);
@@ -203,7 +208,7 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
 
                BKE_reports_init(&reports, RPT_STORE);
 
-               WM_operator_name_call(self->C, self->name, WM_OP_EXEC_DEFAULT, &ptr, &reports);
+               WM_operator_call_py(self->C, ot, &ptr, &reports);
 
                report_str= BKE_reports_string(&reports, RPT_ERROR);
 
index a7b90a7fccd6ac9d8b4c9fe38d6d4a805645dc02..d7559eac30666b221f3f0ce7a8c3dac276dfe460 100644 (file)
@@ -126,7 +126,8 @@ void                WM_operatortype_append_ptr      (void (*opfunc)(wmOperatorType*, void *), void
 int                    WM_operatortype_remove(const char *idname);
 
 int                    WM_operator_call                (struct bContext *C, struct wmOperator *op);
-int         WM_operator_name_call      (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties, struct ReportList *reports);
+int         WM_operator_name_call      (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
+int                    WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports);
 
 void           WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring);
 void           WM_operator_properties_free(struct PointerRNA *ptr);
index a9069abe1139416f71a21c488fd5649407609d6f..0f2df53481fc9e95ccd0df30f8d2b45fc3466a06 100644 (file)
@@ -440,41 +440,49 @@ int WM_operator_call(bContext *C, wmOperator *op)
        return retval;
 }
 
-static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports)
+
+static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, PointerRNA *properties, ReportList *reports)
+{
+       wmOperator *op= MEM_callocN(sizeof(wmOperator), ot->idname);    /* XXX operatortype names are static still. for debug */
+       
+       /* XXX adding new operator could be function, only happens here now */
+       op->type= ot;
+       BLI_strncpy(op->idname, ot->idname, OP_MAX_TYPENAME);
+       
+       /* initialize properties, either copy or create */
+       op->ptr= MEM_callocN(sizeof(PointerRNA), "wmOperatorPtrRNA");
+       if(properties && properties->data) {
+               op->properties= IDP_CopyProperty(properties->data);
+       }
+       else {
+               IDPropertyTemplate val = {0};
+               op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
+       }
+       RNA_pointer_create(&wm->id, ot->srna, op->properties, op->ptr);
+
+       /* initialize error reports */
+       if (reports) {
+               op->reports= reports; /* must be initialized alredy */
+       }
+       else {
+               op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
+               BKE_reports_init(op->reports, RPT_STORE);
+       }
+       
+       return op;
+}
+
+static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
        int retval= OPERATOR_PASS_THROUGH;
 
        if(ot->poll==NULL || ot->poll(C)) {
-               wmOperator *op= MEM_callocN(sizeof(wmOperator), ot->idname);    /* XXX operatortype names are static still. for debug */
-
+               wmOperator *op= wm_operator_create(wm, ot, properties, NULL);
+               
                if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE)
                        printf("handle evt %d win %d op %s\n", event?event->type:0, CTX_wm_screen(C)->subwinactive, ot->idname); 
                
-               /* XXX adding new operator could be function, only happens here now */
-               op->type= ot;
-               BLI_strncpy(op->idname, ot->idname, OP_MAX_TYPENAME);
-               
-               /* initialize properties, either copy or create */
-               op->ptr= MEM_callocN(sizeof(PointerRNA), "wmOperatorPtrRNA");
-               if(properties && properties->data) {
-                       op->properties= IDP_CopyProperty(properties->data);
-               }
-               else {
-                       IDPropertyTemplate val = {0};
-                       op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
-               }
-               RNA_pointer_create(&wm->id, ot->srna, op->properties, op->ptr);
-
-               /* initialize error reports */
-               if (reports) {
-                       op->reports= reports; /* must be initialized alredy */
-               }
-               else {
-                       op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
-                       BKE_reports_init(op->reports, RPT_STORE);
-               }
-
                if(op->type->invoke && event)
                        retval= (*op->type->invoke)(C, op, event);
                else if(op->type->exec)
@@ -483,7 +491,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
                        printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */
 
                if(!(retval & OPERATOR_RUNNING_MODAL)) {
-                       if(reports==NULL && op->reports->list.first) /* only show the report if the report list was not given in the function */
+                       if(op->reports->list.first) /* only show the report if the report list was not given in the function */
                                uiPupmenuReports(C, op->reports);
                
                if (retval & OPERATOR_FINISHED) /* todo - this may conflict with the other WM_operator_print, if theres ever 2 prints for 1 action will may need to add modal check here */
@@ -495,8 +503,6 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
                        wm_operator_register(wm, op);
                }
                else if(!(retval & OPERATOR_RUNNING_MODAL)) {
-                       if (reports)
-                               op->reports= NULL; /* dont let the operator free reports passed to this function */
                        WM_operator_free(op);
                }
        }
@@ -505,7 +511,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
 }
 
 /* invokes operator in context */
-int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties, ReportList *reports)
+int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties)
 {
        wmOperatorType *ot= WM_operatortype_find(opstring);
        wmWindow *window= CTX_wm_window(C);
@@ -535,7 +541,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
                                                CTX_wm_region_set(C, ar1);
                                }
                                
-                               retval= wm_operator_invoke(C, ot, event, properties, reports);
+                               retval= wm_operator_invoke(C, ot, event, properties);
                                
                                /* set region back */
                                CTX_wm_region_set(C, ar);
@@ -550,7 +556,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
                                ARegion *ar= CTX_wm_region(C);
 
                                CTX_wm_region_set(C, NULL);
-                               retval= wm_operator_invoke(C, ot, event, properties, reports);
+                               retval= wm_operator_invoke(C, ot, event, properties);
                                CTX_wm_region_set(C, ar);
 
                                return retval;
@@ -565,7 +571,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
 
                                CTX_wm_region_set(C, NULL);
                                CTX_wm_area_set(C, NULL);
-                               retval= wm_operator_invoke(C, ot, window->eventstate, properties, reports);
+                               retval= wm_operator_invoke(C, ot, window->eventstate, properties);
                                CTX_wm_region_set(C, ar);
                                CTX_wm_area_set(C, area);
 
@@ -574,13 +580,32 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
                        case WM_OP_EXEC_DEFAULT:
                                event= NULL;    /* pass on without break */
                        case WM_OP_INVOKE_DEFAULT:
-                               return wm_operator_invoke(C, ot, event, properties, reports);
+                               return wm_operator_invoke(C, ot, event, properties);
                }
        }
        
        return 0;
 }
 
+/* Similar to WM_operator_name_call called with WM_OP_EXEC_DEFAULT context.
+   - wmOperatorType is used instead of operator name since python alredy has the operator type
+   - poll() must be called by python before this runs.
+   - reports can be passed to this function (so python can report them as exceptions)
+*/
+int WM_operator_call_py(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports)
+{
+       wmWindowManager *wm=    CTX_wm_manager(C);
+       wmOperator *op=                 wm_operator_create(wm, ot, properties, reports);
+       int retval=                             op->type->exec(C, op);
+       
+       if (reports)
+               op->reports= NULL; /* dont let the operator free reports passed to this function */
+       WM_operator_free(op);
+       
+       return retval;
+}
+
+
 /* ********************* handlers *************** */
 
 /* not handler itself, is called by UI to move handlers to other queues, so don't close modal ones */
@@ -773,7 +798,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                wmOperatorType *ot= WM_operatortype_find(event->keymap_idname);
 
                if(ot)
-                       retval= wm_operator_invoke(C, ot, event, properties, NULL);
+                       retval= wm_operator_invoke(C, ot, event, properties);
        }
 
        if(retval & OPERATOR_PASS_THROUGH)