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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-01-24 04:06:47 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-01-24 04:12:23 +0300
commit1d908bffddb4c9815a986305ad4588032b81deee (patch)
treeb72181a876688f19eee81b64c16b3316b5d1893b /source
parent7f77961f1c387a93f3fe1df71558d5602f2ca521 (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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c54
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;