Cleanup: Use std::string for WM API function return values
This commit is contained in:
@@ -1359,6 +1359,7 @@ static bool ui_but_event_property_operator_string(const bContext *C,
|
||||
char *buf,
|
||||
const size_t buf_maxncpy)
|
||||
{
|
||||
using namespace blender;
|
||||
/* Context toggle operator names to check. */
|
||||
|
||||
/* NOTE(@ideasman42): This function could use a refactor to generalize button type to operator
|
||||
@@ -1448,18 +1449,17 @@ static bool ui_but_event_property_operator_string(const bContext *C,
|
||||
/* There may be multiple data-paths to the same properties,
|
||||
* support different variations so key bindings are properly detected no matter which are used.
|
||||
*/
|
||||
char *data_path_variations[2] = {nullptr};
|
||||
int data_path_variations_num = 0;
|
||||
Vector<std::string, 2> data_path_variations;
|
||||
|
||||
{
|
||||
char *data_path = WM_context_path_resolve_property_full(C, ptr, prop, prop_index);
|
||||
std::string data_path = WM_context_path_resolve_property_full(C, ptr, prop, prop_index);
|
||||
|
||||
/* Always iterate once, even if data-path isn't set. */
|
||||
data_path_variations[data_path_variations_num++] = data_path;
|
||||
data_path_variations.append(data_path);
|
||||
|
||||
if (data_path) {
|
||||
if (STRPREFIX(data_path, "scene.tool_settings.")) {
|
||||
data_path_variations[data_path_variations_num++] = BLI_strdup(data_path + 6);
|
||||
if (!data_path.empty()) {
|
||||
if (StringRef(data_path).startswith("scene.tool_settings.")) {
|
||||
data_path_variations.append(StringRef(data_path).drop_known_prefix("scene."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1467,18 +1467,18 @@ static bool ui_but_event_property_operator_string(const bContext *C,
|
||||
/* We have a data-path! */
|
||||
bool found = false;
|
||||
|
||||
for (int data_path_index = 0; data_path_index < data_path_variations_num && (found == false);
|
||||
for (int data_path_index = 0; data_path_index < data_path_variations.size() && (found == false);
|
||||
data_path_index++)
|
||||
{
|
||||
const char *data_path = data_path_variations[data_path_index];
|
||||
if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
|
||||
const StringRefNull data_path = data_path_variations[data_path_index];
|
||||
if (!data_path.is_empty() || (prop_enum_value_ok && prop_enum_value_id)) {
|
||||
/* Create a property to host the "data_path" property we're sending to the operators. */
|
||||
IDProperty *prop_path;
|
||||
|
||||
const IDPropertyTemplate group_val = {0};
|
||||
prop_path = IDP_New(IDP_GROUP, &group_val, __func__);
|
||||
if (data_path) {
|
||||
IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path"));
|
||||
if (!data_path.is_empty()) {
|
||||
IDP_AddToGroup(prop_path, IDP_NewString(data_path.c_str(), "data_path"));
|
||||
}
|
||||
if (prop_enum_value_ok) {
|
||||
const EnumPropertyItem *item;
|
||||
@@ -1522,12 +1522,6 @@ static bool ui_but_event_property_operator_string(const bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
for (int data_path_index = 0; data_path_index < data_path_variations_num; data_path_index++) {
|
||||
char *data_path = data_path_variations[data_path_index];
|
||||
if (data_path) {
|
||||
MEM_freeN(data_path);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,18 +61,16 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but)
|
||||
|
||||
/* If this returns null, we won't be able to bind shortcuts to these RNA properties.
|
||||
* Support can be added at #wm_context_member_from_ptr. */
|
||||
char *final_data_path = WM_context_path_resolve_property_full(
|
||||
std::string final_data_path = WM_context_path_resolve_property_full(
|
||||
C, &but->rnapoin, but->rnaprop, but->rnaindex);
|
||||
if (final_data_path == nullptr) {
|
||||
if (final_data_path.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Create ID property of data path, to pass to the operator. */
|
||||
const IDPropertyTemplate val = {0};
|
||||
IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__);
|
||||
IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path"));
|
||||
|
||||
MEM_freeN((void *)final_data_path);
|
||||
IDP_AddToGroup(prop, IDP_NewString(final_data_path.c_str(), "data_path"));
|
||||
|
||||
return prop;
|
||||
}
|
||||
@@ -321,9 +319,8 @@ static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
|
||||
}
|
||||
else if (but->rnaprop) {
|
||||
if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
|
||||
char *data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
if (data_path != nullptr) {
|
||||
MEM_freeN(data_path);
|
||||
std::string data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
if (!data_path.empty()) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
@@ -346,14 +343,13 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
|
||||
&um->items, but->optype, prop, "", but->opcontext);
|
||||
}
|
||||
if (but->rnaprop) {
|
||||
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
std::string member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
||||
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
||||
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
||||
RNA_property_identifier(but->rnaprop);
|
||||
bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
|
||||
&um->items, member_id_data_path, prop_id, but->rnaindex);
|
||||
MEM_freeN(member_id_data_path);
|
||||
&um->items, member_id_data_path.c_str(), prop_id, but->rnaindex);
|
||||
return umi;
|
||||
}
|
||||
|
||||
@@ -423,14 +419,14 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||
}
|
||||
else if (but->rnaprop) {
|
||||
/* NOTE: 'member_id' may be a path. */
|
||||
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
std::string member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
|
||||
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
||||
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
||||
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
||||
RNA_property_identifier(but->rnaprop);
|
||||
/* NOTE: ignore 'drawstr', use property idname always. */
|
||||
ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
|
||||
MEM_freeN(member_id_data_path);
|
||||
ED_screen_user_menu_item_add_prop(
|
||||
&um->items, "", member_id_data_path.c_str(), prop_id, but->rnaindex);
|
||||
}
|
||||
else if ((mt = UI_but_menutype_get(but))) {
|
||||
ED_screen_user_menu_item_add_menu(&um->items, drawstr.c_str(), mt);
|
||||
|
||||
@@ -1001,13 +1001,12 @@ static void ui_apply_but_autokey(bContext *C, uiBut *but)
|
||||
}
|
||||
|
||||
/* make a little report about what we've done! */
|
||||
char *buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
|
||||
if (buf) {
|
||||
BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
|
||||
MEM_freeN(buf);
|
||||
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, nullptr);
|
||||
const std::string str = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
|
||||
if (str.empty()) {
|
||||
return;
|
||||
}
|
||||
BKE_report(CTX_wm_reports(C), RPT_PROPERTY, str.c_str());
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, nullptr);
|
||||
}
|
||||
|
||||
static void ui_apply_but_funcs_after(bContext *C)
|
||||
@@ -2736,10 +2735,8 @@ static void ui_but_copy_operator(bContext *C, uiBut *but, char *output, int outp
|
||||
{
|
||||
PointerRNA *opptr = UI_but_operator_ptr_ensure(but);
|
||||
|
||||
char *str;
|
||||
str = WM_operator_pystring_ex(C, nullptr, false, true, but->optype, opptr);
|
||||
BLI_strncpy(output, str, output_maxncpy);
|
||||
MEM_freeN(str);
|
||||
std::string str = WM_operator_pystring_ex(C, nullptr, false, true, but->optype, opptr);
|
||||
BLI_strncpy(output, str.c_str(), output_maxncpy);
|
||||
}
|
||||
|
||||
static bool ui_but_copy_menu(uiBut *but, char *output, int output_maxncpy)
|
||||
|
||||
@@ -6287,25 +6287,23 @@ static void ui_layout_introspect_button(DynStr *ds, uiButtonItem *bitem)
|
||||
BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : "");
|
||||
|
||||
if (but->optype) {
|
||||
char *opstr = WM_operator_pystring_ex(static_cast<bContext *>(but->block->evil_C),
|
||||
nullptr,
|
||||
false,
|
||||
true,
|
||||
but->optype,
|
||||
but->opptr);
|
||||
BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : "");
|
||||
MEM_freeN(opstr);
|
||||
std::string opstr = WM_operator_pystring_ex(static_cast<bContext *>(but->block->evil_C),
|
||||
nullptr,
|
||||
false,
|
||||
true,
|
||||
but->optype,
|
||||
but->opptr);
|
||||
BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr.c_str());
|
||||
}
|
||||
|
||||
{
|
||||
PropertyRNA *prop = nullptr;
|
||||
wmOperatorType *ot = UI_but_operatortype_get_from_enum_menu(but, &prop);
|
||||
if (ot) {
|
||||
char *opstr = WM_operator_pystring_ex(
|
||||
std::string opstr = WM_operator_pystring_ex(
|
||||
static_cast<bContext *>(but->block->evil_C), nullptr, false, true, ot, nullptr);
|
||||
BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : "");
|
||||
BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr.c_str());
|
||||
BLI_dynstr_appendf(ds, "'property':'''%s''', ", prop ? RNA_property_identifier(prop) : "");
|
||||
MEM_freeN(opstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,15 +283,12 @@ static int copy_python_command_button_exec(bContext *C, wmOperator * /*op*/)
|
||||
uiBut *but = UI_context_active_but_get(C);
|
||||
|
||||
if (but && (but->optype != nullptr)) {
|
||||
PointerRNA *opptr;
|
||||
char *str;
|
||||
opptr = UI_but_operator_ptr_ensure(but); /* allocated when needed, the button owns it */
|
||||
/* allocated when needed, the button owns it */
|
||||
PointerRNA *opptr = UI_but_operator_ptr_ensure(but);
|
||||
|
||||
str = WM_operator_pystring_ex(C, nullptr, false, true, but->optype, opptr);
|
||||
std::string str = WM_operator_pystring_ex(C, nullptr, false, true, but->optype, opptr);
|
||||
|
||||
WM_clipboard_text_set(str, false);
|
||||
|
||||
MEM_freeN(str);
|
||||
WM_clipboard_text_set(str.c_str(), false);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -347,14 +347,14 @@ static void ui_tooltip_region_free_cb(ARegion *region)
|
||||
/** \name ToolTip Creation Utility Functions
|
||||
* \{ */
|
||||
|
||||
static char *ui_tooltip_text_python_from_op(bContext *C, wmOperatorType *ot, PointerRNA *opptr)
|
||||
static std::string ui_tooltip_text_python_from_op(bContext *C,
|
||||
wmOperatorType *ot,
|
||||
PointerRNA *opptr)
|
||||
{
|
||||
char *str = WM_operator_pystring_ex(C, nullptr, false, false, ot, opptr);
|
||||
std::string str = WM_operator_pystring_ex(C, nullptr, false, false, ot, opptr);
|
||||
|
||||
/* Avoid overly verbose tips (eg, arrays of 20 layers), exact limit is arbitrary. */
|
||||
WM_operator_pystring_abbreviate(str, 32);
|
||||
|
||||
return str;
|
||||
return WM_operator_pystring_abbreviate(std::move(str), 32);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -397,10 +397,9 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data,
|
||||
|
||||
/* Python. */
|
||||
if (U.flag & USER_TOOLTIPS_PYTHON) {
|
||||
char *str = ui_tooltip_text_python_from_op(C, ot, kmi->ptr);
|
||||
std::string str = ui_tooltip_text_python_from_op(C, ot, kmi->ptr);
|
||||
UI_tooltip_text_field_add(
|
||||
data, fmt::format(TIP_("Python: {}"), str), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_PYTHON);
|
||||
MEM_freeN(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -744,14 +743,13 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
|
||||
/* Python */
|
||||
if ((is_label == false) && (U.flag & USER_TOOLTIPS_PYTHON)) {
|
||||
char *str = ui_tooltip_text_python_from_op(C, but->optype, but->opptr);
|
||||
std::string str = ui_tooltip_text_python_from_op(C, but->optype, but->opptr);
|
||||
UI_tooltip_text_field_add(data,
|
||||
fmt::format(TIP_("Python: {}"), str),
|
||||
{},
|
||||
UI_TIP_STYLE_NORMAL,
|
||||
UI_TIP_LC_PYTHON,
|
||||
true);
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
/* Keymap */
|
||||
@@ -985,7 +983,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
|
||||
/* So the context is passed to field functions (some Python field functions use it). */
|
||||
WM_operator_properties_sanitize(opptr, false);
|
||||
|
||||
char *str = ui_tooltip_text_python_from_op(C, optype, opptr);
|
||||
std::string str = ui_tooltip_text_python_from_op(C, optype, opptr);
|
||||
|
||||
/* Operator info. */
|
||||
if (U.flag & USER_TOOLTIPS_PYTHON) {
|
||||
@@ -996,8 +994,6 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
|
||||
UI_TIP_LC_PYTHON,
|
||||
true);
|
||||
}
|
||||
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
/* Button is disabled, we may be able to tell user why. */
|
||||
|
||||
@@ -313,7 +313,6 @@ static PyObject *pyop_as_string(PyObject * /*self*/, PyObject *args)
|
||||
bool macro_args = true;
|
||||
int error_val = 0;
|
||||
|
||||
char *buf = nullptr;
|
||||
PyObject *pybuf;
|
||||
|
||||
bContext *C = BPY_context_get();
|
||||
@@ -370,8 +369,9 @@ static PyObject *pyop_as_string(PyObject * /*self*/, PyObject *args)
|
||||
&ptr, kw, false, "Converting py args to operator properties: ");
|
||||
}
|
||||
|
||||
std::string op_string;
|
||||
if (error_val == 0) {
|
||||
buf = WM_operator_pystring_ex(C, nullptr, all_args, macro_args, ot, &ptr);
|
||||
op_string = WM_operator_pystring_ex(C, nullptr, all_args, macro_args, ot, &ptr);
|
||||
}
|
||||
|
||||
WM_operator_properties_free(&ptr);
|
||||
@@ -380,9 +380,8 @@ static PyObject *pyop_as_string(PyObject * /*self*/, PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
pybuf = PyUnicode_FromString(buf);
|
||||
MEM_freeN(buf);
|
||||
if (!op_string.empty()) {
|
||||
pybuf = PyUnicode_FromString(op_string.c_str());
|
||||
}
|
||||
else {
|
||||
pybuf = PyUnicode_FromString("");
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* \todo document
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_sys_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
@@ -1045,9 +1047,9 @@ bool WM_operator_properties_checker_interval_test(const CheckerIntervalParams *o
|
||||
int depth);
|
||||
|
||||
/**
|
||||
* Operator as a Python command (resulting string must be freed).
|
||||
* Operator as a Python command.
|
||||
*
|
||||
* Print a string representation of the operator,
|
||||
* Return a string representation of the operator,
|
||||
* with the arguments that it runs so Python can run it again.
|
||||
*
|
||||
* When calling from an existing #wmOperator, better to use simple version:
|
||||
@@ -1055,18 +1057,17 @@ bool WM_operator_properties_checker_interval_test(const CheckerIntervalParams *o
|
||||
*
|
||||
* \note Both \a op and \a opptr may be `NULL` (\a op is only used for macro operators).
|
||||
*/
|
||||
char *WM_operator_pystring_ex(bContext *C,
|
||||
wmOperator *op,
|
||||
bool all_args,
|
||||
bool macro_args,
|
||||
wmOperatorType *ot,
|
||||
PointerRNA *opptr);
|
||||
char *WM_operator_pystring(bContext *C, wmOperator *op, bool all_args, bool macro_args);
|
||||
/**
|
||||
* \return true if the string was shortened.
|
||||
*/
|
||||
bool WM_operator_pystring_abbreviate(char *str, int str_len_max);
|
||||
char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
|
||||
std::string WM_operator_pystring_ex(bContext *C,
|
||||
wmOperator *op,
|
||||
bool all_args,
|
||||
bool macro_args,
|
||||
wmOperatorType *ot,
|
||||
PointerRNA *opptr);
|
||||
std::string WM_operator_pystring(bContext *C, wmOperator *op, bool all_args, bool macro_args);
|
||||
|
||||
std::string WM_operator_pystring_abbreviate(std::string str, int str_len_max);
|
||||
|
||||
std::string WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
|
||||
/**
|
||||
* Convert: `some.op` -> `SOME_OT_op` or leave as-is.
|
||||
* \return the length of `dst`.
|
||||
@@ -1087,11 +1088,11 @@ bool WM_operator_py_idname_ok_or_report(ReportList *reports,
|
||||
/**
|
||||
* Calculate the path to `ptr` from context `C`, or return NULL if it can't be calculated.
|
||||
*/
|
||||
char *WM_context_path_resolve_property_full(const bContext *C,
|
||||
const PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index);
|
||||
char *WM_context_path_resolve_full(bContext *C, const PointerRNA *ptr);
|
||||
std::string WM_context_path_resolve_property_full(const bContext *C,
|
||||
const PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index);
|
||||
std::string WM_context_path_resolve_full(bContext *C, const PointerRNA *ptr);
|
||||
|
||||
/* `wm_operator_type.cc` */
|
||||
|
||||
|
||||
@@ -1097,7 +1097,7 @@ static void wm_operator_reports(bContext *C,
|
||||
}
|
||||
|
||||
if (retval & OPERATOR_FINISHED) {
|
||||
CLOG_STR_INFO_N(WM_LOG_OPERATORS, 1, WM_operator_pystring(C, op, false, true));
|
||||
CLOG_STR_INFO_N(WM_LOG_OPERATORS, 1, WM_operator_pystring(C, op, false, true).c_str());
|
||||
|
||||
if (caller_owns_reports == false) {
|
||||
BKE_reports_print(op->reports, RPT_DEBUG); /* Print out reports to console. */
|
||||
@@ -1105,10 +1105,9 @@ static void wm_operator_reports(bContext *C,
|
||||
|
||||
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, false, true);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
|
||||
MEM_freeN(buf);
|
||||
/* Report the python string representation of the operator. */
|
||||
std::string pystring = WM_operator_pystring(C, op, false, true);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, pystring.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1189,9 +1188,8 @@ static void wm_operator_finished(bContext *C,
|
||||
|
||||
if (repeat == 0) {
|
||||
if (G.debug & G_DEBUG_WM) {
|
||||
char *buf = WM_operator_pystring(C, op, false, true);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
|
||||
MEM_freeN(buf);
|
||||
std::string pystring = WM_operator_pystring(C, op, false, true);
|
||||
BKE_report(CTX_wm_reports(C), RPT_OPERATOR, pystring.c_str());
|
||||
}
|
||||
|
||||
if (do_register) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include "GHOST_C-api.h"
|
||||
#endif
|
||||
@@ -40,7 +42,6 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dial_2d.h"
|
||||
#include "BLI_dynstr.h" /* For #WM_operator_pystring. */
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_string_utils.hh"
|
||||
@@ -212,23 +213,23 @@ bool WM_operator_py_idname_ok_or_report(ReportList *reports,
|
||||
return true;
|
||||
}
|
||||
|
||||
char *WM_operator_pystring_ex(bContext *C,
|
||||
wmOperator *op,
|
||||
const bool all_args,
|
||||
const bool macro_args,
|
||||
wmOperatorType *ot,
|
||||
PointerRNA *opptr)
|
||||
std::string WM_operator_pystring_ex(bContext *C,
|
||||
wmOperator *op,
|
||||
const bool all_args,
|
||||
const bool macro_args,
|
||||
wmOperatorType *ot,
|
||||
PointerRNA *opptr)
|
||||
{
|
||||
char idname_py[OP_MAX_TYPENAME];
|
||||
|
||||
/* for building the string */
|
||||
DynStr *dynstr = BLI_dynstr_new();
|
||||
std::stringstream ss;
|
||||
|
||||
/* arbitrary, but can get huge string with stroke painting otherwise */
|
||||
int max_prop_length = 10;
|
||||
|
||||
WM_operator_py_idname(idname_py, ot->idname);
|
||||
BLI_dynstr_appendf(dynstr, "bpy.ops.%s(", idname_py);
|
||||
ss << "bpy.ops." << idname_py << "(";
|
||||
|
||||
if (op && op->macro.first) {
|
||||
/* Special handling for macros, else we only get default values in this case... */
|
||||
@@ -247,11 +248,11 @@ char *WM_operator_pystring_ex(bContext *C,
|
||||
|
||||
char *cstring_args = RNA_pointer_as_string_id(C, opmptr);
|
||||
if (first_op) {
|
||||
BLI_dynstr_appendf(dynstr, "%s=%s", opm->type->idname, cstring_args);
|
||||
ss << opm->type->idname << '=' << cstring_args;
|
||||
first_op = false;
|
||||
}
|
||||
else {
|
||||
BLI_dynstr_appendf(dynstr, ", %s=%s", opm->type->idname, cstring_args);
|
||||
ss << ", " << opm->type->idname << '=' << cstring_args;
|
||||
}
|
||||
MEM_freeN(cstring_args);
|
||||
|
||||
@@ -272,7 +273,7 @@ char *WM_operator_pystring_ex(bContext *C,
|
||||
|
||||
char *cstring_args = RNA_pointer_as_string_keywords(
|
||||
C, opptr, false, all_args, macro_args_test, max_prop_length);
|
||||
BLI_dynstr_append(dynstr, cstring_args);
|
||||
ss << cstring_args;
|
||||
MEM_freeN(cstring_args);
|
||||
|
||||
if (opptr == &opptr_default) {
|
||||
@@ -280,53 +281,53 @@ char *WM_operator_pystring_ex(bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
BLI_dynstr_append(dynstr, ")");
|
||||
ss << ')';
|
||||
|
||||
char *cstring = BLI_dynstr_get_cstring(dynstr);
|
||||
BLI_dynstr_free(dynstr);
|
||||
return cstring;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
char *WM_operator_pystring(bContext *C, wmOperator *op, const bool all_args, const bool macro_args)
|
||||
std::string WM_operator_pystring(bContext *C,
|
||||
wmOperator *op,
|
||||
const bool all_args,
|
||||
const bool macro_args)
|
||||
{
|
||||
return WM_operator_pystring_ex(C, op, all_args, macro_args, op->type, op->ptr);
|
||||
}
|
||||
|
||||
bool WM_operator_pystring_abbreviate(char *str, int str_len_max)
|
||||
std::string WM_operator_pystring_abbreviate(std::string str, int str_len_max)
|
||||
{
|
||||
const int str_len = strlen(str);
|
||||
const char *parens_start = strchr(str, '(');
|
||||
|
||||
if (parens_start) {
|
||||
const int parens_start_pos = parens_start - str;
|
||||
const char *parens_end = strrchr(parens_start + 1, ')');
|
||||
|
||||
if (parens_end) {
|
||||
const int parens_len = parens_end - parens_start;
|
||||
|
||||
if (parens_len > str_len_max) {
|
||||
const char *comma_first = strchr(parens_start, ',');
|
||||
|
||||
/* Truncate after the first comma. */
|
||||
if (comma_first) {
|
||||
const char end_str[] = " ... )";
|
||||
const int end_str_len = sizeof(end_str) - 1;
|
||||
|
||||
/* Leave a place for the first argument. */
|
||||
const int new_str_len = (comma_first - parens_start) + 1;
|
||||
|
||||
if (str_len >= new_str_len + parens_start_pos + end_str_len + 1) {
|
||||
/* Append " ... )" to the string after the comma. */
|
||||
memcpy(str + new_str_len + parens_start_pos, end_str, end_str_len + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const int str_len = str.size();
|
||||
const size_t parens_start = str.find('(');
|
||||
if (parens_start == std::string::npos) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return false;
|
||||
const size_t parens_end = str.find(parens_start + 1, ')');
|
||||
if (parens_end == std::string::npos) {
|
||||
return str;
|
||||
}
|
||||
|
||||
const int parens_len = parens_end - parens_start;
|
||||
if (parens_len <= str_len_max) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Truncate after the first comma. */
|
||||
const size_t comma_first = str.find(parens_start, ',');
|
||||
if (comma_first == std::string::npos) {
|
||||
return str;
|
||||
}
|
||||
const char end_str[] = " ... )";
|
||||
const int end_str_len = sizeof(end_str) - 1;
|
||||
|
||||
/* Leave a place for the first argument. */
|
||||
const int new_str_len = (comma_first - parens_start) + 1;
|
||||
|
||||
if (str_len < new_str_len + parens_start + end_str_len + 1) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.substr(0, comma_first) + end_str;
|
||||
}
|
||||
|
||||
/* return nullptr if no match is found */
|
||||
@@ -595,94 +596,87 @@ static const char *wm_context_member_from_ptr(const bContext *C,
|
||||
}
|
||||
#endif
|
||||
|
||||
char *WM_context_path_resolve_property_full(const bContext *C,
|
||||
const PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index)
|
||||
std::string WM_context_path_resolve_property_full(const bContext *C,
|
||||
const PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index)
|
||||
{
|
||||
bool is_id;
|
||||
const char *member_id = wm_context_member_from_ptr(C, ptr, &is_id);
|
||||
char *member_id_data_path = nullptr;
|
||||
if (member_id != nullptr) {
|
||||
if (is_id && !RNA_struct_is_ID(ptr->type)) {
|
||||
char *data_path = RNA_path_from_ID_to_struct(ptr);
|
||||
if (data_path != nullptr) {
|
||||
if (prop != nullptr) {
|
||||
char *prop_str = RNA_path_property_py(ptr, prop, index);
|
||||
if (prop_str[0] == '[') {
|
||||
member_id_data_path = BLI_string_joinN(member_id, ".", data_path, prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = BLI_string_join_by_sep_charN(
|
||||
'.', member_id, data_path, prop_str);
|
||||
}
|
||||
MEM_freeN(prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = BLI_string_join_by_sep_charN('.', member_id, data_path);
|
||||
}
|
||||
MEM_freeN(data_path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!member_id) {
|
||||
return "";
|
||||
}
|
||||
std::string member_id_data_path;
|
||||
if (is_id && !RNA_struct_is_ID(ptr->type)) {
|
||||
char *data_path = RNA_path_from_ID_to_struct(ptr);
|
||||
if (data_path != nullptr) {
|
||||
if (prop != nullptr) {
|
||||
char *prop_str = RNA_path_property_py(ptr, prop, index);
|
||||
if (prop_str[0] == '[') {
|
||||
member_id_data_path = BLI_string_joinN(member_id, prop_str);
|
||||
member_id_data_path = fmt::format("{}.{}", data_path, prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = BLI_string_join_by_sep_charN('.', member_id, prop_str);
|
||||
member_id_data_path = fmt::format("{}.{}.{}", member_id, data_path, prop_str);
|
||||
}
|
||||
MEM_freeN(prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = BLI_strdup(member_id);
|
||||
member_id_data_path = fmt::format("{}.{}", member_id, data_path);
|
||||
}
|
||||
MEM_freeN(data_path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prop != nullptr) {
|
||||
char *prop_str = RNA_path_property_py(ptr, prop, index);
|
||||
if (prop_str[0] == '[') {
|
||||
member_id_data_path = fmt::format("{}{}", member_id, prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = fmt::format("{}.{}", member_id, prop_str);
|
||||
}
|
||||
MEM_freeN(prop_str);
|
||||
}
|
||||
else {
|
||||
member_id_data_path = member_id;
|
||||
}
|
||||
}
|
||||
|
||||
return member_id_data_path;
|
||||
}
|
||||
|
||||
char *WM_context_path_resolve_full(bContext *C, const PointerRNA *ptr)
|
||||
std::string WM_context_path_resolve_full(bContext *C, const PointerRNA *ptr)
|
||||
{
|
||||
return WM_context_path_resolve_property_full(C, ptr, nullptr, -1);
|
||||
}
|
||||
|
||||
static char *wm_prop_pystring_from_context(bContext *C,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index)
|
||||
static std::string wm_prop_pystring_from_context(bContext *C,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index)
|
||||
{
|
||||
char *member_id_data_path = WM_context_path_resolve_property_full(C, ptr, prop, index);
|
||||
char *ret = nullptr;
|
||||
if (member_id_data_path != nullptr) {
|
||||
ret = BLI_sprintfN("bpy.context.%s", member_id_data_path);
|
||||
MEM_freeN(member_id_data_path);
|
||||
std::string member_id_data_path = WM_context_path_resolve_property_full(C, ptr, prop, index);
|
||||
if (member_id_data_path.empty()) {
|
||||
return "";
|
||||
}
|
||||
return ret;
|
||||
return "bpy.context." + member_id_data_path;
|
||||
}
|
||||
|
||||
char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
std::string WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
{
|
||||
char *lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : nullptr;
|
||||
std::string lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : "";
|
||||
|
||||
if (lhs == nullptr) {
|
||||
if (lhs.empty()) {
|
||||
/* Fallback to `bpy.data.foo[id]` if we don't find in the context. */
|
||||
lhs = RNA_path_full_property_py(ptr, prop, index);
|
||||
}
|
||||
|
||||
if (!lhs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char *rhs = RNA_property_as_string(C, ptr, prop, index, INT_MAX);
|
||||
if (!rhs) {
|
||||
MEM_freeN(lhs);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char *ret = BLI_sprintfN("%s = %s", lhs, rhs);
|
||||
MEM_freeN(lhs);
|
||||
std::string ret = fmt::format("{} = {}", lhs, rhs);
|
||||
MEM_freeN(rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user