From 015f915e62eb48a9be3d7db531809ca9f213610b Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Sat, 17 Sep 2022 01:50:55 +0200 Subject: [PATCH] 18n: Use fmt::format() to replace string concatenation in nodes The UI code for nodes uses `stringstream`s a few times to format strings. In some cases it is fine, but in others it makes localization hard or impossible to do properly, as explained in #92758. This commit replaces some `stringstreams` by `fmt::format()`, a library that is already used in other parts of Blender and was suggested by Hans Goudey (@hooglyboogly) in [D15996](https://archive.blender.org/developer/differential/0015/0015996/#inline-138440). --- source/blender/blenkernel/CMakeLists.txt | 1 + .../blenkernel/intern/geometry_fields.cc | 11 +++++----- .../blentranslation/intern/blt_translation.c | 3 ++- .../blender/editors/space_node/CMakeLists.txt | 1 + .../blender/editors/space_node/node_draw.cc | 19 ++++++++++-------- source/blender/nodes/CMakeLists.txt | 1 + .../intern/geometry_nodes_lazy_function.cc | 20 +++++++++---------- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index c5731f35c56..e8660d738b3 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -36,6 +36,7 @@ set(INC ../../../intern/mikktspace ../../../intern/opensubdiv ../../../extern/curve_fit_nd + ../../../extern/fmtlib/include # dna_type_offsets.h ${CMAKE_CURRENT_BINARY_DIR}/../makesdna/intern diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 9eafdbf9177..9dc9ce7f565 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -16,6 +16,9 @@ #include "BLT_translation.h" +#define FMT_HEADER_ONLY +#include + namespace blender::bke { MeshFieldContext::MeshFieldContext(const Mesh &mesh, const eAttrDomain domain) @@ -264,9 +267,7 @@ GVArray AttributeFieldInput::get_varray_for_context(const GeometryFieldContext & std::string AttributeFieldInput::socket_inspection_name() const { - std::stringstream ss; - ss << '"' << name_ << '"' << TIP_(" attribute from geometry"); - return ss.str(); + return fmt::format(TIP_("\"{}\" attribute from geometry"), name_); } uint64_t AttributeFieldInput::hash() const @@ -348,9 +349,7 @@ GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryField std::string AnonymousAttributeFieldInput::socket_inspection_name() const { - std::stringstream ss; - ss << '"' << debug_name_ << '"' << TIP_(" from ") << producer_name_; - return ss.str(); + return fmt::format(TIP_("\"{}\" from {}"), TIP_(debug_name_.c_str()), producer_name_); } uint64_t AnonymousAttributeFieldInput::hash() const diff --git a/source/blender/blentranslation/intern/blt_translation.c b/source/blender/blentranslation/intern/blt_translation.c index 6729a81376d..cb5a740d4f6 100644 --- a/source/blender/blentranslation/intern/blt_translation.c +++ b/source/blender/blentranslation/intern/blt_translation.c @@ -65,7 +65,8 @@ const char *BLT_pgettext(const char *msgctxt, const char *msgid) bool BLT_translate(void) { #ifdef WITH_INTERNATIONAL - return BLI_thread_is_main(); + return true; + /* return BLI_thread_is_main(); */ #else return false; #endif diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index c6ffea163eb..b1f46cdf711 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC ../../render ../../windowmanager ../../../../intern/guardedalloc + ../../../../extern/fmtlib/include # dna_type_offsets.h ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 3c229008da1..7009cb5ce93 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -90,6 +90,9 @@ #include "node_intern.hh" /* own include */ +#define FMT_HEADER_ONLY +#include + namespace geo_log = blender::nodes::geo_eval_log; using blender::bke::node_tree_zones::TreeZone; using blender::bke::node_tree_zones::TreeZones; @@ -856,7 +859,7 @@ static void create_inspection_string_for_generic_value(const bNodeSocket &socket return; } if (value_type.is()) { - ss << *static_cast(buffer) << " " << TIP_("(String)"); + ss << fmt::format(TIP_("{} (String)"), *static_cast(buffer)); return; } @@ -873,22 +876,22 @@ static void create_inspection_string_for_generic_value(const bNodeSocket &socket BLI_SCOPED_DEFER([&]() { socket_type.destruct(socket_value); }); if (socket_type.is()) { - ss << *static_cast(socket_value) << " " << TIP_("(Integer)"); + ss << fmt::format(TIP_("{} (Integer)"), *static_cast(socket_value)); } else if (socket_type.is()) { - ss << *static_cast(socket_value) << " " << TIP_("(Float)"); + ss << fmt::format(TIP_("{} (Float)"), *static_cast(socket_value)); } else if (socket_type.is()) { - ss << *static_cast(socket_value) << " " << TIP_("(Vector)"); + const blender::float3 &vector = *static_cast(socket_value); + ss << fmt::format(TIP_("({}, {}, {}) (Vector)"), vector.x, vector.y, vector.z); } else if (socket_type.is()) { const blender::ColorGeometry4f &color = *static_cast(socket_value); - ss << "(" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << ") " - << TIP_("(Color)"); + ss << fmt::format(TIP_("({}, {}, {}, {}) (Color)"), color.r, color.g, color.b, color.a); } else if (socket_type.is()) { - ss << ((*static_cast(socket_value)) ? TIP_("True") : TIP_("False")) << " " - << TIP_("(Boolean)"); + ss << fmt::format(TIP_("{} (Boolean)"), + ((*static_cast(socket_value)) ? TIP_("True") : TIP_("False"))); } } diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 445a63be18d..dd1bfdd9c36 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../makesrna ../render ../windowmanager + ../../../extern/fmtlib/include ../../../intern/guardedalloc # dna_type_offsets.h diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index dba08292d0d..384acf71ef6 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -38,6 +38,9 @@ #include "DEG_depsgraph_query.h" +#define FMT_HEADER_ONLY +#include + namespace blender::nodes { using fn::ValueOrField; @@ -315,10 +318,10 @@ class LazyFunctionForGeometryNode : public LazyFunction { { const ValueOrFieldCPPType &value_or_field_cpp_type = *ValueOrFieldCPPType::get_from_self( *outputs_[lf_index].type); - GField output_field{ - std::make_shared(std::move(attribute_id), - value_or_field_cpp_type.value, - node_.label_or_name() + TIP_(" node"))}; + GField output_field{std::make_shared( + std::move(attribute_id), + value_or_field_cpp_type.value, + fmt::format(TIP_("{} node"), node_.label_or_name()))}; void *r_value = params.get_output_data_ptr(lf_index); value_or_field_cpp_type.construct_from_field(r_value, std::move(output_field)); params.output_set(lf_index); @@ -994,9 +997,7 @@ class LazyFunctionForGroupNode : public LazyFunction { std::string name() const override { - std::stringstream ss; - ss << "Group '" << (group_node_.id->name + 2) << "' (" << group_node_.name << ")"; - return ss.str(); + return fmt::format(TIP_("Group '{}' ({})"), group_node_.id->name + 2, group_node_.name); } std::string input_name(const int i) const override @@ -1033,9 +1034,8 @@ class LazyFunctionForGroupNode : public LazyFunction { for (const auto [bsocket_index, lf_socket_index] : lf_output_for_input_bsocket_usage_.items()) { if (i == lf_socket_index) { - std::stringstream ss; - ss << "'" << group_node_.input_socket(bsocket_index).name << "' input is used"; - return ss.str(); + return fmt::format(TIP_("'{}' input is used"), + group_node_.input_socket(bsocket_index).name); } } return outputs_[i].debug_name; -- 2.30.2