diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-01-24 04:06:47 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-01-24 04:12:23 +0300 |
commit | 1d908bffddb4c9815a986305ad4588032b81deee (patch) | |
tree | b72181a876688f19eee81b64c16b3316b5d1893b | |
parent | 7f77961f1c387a93f3fe1df71558d5602f2ca521 (diff) |
WM: Repeat Last no longer reuses skip-save properties
PROP_SKIP_SAVE is often used as a way to detect the difference between
adjusting options from the redo panel and initial execution.
Repeat last operator was executing with skip-save properties set,
preventing operators from initializing them based on the context.
Fixes 60777.
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 54 |
3 files changed, 54 insertions, 5 deletions
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6d332f8e427..8736664d23c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3359,7 +3359,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op)) if (lastop) { WM_operator_free_all_after(wm, lastop); - WM_operator_repeat(C, lastop); + WM_operator_repeat_interactive(C, lastop); } return OPERATOR_CANCELLED; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 4f73e731457..99e4950f3db 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -321,6 +321,8 @@ bool WM_operator_poll_context(struct bContext *C, struct wmOperatorType * int WM_operator_call_ex(struct bContext *C, struct wmOperator *op, const bool store); int WM_operator_call (struct bContext *C, struct wmOperator *op); int WM_operator_call_notest(struct bContext *C, struct wmOperator *op); + +int WM_operator_repeat_interactive(struct bContext *C, struct wmOperator *op); int WM_operator_repeat (struct bContext *C, struct wmOperator *op); bool WM_operator_repeat_check(const struct bContext *C, struct wmOperator *op); bool WM_operator_is_repeat(const struct bContext *C, const struct wmOperator *op); @@ -345,6 +347,7 @@ void WM_operator_last_properties_ensure(struct wmOperatorType *ot, struct wmOperator *WM_operator_last_redo(const struct bContext *C); ID *WM_operator_drop_load_path(struct bContext *C, struct wmOperator *op, const short idcode); +bool WM_operator_last_properties_init_ex(struct wmOperator *op, struct IDProperty *last_properties); bool WM_operator_last_properties_init(struct wmOperator *op); bool WM_operator_last_properties_store(struct wmOperator *op); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5feacea9666..ad8c7bb60a3 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1041,6 +1041,42 @@ int WM_operator_repeat(bContext *C, wmOperator *op) return wm_operator_exec(C, op, true, true); } /** + * Execute this operator again interactively + * without using #PROP_SKIP_SAVE properties, see: T60777. + */ +int WM_operator_repeat_interactive(bContext *C, wmOperator *op) +{ + IDProperty *properties = op->properties ? IDP_New(IDP_GROUP, &(IDPropertyTemplate){0}, "wmOperatorProperties") : NULL; + PointerRNA *ptr = MEM_dupallocN(op->ptr); + + SWAP(IDProperty *, op->properties, properties); + SWAP(PointerRNA *, op->ptr, ptr); + if (op->ptr) { + op->ptr->data = op->properties; + } + + /* Use functionality to initialize from previous execution to avoid re-using PROP_SKIP_SAVE. */ + if (properties) { + WM_operator_last_properties_init_ex(op, properties); + } + + int retval = wm_operator_exec(C, op, true, true); + + SWAP(IDProperty *, op->properties, properties); + SWAP(PointerRNA *, op->ptr, ptr); + + if (properties) { + IDP_FreeProperty(properties); + MEM_freeN(properties); + } + if (ptr) { + MEM_freeN(ptr); + } + + return retval; +} + +/** * \return true if #WM_operator_repeat can run * simple check for now but may become more involved. * To be sure the operator can run call `WM_operator_poll(C, op->type)` also, since this call @@ -1226,13 +1262,13 @@ static bool operator_last_properties_init_impl(wmOperator *op, IDProperty *last_ return changed; } -bool WM_operator_last_properties_init(wmOperator *op) +bool WM_operator_last_properties_init_ex(wmOperator *op, IDProperty *last_properties) { bool changed = false; - if (op->type->last_properties) { - changed |= operator_last_properties_init_impl(op, op->type->last_properties); + if (last_properties) { + changed |= operator_last_properties_init_impl(op, last_properties); for (wmOperator *opm = op->macro.first; opm; opm = opm->next) { - IDProperty *idp_src = IDP_GetPropertyFromGroup(op->type->last_properties, opm->idname); + IDProperty *idp_src = IDP_GetPropertyFromGroup(last_properties, opm->idname); if (idp_src) { changed |= operator_last_properties_init_impl(opm, idp_src); } @@ -1241,6 +1277,11 @@ bool WM_operator_last_properties_init(wmOperator *op) return changed; } +bool WM_operator_last_properties_init(wmOperator *op) +{ + return WM_operator_last_properties_init_ex(op, op->type->last_properties); +} + bool WM_operator_last_properties_store(wmOperator *op) { if (op->type->last_properties) { @@ -1272,6 +1313,11 @@ bool WM_operator_last_properties_store(wmOperator *op) #else +bool WM_operator_last_properties_init_ex(wmOperator *UNUSED(op), IDProperty *UNUSED(last_properties)) +{ + return false; +} + bool WM_operator_last_properties_init(wmOperator *UNUSED(op)) { return false; |