Commit: a5c4dd6b33757ea583e4731c4751b25af30c0019
Author: Campbell Barton
Date:   Fri Jun 7 15:30:49 2019 +1000
Branches: master
https://developer.blender.org/rBa5c4dd6b33757ea583e4731c4751b25af30c0019

Fix T65229: Crash adjusting last operator after using undo history

Undo history also missed updating the tool system and
calling undo pre/post handlers.

===================================================================

M       source/blender/editors/undo/ed_undo.c

===================================================================

diff --git a/source/blender/editors/undo/ed_undo.c 
b/source/blender/editors/undo/ed_undo.c
index f254abcfe99..6d5f486ebe9 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -105,10 +105,12 @@ void ED_undo_push(bContext *C, const char *str)
 /**
  * \note Also check #undo_history_exec in bottom if you change notifiers.
  */
-static int ed_undo_step(bContext *C, int step, const char *undoname, 
ReportList *reports)
+static int ed_undo_step_impl(
+    bContext *C, int step, const char *undoname, int undo_index, ReportList 
*reports)
 {
   /* Mutually exclusives, ensure correct input. */
-  BLI_assert((undoname && !step) || (!undoname && step));
+  BLI_assert(((undoname || undo_index != -1) && !step) ||
+             (!(undoname || undo_index != -1) && step));
   CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step);
   wmWindowManager *wm = CTX_wm_manager(C);
   Scene *scene = CTX_data_scene(C);
@@ -153,6 +155,12 @@ static int ed_undo_step(bContext *C, int step, const char 
*undoname, ReportList
                             1 :
                             -1;
   }
+  else if (undo_index != -1) {
+    step_for_callback = (undo_index <
+                         BLI_findindex(&wm->undo_stack->steps, 
wm->undo_stack->step_active)) ?
+                            1 :
+                            -1;
+  }
 
   /* App-Handlers (pre). */
   {
@@ -169,6 +177,9 @@ static int ed_undo_step(bContext *C, int step, const char 
*undoname, ReportList
     if (undoname) {
       BKE_undosys_step_undo_with_data(wm->undo_stack, C, step_data_from_name);
     }
+    else if (undo_index != -1) {
+      BKE_undosys_step_undo_from_index(wm->undo_stack, C, undo_index);
+    }
     else {
       if (step == 1) {
         BKE_undosys_step_undo(wm->undo_stack, C);
@@ -228,6 +239,21 @@ static int ed_undo_step(bContext *C, int step, const char 
*undoname, ReportList
   return OPERATOR_FINISHED;
 }
 
+static int ed_undo_step_direction(bContext *C, int step, ReportList *reports)
+{
+  return ed_undo_step_impl(C, step, NULL, -1, reports);
+}
+
+static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList 
*reports)
+{
+  return ed_undo_step_impl(C, 0, undo_name, -1, reports);
+}
+
+static int ed_undo_step_by_index(bContext *C, int index, ReportList *reports)
+{
+  return ed_undo_step_impl(C, 0, NULL, index, reports);
+}
+
 void ED_undo_grouped_push(bContext *C, const char *str)
 {
   /* do nothing if previous undo task is the same as this one (or from the 
same undo group) */
@@ -243,11 +269,11 @@ void ED_undo_grouped_push(bContext *C, const char *str)
 
 void ED_undo_pop(bContext *C)
 {
-  ed_undo_step(C, 1, NULL, NULL);
+  ed_undo_step_direction(C, 1, NULL);
 }
 void ED_undo_redo(bContext *C)
 {
-  ed_undo_step(C, -1, NULL, NULL);
+  ed_undo_step_direction(C, -1, NULL);
 }
 
 void ED_undo_push_op(bContext *C, wmOperator *op)
@@ -269,7 +295,7 @@ void ED_undo_grouped_push_op(bContext *C, wmOperator *op)
 void ED_undo_pop_op(bContext *C, wmOperator *op)
 {
   /* search back a couple of undo's, in case something else added pushes */
-  ed_undo_step(C, 0, op->type->name, op->reports);
+  ed_undo_step_by_name(C, op->type->name, op->reports);
 }
 
 /* name optionally, function used to check for operator redo panel */
@@ -318,7 +344,7 @@ static int ed_undo_exec(bContext *C, wmOperator *op)
 {
   /* "last operator" should disappear, later we can tie this with undo stack 
nicer */
   WM_operator_stack_clear(CTX_wm_manager(C));
-  int ret = ed_undo_step(C, 1, NULL, op->reports);
+  int ret = ed_undo_step_direction(C, 1, op->reports);
   if (ret & OPERATOR_FINISHED) {
     /* Keep button under the cursor active. */
     WM_event_add_mousemove(C);
@@ -345,7 +371,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
 
 static int ed_redo_exec(bContext *C, wmOperator *op)
 {
-  int ret = ed_undo_step(C, -1, NULL, op->reports);
+  int ret = ed_undo_step_direction(C, -1, op->reports);
   if (ret & OPERATOR_FINISHED) {
     /* Keep button under the cursor active. */
     WM_event_add_mousemove(C);
@@ -626,8 +652,8 @@ static int undo_history_exec(bContext *C, wmOperator *op)
   PropertyRNA *prop = RNA_struct_find_property(op->ptr, "item");
   if (RNA_property_is_set(op->ptr, prop)) {
     int item = RNA_property_int_get(op->ptr, prop);
-    wmWindowManager *wm = CTX_wm_manager(C);
-    BKE_undosys_step_undo_from_index(wm->undo_stack, C, item);
+    WM_operator_stack_clear(CTX_wm_manager(C));
+    ed_undo_step_by_index(C, item, op->reports);
     WM_event_add_notifier(C, NC_WINDOW, NULL);
     return OPERATOR_FINISHED;
   }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to