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:
Diffstat (limited to 'source/blender/editors/undo/ed_undo.c')
-rw-r--r--source/blender/editors/undo/ed_undo.c73
1 files changed, 61 insertions, 12 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);
+ }
+ }
+}
+
+/** \} */