Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_operator_type.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/windowmanager/intern/wm_operator_type.c
22  *  \ingroup wm
23  *
24  * Operator Registry.
25  */
26
27 #include "MEM_guardedalloc.h"
28
29 #include "CLG_log.h"
30
31 #include "DNA_ID.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_userdef_types.h"
35 #include "DNA_windowmanager_types.h"
36
37 #include "BLT_translation.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_ghash.h"
42
43 #include "BKE_context.h"
44 #include "BKE_idprop.h"
45 #include "BKE_library.h"
46
47 #include "RNA_access.h"
48 #include "RNA_define.h"
49 #include "RNA_enum_types.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
54 #include "wm.h"
55 #include "wm_event_system.h"
56
57 #define UNDOCUMENTED_OPERATOR_TIP N_("(undocumented operator)")
58
59 static void wm_operatortype_free_macro(wmOperatorType *ot);
60
61 /* -------------------------------------------------------------------- */
62 /** \name Operator Type Registry
63  * \{ */
64
65 static GHash *global_ops_hash = NULL;
66 /** Counter for operator-properties that should not be tagged with #OP_PROP_TAG_ADVANCED. */
67 static int ot_prop_basic_count = -1;
68
69 wmOperatorType *WM_operatortype_find(const char *idname, bool quiet)
70 {
71         if (idname[0]) {
72                 wmOperatorType *ot;
73
74                 /* needed to support python style names without the _OT_ syntax */
75                 char idname_bl[OP_MAX_TYPENAME];
76                 WM_operator_bl_idname(idname_bl, idname);
77
78                 ot = BLI_ghash_lookup(global_ops_hash, idname_bl);
79                 if (ot) {
80                         return ot;
81                 }
82
83                 if (!quiet) {
84                         CLOG_INFO(WM_LOG_OPERATORS, 0, "search for unknown operator '%s', '%s'\n", idname_bl, idname);
85                 }
86         }
87         else {
88                 if (!quiet) {
89                         CLOG_INFO(WM_LOG_OPERATORS, 0, "search for empty operator");
90                 }
91         }
92
93         return NULL;
94 }
95
96 /* caller must free */
97 void WM_operatortype_iter(GHashIterator *ghi)
98 {
99         BLI_ghashIterator_init(ghi, global_ops_hash);
100 }
101
102 /** \name Operator Type Append
103  * \{ */
104
105 static wmOperatorType *wm_operatortype_append__begin(void)
106 {
107         wmOperatorType *ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
108
109         BLI_assert(ot_prop_basic_count == -1);
110
111         ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
112         RNA_def_struct_property_tags(ot->srna, rna_enum_operator_property_tags);
113         /* Set the default i18n context now, so that opfunc can redefine it if needed! */
114         RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
115         ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
116
117         return ot;
118 }
119 static void wm_operatortype_append__end(wmOperatorType *ot)
120 {
121         if (ot->name == NULL) {
122                 CLOG_ERROR(WM_LOG_OPERATORS, "Operator '%s' has no name property", ot->idname);
123         }
124
125         /* Allow calling _begin without _end in operatortype creation. */
126         WM_operatortype_props_advanced_end(ot);
127
128         /* XXX All ops should have a description but for now allow them not to. */
129         RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
130         RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
131
132         BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
133 }
134
135 /* all ops in 1 list (for time being... needs evaluation later) */
136 void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
137 {
138         wmOperatorType *ot = wm_operatortype_append__begin();
139         opfunc(ot);
140         wm_operatortype_append__end(ot);
141 }
142
143 void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
144 {
145         wmOperatorType *ot = wm_operatortype_append__begin();
146         opfunc(ot, userdata);
147         wm_operatortype_append__end(ot);
148 }
149
150 /** \} */
151
152
153 /* called on initialize WM_exit() */
154 void WM_operatortype_remove_ptr(wmOperatorType *ot)
155 {
156         BLI_assert(ot == WM_operatortype_find(ot->idname, false));
157
158         RNA_struct_free(&BLENDER_RNA, ot->srna);
159
160         if (ot->last_properties) {
161                 IDP_FreeProperty(ot->last_properties);
162                 MEM_freeN(ot->last_properties);
163         }
164
165         if (ot->macro.first)
166                 wm_operatortype_free_macro(ot);
167
168         BLI_ghash_remove(global_ops_hash, ot->idname, NULL, NULL);
169
170         WM_keyconfig_update_operatortype();
171
172         MEM_freeN(ot);
173 }
174
175 bool WM_operatortype_remove(const char *idname)
176 {
177         wmOperatorType *ot = WM_operatortype_find(idname, 0);
178
179         if (ot == NULL)
180                 return false;
181
182         WM_operatortype_remove_ptr(ot);
183
184         return true;
185 }
186
187 /* called on initialize WM_init() */
188 void wm_operatortype_init(void)
189 {
190         /* reserve size is set based on blender default setup */
191         global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
192 }
193
194 static void operatortype_ghash_free_cb(wmOperatorType *ot)
195 {
196         if (ot->last_properties) {
197                 IDP_FreeProperty(ot->last_properties);
198                 MEM_freeN(ot->last_properties);
199         }
200
201         if (ot->macro.first)
202                 wm_operatortype_free_macro(ot);
203
204         if (ot->ext.srna) /* python operator, allocs own string */
205                 MEM_freeN((void *)ot->idname);
206
207         MEM_freeN(ot);
208 }
209
210 void wm_operatortype_free(void)
211 {
212         BLI_ghash_free(global_ops_hash, NULL, (GHashValFreeFP)operatortype_ghash_free_cb);
213         global_ops_hash = NULL;
214 }
215
216 /**
217  * Tag all operator-properties of \a ot defined after calling this, until
218  * the next #WM_operatortype_props_advanced_end call (if available), with
219  * #OP_PROP_TAG_ADVANCED. Previously defined ones properties not touched.
220  *
221  * Calling this multiple times without a call to #WM_operatortype_props_advanced_end,
222  * all calls after the first one are ignored. Meaning all propereties defined after the
223  * first call are tagged as advanced.
224  *
225  * This doesn't do the actual tagging, #WM_operatortype_props_advanced_end does which is
226  * called for all operators during registration (see #wm_operatortype_append__end).
227  */
228 void WM_operatortype_props_advanced_begin(wmOperatorType *ot)
229 {
230         if (ot_prop_basic_count == -1) { /* Don't do anything if _begin was called before, but not _end  */
231                 ot_prop_basic_count = RNA_struct_count_properties(ot->srna);
232         }
233 }
234
235 /**
236  * Tags all operator-properties of \ot defined since the first #WM_operatortype_props_advanced_begin
237  * call, or the last #WM_operatortype_props_advanced_end call, with #OP_PROP_TAG_ADVANCED.
238  * Note that this is called for all operators during registration (see #wm_operatortype_append__end).
239  * So it does not need to be explicitly called in operator-type definition.
240  */
241 void WM_operatortype_props_advanced_end(wmOperatorType *ot)
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
251         RNA_pointer_create(NULL, ot->srna, NULL, &struct_ptr);
252
253         RNA_STRUCT_BEGIN (&struct_ptr, prop)
254         {
255                 counter++;
256                 if (counter > ot_prop_basic_count) {
257                         WM_operatortype_prop_tag(prop, OP_PROP_TAG_ADVANCED);
258                 }
259         }
260         RNA_STRUCT_END;
261
262         ot_prop_basic_count = -1;
263 }
264
265 /** \} */
266
267 /* -------------------------------------------------------------------- */
268 /** \name Operator Macro Type
269  * \{ */
270
271 typedef struct {
272         int retval;
273 } MacroData;
274
275 static void wm_macro_start(wmOperator *op)
276 {
277         if (op->customdata == NULL) {
278                 op->customdata = MEM_callocN(sizeof(MacroData), "MacroData");
279         }
280 }
281
282 static int wm_macro_end(wmOperator *op, int retval)
283 {
284         if (retval & OPERATOR_CANCELLED) {
285                 MacroData *md = op->customdata;
286
287                 if (md->retval & OPERATOR_FINISHED) {
288                         retval |= OPERATOR_FINISHED;
289                         retval &= ~OPERATOR_CANCELLED;
290                 }
291         }
292
293         /* if modal is ending, free custom data */
294         if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
295                 if (op->customdata) {
296                         MEM_freeN(op->customdata);
297                         op->customdata = NULL;
298                 }
299         }
300
301         return retval;
302 }
303
304 /* macro exec only runs exec calls */
305 static int wm_macro_exec(bContext *C, wmOperator *op)
306 {
307         wmOperator *opm;
308         int retval = OPERATOR_FINISHED;
309
310         wm_macro_start(op);
311
312         for (opm = op->macro.first; opm; opm = opm->next) {
313
314                 if (opm->type->exec) {
315                         retval = opm->type->exec(C, opm);
316                         OPERATOR_RETVAL_CHECK(retval);
317
318                         if (retval & OPERATOR_FINISHED) {
319                                 MacroData *md = op->customdata;
320                                 md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
321                         }
322                         else {
323                                 break; /* operator didn't finish, end macro */
324                         }
325                 }
326                 else {
327                         CLOG_WARN(WM_LOG_OPERATORS, "'%s' cant exec macro", opm->type->idname);
328                 }
329         }
330
331         return wm_macro_end(op, retval);
332 }
333
334 static int wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *event, wmOperator *opm)
335 {
336         int retval = OPERATOR_FINISHED;
337
338         /* start from operator received as argument */
339         for (; opm; opm = opm->next) {
340                 if (opm->type->invoke)
341                         retval = opm->type->invoke(C, opm, event);
342                 else if (opm->type->exec)
343                         retval = opm->type->exec(C, opm);
344
345                 OPERATOR_RETVAL_CHECK(retval);
346
347                 BLI_movelisttolist(&op->reports->list, &opm->reports->list);
348
349                 if (retval & OPERATOR_FINISHED) {
350                         MacroData *md = op->customdata;
351                         md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
352                 }
353                 else {
354                         break; /* operator didn't finish, end macro */
355                 }
356         }
357
358         return wm_macro_end(op, retval);
359 }
360
361 static int wm_macro_invoke(bContext *C, wmOperator *op, const wmEvent *event)
362 {
363         wm_macro_start(op);
364         return wm_macro_invoke_internal(C, op, event, op->macro.first);
365 }
366
367 static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
368 {
369         wmOperator *opm = op->opm;
370         int retval = OPERATOR_FINISHED;
371
372         if (opm == NULL) {
373                 CLOG_ERROR(WM_LOG_OPERATORS, "macro error, calling NULL modal()");
374         }
375         else {
376                 retval = opm->type->modal(C, opm, event);
377                 OPERATOR_RETVAL_CHECK(retval);
378
379                 /* if we're halfway through using a tool and cancel it, clear the options [#37149] */
380                 if (retval & OPERATOR_CANCELLED) {
381                         WM_operator_properties_clear(opm->ptr);
382                 }
383
384                 /* if this one is done but it's not the last operator in the macro */
385                 if ((retval & OPERATOR_FINISHED) && opm->next) {
386                         MacroData *md = op->customdata;
387
388                         md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
389
390                         retval = wm_macro_invoke_internal(C, op, event, opm->next);
391
392                         /* if new operator is modal and also added its own handler */
393                         if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
394                                 wmWindow *win = CTX_wm_window(C);
395                                 wmEventHandler *handler;
396
397                                 handler = BLI_findptr(&win->modalhandlers, op, offsetof(wmEventHandler, op));
398                                 if (handler) {
399                                         BLI_remlink(&win->modalhandlers, handler);
400                                         wm_event_free_handler(handler);
401                                 }
402
403                                 /* if operator is blocking, grab cursor
404                                  * This may end up grabbing twice, but we don't care.
405                                  * */
406                                 if (op->opm->type->flag & OPTYPE_BLOCKING) {
407                                         int bounds[4] = {-1, -1, -1, -1};
408                                         const bool wrap = (
409                                                 (U.uiflag & USER_CONTINUOUS_MOUSE) &&
410                                                 ((op->opm->flag & OP_IS_MODAL_GRAB_CURSOR) || (op->opm->type->flag & OPTYPE_GRAB_CURSOR)));
411
412                                         if (wrap) {
413                                                 ARegion *ar = CTX_wm_region(C);
414                                                 if (ar) {
415                                                         bounds[0] = ar->winrct.xmin;
416                                                         bounds[1] = ar->winrct.ymax;
417                                                         bounds[2] = ar->winrct.xmax;
418                                                         bounds[3] = ar->winrct.ymin;
419                                                 }
420                                         }
421
422                                         WM_cursor_grab_enable(win, wrap, false, bounds);
423                                 }
424                         }
425                 }
426         }
427
428         return wm_macro_end(op, retval);
429 }
430
431 static void wm_macro_cancel(bContext *C, wmOperator *op)
432 {
433         /* call cancel on the current modal operator, if any */
434         if (op->opm && op->opm->type->cancel) {
435                 op->opm->type->cancel(C, op->opm);
436         }
437
438         wm_macro_end(op, OPERATOR_CANCELLED);
439 }
440
441 /* Names have to be static for now */
442 wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)
443 {
444         wmOperatorType *ot;
445         const char *i18n_context;
446
447         if (WM_operatortype_find(idname, true)) {
448                 CLOG_ERROR(WM_LOG_OPERATORS, "operator %s exists, cannot create macro", idname);
449                 return NULL;
450         }
451
452         ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
453         ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
454
455         ot->idname = idname;
456         ot->name = name;
457         ot->description = description;
458         ot->flag = OPTYPE_MACRO | flag;
459
460         ot->exec = wm_macro_exec;
461         ot->invoke = wm_macro_invoke;
462         ot->modal = wm_macro_modal;
463         ot->cancel = wm_macro_cancel;
464         ot->poll = NULL;
465
466         if (!ot->description) /* XXX All ops should have a description but for now allow them not to. */
467                 ot->description = UNDOCUMENTED_OPERATOR_TIP;
468
469         RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
470         RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
471         /* Use i18n context from ext.srna if possible (py operators). */
472         i18n_context = ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) : BLT_I18NCONTEXT_OPERATOR_DEFAULT;
473         RNA_def_struct_translation_context(ot->srna, i18n_context);
474         ot->translation_context = i18n_context;
475
476         BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
477
478         return ot;
479 }
480
481 void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
482 {
483         wmOperatorType *ot;
484
485         ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
486         ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
487
488         ot->flag = OPTYPE_MACRO;
489         ot->exec = wm_macro_exec;
490         ot->invoke = wm_macro_invoke;
491         ot->modal = wm_macro_modal;
492         ot->cancel = wm_macro_cancel;
493         ot->poll = NULL;
494
495         if (!ot->description)
496                 ot->description = UNDOCUMENTED_OPERATOR_TIP;
497
498         /* Set the default i18n context now, so that opfunc can redefine it if needed! */
499         RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
500         ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
501         opfunc(ot, userdata);
502
503         RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
504         RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
505
506         BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
507 }
508
509 wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
510 {
511         wmOperatorTypeMacro *otmacro = MEM_callocN(sizeof(wmOperatorTypeMacro), "wmOperatorTypeMacro");
512
513         BLI_strncpy(otmacro->idname, idname, OP_MAX_TYPENAME);
514
515         /* do this on first use, since operatordefinitions might have been not done yet */
516         WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname);
517         WM_operator_properties_sanitize(otmacro->ptr, 1);
518
519         BLI_addtail(&ot->macro, otmacro);
520
521         {
522                 /* operator should always be found but in the event its not. don't segfault */
523                 wmOperatorType *otsub = WM_operatortype_find(idname, 0);
524                 if (otsub) {
525                         RNA_def_pointer_runtime(ot->srna, otsub->idname, otsub->srna,
526                                                 otsub->name, otsub->description);
527                 }
528         }
529
530         return otmacro;
531 }
532
533 static void wm_operatortype_free_macro(wmOperatorType *ot)
534 {
535         wmOperatorTypeMacro *otmacro;
536
537         for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
538                 if (otmacro->ptr) {
539                         WM_operator_properties_free(otmacro->ptr);
540                         MEM_freeN(otmacro->ptr);
541                 }
542         }
543         BLI_freelistN(&ot->macro);
544 }
545
546 /** \} */