diff options
-rw-r--r-- | source/blender/editors/undo/ed_undo.c | 44 |
1 files changed, 35 insertions, 9 deletions
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; } |