Fix T65824: Span property ignored in mesh.fill_grid
authorCampbell Barton <ideasman42@gmail.com>
Mon, 24 Jun 2019 11:41:17 +0000 (21:41 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 24 Jun 2019 11:41:17 +0000 (21:41 +1000)
The fix for T60777 caused this operator not to work from Python.

Add a repeat_last flag for operator execution.

source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/screen/screen_ops.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesrna/intern/rna_wm.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c

index c196a66332de33e4fcabb73e5bfecd57cd79dda6..48cc46f5060eb18955da78f5af828943bb27bd2b 100644 (file)
@@ -4590,7 +4590,7 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op)
 
       /* Only reuse on redo because these settings need to match the current selection.
        * We never want to use them on other geometry, repeat last for eg, see: T60777. */
-      if ((op->flag & OP_IS_REPEAT) && RNA_property_is_set(op->ptr, prop_span)) {
+      if ((op->flag & OP_IS_REPEAT_LAST) == 0 && RNA_property_is_set(op->ptr, prop_span)) {
         span = RNA_property_int_get(op->ptr, prop_span);
         span = min_ii(span, (clamp / 2) - 1);
         calc_span = false;
index 1a146f5bd07ccc27204f82e4eff82c94c83b119d..ef99d39f990ef4b4e5b6701f85f5ff436f12aee2 100644 (file)
@@ -3555,7 +3555,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
 
   if (lastop) {
     WM_operator_free_all_after(wm, lastop);
-    WM_operator_repeat_interactive(C, lastop);
+    WM_operator_repeat_last(C, lastop);
   }
 
   return OPERATOR_CANCELLED;
index 171c0a2518722b1a83574a4266dca24f4f6ce775..c87d50fedaad87b20c0801344a50abfabae206ca 100644 (file)
@@ -505,8 +505,17 @@ enum {
    * Typically this shouldn't make any difference, but it rare cases its needed
    * (see smooth-view) */
   OP_IS_INVOKE = (1 << 0),
-  /** So we can detect if an operators exec() call is activated from an interactive repeat. */
+  /** So we can detect if an operators exec() call is activated by adjusting the last action. */
   OP_IS_REPEAT = (1 << 1),
+  /**
+   * So we can detect if an operators exec() call is activated from #SCREEN_OT_repeat_last.
+   *
+   * This difference can be important because previous settings may be used,
+   * even with #PROP_SKIP_SAVE the repeat last operator will use the previous settings.
+   * Unlike #OP_IS_REPEAT the selection (and context generally) may be be different each time.
+   * See T60777 for an example of when this is needed.
+   */
+  OP_IS_REPEAT_LAST = (1 << 1),
 
   /** When the cursor is grabbed */
   OP_IS_MODAL_GRAB_CURSOR = (1 << 2),
index 72c23f29b31297dcace41bb2586d96fbfa729a93..81bb550616e97c8b5478a9ca79a7b21d8f7f42ed 100644 (file)
@@ -1795,7 +1795,12 @@ static void rna_def_operator_options_runtime(BlenderRNA *brna)
 
   prop = RNA_def_property(srna, "is_repeat", PROP_BOOLEAN, PROP_BOOLEAN);
   RNA_def_property_boolean_sdna(prop, NULL, "flag", OP_IS_REPEAT);
-  RNA_def_property_ui_text(prop, "Repeat", "True when run from the redo panel");
+  RNA_def_property_ui_text(prop, "Repeat", "True when run from the 'Adjust Last Operation' panel");
+  RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+  prop = RNA_def_property(srna, "is_repeat_last", PROP_BOOLEAN, PROP_BOOLEAN);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", OP_IS_REPEAT_LAST);
+  RNA_def_property_ui_text(prop, "Repeat Call", "True when run from the operator 'Repeat Last'");
   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 
   prop = RNA_def_property(srna, "use_cursor_region", PROP_BOOLEAN, PROP_BOOLEAN);
index 5ed1be81bff5e667535740fbaba3bb61797aa05d..61b3b8aa2a29ae87f02ad2d4b2f1a64bdb6692fc 100644 (file)
@@ -391,7 +391,7 @@ int WM_operator_call_ex(struct bContext *C, struct wmOperator *op, const bool st
 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(struct bContext *C, struct wmOperator *op);
-int WM_operator_repeat_interactive(struct bContext *C, struct wmOperator *op);
+int WM_operator_repeat_last(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);
 int WM_operator_name_call_ptr(struct bContext *C,
index a95ccd65dffd3cd9ac4f56d0440421332f1a6b47..24040568b7b581795e32fbcf54fe0501bf41aeb0 100644 (file)
@@ -1033,11 +1033,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat,
 }
 
 /* if repeat is true, it doesn't register again, nor does it free */
-static int wm_operator_exec(bContext *C,
-                            wmOperator *op,
-                            const bool repeat,
-                            const bool use_repeat_op_flag,
-                            const bool store)
+static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, const bool store)
 {
   wmWindowManager *wm = CTX_wm_manager(C);
   int retval = OPERATOR_CANCELLED;
@@ -1057,14 +1053,8 @@ static int wm_operator_exec(bContext *C,
       wm->op_undo_depth++;
     }
 
-    if (repeat && use_repeat_op_flag) {
-      op->flag |= OP_IS_REPEAT;
-    }
     retval = op->type->exec(C, op);
     OPERATOR_RETVAL_CHECK(retval);
-    if (repeat && use_repeat_op_flag) {
-      op->flag &= ~OP_IS_REPEAT;
-    }
 
     if (op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm) {
       wm->op_undo_depth--;
@@ -1114,7 +1104,7 @@ static int wm_operator_exec_notest(bContext *C, wmOperator *op)
  * warning: do not use this within an operator to call its self! [#29537] */
 int WM_operator_call_ex(bContext *C, wmOperator *op, const bool store)
 {
-  return wm_operator_exec(C, op, false, false, store);
+  return wm_operator_exec(C, op, false, store);
 }
 
 int WM_operator_call(bContext *C, wmOperator *op)
@@ -1137,11 +1127,19 @@ int WM_operator_call_notest(bContext *C, wmOperator *op)
  */
 int WM_operator_repeat(bContext *C, wmOperator *op)
 {
-  return wm_operator_exec(C, op, true, true, true);
+  const int op_flag = OP_IS_REPEAT;
+  op->flag |= op_flag;
+  const int ret = wm_operator_exec(C, op, true, true);
+  op->flag &= ~op_flag;
+  return ret;
 }
-int WM_operator_repeat_interactive(bContext *C, wmOperator *op)
+int WM_operator_repeat_last(bContext *C, wmOperator *op)
 {
-  return wm_operator_exec(C, op, true, false, true);
+  const int op_flag = OP_IS_REPEAT_LAST;
+  op->flag |= op_flag;
+  const int ret = wm_operator_exec(C, op, true, true);
+  op->flag &= ~op_flag;
+  return ret;
 }
 /**
  * \return true if #WM_operator_repeat can run