diff options
Diffstat (limited to 'source/blender/editors/undo')
-rw-r--r-- | source/blender/editors/undo/ed_undo.c | 68 | ||||
-rw-r--r-- | source/blender/editors/undo/memfile_undo.c | 3 |
2 files changed, 58 insertions, 13 deletions
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index d8b194e3336..3950b056e89 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -36,6 +36,7 @@ #include "CLG_log.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" #include "BLI_utildefines.h" @@ -46,6 +47,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_screen.h" +#include "BKE_layer.h" #include "BKE_undo_system.h" #include "ED_gpencil.h" @@ -302,12 +304,42 @@ void ED_OT_undo_redo(wmOperatorType *ot) /** \} */ +struct OperatorRepeatContextHandle { + ScrArea *restore_area; + ARegion *restore_region; +}; + +/** + * Resets the context to the state \a op was executed in (or at least, was in when registering). + * #ED_operator_repeat_reset_context should be called when done repeating! + */ +const OperatorRepeatContextHandle *ED_operator_repeat_prepare_context(bContext *C, wmOperator *op) +{ + static OperatorRepeatContextHandle context_info; + + context_info.restore_area = CTX_wm_area(C); + context_info.restore_region = CTX_wm_region(C); + + CTX_wm_area_set(C, op->execution_area); + CTX_wm_region_set(C, op->execution_region); + + return &context_info; +} +/** + * Resets context to the old state from before #ED_operator_repeat_prepare_context was called. + */ +void ED_operator_repeat_reset_context(bContext *C, const OperatorRepeatContextHandle *context_info) +{ + CTX_wm_area_set(C, context_info->restore_area); + CTX_wm_region_set(C, context_info->restore_region); +} + /* -------------------------------------------------------------------- */ /** \name Operator Repeat * \{ */ /* ui callbacks should call this rather than calling WM_operator_repeat() themselves */ -int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) +int ED_undo_operator_repeat(bContext *C, wmOperator *op) { int ret = 0; @@ -316,12 +348,8 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); struct Scene *scene = CTX_data_scene(C); - /* keep in sync with logic in view3d_panel_operator_redo() */ - ARegion *ar = CTX_wm_region(C); - ARegion *ar1 = BKE_area_find_region_active_win(CTX_wm_area(C)); - - if (ar1) - CTX_wm_region_set(C, ar1); + const OperatorRepeatContextHandle *context_info; + context_info = ED_operator_repeat_prepare_context(C, op); if ((WM_operator_repeat_check(C, op)) && (WM_operator_poll(C, op->type)) && @@ -334,8 +362,6 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int retval; - ED_viewport_render_kill_jobs(wm, CTX_data_main(C), true); - if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); @@ -369,8 +395,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) } } - /* set region back */ - CTX_wm_region_set(C, ar); + ED_operator_repeat_reset_context(C, context_info); } else { CLOG_WARN(&LOG, "called with NULL 'op'"); @@ -495,3 +520,24 @@ void ED_OT_undo_history(wmOperatorType *ot) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Undo Helper Functions + * \{ */ + +void ED_undo_object_set_active_or_warn(ViewLayer *view_layer, Object *ob, const char *info, CLG_LogRef *log) +{ + Object *ob_prev = OBACT(view_layer); + if (ob_prev != ob) { + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base != NULL) { + view_layer->basact = base; + } + else { + /* Should never fail, may not crash but can give odd behavior. */ + CLOG_WARN(log, "'%s' failed to restore active object: '%s'", info, ob->id.name + 2); + } + } +} + +/** \} */ diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c index bb81da74f88..d45470ab0a1 100644 --- a/source/blender/editors/undo/memfile_undo.c +++ b/source/blender/editors/undo/memfile_undo.c @@ -76,6 +76,7 @@ static bool memfile_undosys_step_encode(struct bContext *C, UndoStep *us_p) MemFileUndoStep *us_prev = (MemFileUndoStep *)BKE_undosys_step_find_by_type(ustack, BKE_UNDOSYS_TYPE_MEMFILE); us->data = BKE_memfile_undo_encode(bmain, us_prev ? us_prev->data : NULL); us->step.data_size = us->data->undo_size; + return true; } @@ -84,8 +85,6 @@ static void memfile_undosys_step_decode(struct bContext *C, UndoStep *us_p, int /* Loading the content will correctly switch into compatible non-object modes. */ ED_object_mode_set(C, OB_MODE_OBJECT); - /* This is needed so undoing/redoing doesn't crash with threaded previews going */ - ED_viewport_render_kill_jobs(CTX_wm_manager(C), CTX_data_main(C), true); MemFileUndoStep *us = (MemFileUndoStep *)us_p; BKE_memfile_undo_decode(us->data, C); |