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:
authorCampbell Barton <ideasman42@gmail.com>2009-12-24 19:10:26 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-12-24 19:10:26 +0300
commit4dd3e6c36070e64d8b1d784a34d9881ae2c3eed8 (patch)
treeb5797cbc48a2cffad1a50d07945c8e5b31b68e6c /source/blender
parent1d224ad692c8794500f4d6fd5257887db150a635 (diff)
support for registering operators using the same internal rna api as panels, menus, headers & render engines since there was a fair bit of duplicate functionality.
will remove the old system and update scripts next.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/intern/brush.c4
-rw-r--r--source/blender/editors/mesh/mesh_intern.h4
-rw-r--r--source/blender/editors/space_console/console_intern.h32
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c2
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h63
-rw-r--r--source/blender/makesrna/intern/rna_wm.c212
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c32
-rw-r--r--source/blender/python/intern/bpy_operator.c2
-rw-r--r--source/blender/python/intern/bpy_rna.c16
-rw-r--r--source/blender/windowmanager/WM_api.h22
-rw-r--r--source/blender/windowmanager/WM_types.h54
-rw-r--r--source/blender/windowmanager/wm_window.h5
13 files changed, 352 insertions, 98 deletions
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 070d98ce25f..dc7b6d3ad9b 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -195,7 +195,7 @@ void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_m
void seq_update_sound(struct Sequence *seq);
void seq_update_muting(struct Editing *ed);
-
+void seqbase_sound_reload(Scene *scene, ListBase *seqbase);
void clear_scene_in_allseqs(struct Scene *sce);
struct Sequence *get_seq_by_name(struct ListBase *seqbase, const char *name, int recursive);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 09d73f20b9a..667b0d50ee9 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -40,6 +40,8 @@
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
+#include "WM_types.h"
+
#include "RNA_access.h"
#include "BLI_math.h"
@@ -56,6 +58,8 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
+
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index e8ec85d8bd0..31e8cb16abc 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -34,6 +34,8 @@
struct bContext;
struct wmOperatorType;
+struct wmOperator;
+
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
@@ -197,7 +199,7 @@ extern EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short st
void join_triangles(EditMesh *em);
int removedoublesflag(EditMesh *em, short flag, short automerge, float limit); /* return amount */
void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float fractal, int beauty, int numcuts, int seltype);
-int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc);
+int EdgeSlide(EditMesh *em, struct wmOperator *op, short immediate, float imperc);
void MESH_OT_merge(struct wmOperatorType *ot);
void MESH_OT_subdivide(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index 6d002efcc8e..889ed2dae81 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -51,28 +51,28 @@ ConsoleLine *console_history_verify(const struct bContext *C);
int console_report_mask(SpaceConsole *sc);
-void CONSOLE_OT_move(wmOperatorType *ot);
-void CONSOLE_OT_delete(wmOperatorType *ot);
-void CONSOLE_OT_insert(wmOperatorType *ot);
+void CONSOLE_OT_move(struct wmOperatorType *ot);
+void CONSOLE_OT_delete(struct wmOperatorType *ot);
+void CONSOLE_OT_insert(struct wmOperatorType *ot);
-void CONSOLE_OT_history_append(wmOperatorType *ot);
-void CONSOLE_OT_scrollback_append(wmOperatorType *ot);
+void CONSOLE_OT_history_append(struct wmOperatorType *ot);
+void CONSOLE_OT_scrollback_append(struct wmOperatorType *ot);
-void CONSOLE_OT_clear(wmOperatorType *ot);
-void CONSOLE_OT_history_cycle(wmOperatorType *ot);
-void CONSOLE_OT_copy(wmOperatorType *ot);
-void CONSOLE_OT_paste(wmOperatorType *ot);
-void CONSOLE_OT_zoom(wmOperatorType *ot);
+void CONSOLE_OT_clear(struct wmOperatorType *ot);
+void CONSOLE_OT_history_cycle(struct wmOperatorType *ot);
+void CONSOLE_OT_copy(struct wmOperatorType *ot);
+void CONSOLE_OT_paste(struct wmOperatorType *ot);
+void CONSOLE_OT_zoom(struct wmOperatorType *ot);
/* console_report.c */
-void CONSOLE_OT_select_pick(wmOperatorType *ot); /* report selection */
-void CONSOLE_OT_select_all_toggle(wmOperatorType *ot);
-void CONSOLE_OT_select_border(wmOperatorType *ot);
+void CONSOLE_OT_select_pick(struct wmOperatorType *ot); /* report selection */
+void CONSOLE_OT_select_all_toggle(struct wmOperatorType *ot);
+void CONSOLE_OT_select_border(struct wmOperatorType *ot);
-void CONSOLE_OT_report_replay(wmOperatorType *ot);
-void CONSOLE_OT_report_delete(wmOperatorType *ot);
-void CONSOLE_OT_report_copy(wmOperatorType *ot);
+void CONSOLE_OT_report_replay(struct wmOperatorType *ot);
+void CONSOLE_OT_report_delete(struct wmOperatorType *ot);
+void CONSOLE_OT_report_copy(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 0ee6115bbfe..a0e0ec30912 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1814,7 +1814,7 @@ void UV_OT_select_loop(wmOperatorType *ot)
/* ******************** linked select operator **************** */
-static select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, int pick)
+static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, int pick)
{
SpaceImage *sima= CTX_wm_space_image(C);
Scene *scene= CTX_data_scene(C);
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 2f640d3dfd4..66b50fbad04 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -180,64 +180,15 @@ typedef struct wmWindow {
#
typedef struct wmOperatorTypeMacro {
struct wmOperatorTypeMacro *next, *prev;
-
+
/* operator id */
char idname[MAX_ID_NAME];
/* rna pointer to access properties, like keymap */
struct IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */
- struct PointerRNA *ptr;
+ struct PointerRNA *ptr;
} wmOperatorTypeMacro;
-#
-#
-typedef struct wmOperatorType {
- struct wmOperatorType *next, *prev;
-
- char *name; /* text for ui, undo */
- char *idname; /* unique identifier */
- char *description; /* tooltips and python docs */
-
- /* this callback executes the operator without any interactive input,
- * parameters may be provided through operator properties. cannot use
- * any interface code or input device state.
- * - see defines below for return values */
- int (*exec)(struct bContext *, struct wmOperator *);
-
- /* for modal temporary operators, initially invoke is called. then
- * any further events are handled in modal. if the operation is
- * cancelled due to some external reason, cancel is called
- * - see defines below for return values */
- int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *);
- int (*cancel)(struct bContext *, struct wmOperator *);
- int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *);
-
- /* verify if the operator can be executed in the current context, note
- * that the operator might still fail to execute even if this return true */
- int (*poll)(struct bContext *);
-
- /* optional panel for redo and repeat, autogenerated if not set */
- void (*ui)(struct bContext *, struct wmOperator *, struct uiLayout *);
-
- /* rna for properties */
- struct StructRNA *srna;
-
- /* struct wmOperatorTypeMacro */
- ListBase macro;
-
- short flag;
-
- /* pointer to modal keymap, do not free! */
- struct wmKeyMap *modalkeymap;
-
- /* 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;
-
-
/* partial copy of the event, for matching by eventhandler */
typedef struct wmKeyMapItem {
struct wmKeyMapItem *next, *prev;
@@ -318,18 +269,18 @@ typedef struct wmOperator {
/* saved */
char idname[64]; /* used to retrieve type pointer */
IDProperty *properties; /* saved, user-settable properties */
-
+
/* runtime */
- wmOperatorType *type; /* operator type definition from idname */
+ struct wmOperatorType *type; /* operator type definition from idname */
void *customdata; /* custom storage, only while operator runs */
-
+
struct PointerRNA *ptr; /* rna pointer to access properties */
struct ReportList *reports; /* errors and warnings storage */
-
+
ListBase macro; /* list of operators, can be a tree */
struct wmOperator *opm; /* current running macro, not saved */
short flag, pad[3];
-
+
} wmOperator;
/* operator type exec(), invoke() modal(), return values */
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 3a708cc8563..fdad021291a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -584,6 +584,196 @@ static int rna_wmKeyMapItem_name_length(PointerRNA *ptr)
return 0;
}
+static void rna_Operator_unregister(const bContext *C, StructRNA *type)
+{
+ char *idname;
+ wmOperatorType *ot= RNA_struct_blender_type_get(type);
+
+ if(!ot)
+ return;
+
+ RNA_struct_free_extension(type, &ot->ext);
+
+ idname= ot->idname;
+ WM_operatortype_remove(ot->idname);
+ MEM_freeN(idname);
+
+ // RNA_struct_free(&BLENDER_RNA, type); // WM_operatortype_remove calls this
+
+ /* update while blender is running */
+ if(C)
+ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+}
+
+void operator_wrapper(wmOperatorType *ot, void *userdata)
+{
+ /* take care not to overwrite anything set in
+ * WM_operatortype_append_ptr before opfunc() is called */
+ StructRNA *srna = ot->srna;
+ *ot= *((wmOperatorType *)userdata);
+ ot->srna= srna; /* restore */
+
+ RNA_struct_blender_type_set(ot->ext.srna, ot);
+}
+
+#if 0
+static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event, NULL);
+}
+
+static int PYTHON_OT_execute(bContext *C, wmOperator *op)
+{
+ return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL, NULL);
+}
+
+static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
+{
+ return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL, NULL);
+}
+
+static void PYTHON_OT_draw(bContext *C, wmOperator *op, uiLayout *layout)
+{
+ PYTHON_OT_generic(PYOP_DRAW, C, op->type, op, NULL, layout);
+}
+#endif
+
+static int operator_poll(bContext *C, wmOperatorType *ot)
+{
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int visible;
+
+ RNA_pointer_create(NULL, ot->ext.srna, NULL, &ptr); /* dummy */
+ func= RNA_struct_find_function(&ptr, "poll");
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ ot->ext.call(&ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "visible", &ret);
+ visible= *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return visible;
+}
+
+static int operator_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA opr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int result;
+
+ RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr);
+ func= RNA_struct_find_function(&opr, "execute");
+
+ RNA_parameter_list_create(&list, &opr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ op->type->ext.call(&opr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "result", &ret);
+ result= *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return result;
+}
+
+static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ PointerRNA opr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int result;
+
+ RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr);
+ func= RNA_struct_find_function(&opr, "invoke");
+
+ RNA_parameter_list_create(&list, &opr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "event", &event);
+ op->type->ext.call(&opr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "result", &ret);
+ result= *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return result;
+}
+
+static char _operator_idname[OP_MAX_TYPENAME];
+static char _operator_descr[1024];
+static StructRNA *rna_Operator_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ wmOperatorType dummyot = {0};
+ wmOperator dummyop= {0};
+ PointerRNA dummyotr;
+ int have_function[3];
+
+ /* setup dummy operator & operator type to store static properties in */
+ dummyop.type= &dummyot;
+ dummyot.idname= _operator_idname; /* only assigne the pointer, string is NULL'd */
+ dummyot.description= _operator_descr; /* only assigne the pointer, string is NULL'd */
+ RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr);
+
+ /* validate the python class */
+ if(validate(&dummyotr, data, have_function) != 0)
+ return NULL;
+
+ { /* convert foo.bar to FOO_OT_bar
+ * allocate the description and the idname in 1 go */
+ int idlen = strlen(_operator_idname);
+ int desclen = strlen(_operator_descr);
+ dummyot.idname= MEM_callocN(sizeof(char) * (idlen + desclen + 2 + 3), "_operator_idname"); /* 2 terminators and 3 to convert a.b -> A_OT_b */
+ WM_operator_bl_idname(dummyot.idname, _operator_idname); /* convert the idname from python */
+ dummyot.description = dummyot.idname + (idlen + 4);
+ strcpy(dummyot.description, _operator_descr);
+ }
+
+ if(strlen(identifier) >= sizeof(dummyop.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s' is too long, maximum length is %d.", identifier, sizeof(dummyop.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this operator type before, and remove it */
+ {
+ wmOperatorType *ot= WM_operatortype_exists(dummyot.idname);
+ if(ot && ot->ext.srna)
+ rna_Operator_unregister(C, ot->ext.srna);
+ }
+
+ /* create a new menu type */
+ dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.data= data;
+ dummyot.ext.call= call;
+ dummyot.ext.free= free;
+
+ dummyot.pyop_poll= (have_function[0])? operator_poll: NULL;
+ dummyot.exec= (have_function[1])? operator_exec: NULL;
+ dummyot.invoke= (have_function[2])? operator_invoke: NULL;
+
+ WM_operatortype_append_ptr(operator_wrapper, (void *)&dummyot);
+
+ /* update while blender is running */
+ if(C)
+ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+
+ return dummyot.ext.srna;
+}
+
+static StructRNA* rna_Operator_refine(PointerRNA *opr)
+{
+ wmOperator *op= (wmOperator*)opr->data;
+ return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Operator;
+}
+
#else
static void rna_def_operator(BlenderRNA *brna)
@@ -594,6 +784,8 @@ static void rna_def_operator(BlenderRNA *brna)
srna= RNA_def_struct(brna, "Operator", NULL);
RNA_def_struct_ui_text(srna, "Operator", "Storage of an operator being executed, or registered after execution.");
RNA_def_struct_sdna(srna, "wmOperator");
+ RNA_def_struct_refine_func(srna, "rna_Operator_refine");
+ RNA_def_struct_register_funcs(srna, "rna_Operator_register", "rna_Operator_unregister");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -607,13 +799,31 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Properties", "");
RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL);
+ /* Registration */
+ prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->idname");
+ RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
+ prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->description");
+ RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */
+ RNA_def_property_flag(prop, PROP_REGISTER);
+
+ prop= RNA_def_property(srna, "bl_register", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_REGISTER);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop= RNA_def_property(srna, "bl_undo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_UNDO);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
RNA_api_operator(srna);
srna= RNA_def_struct(brna, "OperatorProperties", NULL);
RNA_def_struct_ui_text(srna, "Operator Properties", "Input properties of an Operator.");
RNA_def_struct_refine_func(srna, "rna_OperatorProperties_refine");
RNA_def_struct_idproperties_func(srna, "rna_OperatorProperties_idproperties");
-
}
static void rna_def_macro_operator(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 0cec66fe264..dcaff1a7c07 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -192,11 +192,43 @@ void RNA_api_operator(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
+ /* utility, not for registering */
func= RNA_def_function(srna, "report", "rna_Operator_report");
parm= RNA_def_enum(func, "type", wm_report_items, 0, "Type", "");
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_ENUM_FLAG);
parm= RNA_def_string(func, "message", "", 0, "Report Message", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
+
+
+ /* Registration */
+
+ /* poll */
+ func= RNA_def_function(srna, "poll", NULL);
+ RNA_def_function_ui_description(func, "Test if the operator can be called or not.");
+ RNA_def_function_flag(func, FUNC_REGISTER|FUNC_REGISTER_OPTIONAL);
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
+ RNA_def_pointer(func, "context", "Context", "", "");
+
+ /* exec */
+ func= RNA_def_function(srna, "execute", NULL);
+ RNA_def_function_ui_description(func, "Execute the operator.");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ RNA_def_pointer(func, "context", "Context", "", "");
+
+ parm= RNA_def_enum(func, "result", operator_return_items, 0, "result", ""); // better name?
+ RNA_def_property_flag(parm, PROP_ENUM_FLAG);
+ RNA_def_function_return(func, parm);
+
+ /* invoke */
+ func= RNA_def_function(srna, "invoke", NULL);
+ RNA_def_function_ui_description(func, "Invoke the operator.");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_pointer(func, "event", "Event", "", "");
+
+ parm= RNA_def_enum(func, "result", operator_return_items, 0, "result", ""); // better name?
+ RNA_def_property_flag(parm, PROP_ENUM_FLAG);
+ RNA_def_function_return(func, parm);
}
void RNA_api_keyconfig(StructRNA *srna)
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index b4a2fb36a97..7ccbe1c16a4 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -63,7 +63,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
ot= WM_operatortype_exists(opname);
if (ot == NULL) {
- PyErr_Format( PyExc_SystemError, "_bpy.ops.call: operator \"%s\"could not be found", opname);
+ PyErr_Format( PyExc_SystemError, "_bpy.ops.call: operator \"%s\" could not be found", opname);
return NULL;
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 65d2b687275..d0cc3e95097 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -3824,13 +3824,12 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
PyObject *item, *fitem;
PyObject *py_arg_count;
int i, flag, arg_count, func_arg_count;
- const char *identifier;
+ const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__
+
if (base_class) {
if (!PyObject_IsSubclass(py_class, base_class)) {
- PyObject *name= PyObject_GetAttrString(base_class, "__name__");
- PyErr_Format( PyExc_TypeError, "expected %.200s subclass of class \"%.200s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
- Py_XDECREF(name);
+ PyErr_Format( PyExc_TypeError, "expected %.200s subclass of class \"%.200s\"", class_type, py_class_name);
return -1;
}
}
@@ -3852,7 +3851,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if (item==NULL) {
if ((flag & FUNC_REGISTER_OPTIONAL)==0) {
- PyErr_Format( PyExc_AttributeError, "expected %.200s class to have an \"%.200s\" attribute", class_type, RNA_function_identifier(func));
+ PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class to have an \"%.200s\" attribute", class_type, py_class_name, RNA_function_identifier(func));
return -1;
}
@@ -3867,7 +3866,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
fitem= item; /* py 3.x */
if (PyFunction_Check(fitem)==0) {
- PyErr_Format( PyExc_TypeError, "expected %.200s class \"%.200s\" attribute to be a function", class_type, RNA_function_identifier(func));
+ PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function", class_type, py_class_name, RNA_function_identifier(func));
return -1;
}
@@ -3879,7 +3878,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
Py_DECREF(py_arg_count);
if (arg_count != func_arg_count) {
- PyErr_Format( PyExc_AttributeError, "expected %.200s class \"%.200s\" function to have %d args", class_type, RNA_function_identifier(func), func_arg_count);
+ PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class \"%.200s\" function to have %d args", class_type, py_class_name, RNA_function_identifier(func), func_arg_count);
return -1;
}
}
@@ -3889,6 +3888,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
/* verify properties */
lb= RNA_struct_defined_properties(srna);
for(link=lb->first; link; link=link->next) {
+ const char *identifier;
prop= (PropertyRNA*)link;
flag= RNA_property_flag(prop);
@@ -3914,7 +3914,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) {
- PyErr_Format( PyExc_AttributeError, "expected %.200s class to have an \"%.200s\" attribute", class_type, identifier);
+ PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class to have an \"%.200s\" attribute", class_type, py_class_name, identifier);
return -1;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 8fe7ac39b35..d2b67142eb5 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -38,6 +38,8 @@ struct wmEventHandler;
struct wmGesture;
struct wmJob;
struct wmNotifier;
+struct wmOperatorType;
+struct wmOperator;
struct rcti;
struct PointerRNA;
struct EnumPropertyItem;
@@ -185,16 +187,16 @@ int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, cha
void WM_operator_free (struct wmOperator *op);
void WM_operator_stack_clear(struct bContext *C);
-wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
-wmOperatorType *WM_operatortype_exists(const char *idname);
-wmOperatorType *WM_operatortype_first(void);
-void WM_operatortype_append (void (*opfunc)(wmOperatorType*));
-void WM_operatortype_append_ptr (void (*opfunc)(wmOperatorType*, void *), void *userdata);
-void WM_operatortype_append_macro_ptr (void (*opfunc)(wmOperatorType*, void *), void *userdata);
+struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
+struct wmOperatorType *WM_operatortype_exists(const char *idname);
+struct wmOperatorType *WM_operatortype_first(void);
+void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*));
+void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
+void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
-wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag);
-wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname);
+struct wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag);
+struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname);
int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
@@ -208,8 +210,8 @@ void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring
void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot);
void WM_operator_properties_free(struct PointerRNA *ptr);
void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type);
-void WM_operator_properties_gesture_border(wmOperatorType *ot, int extend);
-void WM_operator_properties_select_all(wmOperatorType *ot);
+void WM_operator_properties_gesture_border(struct wmOperatorType *ot, int extend);
+void WM_operator_properties_select_all(struct wmOperatorType *ot);
/* MOVE THIS SOMEWHERE ELSE */
#define SEL_TOGGLE 0
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 318945918e7..f0ccbed06c3 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -31,9 +31,13 @@
struct bContext;
struct wmEvent;
struct wmWindowManager;
+struct uiLayout;
+struct wmOperator;
-/* exported types for WM */
+#include "RNA_types.h"
+#include "DNA_listBase.h"
+/* exported types for WM */
#include "wm_cursors.h"
#include "wm_event_types.h"
@@ -353,6 +357,54 @@ typedef struct wmTimer {
} wmTimer;
+typedef struct wmOperatorType {
+ struct wmOperatorType *next, *prev;
+
+ char *name; /* text for ui, undo */
+ char *idname; /* unique identifier */
+ char *description; /* tooltips and python docs */
+
+ /* this callback executes the operator without any interactive input,
+ * parameters may be provided through operator properties. cannot use
+ * any interface code or input device state.
+ * - see defines below for return values */
+ int (*exec)(struct bContext *, struct wmOperator *);
+
+ /* for modal temporary operators, initially invoke is called. then
+ * any further events are handled in modal. if the operation is
+ * cancelled due to some external reason, cancel is called
+ * - see defines below for return values */
+ int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *);
+ int (*cancel)(struct bContext *, struct wmOperator *);
+ int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *);
+
+ /* verify if the operator can be executed in the current context, note
+ * that the operator might still fail to execute even if this return true */
+ int (*poll)(struct bContext *);
+
+ /* optional panel for redo and repeat, autogenerated if not set */
+ void (*ui)(struct bContext *, struct wmOperator *, struct uiLayout *);
+
+ /* rna for properties */
+ struct StructRNA *srna;
+
+ /* struct wmOperatorTypeMacro */
+ ListBase macro;
+
+ short flag;
+
+ /* pointer to modal keymap, do not free! */
+ struct wmKeyMap *modalkeymap;
+
+ /* 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);
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} wmOperatorType;
+
/* **************** Paint Cursor ******************* */
typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata);
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 84e246937e4..28b12a93b18 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -30,6 +30,7 @@
#define WM_WINDOW_H
struct bScreen;
+struct wmOperator;
/* *************** internal api ************** */
void wm_ghost_init (bContext *C);
@@ -62,8 +63,8 @@ wmWindow *wm_window_copy (bContext *C, wmWindow *winorig);
void wm_window_testbreak (void);
/* *************** window operators ************** */
-int wm_window_duplicate_op (bContext *C, wmOperator *op);
-int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op);
+int wm_window_duplicate_op (bContext *C, struct wmOperator *op);
+int wm_window_fullscreen_toggle_op(bContext *C, struct wmOperator *op);
#endif /* WM_WINDOW_H */