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:
authorCampbell Barton <ideasman42@gmail.com>2018-03-19 16:17:59 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-03-31 21:40:37 +0300
commit651b8fb14eb6ee5cbfa98bffe80a966a0753b14e (patch)
tree2281978509d82a25fb5fbf586f34335e3606442d /source/blender/editors/space_text
parent91d0825b5556150c017dad767f7971bb6a731aec (diff)
Undo: unified undo system w/ linear history
- Use a single undo history for all operations. - UndoType's are registered and poll the context to check if they should be used when performing an undo push. - Mode switching is used to ensure the state is correct before undo data is restored. - Some undo types accumulate changes (image & text editing) others store the state multiple times (with de-duplication). This is supported by checking UndoStack.mode `ACCUMULATE` / `STORE`. - Each undo step stores ID datablocks they use with utilities to help manage restoring correct ID's. Needed since global undo is now mixed with other modes undo. - Currently performs each undo step when going up/down history Previously this wasn't done, making history fail in some cases. This can be optimized to skip some combinations of undo steps. grease-pencil is an exception which has not been updated since it integrates undo into the draw-session. See D3113
Diffstat (limited to 'source/blender/editors/space_text')
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_text/text_ops.c70
-rw-r--r--source/blender/editors/space_text/text_undo.c170
3 files changed, 214 insertions, 27 deletions
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index 39b48f5b52c..91420a5d63a 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -48,6 +48,7 @@ set(SRC
text_format_py.c
text_header.c
text_ops.c
+ text_undo.c
text_format.h
text_intern.h
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index f75cd129f67..7580f22321b 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -756,7 +756,10 @@ void TEXT_OT_paste(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_paste_exec;
ot->poll = text_edit_poll;
-
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
RNA_def_boolean(ot->srna, "selection", 0, "Selection", "Paste text selected elsewhere rather than copied (X11 only)");
}
@@ -785,10 +788,13 @@ void TEXT_OT_duplicate_line(wmOperatorType *ot)
ot->name = "Duplicate Line";
ot->idname = "TEXT_OT_duplicate_line";
ot->description = "Duplicate the current line";
-
+
/* api callbacks */
ot->exec = text_duplicate_line_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* copy operator *********************/
@@ -860,6 +866,9 @@ void TEXT_OT_cut(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_cut_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* indent operator *********************/
@@ -895,6 +904,9 @@ void TEXT_OT_indent(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_indent_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* unindent operator *********************/
@@ -926,6 +938,9 @@ void TEXT_OT_unindent(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_unindent_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* line break operator *********************/
@@ -970,10 +985,13 @@ void TEXT_OT_line_break(wmOperatorType *ot)
ot->name = "Line Break";
ot->idname = "TEXT_OT_line_break";
ot->description = "Insert line break at cursor position";
-
+
/* api callbacks */
ot->exec = text_line_break_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* comment operator *********************/
@@ -1003,10 +1021,13 @@ void TEXT_OT_comment(wmOperatorType *ot)
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 *********************/
@@ -1041,6 +1062,9 @@ void TEXT_OT_uncomment(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_uncomment_exec;
ot->poll = text_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* convert whitespace operator *********************/
@@ -1174,6 +1198,9 @@ void TEXT_OT_convert_whitespace(wmOperatorType *ot)
ot->exec = text_convert_whitespace_exec;
ot->poll = text_edit_poll;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
RNA_def_enum(ot->srna, "type", whitespace_type_items, TO_SPACES, "Type", "Type of whitespace to convert to");
}
@@ -1295,6 +1322,9 @@ void TEXT_OT_move_lines(wmOperatorType *ot)
ot->exec = move_lines_exec;
ot->poll = text_edit_poll;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
RNA_def_enum(ot->srna, "direction", direction_items, 1, "Direction", "");
}
@@ -2919,6 +2949,9 @@ void TEXT_OT_insert(wmOperatorType *ot)
ot->invoke = text_insert_invoke;
ot->poll = text_edit_poll;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
prop = RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -3024,6 +3057,9 @@ void TEXT_OT_replace(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_replace_exec;
ot->poll = text_space_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/******************* find set selected *********************/
@@ -3081,6 +3117,9 @@ void TEXT_OT_replace_set_selected(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_replace_set_selected_exec;
ot->poll = text_space_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/****************** resolve conflict operator ******************/
@@ -3201,26 +3240,3 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "split_lines", 0, "Split Lines", "Create one object per line in the text");
}
-
-
-/************************ undo ******************************/
-
-void ED_text_undo_step(bContext *C, int step)
-{
- Text *text = CTX_data_edit_text(C);
-
- if (!text)
- return;
-
- if (step == 1)
- txt_do_undo(text);
- else if (step == -1)
- txt_do_redo(text);
-
- text_update_edited(text);
-
- text_update_cursor_moved(C);
- text_drawcache_tag_update(CTX_wm_space_text(C), 1);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-}
-
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
new file mode 100644
index 00000000000..6bac00fc30c
--- /dev/null
+++ b/source/blender/editors/space_text/text_undo.c
@@ -0,0 +1,170 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_undo.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_text_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_array_utils.h"
+
+#include "BLT_translation.h"
+
+#include "PIL_time.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_text.h"
+#include "BKE_undo_system.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_text.h"
+#include "ED_curve.h"
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "text_intern.h"
+#include "text_format.h"
+
+/* TODO(campbell): undo_system: move text undo out of text block. */
+
+/* -------------------------------------------------------------------- */
+/** \name Implements ED Undo System
+ * \{ */
+typedef struct TextUndoBuf {
+ char *buf;
+ int len;
+ int pos;
+} TextUndoBuf;
+
+typedef struct TextUndoStep {
+ UndoStep step;
+ UndoRefID_Text text_ref;
+ TextUndoBuf data;
+} TextUndoStep;
+
+static bool text_undosys_poll(bContext *C)
+{
+ Text *text = CTX_data_edit_text(C);
+ if (text == NULL) {
+ return false;
+ }
+ if (ID_IS_LINKED(text)) {
+ return false;
+ }
+ return true;
+}
+
+static bool text_undosys_step_encode(struct bContext *C, UndoStep *us_p)
+{
+ TextUndoStep *us = (TextUndoStep *)us_p;
+ Text *text = CTX_data_edit_text(C);
+ us->text_ref.ptr = text;
+
+ BLI_assert(BLI_array_is_zeroed(&us->data, 1));
+
+ us->data.buf = text->undo_buf;
+ us->data.pos = text->undo_pos;
+ us->data.len = text->undo_len;
+
+ text->undo_buf = NULL;
+ text->undo_len = 0;
+ text->undo_pos = -1;
+
+ us->step.data_size = text->undo_len;
+
+ return true;
+}
+
+static void text_undosys_step_decode(struct bContext *C, UndoStep *us_p, int dir)
+{
+ TextUndoStep *us = (TextUndoStep *)us_p;
+ Text *text = us->text_ref.ptr;
+
+ /* TODO(campbell): undo_system: move undo out of Text data block. */
+ text->undo_buf = us->data.buf;
+ text->undo_len = us->data.len;
+ if (dir < 0) {
+ text->undo_pos = us->data.pos;
+ txt_do_undo(text);
+ }
+ else {
+ text->undo_pos = -1;
+ txt_do_redo(text);
+ }
+ text->undo_buf = NULL;
+ text->undo_len = 0;
+ text->undo_pos = -1;
+
+ text_update_edited(text);
+ text_update_cursor_moved(C);
+ text_drawcache_tag_update(CTX_wm_space_text(C), 1);
+ WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+}
+
+static void text_undosys_step_free(UndoStep *us_p)
+{
+ TextUndoStep *us = (TextUndoStep *)us_p;
+ MEM_SAFE_FREE(us->data.buf);
+}
+
+static void text_undosys_foreach_ID_ref(
+ UndoStep *us_p, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
+{
+ TextUndoStep *us = (TextUndoStep *)us_p;
+ foreach_ID_ref_fn(user_data, ((UndoRefID *)&us->text_ref));
+}
+
+/* Export for ED_undo_sys. */
+
+void ED_text_undosys_type(UndoType *ut)
+{
+ ut->name = "Text";
+ ut->poll = text_undosys_poll;
+ ut->step_encode = text_undosys_step_encode;
+ ut->step_decode = text_undosys_step_decode;
+ ut->step_free = text_undosys_step_free;
+
+ ut->step_foreach_ID_ref = text_undosys_foreach_ID_ref;
+
+ ut->mode = BKE_UNDOTYPE_MODE_ACCUMULATE;
+ ut->use_context = true;
+
+ ut->step_size = sizeof(TextUndoStep);
+}
+
+/** \} */