Blender V5.0
wm_operator_type.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "MEM_guardedalloc.h"
12
13#include "CLG_log.h"
14
15#include "DNA_screen_types.h"
17
18#include "BLT_translation.hh"
19
20#include "BLI_listbase.h"
21#include "BLI_string.h"
22#include "BLI_vector_set.hh"
23
24#include "BKE_context.hh"
25#include "BKE_idprop.hh"
26
27#include "RNA_access.hh"
28#include "RNA_define.hh"
29#include "RNA_enum_types.hh"
30#include "RNA_prototypes.hh"
31
32#ifdef WITH_PYTHON
33# include "BPY_extern.hh"
34#endif
35
36#include "WM_api.hh"
37#include "WM_keymap.hh"
38#include "WM_types.hh"
39
40#include "wm.hh"
41#include "wm_event_system.hh"
42
43#define UNDOCUMENTED_OPERATOR_TIP N_("(undocumented operator)")
44
46
47/* -------------------------------------------------------------------- */
50
52
53static auto &get_operators_map()
54{
55 struct OperatorNameGetter {
56 StringRef operator()(const wmOperatorType *value) const
57 {
58 return StringRef(value->idname);
59 }
60 };
61 static auto map = []() {
63 /* Reserve size is set based on blender default setup. */
64 map.reserve(2048);
65 return map;
66 }();
67 return map;
68}
69
74
76static int ot_prop_basic_count = -1;
77
78wmOperatorType *WM_operatortype_find(const char *idname, bool quiet)
79{
80 if (idname[0]) {
81 /* Needed to support python style names without the `_OT_` syntax. */
82 char idname_bl[OP_MAX_TYPENAME];
83 WM_operator_bl_idname(idname_bl, idname);
84
85 if (wmOperatorType *const *ot = get_operators_map().lookup_key_ptr_as(StringRef(idname_bl))) {
86 return *ot;
87 }
88
89 if (!quiet) {
90 CLOG_INFO(WM_LOG_OPERATORS, "Search for unknown operator '%s', '%s'", idname_bl, idname);
91 }
92 }
93 else {
94 if (!quiet) {
95 CLOG_INFO(WM_LOG_OPERATORS, "Search for empty operator");
96 }
97 }
98
99 return nullptr;
100}
101
102/* -------------------------------------------------------------------- */
105
107{
109
111
112 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
114 /* Set the default i18n context now, so that opfunc can redefine it if needed! */
116 ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
117 ot->cursor_pending = WM_CURSOR_PICK_AREA;
118
119 return ot;
120}
122{
123 if (ot->name == nullptr) {
124 CLOG_ERROR(WM_LOG_OPERATORS, "Operator '%s' has no name property", ot->idname);
125 }
126 BLI_assert((ot->description == nullptr) || (ot->description[0]));
127
128 /* Allow calling _begin without _end in operatortype creation. */
130
131 /* XXX All ops should have a description but for now allow them not to. */
133 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
134 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
135
137 get_operators_map().add_new(ot);
138
139 /* Needed so any operators registered after startup will have their shortcuts set,
140 * in "register" scripts for example, see: #143838.
141 *
142 * This only has run-time implications when run after startup,
143 * it's a no-op when run beforehand, see: #WM_keyconfig_update_on_startup. */
145}
146
147/* All ops in 1 list (for time being... needs evaluation later). */
148
155
156void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
157{
159 opfunc(ot, userdata);
161}
162
164
166{
167 BLI_assert(ot == WM_operatortype_find(ot->idname, false));
168
169#ifdef WITH_PYTHON
170 /* The 'unexposed' type (inherited from #RNA_OperatorProperties) created for this operator type's
171 * properties may have had a python type representation created. This needs to be dereferenced
172 * manually here, as other #bpy_class_free (which is part of the unregistering code for runtime
173 * operators) will not be able to handle it. */
175#endif
176
178
179 if (ot->last_properties) {
180 IDP_FreeProperty(ot->last_properties);
181 }
182
183 if (ot->macro.first) {
185 }
186
187 get_operators_map().remove(ot);
188
190
191 MEM_freeN(ot);
192}
193
194bool WM_operatortype_remove(const char *idname)
195{
196 wmOperatorType *ot = WM_operatortype_find(idname, false);
197
198 if (ot == nullptr) {
199 return false;
200 }
201
203
204 return true;
205}
206
208{
209 if (ot->last_properties) {
210 IDP_FreeProperty(ot->last_properties);
211 }
212
213 if (ot->macro.first) {
215 }
216
217 if (ot->rna_ext.srna) {
218 /* A Python operator, allocates its own string. */
219 MEM_freeN(ot->idname);
220 }
221
222 MEM_freeN(ot);
223}
224
226{
229 }
230 get_operators_map().clear();
231}
232
234{
235 if (ot_prop_basic_count == -1) {
236 /* Don't do anything if _begin was called before, but not _end. */
238 }
239}
240
242{
243 PointerRNA struct_ptr;
244 int counter = 0;
245
246 if (ot_prop_basic_count == -1) {
247 /* WM_operatortype_props_advanced_begin was not called. Don't do anything. */
248 return;
249 }
250
252
253 RNA_STRUCT_BEGIN (&struct_ptr, prop) {
254 counter++;
255 if (counter > ot_prop_basic_count) {
257 }
258 }
260
262}
263
265{
267 if (ot->last_properties) {
268 IDP_FreeProperty(ot->last_properties);
269 ot->last_properties = nullptr;
270 }
271 }
272}
273
275 const bContext * /*C*/,
276 PointerRNA * /*ptr*/,
277 PropertyRNA * /*prop*/,
278 const char * /*edit_text*/,
280{
282 char idname_py[OP_MAX_TYPENAME];
283 WM_operator_py_idname(idname_py, ot->idname);
284
285 StringPropertySearchVisitParams visit_params{};
286 visit_params.text = idname_py;
287 visit_params.info = ot->name;
288 visit_fn(visit_params);
289 }
290}
291
293
294/* -------------------------------------------------------------------- */
297
301
303{
304 if (op->customdata == nullptr) {
305 op->customdata = MEM_callocN<MacroData>("MacroData");
306 }
307}
308
310{
311 MacroData *md = static_cast<MacroData *>(op->customdata);
312
313 if (retval & (OPERATOR_CANCELLED | OPERATOR_INTERFACE)) {
314 if (md && (md->retval & OPERATOR_FINISHED)) {
315 retval |= OPERATOR_FINISHED;
317 }
318 }
319
320 /* If modal is ending, free custom data. */
321 if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
322 if (md) {
323 MEM_freeN(md);
324 op->customdata = nullptr;
325 }
326 }
327
328 return retval;
329}
330
331/* Macro exec only runs exec calls. */
333{
335 const int op_inherited_flag = op->flag & (OP_IS_REPEAT | OP_IS_REPEAT_LAST);
336
337 wm_macro_start(op);
338
339 LISTBASE_FOREACH (wmOperator *, opm, &op->macro) {
340 if (opm->type->exec == nullptr) {
341 CLOG_WARN(WM_LOG_OPERATORS, "'%s' can't exec macro", opm->type->idname);
342 continue;
343 }
344
345 opm->flag |= op_inherited_flag;
346 retval = opm->type->exec(C, opm);
347 opm->flag &= ~op_inherited_flag;
348
349 OPERATOR_RETVAL_CHECK(retval);
350
351 if (retval & OPERATOR_FINISHED) {
352 MacroData *md = static_cast<MacroData *>(op->customdata);
353 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
354 }
355 else {
356 break; /* Operator didn't finish, end macro. */
357 }
358 }
359
360 return wm_macro_end(op, retval);
361}
362
364 wmOperator *op,
365 const wmEvent *event,
366 wmOperator *opm)
367{
369 const int op_inherited_flag = op->flag & (OP_IS_REPEAT | OP_IS_REPEAT_LAST);
370
371 /* Start from operator received as argument. */
372 for (; opm; opm = opm->next) {
373
374 opm->flag |= op_inherited_flag;
375 if (opm->type->invoke) {
376 retval = opm->type->invoke(C, opm, event);
377 }
378 else if (opm->type->exec) {
379 retval = opm->type->exec(C, opm);
380 }
381 opm->flag &= ~op_inherited_flag;
382
383 OPERATOR_RETVAL_CHECK(retval);
384
386
387 if (retval & OPERATOR_FINISHED) {
388 MacroData *md = static_cast<MacroData *>(op->customdata);
389 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
390 }
391 else {
392 break; /* Operator didn't finish, end macro. */
393 }
394 }
395
396 return wm_macro_end(op, retval);
397}
398
400{
401 wm_macro_start(op);
402 return wm_macro_invoke_internal(C, op, event, static_cast<wmOperator *>(op->macro.first));
403}
404
406{
407 wmOperator *opm = op->opm;
409
410 if (opm == nullptr) {
411 CLOG_ERROR(WM_LOG_OPERATORS, "macro error, calling nullptr modal()");
412 }
413 else {
414 retval = opm->type->modal(C, opm, event);
415 OPERATOR_RETVAL_CHECK(retval);
416
417 /* If we're halfway through using a tool and cancel it, clear the options, see: #37149. */
418 if (retval & OPERATOR_CANCELLED) {
420 }
421
422 /* If this one is done but it's not the last operator in the macro. */
423 if ((retval & OPERATOR_FINISHED) && opm->next) {
424 MacroData *md = static_cast<MacroData *>(op->customdata);
425
426 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
427
428 retval = wm_macro_invoke_internal(C, op, event, opm->next);
429
430 /* If new operator is modal and also added its own handler. */
431 if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
432 wmWindow *win = CTX_wm_window(C);
433 wmEventHandler_Op *handler;
434
435 handler = static_cast<wmEventHandler_Op *>(
437 if (handler) {
438 BLI_remlink(&win->modalhandlers, handler);
439 wm_event_free_handler(&handler->head);
440 }
441
442 /* If operator is blocking, grab cursor.
443 * This may end up grabbing twice, but we don't care. */
444 if (op->opm->type->flag & OPTYPE_BLOCKING) {
446 const rcti *wrap_region = nullptr;
447
448 if ((op->opm->flag & OP_IS_MODAL_GRAB_CURSOR) ||
450 {
452 }
453 else if (op->opm->type->flag & OPTYPE_GRAB_CURSOR_X) {
455 }
456 else if (op->opm->type->flag & OPTYPE_GRAB_CURSOR_Y) {
458 }
459
460 if (wrap) {
461 ARegion *region = CTX_wm_region(C);
462 if (region) {
463 wrap_region = &region->winrct;
464 }
465 }
466
467 WM_cursor_grab_enable(win, eWM_CursorWrapAxis(wrap), wrap_region, false);
468 }
469 }
470 }
471 }
472
473 return wm_macro_end(op, retval);
474}
475
477{
478 /* Call cancel on the current modal operator, if any. */
479 if (op->opm && op->opm->type->cancel) {
480 op->opm->type->cancel(C, op->opm);
481 }
482
484}
485
487 const char *name,
488 const char *description,
489 int flag)
490{
492 const char *i18n_context;
493
494 if (WM_operatortype_find(idname, true)) {
495 CLOG_ERROR(WM_LOG_OPERATORS, "operator %s exists, cannot create macro", idname);
496 return nullptr;
497 }
498
499 ot = MEM_callocN<wmOperatorType>("operatortype");
500 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
501
502 ot->idname = idname;
503 ot->name = name;
504 ot->description = description;
505 ot->flag = OPTYPE_MACRO | flag;
506
507 ot->exec = wm_macro_exec;
508 ot->invoke = wm_macro_invoke;
509 ot->modal = wm_macro_modal;
510 ot->cancel = wm_macro_cancel;
511 ot->poll = nullptr;
512
513 /* XXX All ops should have a description but for now allow them not to. */
514 BLI_assert((ot->description == nullptr) || (ot->description[0]));
515
517 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
518 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
519 /* Use i18n context from rna_ext.srna if possible (py operators). */
520 i18n_context = ot->rna_ext.srna ? RNA_struct_translation_context(ot->rna_ext.srna) :
522 RNA_def_struct_translation_context(ot->srna, i18n_context);
523 ot->translation_context = i18n_context;
524
526 get_operators_map().add_new(ot);
527
528 return ot;
529}
530
531void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *ot, void *userdata),
532 void *userdata)
533{
535
536 ot = MEM_callocN<wmOperatorType>("operatortype");
537 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
538
539 ot->flag = OPTYPE_MACRO;
540 ot->exec = wm_macro_exec;
541 ot->invoke = wm_macro_invoke;
542 ot->modal = wm_macro_modal;
543 ot->cancel = wm_macro_cancel;
544 ot->poll = nullptr;
545
546 /* XXX All ops should have a description but for now allow them not to. */
547 BLI_assert((ot->description == nullptr) || (ot->description[0]));
548
549 /* Set the default i18n context now, so that opfunc can redefine it if needed! */
551 ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
552 opfunc(ot, userdata);
553
555 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
556 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
557
559 get_operators_map().add_new(ot);
560}
561
563{
564 wmOperatorTypeMacro *otmacro = MEM_callocN<wmOperatorTypeMacro>("wmOperatorTypeMacro");
565
566 STRNCPY(otmacro->idname, idname);
567
568 /* Do this on first use, since operator definitions might have been not done yet. */
569 WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname);
570 WM_operator_properties_sanitize(otmacro->ptr, true);
571
572 BLI_addtail(&ot->macro, otmacro);
573
574 /* Operator should always be found but in the event its not. don't segfault. */
575 if (wmOperatorType *otsub = WM_operatortype_find(idname, false)) {
576 RNA_def_pointer_runtime(ot->srna, otsub->idname, otsub->srna, otsub->name, otsub->description);
577 }
578
579 return otmacro;
580}
581
583{
584 LISTBASE_FOREACH (wmOperatorTypeMacro *, otmacro, &ot->macro) {
585 if (otmacro->ptr) {
586 WM_operator_properties_free(otmacro->ptr);
587 MEM_delete(otmacro->ptr);
588 }
589 }
590 BLI_freelistN(&ot->macro);
591}
592
594{
595 std::string name;
596 if (ot->get_name && properties) {
597 name = ot->get_name(ot, properties);
598 }
599
600 return name.empty() ? std::string(RNA_struct_ui_name(ot->srna)) : name;
601}
602
604{
605 if (ot->get_description && properties) {
606 std::string description = ot->get_description(C, ot, properties);
607 if (!description.empty()) {
608 return description;
609 }
610 }
611
612 const char *info = RNA_struct_ui_description(ot->srna);
613 if (info && info[0]) {
614 return info;
615 }
616 return "";
617}
618
621 PointerRNA *properties)
622{
623 std::string text = WM_operatortype_description(C, ot, properties);
624 if (text.empty()) {
625 std::string text_orig = WM_operatortype_name(ot, properties);
626 if (!text_orig.empty()) {
627 return text_orig;
628 }
629 }
630 return text;
631}
632
634{
635 if (ot.flag & OPTYPE_DEPENDS_ON_CURSOR) {
636 return true;
637 }
638 if (ot.depends_on_cursor) {
639 return ot.depends_on_cursor(C, ot, properties);
640 }
641 return false;
642}
643
wmWindow * CTX_wm_window(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1251
#define BLI_assert(a)
Definition BLI_assert.h:46
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void BPY_free_srna_pytype(StructRNA *srna)
Definition bpy_rna.cc:10084
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:188
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:189
#define CLOG_INFO(clg_ref,...)
Definition CLG_log.h:190
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OP_IS_REPEAT_LAST
@ OP_IS_MODAL_GRAB_CURSOR
#define OPERATOR_RETVAL_CHECK(ret)
#define OP_MAX_TYPENAME
Read Guarded memory(de)allocation.
#define RNA_STRUCT_BEGIN(sptr, prop)
#define RNA_STRUCT_END
#define C
Definition RandGen.cpp:29
#define WM_operatortype_prop_tag(property, tags)
Definition WM_api.hh:1385
CLG_LogRef * WM_LOG_OPERATORS
@ OPTYPE_MACRO
Definition WM_types.hh:185
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_DEPENDS_ON_CURSOR
Definition WM_types.hh:218
@ OPTYPE_GRAB_CURSOR_XY
Definition WM_types.hh:188
@ OPTYPE_GRAB_CURSOR_X
Definition WM_types.hh:190
@ OPTYPE_GRAB_CURSOR_Y
Definition WM_types.hh:192
#define OP_PROP_TAG_ADVANCED
Definition WM_types.hh:266
eWM_CursorWrapAxis
Definition WM_types.hh:225
@ WM_CURSOR_WRAP_X
Definition WM_types.hh:227
@ WM_CURSOR_WRAP_XY
Definition WM_types.hh:229
@ WM_CURSOR_WRAP_Y
Definition WM_types.hh:228
@ WM_CURSOR_WRAP_NONE
Definition WM_types.hh:226
SIMD_FORCE_INLINE btVector3 operator()(const btVector3 &x) const
Return the transform of the vector.
Definition btTransform.h:90
void reserve(const int64_t n)
#define offsetof(t, d)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
VectorSet< T, InlineBufferCapacity, DefaultProbingStrategy, CustomIDHash< T, GetIDFn >, CustomIDEqual< T, GetIDFn > > CustomIDVectorSet
float wrap(float value, float max, float min)
Definition node_math.h:103
const char * name
const char * RNA_struct_ui_description(const StructRNA *type)
const char * RNA_struct_ui_name(const StructRNA *type)
uint RNA_struct_count_properties(StructRNA *srna)
const char * RNA_struct_translation_context(const StructRNA *type)
PropertyRNA * RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
StructRNA * RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
BlenderRNA BLENDER_RNA
const EnumPropertyItem rna_enum_operator_property_tag_items[]
Definition rna_wm.cc:606
void * first
wmOperatorStatus retval
ListBase list
Definition BKE_report.hh:75
std::optional< std::string > info
Definition RNA_types.hh:773
wmEventHandler head
struct IDProperty * properties
wmOperatorStatus(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1049
const char * idname
Definition WM_types.hh:1035
wmOperatorStatus(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1065
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1081
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1073
struct ReportList * reports
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
struct wmOperator * opm
void WM_cursor_grab_enable(wmWindow *win, const eWM_CursorWrapAxis wrap, const rcti *wrap_region, const bool hide)
@ WM_CURSOR_PICK_AREA
Definition wm_cursors.hh:62
void wm_event_free_handler(wmEventHandler *handler)
wmOperatorType * ot
Definition wm_files.cc:4237
void WM_keyconfig_update_operatortype_tag()
void WM_operatortype_append_macro_ptr(void(*opfunc)(wmOperatorType *ot, void *userdata), void *userdata)
void WM_operatortype_idname_visit_for_search(const bContext *, PointerRNA *, PropertyRNA *, const char *, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static wmOperatorType * wm_operatortype_append__begin()
static void wm_operatortype_free_macro(wmOperatorType *ot)
static int ot_prop_basic_count
static auto & get_operators_map()
void WM_operatortype_props_advanced_begin(wmOperatorType *ot)
blender::Span< wmOperatorType * > WM_operatortypes_registered_get()
static void wm_macro_start(wmOperator *op)
wmOperatorTypeMacro * WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
static wmOperatorStatus wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus wm_macro_end(wmOperator *op, wmOperatorStatus retval)
void wm_operatortype_free()
std::string WM_operatortype_name(wmOperatorType *ot, PointerRNA *properties)
static wmOperatorStatus wm_macro_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool WM_operator_depends_on_cursor(bContext &C, wmOperatorType &ot, PointerRNA *properties)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
static wmOperatorStatus wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *event, wmOperator *opm)
std::string WM_operatortype_description_or_name(bContext *C, wmOperatorType *ot, PointerRNA *properties)
std::string WM_operatortype_description(bContext *C, wmOperatorType *ot, PointerRNA *properties)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operatortype_last_properties_clear_all()
void WM_operatortype_append_ptr(void(*opfunc)(wmOperatorType *, void *), void *userdata)
static void wm_operatortype_append__end(wmOperatorType *ot)
#define UNDOCUMENTED_OPERATOR_TIP
static wmOperatorStatus wm_macro_exec(bContext *C, wmOperator *op)
wmOperatorType * WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)
static void operatortype_ghash_free_cb(wmOperatorType *ot)
void WM_operatortype_remove_ptr(wmOperatorType *ot)
void WM_operatortype_props_advanced_end(wmOperatorType *ot)
bool WM_operatortype_remove(const char *idname)
static void wm_macro_cancel(bContext *C, wmOperator *op)
size_t WM_operator_py_idname(char *dst, const char *src)
size_t WM_operator_bl_idname(char *dst, const char *src)
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
bool WM_operator_bl_idname_is_valid(const char *idname)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_clear(PointerRNA *ptr)
void WM_operator_properties_free(PointerRNA *ptr)
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
uint8_t flag
Definition wm_window.cc:145