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.py48
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c18
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c32
6 files changed, 64 insertions, 39 deletions
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index ba56fa12fe1..c6bdc21afa6 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -115,14 +115,34 @@ class bpy_ops_submodule_op(object):
def _get_doc(self):
return op_as_string(self.idname())
+ @staticmethod
+ def _parse_args(args):
+ C_dict = None
+ C_exec = 'EXEC_DEFAULT'
+
+ if len(args) == 0:
+ pass
+ elif len(args) == 1:
+ if type(args[0]) != str:
+ C_dict = args[0]
+ else:
+ C_exec = args[0]
+ elif len(args) == 2:
+ C_exec, C_dict = args
+ else:
+ raise ValueError("1 or 2 args execution context is supported")
+
+ return C_dict, C_exec
+
__doc__ = property(_get_doc)
def __init__(self, module, func):
self.module = module
self.func = func
- def poll(self, context=None):
- return op_poll(self.idname_py(), context)
+ def poll(self, *args):
+ C_dict, C_exec = __class__._parse_args(args)
+ return op_poll(self.idname_py(), C_dict, C_exec)
def idname(self):
# submod.foo -> SUBMOD_OT_foo
@@ -135,31 +155,11 @@ class bpy_ops_submodule_op(object):
def __call__(self, *args, **kw):
# Get the operator from blender
- if len(args) > 2:
- raise ValueError("1 or 2 args execution context is supported")
-
- C_dict = None
-
if args:
-
- C_exec = 'EXEC_DEFAULT'
-
- if len(args) == 2:
- C_exec = args[0]
- C_dict = args[1]
- else:
- if type(args[0]) != str:
- C_dict = args[0]
- else:
- C_exec = args[0]
-
- if len(args) == 2:
- C_dict = args[1]
-
+ C_dict, C_exec = __class__._parse_args(args)
ret = op_call(self.idname_py(), C_dict, kw, C_exec)
-
else:
- ret = op_call(self.idname_py(), C_dict, kw)
+ ret = op_call(self.idname_py(), None, kw)
if 'FINISHED' in ret:
import bpy
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index eee4f133043..099629b0422 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -629,7 +629,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
if(but->context)
CTX_store_set((bContext*)C, but->context);
- if(ot == NULL || WM_operator_poll((bContext*)C, ot)==0) {
+ if(ot == NULL || WM_operator_poll_context((bContext*)C, ot, but->opcontext)==0) {
but->flag |= UI_BUT_DISABLED;
but->lock = 1;
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 5f8d604817a..e244565a6a6 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -434,7 +434,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
if(but->flag & UI_BUT_DISABLED) {
const char *poll_msg;
CTX_wm_operator_poll_msg_set(C, NULL);
- WM_operator_poll(C, but->optype);
+ WM_operator_poll_context(C, but->optype, but->opcontext);
poll_msg= CTX_wm_operator_poll_msg_get(C);
if(poll_msg) {
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Disabled: %s", poll_msg);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 1cf99218bf6..f3e960f87b2 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -46,12 +46,15 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
char *opname;
PyObject *context_dict= NULL; /* optional args */
PyObject *context_dict_back;
+ char *context_str= NULL;
PyObject *ret;
+ int context= WM_OP_EXEC_DEFAULT;
+
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
bContext *C = BPy_GetContext();
- if (!PyArg_ParseTuple(args, "s|O:_bpy.ops.poll", &opname, &context_dict))
+ if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
return NULL;
ot= WM_operatortype_find(opname, TRUE);
@@ -61,6 +64,15 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
+ if(context_str) {
+ if(RNA_enum_value_from_id(operator_context_items, context_str, &context)==0) {
+ char *enum_str= BPy_enum_as_string(operator_context_items);
+ PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s.poll\" error, expected a string enum in (%.200s)", opname, enum_str);
+ MEM_freeN(enum_str);
+ return NULL;
+ }
+ }
+
if(!PyDict_Check(context_dict))
context_dict= NULL;
@@ -70,7 +82,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
Py_XINCREF(context_dict); /* so we done loose it */
/* main purpose of thsi function */
- ret= WM_operator_poll((bContext*)C, ot) ? Py_True : Py_False;
+ ret= WM_operator_poll_context((bContext*)C, ot, context) ? Py_True : Py_False;
/* restore with original context dict, probably NULL but need this for nested operator calls */
Py_XDECREF(context_dict);
@@ -126,7 +138,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
- if(WM_operator_poll((bContext*)C, ot) == FALSE) {
+ if(WM_operator_poll_context((bContext*)C, ot, context) == FALSE) {
const char *msg= CTX_wm_operator_poll_msg_get(C);
PyErr_Format( PyExc_SystemError, "Operator bpy.ops.%.200s.poll() %s", opname, msg ? msg : "failed, context is incorrect");
CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 2a36e91ac66..7d4690ac7e1 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -218,6 +218,7 @@ struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *
int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
+int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context);
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 ed1caa5fafe..910a528d419 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -72,6 +72,8 @@
#include "wm_event_types.h"
#include "wm_draw.h"
+static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, short context, short poll_only);
+
/* ************ event management ************** */
void wm_event_add(wmWindow *win, wmEvent *event_to_add)
@@ -379,6 +381,12 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot)
return 1;
}
+/* sets up the new context and calls 'wm_operator_invoke()' with poll_only */
+int WM_operator_poll_context(bContext *C, wmOperatorType *ot, int context)
+{
+ return wm_operator_call_internal(C, ot, NULL, NULL, context, TRUE);
+}
+
static void wm_operator_print(wmOperator *op)
{
char *buf = WM_operator_pystring(NULL, op->type, op->ptr, 1);
@@ -603,11 +611,15 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
}
}
-int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports)
+int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, short poll_only)
{
wmWindowManager *wm= CTX_wm_manager(C);
int retval= OPERATOR_PASS_THROUGH;
+ /* this is done because complicated setup is done to call this function that is better not duplicated */
+ if(poll_only)
+ return 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 */
@@ -693,7 +705,7 @@ int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerR
* this is for python to access since its done the operator lookup
*
* invokes operator in context */
-static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports)
+static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, short context, short poll_only)
{
wmWindow *window= CTX_wm_window(C);
wmEvent *event;
@@ -758,7 +770,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int contex
CTX_wm_region_set(C, ar1);
}
- retval= wm_operator_invoke(C, ot, event, properties, reports);
+ retval= wm_operator_invoke(C, ot, event, properties, reports, poll_only);
/* set region back */
CTX_wm_region_set(C, ar);
@@ -772,7 +784,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int contex
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, reports, poll_only);
CTX_wm_region_set(C, ar);
return retval;
@@ -786,7 +798,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int contex
CTX_wm_region_set(C, NULL);
CTX_wm_area_set(C, NULL);
- retval= wm_operator_invoke(C, ot, event, properties, reports);
+ retval= wm_operator_invoke(C, ot, event, properties, reports, poll_only);
CTX_wm_region_set(C, ar);
CTX_wm_area_set(C, area);
@@ -794,7 +806,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int contex
}
case WM_OP_EXEC_DEFAULT:
case WM_OP_INVOKE_DEFAULT:
- return wm_operator_invoke(C, ot, event, properties, reports);
+ return wm_operator_invoke(C, ot, event, properties, reports, poll_only);
}
}
@@ -807,7 +819,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
{
wmOperatorType *ot= WM_operatortype_find(opstring, 0);
if(ot)
- return wm_operator_call_internal(C, ot, context, properties, NULL);
+ return wm_operator_call_internal(C, ot, properties, NULL, context, FALSE);
return 0;
}
@@ -839,7 +851,7 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
printf("error \"%s\" operator has no exec function, python cannot call it\n", op->type->name);
#endif
- retval= wm_operator_call_internal(C, ot, context, properties, reports);
+ retval= wm_operator_call_internal(C, ot, properties, reports, context, FALSE);
/* keep the reports around if needed later */
if ( (retval & OPERATOR_RUNNING_MODAL) ||
@@ -1168,7 +1180,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
wmOperatorType *ot= WM_operatortype_find(event->keymap_idname, 0);
if(ot)
- retval= wm_operator_invoke(C, ot, event, properties, NULL);
+ retval= wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
}
/* Finished and pass through flag as handled */
@@ -1421,7 +1433,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if(drop->poll(C, drag, event)) {
drop->copy(drag, drop);
- wm_operator_invoke(C, drop->ot, event, drop->ptr, NULL);
+ wm_operator_invoke(C, drop->ot, event, drop->ptr, NULL, FALSE);
action |= WM_HANDLER_BREAK;
}
}