diff options
Diffstat (limited to 'source/blender/editors/undo')
-rw-r--r-- | source/blender/editors/undo/ed_undo.c | 73 | ||||
-rw-r--r-- | source/blender/editors/undo/memfile_undo.c | 3 |
2 files changed, 62 insertions, 14 deletions
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 539d0245306..6731a0d2e5b 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" @@ -55,6 +57,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "WM_toolsystem.h" #include "RNA_access.h" #include "RNA_define.h" @@ -104,7 +107,6 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step); wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); - // Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); /* undo during jobs are running can easily lead to freeing data using by jobs, @@ -133,6 +135,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) WM_event_add_notifier(C, NC_WINDOW, NULL); WM_event_add_notifier(C, NC_WM | ND_UNDO, NULL); + Main *bmain = CTX_data_main(C); + WM_toolsystem_refresh_screen_all(bmain); + if (win) { win->addmousemove = true; } @@ -297,12 +302,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; @@ -311,12 +346,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)) && @@ -329,8 +360,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); @@ -364,8 +393,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'"); @@ -490,3 +518,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); |