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>2019-06-07 08:30:49 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-06-07 08:33:39 +0300
commita5c4dd6b33757ea583e4731c4751b25af30c0019 (patch)
tree7970d99693d183e1bc4e213cd7678f3df370a9f5 /source/blender/editors/undo
parentbfb05ee15462f83d5cc504e893bc991f067b5afe (diff)
Fix T65229: Crash adjusting last operator after using undo history
Undo history also missed updating the tool system and calling undo pre/post handlers.
Diffstat (limited to 'source/blender/editors/undo')
-rw-r--r--source/blender/editors/undo/ed_undo.c44
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;
}