Undo System: remove accumulate/store modes
[blender.git] / source / blender / editors / space_text / text_undo.c
index e945481a2bd21aa94c2604891a48079069009508..869c7d03af93fb9704021e292e58d6342dfdd6fb 100644 (file)
@@ -101,6 +101,8 @@ static bool text_undosys_step_encode(struct bContext *C, struct Main *UNUSED(bma
                return false;
        }
 
+       us_p->is_applied = true;
+
        us->text_ref.ptr = text;
 
        us->step.data_size = us->data.len;
@@ -108,25 +110,73 @@ static bool text_undosys_step_encode(struct bContext *C, struct Main *UNUSED(bma
        return true;
 }
 
+
+static void text_undosys_step_decode_undo_impl(Text *text, TextUndoStep *us)
+{
+       BLI_assert(us->step.is_applied == true);
+       TextUndoBuf data = us->data;
+       while (data.pos > -1) {
+               txt_do_undo(text, &data);
+       }
+       BLI_assert(data.pos == -1);
+       us->step.is_applied = false;
+}
+
+static void text_undosys_step_decode_redo_impl(Text *text, TextUndoStep *us)
+{
+       BLI_assert(us->step.is_applied == false);
+       TextUndoBuf data = us->data;
+       data.pos = -1;
+       while (data.pos < us->data.pos) {
+               txt_do_redo(text, &data);
+       }
+       BLI_assert(data.pos == us->data.pos);
+       us->step.is_applied = true;
+}
+
+static void text_undosys_step_decode_undo(Text *text, TextUndoStep *us)
+{
+       TextUndoStep *us_iter = us;
+       while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
+               if (us_iter->step.next->is_applied == false) {
+                       break;
+               }
+               us_iter = (TextUndoStep *)us_iter->step.next;
+       }
+       while (us_iter != us) {
+               text_undosys_step_decode_undo_impl(text, us_iter);
+               us_iter = (TextUndoStep *)us_iter->step.prev;
+       }
+}
+
+static void text_undosys_step_decode_redo(Text *text, TextUndoStep *us)
+{
+       TextUndoStep *us_iter = us;
+       while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) {
+               if (us_iter->step.prev->is_applied == true) {
+                       break;
+               }
+               us_iter = (TextUndoStep *)us_iter->step.prev;
+       }
+       while (us_iter && (us_iter->step.is_applied == false)) {
+               text_undosys_step_decode_redo_impl(text, us_iter);
+               if (us_iter == us) {
+                       break;
+               }
+               us_iter = (TextUndoStep *)us_iter->step.next;
+       }
+}
+
 static void text_undosys_step_decode(struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir)
 {
        TextUndoStep *us = (TextUndoStep *)us_p;
        Text *text = us->text_ref.ptr;
 
        if (dir < 0) {
-               TextUndoBuf data = us->data;
-               while (data.pos > -1) {
-                       txt_do_undo(text, &data);
-               }
-               BLI_assert(data.pos == -1);
+               text_undosys_step_decode_undo(text, us);
        }
        else {
-               TextUndoBuf data = us->data;
-               data.pos = -1;
-               while (data.pos < us->data.pos) {
-                       txt_do_redo(text, &data);
-               }
-               BLI_assert(data.pos == us->data.pos);
+               text_undosys_step_decode_redo(text, us);
        }
 
        SpaceText *st = CTX_wm_space_text(C);
@@ -166,7 +216,6 @@ void ED_text_undosys_type(UndoType *ut)
 
        ut->step_foreach_ID_ref = text_undosys_foreach_ID_ref;
 
-       ut->mode = BKE_UNDOTYPE_MODE_ACCUMULATE;
        ut->use_context = false;
 
        ut->step_size = sizeof(TextUndoStep);