Fix T65229: Crash adjusting last operator after using undo history
Undo history also missed updating the tool system and calling undo pre/post handlers.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user