Blender V5.0
console_ops.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
8
9#include <algorithm>
10#include <cctype> /* #ispunct */
11#include <cstdlib>
12#include <cstring>
13#include <sys/stat.h>
14
15#include "MEM_guardedalloc.h"
16
17#include "DNA_userdef_types.h"
18
19#include "BLI_dynstr.h"
20#include "BLI_listbase.h"
21#include "BLI_math_base.h"
22#include "BLI_string.h"
24#include "BLI_string_utf8.h"
25#include "BLI_utildefines.h"
26
27#include "BKE_context.hh"
28#include "BKE_report.hh"
29#include "BKE_screen.hh"
30
31#include "WM_api.hh"
32#include "WM_types.hh"
33
34#include "ED_screen.hh"
35
36#include "UI_view2d.hh"
37
38#include "RNA_access.hh"
39#include "RNA_define.hh"
40
41#include "console_intern.hh"
42
43#define TAB_LENGTH 4
44
45/* -------------------------------------------------------------------- */
48
50{
51 if (sc->sel_start == sc->sel_end) {
52 return nullptr;
53 }
54
55 ConsoleLine cl_dummy = {nullptr};
57
58 int offset = 0;
60 offset += cl->len + 1;
61 }
62
63 char *buf_str = nullptr;
64 if (offset != 0) {
65 offset -= 1;
66 int sel[2] = {offset - sc->sel_end, offset - sc->sel_start};
67 DynStr *buf_dyn = BLI_dynstr_new();
69 if (sel[0] <= cl->len && sel[1] >= 0) {
70 int sta = max_ii(sel[0], 0);
71 int end = min_ii(sel[1], cl->len);
72
73 if (BLI_dynstr_get_len(buf_dyn)) {
74 BLI_dynstr_append(buf_dyn, "\n");
75 }
76
77 BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
78 }
79
80 sel[0] -= cl->len + 1;
81 sel[1] -= cl->len + 1;
82 }
83
84 buf_str = BLI_dynstr_get_cstring(buf_dyn);
85
86 BLI_dynstr_free(buf_dyn);
87 }
88 console_scrollback_prompt_end(sc, &cl_dummy);
89
90 return buf_str;
91}
92
94{
96 return;
97 }
98 if (sc->sel_start == sc->sel_end) {
99 return;
100 }
101 char *buf = console_select_to_buffer(sc);
102 if (buf == nullptr) {
103 return;
104 }
105 WM_clipboard_text_set(buf, true);
106 MEM_freeN(buf);
107}
108
109/* Delete selected characters in the edit line. */
111{
112 if (sc->sel_start == sc->sel_end) {
113 return 0;
114 }
115
116 sc->sel_start = std::max(sc->sel_start, 0);
117
118 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
119 if (!cl || sc->sel_start > cl->len) {
120 sc->sel_start = sc->sel_end;
121 return 0;
122 }
123
124 int del_start = sc->sel_start;
125 int del_end = sc->sel_end;
126
127 del_end = std::min(del_end, cl->len);
128
129 const int len = del_end - del_start;
130 memmove(cl->line + cl->len - del_end, cl->line + cl->len - del_start, del_start);
131 cl->len -= len;
132 cl->line[cl->len] = 0;
133 cl->cursor = cl->len - del_start;
134
135 sc->sel_start = sc->sel_end = cl->cursor;
136 return len;
137}
138
140
141/* so when we type - the view scrolls to the bottom */
142static void console_scroll_bottom(ARegion *region)
143{
144 View2D *v2d = &region->v2d;
145 v2d->cur.ymin = 0.0;
146 v2d->cur.ymax = float(v2d->winy);
147}
148
150{
151 View2D *v2d = &region->v2d;
152
153 UI_view2d_totRect_set(v2d, region->winx - 1, console_textview_height(sc, region));
154}
155
156static void console_select_offset(SpaceConsole *sc, const int offset)
157{
158 sc->sel_start += offset;
159 sc->sel_end += offset;
160}
161
163{
164 BLI_remlink(&sc->history, cl);
165 MEM_freeN(cl->line);
166 MEM_freeN(cl);
167}
169{
170 BLI_remlink(&sc->scrollback, cl);
171 MEM_freeN(cl->line);
172 MEM_freeN(cl);
173}
174
176{
177 int tot;
178
179 for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--) {
180 console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
181 }
182}
183
184/* return 0 if no change made, clamps the range */
185static bool console_line_cursor_set(ConsoleLine *cl, int cursor)
186{
187 int cursor_new;
188
189 if (cursor < 0) {
190 cursor_new = 0;
191 }
192 else if (cursor > cl->len) {
193 cursor_new = cl->len;
194 }
195 else {
196 cursor_new = cursor;
197 }
198
199 if (cursor_new == cl->cursor) {
200 return false;
201 }
202
203 cl->cursor = cursor_new;
204 return true;
205}
206
207#if 0 /* XXX unused */
208static void console_lb_debug__internal(ListBase *lb)
209{
210 ConsoleLine *cl;
211
212 printf("%d: ", BLI_listbase_count(lb));
213 for (cl = lb->first; cl; cl = cl->next) {
214 printf("<%s> ", cl->line);
215 }
216 printf("\n");
217}
218
219static void console_history_debug(const bContext *C)
220{
222
223 console_lb_debug__internal(&sc->history);
224}
225#endif
226
228{
229 ConsoleLine *ci = MEM_callocN<ConsoleLine>("ConsoleLine Add");
230
231 if (from) {
232 BLI_assert(strlen(from->line) == from->len);
233 ci->line = BLI_strdupn(from->line, from->len);
234 ci->len = ci->len_alloc = from->len;
235 ci->cursor = from->cursor;
236 ci->type = from->type;
237 }
238 else {
239 ci->line = MEM_calloc_arrayN<char>(64, "console-in-line");
240 ci->len_alloc = 64;
241 ci->len = 0;
242 }
243
244 BLI_addtail(lb, ci);
245 return ci;
246}
247
249{
250 return console_lb_add__internal(&sc->history, from);
251}
252
253#if 0 /* may use later ? */
254static ConsoleLine *console_scrollback_add(const bContext *C, ConsoleLine *from)
255{
257
258 return console_lb_add__internal(&sc->scrollback, from);
259}
260#endif
261
263{
264 ConsoleLine *ci = MEM_callocN<ConsoleLine>("ConsoleLine Add");
265 const int str_len = strlen(str);
266 if (own) {
267 ci->line = str;
268 }
269 else {
270 ci->line = BLI_strdupn(str, str_len);
271 }
272
273 ci->len = ci->len_alloc = str_len;
274
275 BLI_addtail(lb, ci);
276 return ci;
277}
279{
280 return console_lb_add_str__internal(&sc->history, str, own);
281}
283{
285 console_select_offset(sc, ci->len + 1);
286 return ci;
287}
288
290{
292 ConsoleLine *ci = static_cast<ConsoleLine *>(sc->history.last);
293 if (ci == nullptr) {
294 ci = console_history_add(sc, nullptr);
295 }
296
297 return ci;
298}
299
301{
302 /* resize the buffer if needed */
303 if (len >= ci->len_alloc) {
304 /* new length */
305#ifndef NDEBUG
306 int new_len = len + 1;
307#else
308 int new_len = (len + 1) * 2;
309#endif
310 ci->line = static_cast<char *>(MEM_recallocN_id(ci->line, new_len, "console line"));
311 ci->len_alloc = new_len;
312 }
313}
314
315static void console_line_insert(ConsoleLine *ci, const char *str, int len)
316{
317 if (len == 0) {
318 return;
319 }
320
321 BLI_assert(len <= strlen(str));
322 /* The caller must delimit new-lines. */
323 BLI_assert(str[len - 1] != '\n');
324
326
327 memmove(ci->line + ci->cursor + len, ci->line + ci->cursor, (ci->len - ci->cursor) + 1);
328 memcpy(ci->line + ci->cursor, str, len);
329
330 ci->len += len;
331 ci->cursor += len;
332}
333
340 SpaceConsole *sc, const int pos, ConsoleLine **r_cl, int *r_cl_offset, int *r_col)
341{
342 ConsoleLine *cl;
343 int offset = 0;
344
345 for (cl = static_cast<ConsoleLine *>(sc->scrollback.last); cl; cl = cl->prev) {
346 offset += cl->len + 1;
347 if (offset > pos) {
348 break;
349 }
350 }
351
352 if (cl) {
353 offset -= 1;
354 *r_cl = cl;
355 *r_cl_offset = offset;
356 *r_col = offset - pos;
357 return true;
358 }
359
360 *r_cl = nullptr;
361 *r_cl_offset = -1;
362 *r_col = -1;
363 return false;
364}
365
366/* Static functions for text editing. */
367
368/* similar to the text editor, with some not used. keep compatible */
370 {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
371 {LINE_END, "LINE_END", 0, "Line End", ""},
372 {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
373 {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
374 {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
375 {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
376 {0, nullptr, 0, nullptr, nullptr},
377};
378
380{
383 ScrArea *area = CTX_wm_area(C);
385
386 int type = RNA_enum_get(op->ptr, "type");
387 const bool select = RNA_boolean_get(op->ptr, "select");
388
389 bool done = false;
390 const int old_pos = ci->cursor;
391 int pos = 0;
392
393 if (!select && sc->sel_start != sc->sel_end) {
394 /* Clear selection if we are not extending it. */
395 sc->sel_start = sc->sel_end;
396 }
397 const bool had_select = sc->sel_start != sc->sel_end;
398
399 int select_side = 0;
400 if (had_select) {
401 if (sc->sel_start == ci->len - old_pos) {
402 select_side = -1;
403 }
404 else if (sc->sel_end == ci->len - old_pos) {
405 select_side = 1;
406 }
407 }
408
409 switch (type) {
410 case LINE_BEGIN:
411 pos = ci->cursor;
413 done = console_line_cursor_set(ci, pos);
414 break;
415 case LINE_END:
416 pos = ci->cursor;
418 done = console_line_cursor_set(ci, pos);
419 break;
420 case PREV_CHAR:
421 pos = ci->cursor;
423 done = console_line_cursor_set(ci, pos);
424 break;
425 case NEXT_CHAR:
426 pos = ci->cursor;
428 done = console_line_cursor_set(ci, pos);
429 break;
430
431 /* - if the character is a delimiter then skip delimiters (including white space)
432 * - when jump over the word */
433 case PREV_WORD:
434 pos = ci->cursor;
436 done = console_line_cursor_set(ci, pos);
437 break;
438 case NEXT_WORD:
439 pos = ci->cursor;
441 done = console_line_cursor_set(ci, pos);
442 break;
443 }
444
445 if (select) {
446 if (had_select) {
447 if (select_side != 0) {
448 /* Modify the current selection if either side was positioned at the cursor. */
449 if (select_side == -1) {
450 sc->sel_start = ci->len - pos;
451 }
452 else if (select_side == 1) {
453 sc->sel_end = ci->len - pos;
454 }
455 if (sc->sel_start > sc->sel_end) {
456 std::swap(sc->sel_start, sc->sel_end);
457 }
458 }
459 }
460 else {
461 /* Create a new selection. */
462 if (old_pos > pos) {
463 sc->sel_start = ci->len - old_pos;
464 sc->sel_end = ci->len - pos;
465 BLI_assert(sc->sel_start < sc->sel_end);
466 }
467 else if (old_pos < pos) {
468 sc->sel_start = ci->len - pos;
469 sc->sel_end = ci->len - old_pos;
470 BLI_assert(sc->sel_start < sc->sel_end);
471 }
472 }
473 }
474
475 if (done) {
476 ED_area_tag_redraw(area);
477 console_scroll_bottom(region);
478 }
479
480 return OPERATOR_FINISHED;
481}
482
484{
485 /* identifiers */
486 ot->name = "Move Cursor";
487 ot->description = "Move cursor position";
488 ot->idname = "CONSOLE_OT_move";
489
490 /* API callbacks. */
491 ot->exec = console_move_exec;
493
494 /* properties */
496 ot->srna, "type", console_move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
498 ot->srna, "select", false, "Select", "Whether to select while moving");
500}
501
503{
505 ScrArea *area = CTX_wm_area(C);
508 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
509 int len = strlen(str);
510
511 /* Allow trailing newlines (but strip them). */
512 while (len > 0 && str[len - 1] == '\n') {
513 len--;
514 str[len] = '\0';
515 }
516
517 if (strchr(str, '\n')) {
518 BKE_report(op->reports, RPT_ERROR, "New lines unsupported, call this operator multiple times");
519 /* Force cancel. */
520 len = 0;
521 }
522
523 if (len != 0) {
526 }
527
528 MEM_freeN(str);
529
530 if (len == 0) {
531 return OPERATOR_CANCELLED;
532 }
533
535
537 ED_area_tag_redraw(area);
538
539 console_scroll_bottom(region);
540
541 return OPERATOR_FINISHED;
542}
543
545{
546 /* NOTE: the "text" property is always set from key-map,
547 * so we can't use #RNA_struct_property_is_set, check the length instead. */
548 if (!RNA_string_length(op->ptr, "text")) {
549 /* If alt/control/super are pressed pass through except for UTF8 character event
550 * (when input method are used for UTF8 inputs, the user may assign key event
551 * including alt/control/super like control-m to commit UTF8 string.
552 * in such case, the modifiers in the UTF8 character event make no sense.) */
553 if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
555 }
556
557 char str[BLI_UTF8_MAX + 1];
558 const size_t len = BLI_str_utf8_size_safe(event->utf8_buf);
559 memcpy(str, event->utf8_buf, len);
560 str[len] = '\0';
561 RNA_string_set(op->ptr, "text", str);
562 }
563 return console_insert_exec(C, op);
564}
565
567{
568 PropertyRNA *prop;
569
570 /* identifiers */
571 ot->name = "Insert";
572 ot->description = "Insert text at cursor position";
573 ot->idname = "CONSOLE_OT_insert";
574
575 /* API callbacks. */
576 ot->exec = console_insert_exec;
577 ot->invoke = console_insert_invoke;
579
580 /* properties */
581 prop = RNA_def_string(
582 ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
584}
585
586/* -------------------------------------------------------------------- */
589
591{
593 bool text_before_cursor = false;
594
595 /* Check any text before cursor (not just the previous character) as is done for
596 * #TEXT_OT_indent_or_autocomplete because Python auto-complete operates on import
597 * statements such as completing possible sub-modules: `from bpy import `. */
598 for (int i = 0; i < ci->cursor; i += BLI_str_utf8_size_safe(&ci->line[i])) {
599 if (!ELEM(ci->line[i], ' ', '\t')) {
600 text_before_cursor = true;
601 break;
602 }
603 }
604
605 if (text_before_cursor) {
607 C, "CONSOLE_OT_autocomplete", blender::wm::OpCallContext::InvokeDefault, nullptr, nullptr);
608 }
609 else {
611 C, "CONSOLE_OT_indent", blender::wm::OpCallContext::ExecDefault, nullptr, nullptr);
612 }
613 return OPERATOR_FINISHED;
614}
615
617{
618 /* identifiers */
619 ot->name = "Indent or Autocomplete";
620 ot->idname = "CONSOLE_OT_indent_or_autocomplete";
621 ot->description = "Indent selected text or autocomplete";
622
623 /* API callbacks. */
626
627 /* flags */
628 ot->flag = 0;
629}
630
632
633/* -------------------------------------------------------------------- */
636
638{
641 ScrArea *area = CTX_wm_area(C);
643
644 int spaces;
645 int len;
646
647 for (spaces = 0; spaces < ci->len; spaces++) {
648 if (ci->line[spaces] != ' ') {
649 break;
650 }
651 }
652
653 len = TAB_LENGTH - spaces % TAB_LENGTH;
654
656
657 memmove(ci->line + len, ci->line, ci->len + 1);
658 memset(ci->line, ' ', len);
659 ci->len += len;
660 BLI_assert(ci->len >= 0);
663
665 ED_area_tag_redraw(area);
666
667 console_scroll_bottom(region);
668
669 return OPERATOR_FINISHED;
670}
671
673{
674 /* identifiers */
675 ot->name = "Indent";
676 ot->description = "Add 4 spaces at line beginning";
677 ot->idname = "CONSOLE_OT_indent";
678
679 /* API callbacks. */
680 ot->exec = console_indent_exec;
682}
683
685
687{
690 ScrArea *area = CTX_wm_area(C);
692
693 int spaces;
694 int len;
695
696 for (spaces = 0; spaces < ci->len; spaces++) {
697 if (ci->line[spaces] != ' ') {
698 break;
699 }
700 }
701
702 if (spaces == 0) {
703 return OPERATOR_CANCELLED;
704 }
705
706 len = spaces % TAB_LENGTH;
707 if (len == 0) {
708 len = TAB_LENGTH;
709 }
710
712
713 memmove(ci->line, ci->line + len, (ci->len - len) + 1);
714 ci->len -= len;
715 BLI_assert(ci->len >= 0);
716
719
721 ED_area_tag_redraw(area);
722
723 console_scroll_bottom(region);
724
725 return OPERATOR_FINISHED;
726}
727
729{
730 /* identifiers */
731 ot->name = "Unindent";
732 ot->description = "Delete 4 spaces from line beginning";
733 ot->idname = "CONSOLE_OT_unindent";
734
735 /* API callbacks. */
738}
739
741 {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
742 {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
743 {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
744 {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
745 {0, nullptr, 0, nullptr, nullptr},
746};
747
749{
752 ScrArea *area = CTX_wm_area(C);
754
755 int pos;
756 int stride;
757
758 const short type = RNA_enum_get(op->ptr, "type");
759 bool done = false;
760
761 if (ci->len == 0) {
762 return OPERATOR_CANCELLED;
763 }
764
765 /* If there is a selection just delete it and nothing else. */
766 if (sc->sel_start != sc->sel_end && console_delete_editable_selection(sc) > 0) {
768 ED_area_tag_redraw(area);
769 console_scroll_bottom(region);
770 return OPERATOR_FINISHED;
771 }
772
773 switch (type) {
774 case DEL_NEXT_CHAR:
775 case DEL_NEXT_WORD:
776 if (ci->cursor < ci->len) {
777 pos = ci->cursor;
779 ci->len,
780 &pos,
783 true);
784 stride = pos - ci->cursor;
785 if (stride) {
786 memmove(ci->line + ci->cursor,
787 ci->line + ci->cursor + stride,
788 (ci->len - (ci->cursor + stride)) + 1);
789 ci->len -= stride;
790 BLI_assert(ci->len >= 0);
791 done = true;
792 }
793 }
794 break;
795 case DEL_PREV_CHAR:
796 case DEL_PREV_WORD:
797 if (ci->cursor > 0) {
798 pos = ci->cursor;
800 ci->len,
801 &pos,
804 true);
805 stride = ci->cursor - pos;
806 if (stride) {
807 ci->cursor -= stride; /* same as above */
808 memmove(ci->line + ci->cursor,
809 ci->line + ci->cursor + stride,
810 (ci->len - (ci->cursor + stride)) + 1);
811 ci->len -= stride;
812 BLI_assert(ci->len >= 0);
813 done = true;
814 }
815 }
816 break;
817 }
818
819 if (!done) {
820 return OPERATOR_CANCELLED;
821 }
822
823 console_select_offset(sc, -stride);
824
826 ED_area_tag_redraw(area);
827
828 console_scroll_bottom(region);
829
830 return OPERATOR_FINISHED;
831}
832
834{
835 /* identifiers */
836 ot->name = "Delete";
837 ot->description = "Delete text by cursor position";
838 ot->idname = "CONSOLE_OT_delete";
839
840 /* API callbacks. */
841 ot->exec = console_delete_exec;
843
844 /* properties */
845 RNA_def_enum(ot->srna,
846 "type",
849 "Type",
850 "Which part of the text to delete");
851}
852
854{
857 ScrArea *area = CTX_wm_area(C);
859
860 if (ci->len == 0) {
861 return OPERATOR_CANCELLED;
862 }
863
864 console_history_add(sc, ci);
865 console_history_add(sc, nullptr);
866 console_select_offset(sc, -ci->len);
867
869
870 ED_area_tag_redraw(area);
871
872 console_scroll_bottom(region);
873
874 return OPERATOR_FINISHED;
875}
876
878{
879 /* identifiers */
880 ot->name = "Clear Line";
881 ot->description = "Clear the line and store in history";
882 ot->idname = "CONSOLE_OT_clear_line";
883
884 /* API callbacks. */
887}
888
889/* the python exec operator uses this */
891{
893 ScrArea *area = CTX_wm_area(C);
895
896 const bool scrollback = RNA_boolean_get(op->ptr, "scrollback");
897 const bool history = RNA_boolean_get(op->ptr, "history");
898
899 /* ConsoleLine *ci = */ console_history_verify(C);
900
901 if (scrollback) { /* Last item in history. */
902 while (sc->scrollback.first) {
903 console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
904 }
905 }
906
907 if (history) {
908 while (sc->history.first) {
909 console_history_free(sc, static_cast<ConsoleLine *>(sc->history.first));
910 }
912 }
913
915 ED_area_tag_redraw(area);
916
917 return OPERATOR_FINISHED;
918}
919
921{
922 /* identifiers */
923 ot->name = "Clear All";
924 ot->description = "Clear text by type";
925 ot->idname = "CONSOLE_OT_clear";
926
927 /* API callbacks. */
928 ot->exec = console_clear_exec;
930
931 /* properties */
932 RNA_def_boolean(ot->srna, "scrollback", true, "Scrollback", "Clear the scrollback history");
933 RNA_def_boolean(ot->srna, "history", false, "History", "Clear the command history");
934}
935
936/* the python exec operator uses this */
938{
940 ScrArea *area = CTX_wm_area(C);
942
943 /* TODO: stupid, just prevents crashes when no command line. */
945 const bool reverse = RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */
946 int prev_len = ci->len;
947
948 int old_index = sc->history_index;
949 int new_index;
950 if (reverse) {
951 if (old_index <= 0) {
952 new_index = 1;
953 }
954 else {
955 new_index = old_index + 1;
956 }
957 }
958 else {
959 if (old_index <= 0) { /* Down-arrow after exec. */
960 new_index = -old_index;
961 }
962 else {
963 new_index = old_index - 1;
964 }
965 }
966
967 /* Find the history item. */
968 ConsoleLine *ci_prev = ci;
969 if (old_index > 0) {
970 /* Skip a previous copy of history item. */
971 if (ci_prev->prev) {
972 ci_prev = ci_prev->prev;
973 }
974 else { /* Just in case the duplicate item got deleted. */
975 old_index = 0;
976 }
977 }
978 for (int i = 0; i < new_index; i++) {
979 if (!ci_prev->prev) {
980 new_index = i;
981 break;
982 }
983 ci_prev = ci_prev->prev;
984 }
985
986 sc->history_index = new_index;
987
988 if (old_index > 0) { /* Remove old copy. */
989 console_history_free(sc, ci);
990 ci = ci_prev;
991 }
992 if (new_index > 0) { /* Copy history item to the end. */
993 ci = console_history_add(sc, ci_prev);
994 }
995
996 console_select_offset(sc, ci->len - prev_len);
997
998 /* could be wrapped so update scroll rect */
1000 ED_area_tag_redraw(area);
1001
1002 console_scroll_bottom(region);
1003
1004 return OPERATOR_FINISHED;
1005}
1006
1008{
1009 /* identifiers */
1010 ot->name = "History Cycle";
1011 ot->description = "Cycle through history";
1012 ot->idname = "CONSOLE_OT_history_cycle";
1013
1014 /* API callbacks. */
1017
1018 /* properties */
1019 RNA_def_boolean(ot->srna, "reverse", false, "Reverse", "Reverse cycle history");
1020}
1021
1022/* the python exec operator uses this */
1024{
1026 ScrArea *area = CTX_wm_area(C);
1028
1030 /* own this text in the new line, don't free */
1031 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
1032 int cursor = RNA_int_get(op->ptr, "current_character");
1033 const bool rem_dupes = RNA_boolean_get(op->ptr, "remove_duplicates");
1034 int prev_len = ci->len;
1035
1036 if (sc->history_index > 0) {
1037 /* Keep the copy of history item, remove the saved "history 0". */
1038 ConsoleLine *cl = ci->prev;
1039 if (cl) {
1040 console_history_free(sc, cl);
1041 }
1042 /* Negative number makes down-arrow go to same item as before. */
1043 sc->history_index = -sc->history_index;
1044 }
1045
1046 if (rem_dupes) {
1047 /* Remove a repeated command. */
1048 ConsoleLine *cl = ci->prev;
1049 if (cl && STREQ(cl->line, ci->line)) {
1050 console_history_free(sc, cl);
1051 }
1052 /* Remove blank command. */
1053 if (STREQ(str, ci->line)) {
1054 MEM_freeN(str);
1055 return OPERATOR_FINISHED;
1056 }
1057 }
1058
1059 ci = console_history_add_str(sc, str, true); /* own the string */
1060 console_select_offset(sc, ci->len - prev_len);
1061 console_line_cursor_set(ci, cursor);
1062
1063 ED_area_tag_redraw(area);
1064 console_scroll_bottom(region);
1065
1066 return OPERATOR_FINISHED;
1067}
1068
1070{
1071 /* identifiers */
1072 ot->name = "History Append";
1073 ot->description = "Append history at cursor position";
1074 ot->idname = "CONSOLE_OT_history_append";
1075
1076 /* API callbacks. */
1079
1080 /* properties */
1081 RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
1083 ot->srna, "current_character", 0, 0, INT_MAX, "Cursor", "The index of the cursor", 0, 10000);
1084 RNA_def_boolean(ot->srna,
1085 "remove_duplicates",
1086 false,
1087 "Remove Duplicates",
1088 "Remove duplicate items in the history");
1089}
1090
1091/* the python exec operator uses this */
1093{
1095 ConsoleLine *ci;
1096 ScrArea *area = CTX_wm_area(C);
1098
1099 /* own this text in the new line, don't free */
1100 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
1101 int type = RNA_enum_get(op->ptr, "type");
1102
1104
1105 ci = console_scrollback_add_str(sc, str, true); /* own the string */
1106 ci->type = type;
1107
1109
1110 console_textview_update_rect(sc, region);
1111 ED_area_tag_redraw(area);
1112
1113 return OPERATOR_FINISHED;
1114}
1115
1117{
1118 /* defined in DNA_space_types.h */
1119 static const EnumPropertyItem console_line_type_items[] = {
1120 {CONSOLE_LINE_OUTPUT, "OUTPUT", 0, "Output", ""},
1121 {CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""},
1122 {CONSOLE_LINE_INFO, "INFO", 0, "Information", ""},
1123 {CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""},
1124 {0, nullptr, 0, nullptr, nullptr},
1125 };
1126
1127 /* identifiers */
1128 ot->name = "Scrollback Append";
1129 ot->description = "Append scrollback text by type";
1130 ot->idname = "CONSOLE_OT_scrollback_append";
1131
1132 /* API callbacks. */
1135
1136 /* properties */
1137 RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
1138 RNA_def_enum(ot->srna,
1139 "type",
1140 console_line_type_items,
1142 "Type",
1143 "Console output type");
1144}
1145
1147{
1149 char *buf = console_select_to_buffer(sc);
1150 if (buf == nullptr) {
1151 return OPERATOR_CANCELLED;
1152 }
1153
1154 WM_clipboard_text_set(buf, false);
1155
1156 if (RNA_boolean_get(op->ptr, "delete")) {
1159 }
1160
1161 MEM_freeN(buf);
1162 return OPERATOR_FINISHED;
1163}
1164
1166{
1168 return ED_operator_console_active(C) && sc && (sc->sel_start != sc->sel_end);
1169}
1170
1172{
1173 /* identifiers */
1174 ot->name = "Copy to Clipboard";
1175 ot->description = "Copy selected text to clipboard";
1176 ot->idname = "CONSOLE_OT_copy";
1177
1178 /* API callbacks. */
1179 ot->poll = console_copy_poll;
1180 ot->exec = console_copy_exec;
1181
1182 /* properties */
1183 PropertyRNA *prop = RNA_def_boolean(ot->srna,
1184 "delete",
1185 false,
1186 "Delete Selection",
1187 "Whether to delete the selection after copying");
1189}
1190
1192{
1193 const bool selection = RNA_boolean_get(op->ptr, "selection");
1196 ScrArea *area = CTX_wm_area(C);
1198
1199 int buf_str_len;
1200
1201 char *buf_str = WM_clipboard_text_get(selection, true, &buf_str_len);
1202 if (buf_str == nullptr) {
1203 return OPERATOR_CANCELLED;
1204 }
1205 if (*buf_str == '\0') {
1206 MEM_freeN(buf_str);
1207 return OPERATOR_CANCELLED;
1208 }
1209 const char *buf_step = buf_str;
1210 do {
1211 const char *buf = buf_step;
1212 buf_step = (char *)BLI_strchr_or_end(buf, '\n');
1213 const int buf_len = buf_step - buf;
1214 if (buf != buf_str) {
1216 C, "CONSOLE_OT_execute", blender::wm::OpCallContext::ExecDefault, nullptr, nullptr);
1218 }
1220 console_line_insert(ci, buf, buf_len);
1221 console_select_offset(sc, buf_len);
1222 } while (*buf_step ? ((void)buf_step++, true) : false);
1223
1224 MEM_freeN(buf_str);
1225
1226 console_textview_update_rect(sc, region);
1227 ED_area_tag_redraw(area);
1228
1229 console_scroll_bottom(region);
1230
1231 return OPERATOR_FINISHED;
1232}
1233
1235{
1236 /* identifiers */
1237 ot->name = "Paste from Clipboard";
1238 ot->description = "Paste text from clipboard";
1239 ot->idname = "CONSOLE_OT_paste";
1240
1241 /* API callbacks. */
1243 ot->exec = console_paste_exec;
1244
1245 /* properties */
1246 PropertyRNA *prop;
1247 prop = RNA_def_boolean(ot->srna,
1248 "selection",
1249 false,
1250 "Selection",
1251 "Paste text selected elsewhere rather than copied (X11/Wayland only)");
1253}
1254
1256 int sel_old[2];
1258};
1259
1261 ARegion *region,
1262 SetConsoleCursor *scu,
1263 const wmEvent *event)
1264{
1265 int pos = console_char_pick(sc, region, event->mval);
1266 bool dragging = event->type == MOUSEMOVE;
1267
1268 if (scu->sel_init == INT_MAX) {
1269 scu->sel_init = pos;
1270 sc->sel_start = sc->sel_end = pos;
1271 return;
1272 }
1273
1274 if (pos < scu->sel_init) {
1275 sc->sel_start = pos;
1276 sc->sel_end = scu->sel_init;
1277 }
1278 else if (pos > sc->sel_start) {
1279 sc->sel_start = scu->sel_init;
1280 sc->sel_end = pos;
1281 }
1282 else {
1283 sc->sel_start = sc->sel_end = pos;
1284 }
1285
1286 /* Move text cursor to the last selection point. */
1287 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1288
1289 if (cl != nullptr) {
1290 if (dragging && sc->sel_end > cl->len && pos <= cl->len) {
1291 /* Do not move cursor while dragging into the editable area. */
1292 }
1293 else if (pos <= cl->len) {
1294 console_line_cursor_set(cl, cl->len - pos);
1295 }
1296 else if (pos > cl->len && sc->sel_start < cl->len) {
1297 /* Dragging out of editable area, move cursor to start of selection. */
1298 console_line_cursor_set(cl, cl->len - sc->sel_start);
1299 }
1300 }
1301}
1302
1304{
1306 ScrArea *area = CTX_wm_area(C);
1308
1309 SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
1310 const int sel_prev[2] = {sc->sel_start, sc->sel_end};
1311
1312 console_cursor_set_to_pos(sc, region, scu, event);
1313
1314 /* only redraw if the selection changed */
1315 if (sel_prev[0] != sc->sel_start || sel_prev[1] != sc->sel_end) {
1316 ED_area_tag_redraw(area);
1317 }
1318}
1319
1321{
1323 SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
1324
1326
1327 MEM_freeN(scu);
1328}
1329
1331 wmOperator *op,
1332 const wmEvent *event)
1333{
1335 ScrArea *area = CTX_wm_area(C);
1337
1338 SetConsoleCursor *scu;
1339
1340 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1341 if (cl != nullptr) {
1342 const int pos = console_char_pick(sc, region, event->mval);
1343 if (pos >= 0 && pos <= cl->len) {
1344 /* Set text cursor immediately. */
1345 console_line_cursor_set(cl, cl->len - pos);
1346 }
1347 }
1348
1349 op->customdata = MEM_callocN(sizeof(SetConsoleCursor), "SetConsoleCursor");
1350 scu = static_cast<SetConsoleCursor *>(op->customdata);
1351
1352 scu->sel_old[0] = sc->sel_start;
1353 scu->sel_old[1] = sc->sel_end;
1354
1355 scu->sel_init = INT_MAX;
1356
1358
1359 console_modal_select_apply(C, op, event);
1360
1362}
1363
1365{
1366 /* Move text cursor to the last selection point. */
1367 switch (event->type) {
1368 case LEFTMOUSE:
1369 case MIDDLEMOUSE:
1370 case RIGHTMOUSE:
1371 if (event->val == KM_PRESS) {
1372 console_modal_select_apply(C, op, event);
1373 break;
1374 }
1375 else if (event->val == KM_RELEASE) {
1376 console_modal_select_apply(C, op, event);
1379 return OPERATOR_FINISHED;
1380 }
1381 break;
1382 case MOUSEMOVE:
1383 console_modal_select_apply(C, op, event);
1384 break;
1385 default: {
1386 break;
1387 }
1388 }
1389
1391}
1392
1397
1399{
1400 /* identifiers */
1401 ot->name = "Set Selection";
1402 ot->idname = "CONSOLE_OT_select_set";
1403 ot->description = "Set the console selection";
1404
1405 /* API callbacks. */
1406 ot->invoke = console_select_set_invoke;
1408 ot->cancel = console_select_set_cancel;
1410}
1411
1413 wmOperator * /*op*/,
1414 const wmEvent * /*event*/)
1415{
1416 ScrArea *area = CTX_wm_area(C);
1418
1419 int offset = strlen(sc->prompt);
1420
1422 offset += cl->len + 1;
1423 }
1424
1425 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1426 if (cl) {
1427 offset += cl->len + 1;
1428 }
1429
1430 sc->sel_start = 0;
1431 sc->sel_end = offset;
1432
1433 ED_area_tag_redraw(area);
1434
1435 return OPERATOR_FINISHED;
1436}
1437
1439{
1440 /* identifiers */
1441 ot->name = "Select All";
1442 ot->idname = "CONSOLE_OT_select_all";
1443 ot->description = "Select all the text";
1444
1445 /* API callbacks. */
1448}
1449
1451 wmOperator * /*op*/,
1452 const wmEvent *event)
1453{
1455 ScrArea *area = CTX_wm_area(C);
1457
1458 ConsoleLine cl_dummy = {nullptr};
1459 ConsoleLine *cl;
1461 int pos, offset, n;
1462
1463 pos = console_char_pick(sc, region, event->mval);
1464
1465 console_scrollback_prompt_begin(sc, &cl_dummy);
1466
1467 if (console_line_column_from_index(sc, pos, &cl, &offset, &n)) {
1468 int sel[2] = {n, n};
1469
1470 BLI_str_cursor_step_bounds_utf8(cl->line, cl->len, n, &sel[1], &sel[0]);
1471
1472 sel[0] = offset - sel[0];
1473 sel[1] = offset - sel[1];
1474
1475 if ((sel[0] != sc->sel_start) || (sel[1] != sc->sel_end)) {
1476 sc->sel_start = sel[0];
1477 sc->sel_end = sel[1];
1478 ED_area_tag_redraw(area);
1480 }
1481 }
1482
1483 console_scrollback_prompt_end(sc, &cl_dummy);
1484
1485 ConsoleLine *ci = static_cast<ConsoleLine *>(sc->history.last);
1486 if (ci && sc->sel_start <= ci->len) {
1487 console_line_cursor_set(ci, ci->len - sc->sel_start);
1488 }
1489
1490 if (ret & OPERATOR_FINISHED) {
1492 }
1493
1494 return ret;
1495}
1496
1498{
1499 /* identifiers */
1500 ot->name = "Select Word";
1501 ot->description = "Select word at cursor position";
1502 ot->idname = "CONSOLE_OT_select_word";
1503
1504 /* API callbacks. */
1505 ot->invoke = console_selectword_invoke;
1507}
SpaceConsole * CTX_wm_space_console(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
Definition screen.cc:846
#define BLI_assert(a)
Definition BLI_assert.h:46
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL()
Definition BLI_dynstr.cc:75
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:37
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.cc:56
#define LISTBASE_FOREACH(type, var, list)
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
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:30
char char size_t char const char * BLI_strchr_or_end(const char *str, char ch) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition string.cc:931
@ STRCUR_DIR_NEXT
@ STRCUR_DIR_PREV
void BLI_str_cursor_step_utf8(const char *str, int str_maxlen, int *pos, eStrCursorJumpDirection direction, eStrCursorJumpType jump, bool use_init_step)
void BLI_str_cursor_step_bounds_utf8(const char *str, int str_maxlen, int pos, int *r_start, int *r_end)
@ STRCUR_JUMP_ALL
@ STRCUR_JUMP_NONE
@ STRCUR_JUMP_DELIM
#define BLI_UTF8_MAX
int BLI_str_utf8_size_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define ELEM(...)
#define STREQ(a, b)
@ RGN_TYPE_WINDOW
@ CONSOLE_LINE_INFO
@ CONSOLE_LINE_ERROR
@ CONSOLE_LINE_INPUT
@ CONSOLE_LINE_OUTPUT
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:693
bool ED_operator_console_active(bContext *C)
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
#define C
Definition RandGen.cpp:29
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
Definition view2d.cc:1036
@ WM_CAPABILITY_CLIPBOARD_PRIMARY
Definition WM_api.hh:189
@ KM_CTRL
Definition WM_types.hh:279
@ KM_OSKEY
Definition WM_types.hh:282
@ KM_PRESS
Definition WM_types.hh:311
@ KM_RELEASE
Definition WM_types.hh:312
#define U
#define NEXT_CHAR(fmt)
nullptr float
void console_scrollback_prompt_end(SpaceConsole *sc, ConsoleLine *cl_dummy)
int console_textview_height(SpaceConsole *sc, const ARegion *region)
void console_scrollback_prompt_begin(SpaceConsole *sc, ConsoleLine *cl_dummy)
int console_char_pick(SpaceConsole *sc, const ARegion *region, const int mval[2])
static bool console_line_cursor_set(ConsoleLine *cl, int cursor)
void CONSOLE_OT_select_all(wmOperatorType *ot)
static ConsoleLine * console_history_add(SpaceConsole *sc, ConsoleLine *from)
static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEvent *event)
static void console_select_update_primary_clipboard(SpaceConsole *sc)
static void console_line_verify_length(ConsoleLine *ci, int len)
static wmOperatorStatus console_selectword_invoke(bContext *C, wmOperator *, const wmEvent *event)
static wmOperatorStatus console_scrollback_append_exec(bContext *C, wmOperator *op)
static void console_select_set_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus console_select_set_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus console_insert_exec(bContext *C, wmOperator *op)
void CONSOLE_OT_copy(wmOperatorType *ot)
void CONSOLE_OT_clear(wmOperatorType *ot)
static wmOperatorStatus console_modal_select_all_invoke(bContext *C, wmOperator *, const wmEvent *)
static wmOperatorStatus console_clear_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem console_move_type_items[]
static const EnumPropertyItem console_delete_type_items[]
static wmOperatorStatus console_history_append_exec(bContext *C, wmOperator *op)
static bool console_line_column_from_index(SpaceConsole *sc, const int pos, ConsoleLine **r_cl, int *r_cl_offset, int *r_col)
static wmOperatorStatus console_paste_exec(bContext *C, wmOperator *op)
void console_textview_update_rect(SpaceConsole *sc, ARegion *region)
#define TAB_LENGTH
static wmOperatorStatus console_unindent_exec(bContext *C, wmOperator *)
static void console_cursor_set_exit(bContext *C, wmOperator *op)
void CONSOLE_OT_select_word(wmOperatorType *ot)
void CONSOLE_OT_delete(wmOperatorType *ot)
static char * console_select_to_buffer(SpaceConsole *sc)
void CONSOLE_OT_indent(wmOperatorType *ot)
void CONSOLE_OT_select_set(wmOperatorType *ot)
static void console_scrollback_limit(SpaceConsole *sc)
void CONSOLE_OT_indent_or_autocomplete(wmOperatorType *ot)
void CONSOLE_OT_move(wmOperatorType *ot)
static wmOperatorStatus console_copy_exec(bContext *C, wmOperator *op)
static void console_scroll_bottom(ARegion *region)
void console_history_free(SpaceConsole *sc, ConsoleLine *cl)
void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl)
void CONSOLE_OT_clear_line(wmOperatorType *ot)
void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
void CONSOLE_OT_insert(wmOperatorType *ot)
static ConsoleLine * console_lb_add__internal(ListBase *lb, ConsoleLine *from)
static wmOperatorStatus console_history_cycle_exec(bContext *C, wmOperator *op)
ConsoleLine * console_history_add_str(SpaceConsole *sc, char *str, bool own)
static void console_line_insert(ConsoleLine *ci, const char *str, int len)
static ConsoleLine * console_lb_add_str__internal(ListBase *lb, char *str, bool own)
static bool console_copy_poll(bContext *C)
void CONSOLE_OT_history_cycle(wmOperatorType *ot)
void CONSOLE_OT_unindent(wmOperatorType *ot)
void CONSOLE_OT_history_append(wmOperatorType *ot)
static wmOperatorStatus console_select_set_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int console_delete_editable_selection(SpaceConsole *sc)
static wmOperatorStatus console_indent_exec(bContext *C, wmOperator *)
static wmOperatorStatus console_clear_line_exec(bContext *C, wmOperator *)
void CONSOLE_OT_paste(wmOperatorType *ot)
static wmOperatorStatus console_indent_or_autocomplete_exec(bContext *C, wmOperator *)
static wmOperatorStatus console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ConsoleLine * console_history_verify(const bContext *C)
static void console_cursor_set_to_pos(SpaceConsole *sc, ARegion *region, SetConsoleCursor *scu, const wmEvent *event)
static wmOperatorStatus console_move_exec(bContext *C, wmOperator *op)
static void console_select_offset(SpaceConsole *sc, const int offset)
static wmOperatorStatus console_delete_exec(bContext *C, wmOperator *op)
ConsoleLine * console_scrollback_add_str(SpaceConsole *sc, char *str, bool own)
@ DEL_PREV_WORD
@ DEL_PREV_CHAR
@ DEL_NEXT_WORD
@ DEL_NEXT_CHAR
@ LINE_BEGIN
@ PREV_WORD
@ PREV_CHAR
@ LINE_END
@ NEXT_WORD
#define str(s)
uint pos
#define printf(...)
#define select(A, B, C)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition mallocn.cc:41
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
return ret
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
int RNA_string_length(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
struct ConsoleLine * next
struct ConsoleLine * prev
void * last
void * first
ListBase scrollback
float ymax
float ymin
wmEventModifierFlag modifier
Definition WM_types.hh:774
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
char utf8_buf[6]
Definition WM_types.hh:771
int mval[2]
Definition WM_types.hh:763
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
uint len
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
wmOperatorStatus WM_operator_name_call(bContext *C, const char *opstring, blender::wm::OpCallContext context, PointerRNA *properties, const wmEvent *event)
@ RIGHTMOUSE
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
wmOperatorType * ot
Definition wm_files.cc:4237
void WM_clipboard_text_set(const char *buf, bool selection)
char * WM_clipboard_text_get(bool selection, bool ensure_utf8, int *r_len)
eWM_CapabilitiesFlag WM_capabilities_flag()