Blender V4.5
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_string.h"
23#include "BLI_string_utf8.h"
24#include "BLI_utildefines.h"
25
26#include "BKE_context.hh"
27#include "BKE_report.hh"
28#include "BKE_screen.hh"
29
30#include "WM_api.hh"
31#include "WM_types.hh"
32
33#include "ED_screen.hh"
34#include "UI_view2d.hh"
35
36#include "RNA_access.hh"
37#include "RNA_define.hh"
38
39#include "console_intern.hh"
40
41#define TAB_LENGTH 4
42
43/* -------------------------------------------------------------------- */
46
48{
49 if (sc->sel_start == sc->sel_end) {
50 return nullptr;
51 }
52
53 ConsoleLine cl_dummy = {nullptr};
55
56 int offset = 0;
58 offset += cl->len + 1;
59 }
60
61 char *buf_str = nullptr;
62 if (offset != 0) {
63 offset -= 1;
64 int sel[2] = {offset - sc->sel_end, offset - sc->sel_start};
65 DynStr *buf_dyn = BLI_dynstr_new();
67 if (sel[0] <= cl->len && sel[1] >= 0) {
68 int sta = max_ii(sel[0], 0);
69 int end = min_ii(sel[1], cl->len);
70
71 if (BLI_dynstr_get_len(buf_dyn)) {
72 BLI_dynstr_append(buf_dyn, "\n");
73 }
74
75 BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
76 }
77
78 sel[0] -= cl->len + 1;
79 sel[1] -= cl->len + 1;
80 }
81
82 buf_str = BLI_dynstr_get_cstring(buf_dyn);
83
84 BLI_dynstr_free(buf_dyn);
85 }
86 console_scrollback_prompt_end(sc, &cl_dummy);
87
88 return buf_str;
89}
90
92{
94 return;
95 }
96 if (sc->sel_start == sc->sel_end) {
97 return;
98 }
99 char *buf = console_select_to_buffer(sc);
100 if (buf == nullptr) {
101 return;
102 }
103 WM_clipboard_text_set(buf, true);
104 MEM_freeN(buf);
105}
106
107/* Delete selected characters in the edit line. */
109{
110 if (sc->sel_start == sc->sel_end) {
111 return 0;
112 }
113
114 sc->sel_start = std::max(sc->sel_start, 0);
115
116 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
117 if (!cl || sc->sel_start > cl->len) {
118 sc->sel_start = sc->sel_end;
119 return 0;
120 }
121
122 int del_start = sc->sel_start;
123 int del_end = sc->sel_end;
124
125 del_end = std::min(del_end, cl->len);
126
127 const int len = del_end - del_start;
128 memmove(cl->line + cl->len - del_end, cl->line + cl->len - del_start, del_start);
129 cl->len -= len;
130 cl->line[cl->len] = 0;
131 cl->cursor = cl->len - del_start;
132
133 sc->sel_start = sc->sel_end = cl->cursor;
134 return len;
135}
136
138
139/* so when we type - the view scrolls to the bottom */
140static void console_scroll_bottom(ARegion *region)
141{
142 View2D *v2d = &region->v2d;
143 v2d->cur.ymin = 0.0;
144 v2d->cur.ymax = float(v2d->winy);
145}
146
148{
149 View2D *v2d = &region->v2d;
150
151 UI_view2d_totRect_set(v2d, region->winx - 1, console_textview_height(sc, region));
152}
153
154static void console_select_offset(SpaceConsole *sc, const int offset)
155{
156 sc->sel_start += offset;
157 sc->sel_end += offset;
158}
159
161{
162 BLI_remlink(&sc->history, cl);
163 MEM_freeN(cl->line);
164 MEM_freeN(cl);
165}
167{
168 BLI_remlink(&sc->scrollback, cl);
169 MEM_freeN(cl->line);
170 MEM_freeN(cl);
171}
172
174{
175 int tot;
176
177 for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--) {
178 console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
179 }
180}
181
182/* return 0 if no change made, clamps the range */
183static bool console_line_cursor_set(ConsoleLine *cl, int cursor)
184{
185 int cursor_new;
186
187 if (cursor < 0) {
188 cursor_new = 0;
189 }
190 else if (cursor > cl->len) {
191 cursor_new = cl->len;
192 }
193 else {
194 cursor_new = cursor;
195 }
196
197 if (cursor_new == cl->cursor) {
198 return false;
199 }
200
201 cl->cursor = cursor_new;
202 return true;
203}
204
205#if 0 /* XXX unused */
206static void console_lb_debug__internal(ListBase *lb)
207{
208 ConsoleLine *cl;
209
210 printf("%d: ", BLI_listbase_count(lb));
211 for (cl = lb->first; cl; cl = cl->next) {
212 printf("<%s> ", cl->line);
213 }
214 printf("\n");
215}
216
217static void console_history_debug(const bContext *C)
218{
220
221 console_lb_debug__internal(&sc->history);
222}
223#endif
224
226{
227 ConsoleLine *ci = MEM_callocN<ConsoleLine>("ConsoleLine Add");
228
229 if (from) {
230 BLI_assert(strlen(from->line) == from->len);
231 ci->line = BLI_strdupn(from->line, from->len);
232 ci->len = ci->len_alloc = from->len;
233 ci->cursor = from->cursor;
234 ci->type = from->type;
235 }
236 else {
237 ci->line = MEM_calloc_arrayN<char>(64, "console-in-line");
238 ci->len_alloc = 64;
239 ci->len = 0;
240 }
241
242 BLI_addtail(lb, ci);
243 return ci;
244}
245
247{
248 return console_lb_add__internal(&sc->history, from);
249}
250
251#if 0 /* may use later ? */
252static ConsoleLine *console_scrollback_add(const bContext *C, ConsoleLine *from)
253{
255
256 return console_lb_add__internal(&sc->scrollback, from);
257}
258#endif
259
261{
262 ConsoleLine *ci = MEM_callocN<ConsoleLine>("ConsoleLine Add");
263 const int str_len = strlen(str);
264 if (own) {
265 ci->line = str;
266 }
267 else {
268 ci->line = BLI_strdupn(str, str_len);
269 }
270
271 ci->len = ci->len_alloc = str_len;
272
273 BLI_addtail(lb, ci);
274 return ci;
275}
277{
278 return console_lb_add_str__internal(&sc->history, str, own);
279}
281{
283 console_select_offset(sc, ci->len + 1);
284 return ci;
285}
286
288{
290 ConsoleLine *ci = static_cast<ConsoleLine *>(sc->history.last);
291 if (ci == nullptr) {
292 ci = console_history_add(sc, nullptr);
293 }
294
295 return ci;
296}
297
299{
300 /* resize the buffer if needed */
301 if (len >= ci->len_alloc) {
302 /* new length */
303#ifndef NDEBUG
304 int new_len = len + 1;
305#else
306 int new_len = (len + 1) * 2;
307#endif
308 ci->line = static_cast<char *>(MEM_recallocN_id(ci->line, new_len, "console line"));
309 ci->len_alloc = new_len;
310 }
311}
312
313static void console_line_insert(ConsoleLine *ci, const char *str, int len)
314{
315 if (len == 0) {
316 return;
317 }
318
319 BLI_assert(len <= strlen(str));
320 /* The caller must delimit new-lines. */
321 BLI_assert(str[len - 1] != '\n');
322
324
325 memmove(ci->line + ci->cursor + len, ci->line + ci->cursor, (ci->len - ci->cursor) + 1);
326 memcpy(ci->line + ci->cursor, str, len);
327
328 ci->len += len;
329 ci->cursor += len;
330}
331
338 SpaceConsole *sc, const int pos, ConsoleLine **r_cl, int *r_cl_offset, int *r_col)
339{
340 ConsoleLine *cl;
341 int offset = 0;
342
343 for (cl = static_cast<ConsoleLine *>(sc->scrollback.last); cl; cl = cl->prev) {
344 offset += cl->len + 1;
345 if (offset > pos) {
346 break;
347 }
348 }
349
350 if (cl) {
351 offset -= 1;
352 *r_cl = cl;
353 *r_cl_offset = offset;
354 *r_col = offset - pos;
355 return true;
356 }
357
358 *r_cl = nullptr;
359 *r_cl_offset = -1;
360 *r_col = -1;
361 return false;
362}
363
364/* Static functions for text editing. */
365
366/* similar to the text editor, with some not used. keep compatible */
368 {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
369 {LINE_END, "LINE_END", 0, "Line End", ""},
370 {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
371 {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
372 {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
373 {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
374 {0, nullptr, 0, nullptr, nullptr},
375};
376
378{
381 ScrArea *area = CTX_wm_area(C);
383
384 int type = RNA_enum_get(op->ptr, "type");
385 const bool select = RNA_boolean_get(op->ptr, "select");
386
387 bool done = false;
388 const int old_pos = ci->cursor;
389 int pos = 0;
390
391 if (!select && sc->sel_start != sc->sel_end) {
392 /* Clear selection if we are not extending it. */
393 sc->sel_start = sc->sel_end;
394 }
395 const bool had_select = sc->sel_start != sc->sel_end;
396
397 int select_side = 0;
398 if (had_select) {
399 if (sc->sel_start == ci->len - old_pos) {
400 select_side = -1;
401 }
402 else if (sc->sel_end == ci->len - old_pos) {
403 select_side = 1;
404 }
405 }
406
407 switch (type) {
408 case LINE_BEGIN:
409 pos = ci->cursor;
411 done = console_line_cursor_set(ci, pos);
412 break;
413 case LINE_END:
414 pos = ci->cursor;
416 done = console_line_cursor_set(ci, pos);
417 break;
418 case PREV_CHAR:
419 pos = ci->cursor;
421 done = console_line_cursor_set(ci, pos);
422 break;
423 case NEXT_CHAR:
424 pos = ci->cursor;
426 done = console_line_cursor_set(ci, pos);
427 break;
428
429 /* - if the character is a delimiter then skip delimiters (including white space)
430 * - when jump over the word */
431 case PREV_WORD:
432 pos = ci->cursor;
434 done = console_line_cursor_set(ci, pos);
435 break;
436 case NEXT_WORD:
437 pos = ci->cursor;
439 done = console_line_cursor_set(ci, pos);
440 break;
441 }
442
443 if (select) {
444 if (had_select) {
445 if (select_side != 0) {
446 /* Modify the current selection if either side was was positioned at the cursor. */
447 if (select_side == -1) {
448 sc->sel_start = ci->len - pos;
449 }
450 else if (select_side == 1) {
451 sc->sel_end = ci->len - pos;
452 }
453 if (sc->sel_start > sc->sel_end) {
454 std::swap(sc->sel_start, sc->sel_end);
455 }
456 }
457 }
458 else {
459 /* Create a new selection. */
460 if (old_pos > pos) {
461 sc->sel_start = ci->len - old_pos;
462 sc->sel_end = ci->len - pos;
463 BLI_assert(sc->sel_start < sc->sel_end);
464 }
465 else if (old_pos < pos) {
466 sc->sel_start = ci->len - pos;
467 sc->sel_end = ci->len - old_pos;
468 BLI_assert(sc->sel_start < sc->sel_end);
469 }
470 }
471 }
472
473 if (done) {
474 ED_area_tag_redraw(area);
475 console_scroll_bottom(region);
476 }
477
478 return OPERATOR_FINISHED;
479}
480
482{
483 /* identifiers */
484 ot->name = "Move Cursor";
485 ot->description = "Move cursor position";
486 ot->idname = "CONSOLE_OT_move";
487
488 /* API callbacks. */
489 ot->exec = console_move_exec;
491
492 /* properties */
494 ot->srna, "type", console_move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
496 ot->srna, "select", false, "Select", "Whether to select while moving");
498}
499
501{
503 ScrArea *area = CTX_wm_area(C);
506 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
507 int len = strlen(str);
508
509 /* Allow trailing newlines (but strip them). */
510 while (len > 0 && str[len - 1] == '\n') {
511 len--;
512 str[len] = '\0';
513 }
514
515 if (strchr(str, '\n')) {
516 BKE_report(op->reports, RPT_ERROR, "New lines unsupported, call this operator multiple times");
517 /* Force cancel. */
518 len = 0;
519 }
520
521 if (len != 0) {
524 }
525
526 MEM_freeN(str);
527
528 if (len == 0) {
529 return OPERATOR_CANCELLED;
530 }
531
533
535 ED_area_tag_redraw(area);
536
537 console_scroll_bottom(region);
538
539 return OPERATOR_FINISHED;
540}
541
543{
544 /* NOTE: the "text" property is always set from key-map,
545 * so we can't use #RNA_struct_property_is_set, check the length instead. */
546 if (!RNA_string_length(op->ptr, "text")) {
547 /* If alt/control/super are pressed pass through except for UTF8 character event
548 * (when input method are used for UTF8 inputs, the user may assign key event
549 * including alt/control/super like control-m to commit UTF8 string.
550 * in such case, the modifiers in the UTF8 character event make no sense.) */
551 if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
553 }
554
555 char str[BLI_UTF8_MAX + 1];
556 const size_t len = BLI_str_utf8_size_safe(event->utf8_buf);
557 memcpy(str, event->utf8_buf, len);
558 str[len] = '\0';
559 RNA_string_set(op->ptr, "text", str);
560 }
561 return console_insert_exec(C, op);
562}
563
565{
566 PropertyRNA *prop;
567
568 /* identifiers */
569 ot->name = "Insert";
570 ot->description = "Insert text at cursor position";
571 ot->idname = "CONSOLE_OT_insert";
572
573 /* API callbacks. */
574 ot->exec = console_insert_exec;
575 ot->invoke = console_insert_invoke;
577
578 /* properties */
579 prop = RNA_def_string(
580 ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
582}
583
584/* -------------------------------------------------------------------- */
587
589{
591 bool text_before_cursor = false;
592
593 /* Check any text before cursor (not just the previous character) as is done for
594 * #TEXT_OT_indent_or_autocomplete because Python auto-complete operates on import
595 * statements such as completing possible sub-modules: `from bpy import `. */
596 for (int i = 0; i < ci->cursor; i += BLI_str_utf8_size_safe(&ci->line[i])) {
597 if (!ELEM(ci->line[i], ' ', '\t')) {
598 text_before_cursor = true;
599 break;
600 }
601 }
602
603 if (text_before_cursor) {
604 WM_operator_name_call(C, "CONSOLE_OT_autocomplete", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
605 }
606 else {
607 WM_operator_name_call(C, "CONSOLE_OT_indent", WM_OP_EXEC_DEFAULT, nullptr, nullptr);
608 }
609 return OPERATOR_FINISHED;
610}
611
613{
614 /* identifiers */
615 ot->name = "Indent or Autocomplete";
616 ot->idname = "CONSOLE_OT_indent_or_autocomplete";
617 ot->description = "Indent selected text or autocomplete";
618
619 /* API callbacks. */
622
623 /* flags */
624 ot->flag = 0;
625}
626
628
629/* -------------------------------------------------------------------- */
632
634{
637 ScrArea *area = CTX_wm_area(C);
639
640 int spaces;
641 int len;
642
643 for (spaces = 0; spaces < ci->len; spaces++) {
644 if (ci->line[spaces] != ' ') {
645 break;
646 }
647 }
648
649 len = TAB_LENGTH - spaces % TAB_LENGTH;
650
652
653 memmove(ci->line + len, ci->line, ci->len + 1);
654 memset(ci->line, ' ', len);
655 ci->len += len;
656 BLI_assert(ci->len >= 0);
659
661 ED_area_tag_redraw(area);
662
663 console_scroll_bottom(region);
664
665 return OPERATOR_FINISHED;
666}
667
669{
670 /* identifiers */
671 ot->name = "Indent";
672 ot->description = "Add 4 spaces at line beginning";
673 ot->idname = "CONSOLE_OT_indent";
674
675 /* API callbacks. */
676 ot->exec = console_indent_exec;
678}
679
681
683{
686 ScrArea *area = CTX_wm_area(C);
688
689 int spaces;
690 int len;
691
692 for (spaces = 0; spaces < ci->len; spaces++) {
693 if (ci->line[spaces] != ' ') {
694 break;
695 }
696 }
697
698 if (spaces == 0) {
699 return OPERATOR_CANCELLED;
700 }
701
702 len = spaces % TAB_LENGTH;
703 if (len == 0) {
704 len = TAB_LENGTH;
705 }
706
708
709 memmove(ci->line, ci->line + len, (ci->len - len) + 1);
710 ci->len -= len;
711 BLI_assert(ci->len >= 0);
712
715
717 ED_area_tag_redraw(area);
718
719 console_scroll_bottom(region);
720
721 return OPERATOR_FINISHED;
722}
723
725{
726 /* identifiers */
727 ot->name = "Unindent";
728 ot->description = "Delete 4 spaces from line beginning";
729 ot->idname = "CONSOLE_OT_unindent";
730
731 /* API callbacks. */
734}
735
737 {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
738 {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
739 {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
740 {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
741 {0, nullptr, 0, nullptr, nullptr},
742};
743
745{
748 ScrArea *area = CTX_wm_area(C);
750
751 int pos;
752 int stride;
753
754 const short type = RNA_enum_get(op->ptr, "type");
755 bool done = false;
756
757 if (ci->len == 0) {
758 return OPERATOR_CANCELLED;
759 }
760
761 /* If there is a selection just delete it and nothing else. */
762 if (sc->sel_start != sc->sel_end && console_delete_editable_selection(sc) > 0) {
764 ED_area_tag_redraw(area);
765 console_scroll_bottom(region);
766 return OPERATOR_FINISHED;
767 }
768
769 switch (type) {
770 case DEL_NEXT_CHAR:
771 case DEL_NEXT_WORD:
772 if (ci->cursor < ci->len) {
773 pos = ci->cursor;
775 ci->len,
776 &pos,
779 true);
780 stride = pos - ci->cursor;
781 if (stride) {
782 memmove(ci->line + ci->cursor,
783 ci->line + ci->cursor + stride,
784 (ci->len - (ci->cursor + stride)) + 1);
785 ci->len -= stride;
786 BLI_assert(ci->len >= 0);
787 done = true;
788 }
789 }
790 break;
791 case DEL_PREV_CHAR:
792 case DEL_PREV_WORD:
793 if (ci->cursor > 0) {
794 pos = ci->cursor;
796 ci->len,
797 &pos,
800 true);
801 stride = ci->cursor - pos;
802 if (stride) {
803 ci->cursor -= stride; /* same as above */
804 memmove(ci->line + ci->cursor,
805 ci->line + ci->cursor + stride,
806 (ci->len - (ci->cursor + stride)) + 1);
807 ci->len -= stride;
808 BLI_assert(ci->len >= 0);
809 done = true;
810 }
811 }
812 break;
813 }
814
815 if (!done) {
816 return OPERATOR_CANCELLED;
817 }
818
819 console_select_offset(sc, -stride);
820
822 ED_area_tag_redraw(area);
823
824 console_scroll_bottom(region);
825
826 return OPERATOR_FINISHED;
827}
828
830{
831 /* identifiers */
832 ot->name = "Delete";
833 ot->description = "Delete text by cursor position";
834 ot->idname = "CONSOLE_OT_delete";
835
836 /* API callbacks. */
837 ot->exec = console_delete_exec;
839
840 /* properties */
841 RNA_def_enum(ot->srna,
842 "type",
845 "Type",
846 "Which part of the text to delete");
847}
848
850{
853 ScrArea *area = CTX_wm_area(C);
855
856 if (ci->len == 0) {
857 return OPERATOR_CANCELLED;
858 }
859
860 console_history_add(sc, ci);
861 console_history_add(sc, nullptr);
862 console_select_offset(sc, -ci->len);
863
865
866 ED_area_tag_redraw(area);
867
868 console_scroll_bottom(region);
869
870 return OPERATOR_FINISHED;
871}
872
874{
875 /* identifiers */
876 ot->name = "Clear Line";
877 ot->description = "Clear the line and store in history";
878 ot->idname = "CONSOLE_OT_clear_line";
879
880 /* API callbacks. */
883}
884
885/* the python exec operator uses this */
887{
889 ScrArea *area = CTX_wm_area(C);
891
892 const bool scrollback = RNA_boolean_get(op->ptr, "scrollback");
893 const bool history = RNA_boolean_get(op->ptr, "history");
894
895 /* ConsoleLine *ci = */ console_history_verify(C);
896
897 if (scrollback) { /* Last item in history. */
898 while (sc->scrollback.first) {
899 console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
900 }
901 }
902
903 if (history) {
904 while (sc->history.first) {
905 console_history_free(sc, static_cast<ConsoleLine *>(sc->history.first));
906 }
908 }
909
911 ED_area_tag_redraw(area);
912
913 return OPERATOR_FINISHED;
914}
915
917{
918 /* identifiers */
919 ot->name = "Clear All";
920 ot->description = "Clear text by type";
921 ot->idname = "CONSOLE_OT_clear";
922
923 /* API callbacks. */
924 ot->exec = console_clear_exec;
926
927 /* properties */
928 RNA_def_boolean(ot->srna, "scrollback", true, "Scrollback", "Clear the scrollback history");
929 RNA_def_boolean(ot->srna, "history", false, "History", "Clear the command history");
930}
931
932/* the python exec operator uses this */
934{
936 ScrArea *area = CTX_wm_area(C);
938
939 /* TODO: stupid, just prevents crashes when no command line. */
941 const bool reverse = RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */
942 int prev_len = ci->len;
943
944 int old_index = sc->history_index;
945 int new_index;
946 if (reverse) {
947 if (old_index <= 0) {
948 new_index = 1;
949 }
950 else {
951 new_index = old_index + 1;
952 }
953 }
954 else {
955 if (old_index <= 0) { /* Down-arrow after exec. */
956 new_index = -old_index;
957 }
958 else {
959 new_index = old_index - 1;
960 }
961 }
962
963 /* Find the history item. */
964 ConsoleLine *ci_prev = ci;
965 if (old_index > 0) {
966 /* Skip a previous copy of history item. */
967 if (ci_prev->prev) {
968 ci_prev = ci_prev->prev;
969 }
970 else { /* Just in case the duplicate item got deleted. */
971 old_index = 0;
972 }
973 }
974 for (int i = 0; i < new_index; i++) {
975 if (!ci_prev->prev) {
976 new_index = i;
977 break;
978 }
979 ci_prev = ci_prev->prev;
980 }
981
982 sc->history_index = new_index;
983
984 if (old_index > 0) { /* Remove old copy. */
985 console_history_free(sc, ci);
986 ci = ci_prev;
987 }
988 if (new_index > 0) { /* Copy history item to the end. */
989 ci = console_history_add(sc, ci_prev);
990 }
991
992 console_select_offset(sc, ci->len - prev_len);
993
994 /* could be wrapped so update scroll rect */
996 ED_area_tag_redraw(area);
997
998 console_scroll_bottom(region);
999
1000 return OPERATOR_FINISHED;
1001}
1002
1004{
1005 /* identifiers */
1006 ot->name = "History Cycle";
1007 ot->description = "Cycle through history";
1008 ot->idname = "CONSOLE_OT_history_cycle";
1009
1010 /* API callbacks. */
1013
1014 /* properties */
1015 RNA_def_boolean(ot->srna, "reverse", false, "Reverse", "Reverse cycle history");
1016}
1017
1018/* the python exec operator uses this */
1020{
1022 ScrArea *area = CTX_wm_area(C);
1024
1026 /* own this text in the new line, don't free */
1027 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
1028 int cursor = RNA_int_get(op->ptr, "current_character");
1029 const bool rem_dupes = RNA_boolean_get(op->ptr, "remove_duplicates");
1030 int prev_len = ci->len;
1031
1032 if (sc->history_index > 0) {
1033 /* Keep the copy of history item, remove the saved "history 0". */
1034 ConsoleLine *cl = ci->prev;
1035 if (cl) {
1036 console_history_free(sc, cl);
1037 }
1038 /* Negative number makes down-arrow go to same item as before. */
1039 sc->history_index = -sc->history_index;
1040 }
1041
1042 if (rem_dupes) {
1043 /* Remove a repeated command. */
1044 ConsoleLine *cl = ci->prev;
1045 if (cl && STREQ(cl->line, ci->line)) {
1046 console_history_free(sc, cl);
1047 }
1048 /* Remove blank command. */
1049 if (STREQ(str, ci->line)) {
1050 MEM_freeN(str);
1051 return OPERATOR_FINISHED;
1052 }
1053 }
1054
1055 ci = console_history_add_str(sc, str, true); /* own the string */
1056 console_select_offset(sc, ci->len - prev_len);
1057 console_line_cursor_set(ci, cursor);
1058
1059 ED_area_tag_redraw(area);
1060 console_scroll_bottom(region);
1061
1062 return OPERATOR_FINISHED;
1063}
1064
1066{
1067 /* identifiers */
1068 ot->name = "History Append";
1069 ot->description = "Append history at cursor position";
1070 ot->idname = "CONSOLE_OT_history_append";
1071
1072 /* API callbacks. */
1075
1076 /* properties */
1077 RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
1079 ot->srna, "current_character", 0, 0, INT_MAX, "Cursor", "The index of the cursor", 0, 10000);
1080 RNA_def_boolean(ot->srna,
1081 "remove_duplicates",
1082 false,
1083 "Remove Duplicates",
1084 "Remove duplicate items in the history");
1085}
1086
1087/* the python exec operator uses this */
1089{
1091 ConsoleLine *ci;
1092 ScrArea *area = CTX_wm_area(C);
1094
1095 /* own this text in the new line, don't free */
1096 char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
1097 int type = RNA_enum_get(op->ptr, "type");
1098
1100
1101 ci = console_scrollback_add_str(sc, str, true); /* own the string */
1102 ci->type = type;
1103
1105
1106 console_textview_update_rect(sc, region);
1107 ED_area_tag_redraw(area);
1108
1109 return OPERATOR_FINISHED;
1110}
1111
1113{
1114 /* defined in DNA_space_types.h */
1115 static const EnumPropertyItem console_line_type_items[] = {
1116 {CONSOLE_LINE_OUTPUT, "OUTPUT", 0, "Output", ""},
1117 {CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""},
1118 {CONSOLE_LINE_INFO, "INFO", 0, "Information", ""},
1119 {CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""},
1120 {0, nullptr, 0, nullptr, nullptr},
1121 };
1122
1123 /* identifiers */
1124 ot->name = "Scrollback Append";
1125 ot->description = "Append scrollback text by type";
1126 ot->idname = "CONSOLE_OT_scrollback_append";
1127
1128 /* API callbacks. */
1131
1132 /* properties */
1133 RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
1134 RNA_def_enum(ot->srna,
1135 "type",
1136 console_line_type_items,
1138 "Type",
1139 "Console output type");
1140}
1141
1143{
1145 char *buf = console_select_to_buffer(sc);
1146 if (buf == nullptr) {
1147 return OPERATOR_CANCELLED;
1148 }
1149
1150 WM_clipboard_text_set(buf, false);
1151
1152 if (RNA_boolean_get(op->ptr, "delete")) {
1155 }
1156
1157 MEM_freeN(buf);
1158 return OPERATOR_FINISHED;
1159}
1160
1162{
1164 return ED_operator_console_active(C) && sc && (sc->sel_start != sc->sel_end);
1165}
1166
1168{
1169 /* identifiers */
1170 ot->name = "Copy to Clipboard";
1171 ot->description = "Copy selected text to clipboard";
1172 ot->idname = "CONSOLE_OT_copy";
1173
1174 /* API callbacks. */
1175 ot->poll = console_copy_poll;
1176 ot->exec = console_copy_exec;
1177
1178 /* properties */
1179 PropertyRNA *prop = RNA_def_boolean(ot->srna,
1180 "delete",
1181 false,
1182 "Delete Selection",
1183 "Whether to delete the selection after copying");
1185}
1186
1188{
1189 const bool selection = RNA_boolean_get(op->ptr, "selection");
1192 ScrArea *area = CTX_wm_area(C);
1194
1195 int buf_str_len;
1196
1197 char *buf_str = WM_clipboard_text_get(selection, true, &buf_str_len);
1198 if (buf_str == nullptr) {
1199 return OPERATOR_CANCELLED;
1200 }
1201 if (*buf_str == '\0') {
1202 MEM_freeN(buf_str);
1203 return OPERATOR_CANCELLED;
1204 }
1205 const char *buf_step = buf_str;
1206 do {
1207 const char *buf = buf_step;
1208 buf_step = (char *)BLI_strchr_or_end(buf, '\n');
1209 const int buf_len = buf_step - buf;
1210 if (buf != buf_str) {
1211 WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, nullptr, nullptr);
1213 }
1215 console_line_insert(ci, buf, buf_len);
1216 console_select_offset(sc, buf_len);
1217 } while (*buf_step ? ((void)buf_step++, true) : false);
1218
1219 MEM_freeN(buf_str);
1220
1221 console_textview_update_rect(sc, region);
1222 ED_area_tag_redraw(area);
1223
1224 console_scroll_bottom(region);
1225
1226 return OPERATOR_FINISHED;
1227}
1228
1230{
1231 /* identifiers */
1232 ot->name = "Paste from Clipboard";
1233 ot->description = "Paste text from clipboard";
1234 ot->idname = "CONSOLE_OT_paste";
1235
1236 /* API callbacks. */
1238 ot->exec = console_paste_exec;
1239
1240 /* properties */
1241 PropertyRNA *prop;
1242 prop = RNA_def_boolean(ot->srna,
1243 "selection",
1244 false,
1245 "Selection",
1246 "Paste text selected elsewhere rather than copied (X11/Wayland only)");
1248}
1249
1251 int sel_old[2];
1253};
1254
1256 ARegion *region,
1257 SetConsoleCursor *scu,
1258 const wmEvent *event)
1259{
1260 int pos = console_char_pick(sc, region, event->mval);
1261 bool dragging = event->type == MOUSEMOVE;
1262
1263 if (scu->sel_init == INT_MAX) {
1264 scu->sel_init = pos;
1265 sc->sel_start = sc->sel_end = pos;
1266 return;
1267 }
1268
1269 if (pos < scu->sel_init) {
1270 sc->sel_start = pos;
1271 sc->sel_end = scu->sel_init;
1272 }
1273 else if (pos > sc->sel_start) {
1274 sc->sel_start = scu->sel_init;
1275 sc->sel_end = pos;
1276 }
1277 else {
1278 sc->sel_start = sc->sel_end = pos;
1279 }
1280
1281 /* Move text cursor to the last selection point. */
1282 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1283
1284 if (cl != nullptr) {
1285 if (dragging && sc->sel_end > cl->len && pos <= cl->len) {
1286 /* Do not move cursor while dragging into the editable area. */
1287 }
1288 else if (pos <= cl->len) {
1289 console_line_cursor_set(cl, cl->len - pos);
1290 }
1291 else if (pos > cl->len && sc->sel_start < cl->len) {
1292 /* Dragging out of editable area, move cursor to start of selection. */
1293 console_line_cursor_set(cl, cl->len - sc->sel_start);
1294 }
1295 }
1296}
1297
1299{
1301 ScrArea *area = CTX_wm_area(C);
1303
1304 SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
1305 const int sel_prev[2] = {sc->sel_start, sc->sel_end};
1306
1307 console_cursor_set_to_pos(sc, region, scu, event);
1308
1309 /* only redraw if the selection changed */
1310 if (sel_prev[0] != sc->sel_start || sel_prev[1] != sc->sel_end) {
1311 ED_area_tag_redraw(area);
1312 }
1313}
1314
1316{
1318 SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
1319
1321
1322 MEM_freeN(scu);
1323}
1324
1326 wmOperator *op,
1327 const wmEvent *event)
1328{
1330 ScrArea *area = CTX_wm_area(C);
1332
1333 SetConsoleCursor *scu;
1334
1335 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1336 if (cl != nullptr) {
1337 const int pos = console_char_pick(sc, region, event->mval);
1338 if (pos >= 0 && pos <= cl->len) {
1339 /* Set text cursor immediately. */
1340 console_line_cursor_set(cl, cl->len - pos);
1341 }
1342 }
1343
1344 op->customdata = MEM_callocN(sizeof(SetConsoleCursor), "SetConsoleCursor");
1345 scu = static_cast<SetConsoleCursor *>(op->customdata);
1346
1347 scu->sel_old[0] = sc->sel_start;
1348 scu->sel_old[1] = sc->sel_end;
1349
1350 scu->sel_init = INT_MAX;
1351
1353
1354 console_modal_select_apply(C, op, event);
1355
1357}
1358
1360{
1361 /* Move text cursor to the last selection point. */
1362 switch (event->type) {
1363 case LEFTMOUSE:
1364 case MIDDLEMOUSE:
1365 case RIGHTMOUSE:
1366 if (event->val == KM_PRESS) {
1367 console_modal_select_apply(C, op, event);
1368 break;
1369 }
1370 else if (event->val == KM_RELEASE) {
1371 console_modal_select_apply(C, op, event);
1374 return OPERATOR_FINISHED;
1375 }
1376 break;
1377 case MOUSEMOVE:
1378 console_modal_select_apply(C, op, event);
1379 break;
1380 default: {
1381 break;
1382 }
1383 }
1384
1386}
1387
1392
1394{
1395 /* identifiers */
1396 ot->name = "Set Selection";
1397 ot->idname = "CONSOLE_OT_select_set";
1398 ot->description = "Set the console selection";
1399
1400 /* API callbacks. */
1401 ot->invoke = console_select_set_invoke;
1403 ot->cancel = console_select_set_cancel;
1405}
1406
1408 wmOperator * /*op*/,
1409 const wmEvent * /*event*/)
1410{
1411 ScrArea *area = CTX_wm_area(C);
1413
1414 int offset = strlen(sc->prompt);
1415
1417 offset += cl->len + 1;
1418 }
1419
1420 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
1421 if (cl) {
1422 offset += cl->len + 1;
1423 }
1424
1425 sc->sel_start = 0;
1426 sc->sel_end = offset;
1427
1428 ED_area_tag_redraw(area);
1429
1430 return OPERATOR_FINISHED;
1431}
1432
1434{
1435 /* identifiers */
1436 ot->name = "Select All";
1437 ot->idname = "CONSOLE_OT_select_all";
1438 ot->description = "Select all the text";
1439
1440 /* API callbacks. */
1443}
1444
1446 wmOperator * /*op*/,
1447 const wmEvent *event)
1448{
1450 ScrArea *area = CTX_wm_area(C);
1452
1453 ConsoleLine cl_dummy = {nullptr};
1454 ConsoleLine *cl;
1456 int pos, offset, n;
1457
1458 pos = console_char_pick(sc, region, event->mval);
1459
1460 console_scrollback_prompt_begin(sc, &cl_dummy);
1461
1462 if (console_line_column_from_index(sc, pos, &cl, &offset, &n)) {
1463 int sel[2] = {n, n};
1464
1465 BLI_str_cursor_step_bounds_utf8(cl->line, cl->len, n, &sel[1], &sel[0]);
1466
1467 sel[0] = offset - sel[0];
1468 sel[1] = offset - sel[1];
1469
1470 if ((sel[0] != sc->sel_start) || (sel[1] != sc->sel_end)) {
1471 sc->sel_start = sel[0];
1472 sc->sel_end = sel[1];
1473 ED_area_tag_redraw(area);
1475 }
1476 }
1477
1478 console_scrollback_prompt_end(sc, &cl_dummy);
1479
1480 ConsoleLine *ci = static_cast<ConsoleLine *>(sc->history.last);
1481 if (ci && sc->sel_start <= ci->len) {
1482 console_line_cursor_set(ci, ci->len - sc->sel_start);
1483 }
1484
1485 if (ret & OPERATOR_FINISHED) {
1487 }
1488
1489 return ret;
1490}
1491
1493{
1494 /* identifiers */
1495 ot->name = "Select Word";
1496 ot->description = "Select word at cursor position";
1497 ot->idname = "CONSOLE_OT_select_word";
1498
1499 /* API callbacks. */
1500 ot->invoke = console_selectword_invoke;
1502}
SpaceConsole * CTX_wm_space_console(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
Definition screen.cc:840
#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:74
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:36
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.cc:55
#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:941
@ 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:714
bool ED_operator_console_active(bContext *C)
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
#define C
Definition RandGen.cpp:29
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
Definition view2d.cc:1036
@ WM_CAPABILITY_PRIMARY_CLIPBOARD
Definition WM_api.hh:187
@ KM_CTRL
Definition WM_types.hh:276
@ KM_OSKEY
Definition WM_types.hh:279
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:238
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:245
@ KM_PRESS
Definition WM_types.hh:308
@ KM_RELEASE
Definition WM_types.hh:309
#define U
#define NEXT_CHAR(fmt)
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 select(A, B, C)
#define printf(...)
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:771
wmEventType type
Definition WM_types.hh:754
short val
Definition WM_types.hh:756
char utf8_buf[6]
Definition WM_types.hh:768
int mval[2]
Definition WM_types.hh:760
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, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
@ RIGHTMOUSE
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
wmOperatorType * ot
Definition wm_files.cc:4225
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()