Fix [#34675] *AFTER 2.69* Info view shows duplicate operators with incorrect values of args
Refactored a bit WM api to generate operator's pystring, now it can also handle correctly macro operators. Thanks to Campbell for the review!
This commit is contained in:
parent
5cd28bbe80
commit
ad34a5cc1b
|
@ -1534,7 +1534,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
|
|||
char *str;
|
||||
opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */
|
||||
|
||||
str = WM_operator_pystring(C, but->optype, opptr, 0);
|
||||
str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr);
|
||||
|
||||
WM_clipboard_text_set(str, 0);
|
||||
|
||||
|
|
|
@ -2931,7 +2931,7 @@ static void ui_intro_button(DynStr *ds, uiButtonItem *bitem)
|
|||
BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : ""); /* not exactly needed, rna has this */
|
||||
|
||||
if (but->optype) {
|
||||
char *opstr = WM_operator_pystring(but->block->evil_C, but->optype, but->opptr, 0);
|
||||
char *opstr = WM_operator_pystring_ex(but->block->evil_C, NULL, false, but->optype, but->opptr);
|
||||
BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : "");
|
||||
MEM_freeN(opstr);
|
||||
}
|
||||
|
|
|
@ -539,7 +539,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
|
|||
/* so the context is passed to itemf functions (some py itemf functions use it) */
|
||||
WM_operator_properties_sanitize(opptr, false);
|
||||
|
||||
str = WM_operator_pystring(C, but->optype, opptr, 0);
|
||||
str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr);
|
||||
|
||||
/* operator info */
|
||||
if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
|
||||
|
|
|
@ -1034,6 +1034,7 @@ void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier);
|
|||
|
||||
/* python compatible string representation of this property, (must be freed!) */
|
||||
char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length);
|
||||
char *RNA_pointer_as_string_id(struct bContext *C, PointerRNA *ptr);
|
||||
char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop);
|
||||
char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr,
|
||||
const bool skip_optional_value, const bool all_args,
|
||||
|
|
|
@ -4980,7 +4980,7 @@ bool RNA_property_is_unlink(PropertyRNA *prop)
|
|||
/* string representation of a property, python
|
||||
* compatible but can be used for display too,
|
||||
* context may be NULL */
|
||||
static char *rna_pointer_as_string__idprop(bContext *C, PointerRNA *ptr)
|
||||
char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
DynStr *dynstr = BLI_dynstr_new();
|
||||
char *cstring;
|
||||
|
@ -5031,7 +5031,7 @@ static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
|
|||
char *RNA_pointer_as_string(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
|
||||
{
|
||||
if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) {
|
||||
return rna_pointer_as_string__idprop(C, ptr_prop);
|
||||
return RNA_pointer_as_string_id(C, ptr_prop);
|
||||
}
|
||||
else {
|
||||
return rna_pointer_as_string__bldata(ptr_prop);
|
||||
|
|
|
@ -345,7 +345,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
|
|||
error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");
|
||||
|
||||
if (error_val == 0)
|
||||
buf = WM_operator_pystring(C, ot, &ptr, all_args);
|
||||
buf = WM_operator_pystring_ex(C, NULL, all_args, ot, &ptr);
|
||||
|
||||
WM_operator_properties_free(&ptr);
|
||||
|
||||
|
|
|
@ -272,7 +272,9 @@ bool WM_operator_last_properties_store(struct wmOperator *op);
|
|||
|
||||
|
||||
/* operator as a python command (resultuing string must be freed) */
|
||||
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args);
|
||||
char *WM_operator_pystring_ex(struct bContext *C, struct wmOperator *op, const bool all_args,
|
||||
struct wmOperatorType *ot, struct PointerRNA *opptr);
|
||||
char *WM_operator_pystring(struct bContext *C, struct wmOperator *op, const bool all_args);
|
||||
char *WM_prop_pystring_assign(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
|
||||
void WM_operator_bl_idname(char *to, const char *from);
|
||||
void WM_operator_py_idname(char *to, const char *from);
|
||||
|
|
|
@ -491,7 +491,7 @@ int WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context)
|
|||
static void wm_operator_print(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* context is needed for enum function */
|
||||
char *buf = WM_operator_pystring(C, op->type, op->ptr, false);
|
||||
char *buf = WM_operator_pystring(C, op, false);
|
||||
printf("%s\n", buf);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int cal
|
|||
if (op->type->flag & OPTYPE_REGISTER) {
|
||||
if (G.background == 0) { /* ends up printing these in the terminal, gets annoying */
|
||||
/* Report the python string representation of the operator */
|
||||
char *buf = WM_operator_pystring(C, op->type, op->ptr, false);
|
||||
char *buf = WM_operator_pystring(C, op, false);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
@ -660,7 +660,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
|
|||
|
||||
if (repeat == 0) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
char *buf = WM_operator_pystring(C, op->type, op->ptr, false);
|
||||
char *buf = WM_operator_pystring(C, op, false);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
|
|
@ -521,13 +521,14 @@ void WM_operator_bl_idname(char *to, const char *from)
|
|||
to[0] = 0;
|
||||
}
|
||||
|
||||
/* print a string representation of the operator, with the args that it runs
|
||||
* so python can run it again,
|
||||
/* Print a string representation of the operator, with the args that it runs so python can run it again.
|
||||
*
|
||||
* When calling from an existing wmOperator do.
|
||||
* WM_operator_pystring(op->type, op->ptr);
|
||||
* When calling from an existing wmOperator, better to use simple version:
|
||||
* WM_operator_pystring(C, op);
|
||||
*
|
||||
* Note: both op and opptr may be NULL (op is only used for macro operators).
|
||||
*/
|
||||
char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, int all_args)
|
||||
char *WM_operator_pystring_ex(bContext *C, wmOperator *op, const bool all_args, wmOperatorType *ot, PointerRNA *opptr)
|
||||
{
|
||||
char idname_py[OP_MAX_TYPENAME];
|
||||
|
||||
|
@ -539,24 +540,53 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i
|
|||
/* arbitrary, but can get huge string with stroke painting otherwise */
|
||||
int max_prop_length = 10;
|
||||
|
||||
/* only to get the orginal props for comparisons */
|
||||
PointerRNA opptr_default;
|
||||
|
||||
if (opptr == NULL) {
|
||||
WM_operator_properties_create_ptr(&opptr_default, ot);
|
||||
opptr = &opptr_default;
|
||||
}
|
||||
|
||||
WM_operator_py_idname(idname_py, ot->idname);
|
||||
BLI_dynstr_appendf(dynstr, "bpy.ops.%s(", idname_py);
|
||||
|
||||
cstring_args = RNA_pointer_as_string_keywords(C, opptr, false,
|
||||
all_args, max_prop_length);
|
||||
BLI_dynstr_append(dynstr, cstring_args);
|
||||
MEM_freeN(cstring_args);
|
||||
if (op && op->macro.first) {
|
||||
/* Special handling for macros, else we only get default values in this case... */
|
||||
wmOperator *opm;
|
||||
bool first_op = true;
|
||||
for (opm = op->macro.first; opm; opm = opm->next) {
|
||||
PointerRNA *opmptr = opm->ptr;
|
||||
PointerRNA opmptr_default;
|
||||
if (opmptr == NULL) {
|
||||
WM_operator_properties_create_ptr(&opmptr_default, opm->type);
|
||||
opmptr = &opmptr_default;
|
||||
}
|
||||
|
||||
if (opptr == &opptr_default)
|
||||
WM_operator_properties_free(&opptr_default);
|
||||
cstring_args = RNA_pointer_as_string_id(C, opmptr);
|
||||
if (first_op) {
|
||||
BLI_dynstr_appendf(dynstr, "%s=%s", opm->type->idname, cstring_args);
|
||||
first_op = false;
|
||||
}
|
||||
else {
|
||||
BLI_dynstr_appendf(dynstr, ", %s=%s", opm->type->idname, cstring_args);
|
||||
}
|
||||
MEM_freeN(cstring_args);
|
||||
|
||||
if (opmptr == &opmptr_default) {
|
||||
WM_operator_properties_free(&opmptr_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only to get the orginal props for comparisons */
|
||||
PointerRNA opptr_default;
|
||||
|
||||
if (opptr == NULL) {
|
||||
WM_operator_properties_create_ptr(&opptr_default, ot);
|
||||
opptr = &opptr_default;
|
||||
}
|
||||
|
||||
cstring_args = RNA_pointer_as_string_keywords(C, opptr, false, all_args, max_prop_length);
|
||||
BLI_dynstr_append(dynstr, cstring_args);
|
||||
MEM_freeN(cstring_args);
|
||||
|
||||
if (opptr == &opptr_default) {
|
||||
WM_operator_properties_free(&opptr_default);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_dynstr_append(dynstr, ")");
|
||||
|
||||
|
@ -565,6 +595,11 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i
|
|||
return cstring;
|
||||
}
|
||||
|
||||
char *WM_operator_pystring(bContext *C, wmOperator *op, const bool all_args)
|
||||
{
|
||||
return WM_operator_pystring_ex(C, op, all_args, op->type, op->ptr);
|
||||
}
|
||||
|
||||
/* return NULL if no match is found */
|
||||
#if 0
|
||||
static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
|
|
|
@ -541,7 +541,8 @@ void WM_operator_py_idname(char *to, const char *from) {STUB_ASSERT(0);}
|
|||
void WM_operator_ui_popup(struct bContext *C, struct wmOperator *op, int width, int height) {STUB_ASSERT(0);}
|
||||
short insert_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) {STUB_ASSERT(0); return 0;}
|
||||
short delete_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) {STUB_ASSERT(0); return 0;}
|
||||
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args) {STUB_ASSERT(0); return (char *)NULL;}
|
||||
char *WM_operator_pystring_ex(struct bContext *C, struct wmOperator *op, const bool all_args, struct wmOperatorType *ot, struct PointerRNA *opptr) {STUB_ASSERT(0); return (char *)NULL;}
|
||||
char *WM_operator_pystring(struct bContext *C, struct wmOperator *op, const bool all_args) {STUB_ASSERT(0); return (char *)NULL;}
|
||||
struct wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value) {STUB_ASSERT(0); return (struct wmKeyMapItem *)NULL;}
|
||||
struct wmKeyMapItem *WM_modalkeymap_add_item_str(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value) {STUB_ASSERT(0); return (struct wmKeyMapItem *)NULL;}
|
||||
struct wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, char *idname, EnumPropertyItem *items) {STUB_ASSERT(0); return (struct wmKeyMap *) NULL;}
|
||||
|
|
Loading…
Reference in New Issue