Blender V4.5
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) {
91 WM_LOG_OPERATORS, 0, "search for unknown operator '%s', '%s'\n", idname_bl, idname);
92 }
93 }
94 else {
95 if (!quiet) {
96 CLOG_INFO(WM_LOG_OPERATORS, 0, "search for empty operator");
97 }
98 }
99
100 return nullptr;
101}
102
103/* -------------------------------------------------------------------- */
106
108{
110
112
113 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
115 /* Set the default i18n context now, so that opfunc can redefine it if needed! */
117 ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
118 ot->cursor_pending = WM_CURSOR_PICK_AREA;
119
120 return ot;
121}
123{
124 if (ot->name == nullptr) {
125 CLOG_ERROR(WM_LOG_OPERATORS, "Operator '%s' has no name property", ot->idname);
126 }
127 BLI_assert((ot->description == nullptr) || (ot->description[0]));
128
129 /* Allow calling _begin without _end in operatortype creation. */
131
132 /* XXX All ops should have a description but for now allow them not to. */
134 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
135 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
136
138 get_operators_map().add_new(ot);
139
140 /* Needed so any operators registered after startup will have their shortcuts set,
141 * in "register" scripts for example, see: #143838.
142 *
143 * This only has run-time implications when run after startup,
144 * it's a no-op when run beforehand, see: #WM_keyconfig_update_on_startup. */
146}
147
148/* All ops in 1 list (for time being... needs evaluation later). */
149
156
157void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
158{
160 opfunc(ot, userdata);
162}
163
165
167{
168 BLI_assert(ot == WM_operatortype_find(ot->idname, false));
169
170#ifdef WITH_PYTHON
171 /* The 'unexposed' type (inherited from #RNA_OperatorProperties) created for this operator type's
172 * properties may have had a python type representation created. This needs to be dereferenced
173 * manually here, as other #bpy_class_free (which is part of the unregistering code for runtime
174 * operators) will not be able to handle it. */
176#endif
177
179
180 if (ot->last_properties) {
181 IDP_FreeProperty(ot->last_properties);
182 }
183
184 if (ot->macro.first) {
186 }
187
188 get_operators_map().remove(ot);
189
191
192 MEM_freeN(ot);
193}
194
195bool WM_operatortype_remove(const char *idname)
196{
197 wmOperatorType *ot = WM_operatortype_find(idname, false);
198
199 if (ot == nullptr) {
200 return false;
201 }
202
204
205 return true;
206}
207
209{
210 if (ot->last_properties) {
211 IDP_FreeProperty(ot->last_properties);
212 }
213
214 if (ot->macro.first) {
216 }
217
218 if (ot->rna_ext.srna) {
219 /* A Python operator, allocates its own string. */
220 MEM_freeN(ot->idname);
221 }
222
223 MEM_freeN(ot);
224}
225
227{
230 }
231 get_operators_map().clear();
232}
233
235{
236 if (ot_prop_basic_count == -1) {
237 /* Don't do anything if _begin was called before, but not _end. */
239 }
240}
241
243{
244 PointerRNA struct_ptr;
245 int counter = 0;
246
247 if (ot_prop_basic_count == -1) {
248 /* WM_operatortype_props_advanced_begin was not called. Don't do anything. */
249 return;
250 }
251
253
254 RNA_STRUCT_BEGIN (&struct_ptr, prop) {
255 counter++;
256 if (counter > ot_prop_basic_count) {
258 }
259 }
261
263}
264
266{
268 if (ot->last_properties) {
269 IDP_FreeProperty(ot->last_properties);
270 ot->last_properties = nullptr;
271 }
272 }
273}
274
276 const bContext * /*C*/,
277 PointerRNA * /*ptr*/,
278 PropertyRNA * /*prop*/,
279 const char * /*edit_text*/,
281{
283 char idname_py[OP_MAX_TYPENAME];
284 WM_operator_py_idname(idname_py, ot->idname);
285
286 StringPropertySearchVisitParams visit_params{};
287 visit_params.text = idname_py;
288 visit_params.info = ot->name;
289 visit_fn(visit_params);
290 }
291}
292
294
295/* -------------------------------------------------------------------- */
298
302
304{
305 if (op->customdata == nullptr) {
306 op->customdata = MEM_callocN<MacroData>("MacroData");
307 }
308}
309
311{
312 MacroData *md = static_cast<MacroData *>(op->customdata);
313
314 if (retval & OPERATOR_CANCELLED) {
315 if (md && (md->retval & OPERATOR_FINISHED)) {
316 retval |= OPERATOR_FINISHED;
317 retval &= ~OPERATOR_CANCELLED;
318 }
319 }
320
321 /* If modal is ending, free custom data. */
322 if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
323 if (md) {
324 MEM_freeN(md);
325 op->customdata = nullptr;
326 }
327 }
328
329 return retval;
330}
331
332/* Macro exec only runs exec calls. */
334{
336 const int op_inherited_flag = op->flag & (OP_IS_REPEAT | OP_IS_REPEAT_LAST);
337
338 wm_macro_start(op);
339
340 LISTBASE_FOREACH (wmOperator *, opm, &op->macro) {
341 if (opm->type->exec == nullptr) {
342 CLOG_WARN(WM_LOG_OPERATORS, "'%s' can't exec macro", opm->type->idname);
343 continue;
344 }
345
346 opm->flag |= op_inherited_flag;
347 retval = opm->type->exec(C, opm);
348 opm->flag &= ~op_inherited_flag;
349
350 OPERATOR_RETVAL_CHECK(retval);
351
352 if (retval & OPERATOR_FINISHED) {
353 MacroData *md = static_cast<MacroData *>(op->customdata);
354 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
355 }
356 else {
357 break; /* Operator didn't finish, end macro. */
358 }
359 }
360
361 return wm_macro_end(op, retval);
362}
363
365 wmOperator *op,
366 const wmEvent *event,
367 wmOperator *opm)
368{
370 const int op_inherited_flag = op->flag & (OP_IS_REPEAT | OP_IS_REPEAT_LAST);
371
372 /* Start from operator received as argument. */
373 for (; opm; opm = opm->next) {
374
375 opm->flag |= op_inherited_flag;
376 if (opm->type->invoke) {
377 retval = opm->type->invoke(C, opm, event);
378 }
379 else if (opm->type->exec) {
380 retval = opm->type->exec(C, opm);
381 }
382 opm->flag &= ~op_inherited_flag;
383
384 OPERATOR_RETVAL_CHECK(retval);
385
387
388 if (retval & OPERATOR_FINISHED) {
389 MacroData *md = static_cast<MacroData *>(op->customdata);
390 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
391 }
392 else {
393 break; /* Operator didn't finish, end macro. */
394 }
395 }
396
397 return wm_macro_end(op, retval);
398}
399
401{
402 wm_macro_start(op);
403 return wm_macro_invoke_internal(C, op, event, static_cast<wmOperator *>(op->macro.first));
404}
405
407{
408 wmOperator *opm = op->opm;
410
411 if (opm == nullptr) {
412 CLOG_ERROR(WM_LOG_OPERATORS, "macro error, calling nullptr modal()");
413 }
414 else {
415 retval = opm->type->modal(C, opm, event);
416 OPERATOR_RETVAL_CHECK(retval);
417
418 /* If we're halfway through using a tool and cancel it, clear the options, see: #37149. */
419 if (retval & OPERATOR_CANCELLED) {
421 }
422
423 /* If this one is done but it's not the last operator in the macro. */
424 if ((retval & OPERATOR_FINISHED) && opm->next) {
425 MacroData *md = static_cast<MacroData *>(op->customdata);
426
427 md->retval = OPERATOR_FINISHED; /* Keep in mind that at least one operator finished. */
428
429 retval = wm_macro_invoke_internal(C, op, event, opm->next);
430
431 /* If new operator is modal and also added its own handler. */
432 if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
433 wmWindow *win = CTX_wm_window(C);
434 wmEventHandler_Op *handler;
435
436 handler = static_cast<wmEventHandler_Op *>(
438 if (handler) {
439 BLI_remlink(&win->modalhandlers, handler);
440 wm_event_free_handler(&handler->head);
441 }
442
443 /* If operator is blocking, grab cursor.
444 * This may end up grabbing twice, but we don't care. */
445 if (op->opm->type->flag & OPTYPE_BLOCKING) {
447 const rcti *wrap_region = nullptr;
448
449 if ((op->opm->flag & OP_IS_MODAL_GRAB_CURSOR) ||
451 {
453 }
454 else if (op->opm->type->flag & OPTYPE_GRAB_CURSOR_X) {
456 }
457 else if (op->opm->type->flag & OPTYPE_GRAB_CURSOR_Y) {
459 }
460
461 if (wrap) {
462 ARegion *region = CTX_wm_region(C);
463 if (region) {
464 wrap_region = &region->winrct;
465 }
466 }
467
468 WM_cursor_grab_enable(win, eWM_CursorWrapAxis(wrap), wrap_region, false);
469 }
470 }
471 }
472 }
473
474 return wm_macro_end(op, retval);
475}
476
478{
479 /* Call cancel on the current modal operator, if any. */
480 if (op->opm && op->opm->type->cancel) {
481 op->opm->type->cancel(C, op->opm);
482 }
483
485}
486
488 const char *name,
489 const char *description,
490 int flag)
491{
493 const char *i18n_context;
494
495 if (WM_operatortype_find(idname, true)) {
496 CLOG_ERROR(WM_LOG_OPERATORS, "operator %s exists, cannot create macro", idname);
497 return nullptr;
498 }
499
500 ot = MEM_callocN<wmOperatorType>("operatortype");
501 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
502
503 ot->idname = idname;
504 ot->name = name;
505 ot->description = description;
506 ot->flag = OPTYPE_MACRO | flag;
507
508 ot->exec = wm_macro_exec;
509 ot->invoke = wm_macro_invoke;
510 ot->modal = wm_macro_modal;
511 ot->cancel = wm_macro_cancel;
512 ot->poll = nullptr;
513
514 /* XXX All ops should have a description but for now allow them not to. */
515 BLI_assert((ot->description == nullptr) || (ot->description[0]));
516
518 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
519 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
520 /* Use i18n context from rna_ext.srna if possible (py operators). */
521 i18n_context = ot->rna_ext.srna ? RNA_struct_translation_context(ot->rna_ext.srna) :
523 RNA_def_struct_translation_context(ot->srna, i18n_context);
524 ot->translation_context = i18n_context;
525
527 get_operators_map().add_new(ot);
528
529 return ot;
530}
531
532void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *ot, void *userdata),
533 void *userdata)
534{
536
537 ot = MEM_callocN<wmOperatorType>("operatortype");
538 ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
539
540 ot->flag = OPTYPE_MACRO;
541 ot->exec = wm_macro_exec;
542 ot->invoke = wm_macro_invoke;
543 ot->modal = wm_macro_modal;
544 ot->cancel = wm_macro_cancel;
545 ot->poll = nullptr;
546
547 /* XXX All ops should have a description but for now allow them not to. */
548 BLI_assert((ot->description == nullptr) || (ot->description[0]));
549
550 /* Set the default i18n context now, so that opfunc can redefine it if needed! */
552 ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
553 opfunc(ot, userdata);
554
556 ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
557 RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
558
560 get_operators_map().add_new(ot);
561}
562
564{
565 wmOperatorTypeMacro *otmacro = MEM_callocN<wmOperatorTypeMacro>("wmOperatorTypeMacro");
566
567 STRNCPY(otmacro->idname, idname);
568
569 /* Do this on first use, since operator definitions might have been not done yet. */
570 WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname);
571 WM_operator_properties_sanitize(otmacro->ptr, true);
572
573 BLI_addtail(&ot->macro, otmacro);
574
575 /* Operator should always be found but in the event its not. don't segfault. */
576 if (wmOperatorType *otsub = WM_operatortype_find(idname, false)) {
577 RNA_def_pointer_runtime(ot->srna, otsub->idname, otsub->srna, otsub->name, otsub->description);
578 }
579
580 return otmacro;
581}
582
584{
585 LISTBASE_FOREACH (wmOperatorTypeMacro *, otmacro, &ot->macro) {
586 if (otmacro->ptr) {
587 WM_operator_properties_free(otmacro->ptr);
588 MEM_delete(otmacro->ptr);
589 }
590 }
591 BLI_freelistN(&ot->macro);
592}
593
595{
596 std::string name;
597 if (ot->get_name && properties) {
598 name = ot->get_name(ot, properties);
599 }
600
601 return name.empty() ? std::string(RNA_struct_ui_name(ot->srna)) : name;
602}
603
605{
606 if (ot->get_description && properties) {
607 std::string description = ot->get_description(C, ot, properties);
608 if (!description.empty()) {
609 return description;
610 }
611 }
612
613 const char *info = RNA_struct_ui_description(ot->srna);
614 if (info && info[0]) {
615 return info;
616 }
617 return "";
618}
619
622 PointerRNA *properties)
623{
624 std::string text = WM_operatortype_description(C, ot, properties);
625 if (text.empty()) {
626 std::string text_orig = WM_operatortype_name(ot, properties);
627 if (!text_orig.empty()) {
628 return text_orig;
629 }
630 }
631 return text;
632}
633
635{
636 if (ot.flag & OPTYPE_DEPENDS_ON_CURSOR) {
637 return true;
638 }
639 if (ot.depends_on_cursor) {
640 return ot.depends_on_cursor(C, ot, properties);
641 }
642 return false;
643}
644
wmWindow * CTX_wm_window(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1243
#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:688
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void BPY_free_srna_pytype(StructRNA *srna)
Definition bpy_rna.cc:9940
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
#define CLOG_INFO(clg_ref, level,...)
Definition CLG_log.h:179
@ OPERATOR_CANCELLED
@ 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:1336
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:263
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:71
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
std::optional< std::string > info
Definition RNA_types.hh:682
wmEventHandler head
struct IDProperty * properties
wmOperatorStatus(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1046
const char * idname
Definition WM_types.hh:1032
wmOperatorStatus(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1062
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1078
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1070
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:4225
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:139