From 1d908bffddb4c9815a986305ad4588032b81deee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Jan 2019 12:06:47 +1100 Subject: 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. --- .../blender/windowmanager/intern/wm_event_system.c | 54 ++++++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'source/blender/windowmanager/intern/wm_event_system.c') 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 @@ -1040,6 +1040,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. @@ -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; -- cgit v1.2.3