Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_text')
-rw-r--r--source/blender/editors/space_text/space_text.c9
-rw-r--r--source/blender/editors/space_text/text_draw.c6
-rw-r--r--source/blender/editors/space_text/text_intern.h3
-rw-r--r--source/blender/editors/space_text/text_ops.c326
-rw-r--r--source/blender/editors/space_text/text_undo.c184
5 files changed, 365 insertions, 163 deletions
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 24f282ff920..8bfb6c87625 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -82,7 +82,7 @@ static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
BLI_addtail(&stext->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
- ar->alignment = RGN_ALIGN_LEFT;
+ ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
/* main region */
@@ -197,8 +197,7 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_duplicate_line);
WM_operatortype_append(TEXT_OT_convert_whitespace);
- WM_operatortype_append(TEXT_OT_uncomment);
- WM_operatortype_append(TEXT_OT_comment);
+ WM_operatortype_append(TEXT_OT_comment_toggle);
WM_operatortype_append(TEXT_OT_unindent);
WM_operatortype_append(TEXT_OT_indent);
@@ -254,7 +253,9 @@ static int text_context(const bContext *C, const char *member, bContextDataResul
return 1;
}
else if (CTX_data_equals(member, "edit_text")) {
- CTX_data_id_pointer_set(result, &st->text->id);
+ if (st->text != NULL) {
+ CTX_data_id_pointer_set(result, &st->text->id);
+ }
return 1;
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index c03b804aa2c..9dc8dfa93b6 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -240,7 +240,7 @@ void wrap_offset(
}
max = wrap_width(st, ar);
- cursin = txt_utf8_offset_to_column(linein->line, cursin);
+ cursin = BLI_str_utf8_offset_to_column(linein->line, cursin);
while (linep) {
start = 0;
@@ -323,7 +323,7 @@ void wrap_offset_in_line(
end = max;
chop = 1;
*offc = 0;
- cursin = txt_utf8_offset_to_column(linein->line, cursin);
+ cursin = BLI_str_utf8_offset_to_column(linein->line, cursin);
for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size_safe(linein->line + j)) {
int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */
@@ -1400,7 +1400,7 @@ static void draw_brackets(const SpaceText *st, const TextDrawContext *tdc, ARegi
linep = startl;
c = startc;
- fc = txt_utf8_offset_to_index(linep->line, startc);
+ fc = BLI_str_utf8_offset_to_index(linep->line, startc);
endl = NULL;
endc = -1;
find = -b;
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index aab5069f919..7a1dd312d02 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -119,8 +119,7 @@ void TEXT_OT_cut(struct wmOperatorType *ot);
void TEXT_OT_duplicate_line(struct wmOperatorType *ot);
void TEXT_OT_convert_whitespace(struct wmOperatorType *ot);
-void TEXT_OT_uncomment(struct wmOperatorType *ot);
-void TEXT_OT_comment(struct wmOperatorType *ot);
+void TEXT_OT_comment_toggle(struct wmOperatorType *ot);
void TEXT_OT_unindent(struct wmOperatorType *ot);
void TEXT_OT_indent(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 8f7bd83cbf4..a8af9c73bf2 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -61,7 +61,9 @@
static void txt_screen_clamp(SpaceText *st, ARegion *ar);
-/************************ util ***************************/
+/* -------------------------------------------------------------------- */
+/** \name Util
+ * \{ */
/**
* Tests if the given character represents a start of a new line or the
@@ -138,14 +140,18 @@ static char *buf_tabs_to_spaces(const char *in_buf, const int tab_size)
return out_buf;
}
-/************************ poll ***************************/
-
BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x)
{
/* add half the char width so mouse cursor selection is inbetween letters */
return (x + (st->cwidth / 2)) / st->cwidth;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operator Poll
+ * \{ */
+
static bool text_new_poll(bContext *UNUSED(C))
{
return 1;
@@ -206,7 +212,11 @@ static bool text_region_edit_poll(bContext *C)
return 1;
}
-/********************** updates *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Updates
+ * \{ */
void text_update_line_edited(TextLine *line)
{
@@ -230,7 +240,11 @@ void text_update_edited(Text *text)
}
}
-/******************* new operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name New Operator
+ * \{ */
static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -281,7 +295,11 @@ void TEXT_OT_new(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* open operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Open Operator
+ * \{ */
static void text_open_init(bContext *C, wmOperator *op)
{
@@ -392,7 +410,11 @@ void TEXT_OT_open(wmOperatorType *ot)
ot->srna, "internal", 0, "Make internal", "Make text file internal after loading");
}
-/******************* reload operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Reload Operator
+ * \{ */
static int text_reload_exec(bContext *C, wmOperator *op)
{
@@ -443,7 +465,11 @@ void TEXT_OT_reload(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/******************* delete operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Operator
+ * \{ */
static bool text_unlink_poll(bContext *C)
{
@@ -495,7 +521,11 @@ void TEXT_OT_unlink(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* make internal operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Make Internal Operator
+ * \{ */
static int text_make_internal_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -529,7 +559,11 @@ void TEXT_OT_make_internal(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* save operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Save Operator
+ * \{ */
static bool text_save_poll(bContext *C)
{
@@ -614,7 +648,11 @@ void TEXT_OT_save(wmOperatorType *ot)
ot->poll = text_save_poll;
}
-/******************* save as operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Save As Operator
+ * \{ */
static int text_save_as_exec(bContext *C, wmOperator *op)
{
@@ -690,7 +728,11 @@ void TEXT_OT_save_as(wmOperatorType *ot)
FILE_SORT_ALPHA); // XXX TODO, relative_path
}
-/******************* run script operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run Script Operator
+ * \{ */
static bool text_run_script_poll(bContext *C)
{
@@ -765,7 +807,11 @@ void TEXT_OT_run_script(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/******************* refresh pyconstraints operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Refresh Pyconstraints Operator
+ * \{ */
static int text_refresh_pyconstraints_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
@@ -825,7 +871,11 @@ void TEXT_OT_refresh_pyconstraints(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/******************* paste operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paste Operator
+ * \{ */
static int text_paste_exec(bContext *C, wmOperator *op)
{
@@ -889,7 +939,11 @@ void TEXT_OT_paste(wmOperatorType *ot)
"Paste text selected elsewhere rather than copied (X11 only)");
}
-/**************** duplicate operator *******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Duplicate Operator
+ * \{ */
static int text_duplicate_line_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -924,7 +978,11 @@ void TEXT_OT_duplicate_line(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* copy operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Copy Operator
+ * \{ */
static void txt_copy_clipboard(Text *text)
{
@@ -963,7 +1021,11 @@ void TEXT_OT_copy(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/******************* cut operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cut Operator
+ * \{ */
static int text_cut_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1002,7 +1064,11 @@ void TEXT_OT_cut(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* indent operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Indent Operator
+ * \{ */
static int text_indent_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1043,7 +1109,11 @@ void TEXT_OT_indent(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* unindent operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Unindent Operator
+ * \{ */
static int text_unindent_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1079,7 +1149,11 @@ void TEXT_OT_unindent(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* line break operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Line Break Operator
+ * \{ */
static int text_line_break_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1132,11 +1206,16 @@ void TEXT_OT_line_break(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* comment operator *********************/
+/** \} */
-static int text_comment_exec(bContext *C, wmOperator *UNUSED(op))
+/* -------------------------------------------------------------------- */
+/** \name Toggle-Comment Operator
+ * \{ */
+
+static int text_comment_exec(bContext *C, wmOperator *op)
{
Text *text = CTX_data_edit_text(C);
+ int type = RNA_enum_get(op->ptr, "type");
if (txt_has_sel(text)) {
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
@@ -1144,45 +1223,21 @@ static int text_comment_exec(bContext *C, wmOperator *UNUSED(op))
ED_text_undo_push_init(C);
txt_order_cursors(text, false);
- txt_comment(text);
- text_update_edited(text);
-
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_CANCELLED;
-}
-
-void TEXT_OT_comment(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Comment";
- ot->idname = "TEXT_OT_comment";
- ot->description = "Convert selected text to comment";
-
- /* api callbacks */
- ot->exec = text_comment_exec;
- ot->poll = text_edit_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-}
-
-/******************* uncomment operator *********************/
-static int text_uncomment_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Text *text = CTX_data_edit_text(C);
-
- if (txt_has_sel(text)) {
- text_drawcache_tag_update(CTX_wm_space_text(C), 0);
-
- ED_text_undo_push_init(C);
+ switch (type) {
+ case 1:
+ txt_comment(text);
+ break;
+ case -1:
+ txt_uncomment(text);
+ break;
+ default:
+ if (txt_uncomment(text) == false) {
+ txt_comment(text);
+ }
+ break;
+ }
- txt_order_cursors(text, false);
- txt_uncomment(text);
text_update_edited(text);
text_update_cursor_moved(C);
@@ -1194,22 +1249,37 @@ static int text_uncomment_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
-void TEXT_OT_uncomment(wmOperatorType *ot)
+void TEXT_OT_comment_toggle(wmOperatorType *ot)
{
+ static const EnumPropertyItem comment_items[] = {
+ {0, "TOGGLE", 0, "Toggle Comments", NULL},
+ {1, "COMMENT", 0, "Comment", NULL},
+ {-1, "UNCOMMENT", 0, "Un-Comment", NULL},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
- ot->name = "Uncomment";
- ot->idname = "TEXT_OT_uncomment";
- ot->description = "Convert selected comment to text";
+ ot->name = "Toggle Comments";
+ ot->idname = "TEXT_OT_comment_toggle";
/* api callbacks */
- ot->exec = text_uncomment_exec;
+ ot->exec = text_comment_exec;
ot->poll = text_edit_poll;
/* flags */
ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop;
+ prop = RNA_def_enum(ot->srna, "type", comment_items, 0, "Type", "Add or remove comments");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
-/******************* convert whitespace operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Whitespace Operator
+ * \{ */
enum { TO_SPACES, TO_TABS };
static const EnumPropertyItem whitespace_type_items[] = {
@@ -1360,7 +1430,11 @@ void TEXT_OT_convert_whitespace(wmOperatorType *ot)
"Type of whitespace to convert to");
}
-/******************* select all operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select All Operator
+ * \{ */
static int text_select_all_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1386,7 +1460,11 @@ void TEXT_OT_select_all(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/******************* select line operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Line Operator
+ * \{ */
static int text_select_line_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1412,7 +1490,11 @@ void TEXT_OT_select_line(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/******************* select word operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Word Operator
+ * \{ */
static int text_select_word_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1441,7 +1523,11 @@ void TEXT_OT_select_word(wmOperatorType *ot)
ot->poll = text_edit_poll;
}
-/********************* move lines operators ***********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move Lines Operators
+ * \{ */
static int move_lines_exec(bContext *C, wmOperator *op)
{
@@ -1487,7 +1573,11 @@ void TEXT_OT_move_lines(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", direction_items, 1, "Direction", "");
}
-/************************ move operator ************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move Operator
+ * \{ */
static const EnumPropertyItem move_type_items[] = {
{LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
@@ -1737,7 +1827,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, const bool sel)
if (j >= oldc) {
if (ch == '\0') {
- *charp = txt_utf8_column_to_offset((*linep)->line, start);
+ *charp = BLI_str_utf8_offset_from_column((*linep)->line, start);
}
loop = 0;
break;
@@ -1753,7 +1843,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, const bool sel)
}
else if (ch == ' ' || ch == '-' || ch == '\0') {
if (j >= oldc) {
- *charp = txt_utf8_column_to_offset((*linep)->line, start);
+ *charp = BLI_str_utf8_offset_from_column((*linep)->line, start);
loop = 0;
break;
}
@@ -2126,7 +2216,11 @@ void TEXT_OT_move(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
}
-/******************* move select operator ********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move Select Operator
+ * \{ */
static int text_move_select_exec(bContext *C, wmOperator *op)
{
@@ -2155,7 +2249,11 @@ void TEXT_OT_move_select(wmOperatorType *ot)
"Where to move cursor to, to make a selection");
}
-/******************* jump operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Jump Operator
+ * \{ */
static int text_jump_exec(bContext *C, wmOperator *op)
{
@@ -2203,7 +2301,11 @@ void TEXT_OT_jump(wmOperatorType *ot)
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
}
-/******************* delete operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Operator
+ * \{ */
static const EnumPropertyItem delete_type_items[] = {
{DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
@@ -2317,7 +2419,11 @@ void TEXT_OT_delete(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
-/******************* toggle overwrite operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Toggle Overwrite Operator
+ * \{ */
static int text_toggle_overwrite_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2342,7 +2448,11 @@ void TEXT_OT_overwrite_toggle(wmOperatorType *ot)
ot->poll = text_space_edit_poll;
}
-/******************* scroll operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Scroll Operator
+ * \{ */
static void txt_screen_clamp(SpaceText *st, ARegion *ar)
{
@@ -2571,7 +2681,11 @@ void TEXT_OT_scroll(wmOperatorType *ot)
ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
}
-/******************** scroll bar operator *******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Scroll Bar Operator
+ * \{ */
static bool text_region_scroll_poll(bContext *C)
{
@@ -3073,7 +3187,11 @@ void TEXT_OT_selection_set(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "select", 0, "Select", "Set selection end rather than cursor");
}
-/******************* set cursor operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Cursor Operator
+ * \{ */
static int text_cursor_set_exec(bContext *C, wmOperator *op)
{
@@ -3121,7 +3239,11 @@ void TEXT_OT_cursor_set(wmOperatorType *ot)
RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
}
-/******************* line number operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Line Number Operator
+ * \{ */
static int text_line_number_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
@@ -3177,7 +3299,11 @@ void TEXT_OT_line_number(wmOperatorType *ot)
ot->poll = text_region_edit_poll;
}
-/******************* insert operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Insert Operator
+ * \{ */
static int text_insert_exec(bContext *C, wmOperator *op)
{
@@ -3284,7 +3410,11 @@ void TEXT_OT_insert(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/******************* find operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Find Operator
+ * \{ */
/* mode */
#define TEXT_FIND 0
@@ -3378,7 +3508,11 @@ void TEXT_OT_find(wmOperatorType *ot)
ot->poll = text_space_edit_poll;
}
-/******************* replace operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Replace Operator
+ * \{ */
static int text_replace_exec(bContext *C, wmOperator *op)
{
@@ -3400,7 +3534,11 @@ void TEXT_OT_replace(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/******************* find set selected *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Find Set Selected
+ * \{ */
static int text_find_set_selected_exec(bContext *C, wmOperator *op)
{
@@ -3431,7 +3569,11 @@ void TEXT_OT_find_set_selected(wmOperatorType *ot)
ot->poll = text_space_edit_poll;
}
-/******************* replace set selected *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Replace Set Selected
+ * \{ */
static int text_replace_set_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -3461,7 +3603,11 @@ void TEXT_OT_replace_set_selected(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-/****************** resolve conflict operator ******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Resolve Conflict Operator
+ * \{ */
enum { RESOLVE_IGNORE, RESOLVE_RELOAD, RESOLVE_SAVE, RESOLVE_MAKE_INTERNAL };
static const EnumPropertyItem resolution_items[] = {
@@ -3574,7 +3720,11 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot)
"How to solve conflict due to differences in internal and external text");
}
-/********************** to 3d object operator *****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name To 3D Object Operator
+ * \{ */
static int text_to_3d_object_exec(bContext *C, wmOperator *op)
{
@@ -3604,3 +3754,5 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
RNA_def_boolean(
ot->srna, "split_lines", 0, "Split Lines", "Create one object per line in the text");
}
+
+/** \} */
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
index 6ecb2b731b0..a6393291f9a 100644
--- a/source/blender/editors/space_text/text_undo.c
+++ b/source/blender/editors/space_text/text_undo.c
@@ -61,19 +61,69 @@
#define ARRAY_CHUNK_SIZE 128
+/**
+ * Only stores the state of a text buffer.
+ */
+typedef struct TextState {
+ BArrayState *buf_array_state;
+
+ int cursor_line, cursor_line_select;
+ int cursor_column, cursor_column_select;
+} TextState;
+
+static void text_state_encode(TextState *state, Text *text, BArrayStore *buffer_store)
+{
+ int buf_len = 0;
+ uchar *buf = (uchar *)txt_to_buf_for_undo(text, &buf_len);
+ state->buf_array_state = BLI_array_store_state_add(buffer_store, buf, buf_len, NULL);
+ MEM_freeN(buf);
+
+ state->cursor_line = txt_get_span(text->lines.first, text->curl);
+ state->cursor_column = text->curc;
+
+ if (txt_has_sel(text)) {
+ state->cursor_line_select = (text->curl == text->sell) ?
+ state->cursor_line :
+ txt_get_span(text->lines.first, text->sell);
+ state->cursor_column_select = text->selc;
+ }
+ else {
+ state->cursor_line_select = state->cursor_line;
+ state->cursor_column_select = state->cursor_column;
+ }
+}
+
+static void text_state_decode(TextState *state, Text *text)
+{
+ size_t buf_len;
+ {
+ const uchar *buf = BLI_array_store_state_data_get_alloc(state->buf_array_state, &buf_len);
+ txt_from_buf_for_undo(text, (const char *)buf, buf_len);
+ MEM_freeN((void *)buf);
+ }
+
+ const bool has_select = ((state->cursor_line != state->cursor_line_select) ||
+ (state->cursor_column != state->cursor_column_select));
+ if (has_select) {
+ txt_move_to(text, state->cursor_line_select, state->cursor_column_select, false);
+ }
+ txt_move_to(text, state->cursor_line, state->cursor_column, has_select);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Implements ED Undo System
+ * \{ */
+
typedef struct TextUndoStep {
UndoStep step;
UndoRefID_Text text_ref;
- struct {
- BArrayState *state;
- int buf_len;
- } data;
-
- struct {
- int line, line_select;
- int column, column_select;
- } cursor;
-
+ /**
+ * First state is optional (initial state),
+ * the second is the state after the operation is done.
+ */
+ TextState states[2];
} TextUndoStep;
static struct {
@@ -81,6 +131,21 @@ static struct {
int users;
} g_text_buffers = {NULL};
+static size_t text_undosys_step_encode_to_state(TextState *state, Text *text)
+{
+ BLI_assert(BLI_array_is_zeroed(state, 1));
+ if (g_text_buffers.buffer_store == NULL) {
+ g_text_buffers.buffer_store = BLI_array_store_create(1, ARRAY_CHUNK_SIZE);
+ }
+ g_text_buffers.users += 1;
+ const size_t total_size_prev = BLI_array_store_calc_size_compacted_get(
+ g_text_buffers.buffer_store);
+
+ text_state_encode(state, text, g_text_buffers.buffer_store);
+
+ return BLI_array_store_calc_size_compacted_get(g_text_buffers.buffer_store) - total_size_prev;
+}
+
static bool text_undosys_poll(bContext *UNUSED(C))
{
/* Only use when operators initialized. */
@@ -91,10 +156,27 @@ static bool text_undosys_poll(bContext *UNUSED(C))
static void text_undosys_step_encode_init(struct bContext *C, UndoStep *us_p)
{
TextUndoStep *us = (TextUndoStep *)us_p;
- BLI_assert(BLI_array_is_zeroed(&us->data, 1));
+ BLI_assert(BLI_array_is_zeroed(us->states, ARRAY_SIZE(us->states)));
- UNUSED_VARS(C, us);
- /* XXX, use to set the undo type only. */
+ Text *text = CTX_data_edit_text(C);
+
+ /* Avoid writing the initial state where possible,
+ * failing to do this won't cause bugs, it's just inefficient. */
+ bool write_init = true;
+ UndoStack *ustack = ED_undo_stack_get();
+ if (ustack->step_active) {
+ if (ustack->step_active->type == BKE_UNDOSYS_TYPE_TEXT) {
+ TextUndoStep *us_active = (TextUndoStep *)ustack->step_active;
+ if (STREQ(text->id.name, us_active->text_ref.name)) {
+ write_init = false;
+ }
+ }
+ }
+
+ if (write_init) {
+ us->step.data_size = text_undosys_step_encode_to_state(&us->states[0], text);
+ }
+ us->text_ref.ptr = text;
}
static bool text_undosys_step_encode(struct bContext *C,
@@ -103,67 +185,31 @@ static bool text_undosys_step_encode(struct bContext *C,
{
TextUndoStep *us = (TextUndoStep *)us_p;
- Text *text = CTX_data_edit_text(C);
-
- int buf_len = 0;
-
- uchar *buf = (uchar *)txt_to_buf_for_undo(text, &buf_len);
- if (g_text_buffers.buffer_store == NULL) {
- g_text_buffers.buffer_store = BLI_array_store_create(1, ARRAY_CHUNK_SIZE);
- }
- g_text_buffers.users += 1;
- const size_t total_size_prev = BLI_array_store_calc_size_compacted_get(
- g_text_buffers.buffer_store);
-
- us->data.state = BLI_array_store_state_add(g_text_buffers.buffer_store, buf, buf_len, NULL);
- MEM_freeN(buf);
+ Text *text = us->text_ref.ptr;
+ BLI_assert(text == CTX_data_edit_text(C));
- us->cursor.line = txt_get_span(text->lines.first, text->curl);
- us->cursor.column = text->curc;
-
- if (txt_has_sel(text)) {
- us->cursor.line_select = (text->curl == text->sell) ?
- us->cursor.line :
- txt_get_span(text->lines.first, text->sell);
- us->cursor.column_select = text->selc;
- }
- else {
- us->cursor.line_select = us->cursor.line;
- us->cursor.column_select = us->cursor.column;
- }
+ us->step.data_size += text_undosys_step_encode_to_state(&us->states[1], text);
us_p->is_applied = true;
- us->text_ref.ptr = text;
-
- us->step.data_size = BLI_array_store_calc_size_compacted_get(g_text_buffers.buffer_store) -
- total_size_prev;
-
return true;
}
-static void text_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void text_undosys_step_decode(
+ struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir, bool is_final)
{
TextUndoStep *us = (TextUndoStep *)us_p;
Text *text = us->text_ref.ptr;
- size_t buf_len;
- {
- const uchar *buf = BLI_array_store_state_data_get_alloc(us->data.state, &buf_len);
- txt_from_buf_for_undo(text, (const char *)buf, buf_len);
- MEM_freeN((void *)buf);
+ TextState *state;
+ if ((us->states[0].buf_array_state != NULL) && (dir == -1) && !is_final) {
+ state = &us->states[0];
}
-
- const bool has_select = ((us->cursor.line != us->cursor.line_select) ||
- (us->cursor.column != us->cursor.column_select));
- if (has_select) {
- txt_move_to(text, us->cursor.line_select, us->cursor.column_select, false);
+ else {
+ state = &us->states[1];
}
- txt_move_to(text, us->cursor.line, us->cursor.column, has_select);
+
+ text_state_decode(state, text);
SpaceText *st = CTX_wm_space_text(C);
if (st) {
@@ -179,12 +225,16 @@ static void text_undosys_step_free(UndoStep *us_p)
{
TextUndoStep *us = (TextUndoStep *)us_p;
- BLI_array_store_state_remove(g_text_buffers.buffer_store, us->data.state);
-
- g_text_buffers.users -= 1;
- if (g_text_buffers.users == 0) {
- BLI_array_store_destroy(g_text_buffers.buffer_store);
- g_text_buffers.buffer_store = NULL;
+ for (int i = 0; i < ARRAY_SIZE(us->states); i++) {
+ TextState *state = &us->states[i];
+ if (state->buf_array_state) {
+ BLI_array_store_state_remove(g_text_buffers.buffer_store, state->buf_array_state);
+ g_text_buffers.users -= 1;
+ if (g_text_buffers.users == 0) {
+ BLI_array_store_destroy(g_text_buffers.buffer_store);
+ g_text_buffers.buffer_store = NULL;
+ }
+ }
}
}